使用FFmpeg进行视频解析上传视频数据
package com.greathiit.videoupload.ffmpeg;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class VideoFFmpeg {
public static void main(String[] args) {
String path="E:\\视频批量上传项目\\视频";
String timeLength = getVideoTime("E:\\视频批量上传项目\\视频\\aa.mp4","D:\\learn\\FFmpeg\\ffmpeg-N-102841-g041267b558-win64-lgpl-shared\\bin\\ffmpeg.exe");
if(timeLength.length()>0){
timeLength =timeLength.substring(0,timeLength.indexOf("."));
}
System.out.println("视频时长:"+timeLength);
traverseFolder1(path);
}
public static String getVideoTime(String video_path, String ffmpeg_path) {
List<String> commands = new java.util.ArrayList<String>();
commands.add(ffmpeg_path);
commands.add("-i");
commands.add(video_path);
System.out.println("命令行:"+ffmpeg_path+" -i "+video_path);
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commands);
final Process p = builder.start();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
Pattern pattern = Pattern.compile(regexDuration);
Matcher m = pattern.matcher(sb.toString());
if (m.find()) {
System.out.println(video_path+",视频时长:"+m.group(1)+", 开始时间:"+m.group(2)+",比特率:"+m.group(3)+"kb/s");
return m.group(1);
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static void traverseFolder1(String path) {
int fileNum = 0, folderNum = 0;
File file = new File(path);
if (file.exists()) {
LinkedList<File> list = new LinkedList<File>();
File[] files = file.listFiles();
for (File file2 : files) {
if (file2.isDirectory()) {
System.out.println("文件夹:" + file2.getAbsolutePath());
list.add(file2);
folderNum++;
} else {
System.out.println("文件:" + file2.getAbsolutePath());
fileNum++;
}
}
File temp_file;
while (!list.isEmpty()) {
temp_file = list.removeFirst();
files = temp_file.listFiles();
for (File file2 : files) {
if (file2.isDirectory()) {
System.out.println("文件夹:" + file2.getAbsolutePath());
list.add(file2);
folderNum++;
} else {
System.out.println("文件:" + file2.getAbsolutePath());
fileNum++;
}
}
}
} else {
System.out.println("文件不存在!");
}
System.out.println("文件夹共有:" + folderNum + ",文件共有:" + fileNum);
}
}
使用ffmpeg来获取文件的时长
https://www.cnblogs.com/firstdream/p/7676732.html : 遍历文件夹中的目录和文件
https://www.jb51.net/article/122711.htm :文件名称修改
遇到问题: 在视频修改的时候由于遍历文件目录和文件名称的时候A层目录修改了到遍历A下一层目录或者文件的时候由于保存在List集合中的绝对路径并没有发生变化就会出现文件找不到的问题。例如:
第一次修改的目录:F:\BaiduNetdiskDownload\mksz355 - 编程必备基础 计算机组成原理+操作系统+计算机网络(更多IT教程 微信352852792)==》F:\BaiduNetdiskDownload\mksz355 - 编程必备基础 计算机组成原理+操作系统+计算机网络
第遍历下一层目录:F:\BaiduNetdiskDownload\mksz355 - 编程必备基础 计算机组成原理+操作系统+计算机网络**(更多IT教程 微信352852792)**\第1章 编程必备基础:计算机组成原理、操作系统、计算机网络(更多IT教程 微信352852792) 此时加黑部分文字已经被第一次修改这时如果执行文件修改就会出现文件找不到的异常
解决办法: 使用回调函数当第一次进行修改后跳出循环重新遍历保存到List集合中如果上一次没有做修改则继续循环
具体逻辑代码如下:
package com.greathiit.videoupload.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.greathiit.videoupload.entity.Course;
import com.greathiit.videoupload.entity.Lesson;
import com.greathiit.videoupload.entity.Section;
import com.greathiit.videoupload.mapper.CourseMapper;
import com.greathiit.videoupload.service.ICourseService;
import com.greathiit.videoupload.service.ILessonService;
import com.greathiit.videoupload.service.ISectionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {
private String NO="no";
@Autowired
private ILessonService lessonService;
@Autowired
private ISectionService statisticsService;
@Override
public void saveCourse(String path) {
traverseFolder1(path);
}
private void dataEntry(List<String> stringList) {
System.out.println(stringList);
Course course = new Course();
course.setTitle(stringList.get(0));
course.setDescription("<p>"+stringList.get(0)+"<br>></p>");
course.setLanguage("chinese");
course.setCategoryId(4);
course.setSubCategoryId(3);
course.setSection("[]");
course.setRequirements("[]");
course.setLevel("beginner");
course.setUserId(85);
course.setDateAdded(1623999600);
course.setIsAdmin(0);
course.setStatus("active");
course.setMetaKeywords(stringList.get(0));
course.setIsFreeCourse(1);
QueryWrapper<Course> queryWrapper=new QueryWrapper<>();
queryWrapper.lambda().eq(Course::getTitle,course.getTitle());
Section section=new Section();
section.setTitle(stringList.get(1));
section.setCourseId(417);
try {
section.setOrder(Integer.parseInt(section.getTitle().substring(1,3)));
}catch (NumberFormatException e){
section.setOrder(Integer.parseInt(section.getTitle().substring(1,2)));
}
QueryWrapper<Section> sectionQueryWrapper=new QueryWrapper<>();
sectionQueryWrapper.lambda().eq(Section::getTitle,section.getTitle());
Lesson lesson = new Lesson();
lesson.setTitle(stringList.get(2));
lesson.setDuration(stringList.get(3));
lesson.setVideoUrl(stringList.get(6).replace("F:\\BaiduNetdiskDownload",""));
lesson.setVideoUrlForMobileApplication(stringList.get(6).replace("F:\\BaiduNetdiskDownload",""));
Long dateAdded = System.currentTimeMillis();
lesson.setLessonType("video");
lesson.setAttachmentType("url");
try {
lesson.setOrder(Integer.parseInt(lesson.getTitle().substring(2,4)));
}catch (NumberFormatException e){
lesson.setOrder(Integer.parseInt(lesson.getTitle().substring(2,3)));
}
lesson.setVideoType("Vimeo");
lesson.setVideoTypeForMobileApplication("html5");
Course one = this.getOne(queryWrapper);
lesson.setCourseId(one.getId());
Section one1 = statisticsService.getOne(sectionQueryWrapper);
lesson.setSectionId(one1.getId());
lesson.setVideoTypeForMobileApplication(stringList.get(6).replace("F:\\BaiduNetdiskDownload",""));
QueryWrapper<Lesson> queryWrapperlqueryWrap=new QueryWrapper<>();
queryWrapperlqueryWrap.lambda().eq(Lesson::getTitle,lesson.getTitle());
lessonService.saveOrUpdate(lesson,queryWrapperlqueryWrap);
System.out.println(lesson.toString());
}
public String getVideoTime(String video_path, String ffmpeg_path) {
List<String> commands = new java.util.ArrayList<String>();
commands.add(ffmpeg_path);
commands.add("-i");
commands.add(video_path);
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commands);
final Process p = builder.start();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
String regexDuration = "Duration: (.*?), start: (.*?), bitrate: (\\d*) kb\\/s";
Pattern pattern = Pattern.compile(regexDuration);
Matcher m = pattern.matcher(sb.toString());
if (m.find()) {
List<String > re=replace(video_path);
System.out.println(video_path+",视频时长:"+m.group(1)+", 开始时间:"+m.group(2)+",比特率:"+m.group(3)+"kb/s" );
re.add(m.group(1));
re.add(m.group(2));
re.add(m.group(3));
re.add(video_path);
dataEntry(re);
return m.group(1);
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
private List<String> replace(String video_path) {
String replace = video_path.replace("F:\\BaiduNetdiskDownload\\mksz355 - ", "");
Character a=92;
String am=a.toString();
System.out.println(replace);
System.out.println("");
String[] split1 = replace.split("\\\\");
int ac=split1.length;
System.out.println(ac);
String course = split1[0];
String chapter = split1[1];
String blues = split1[2];
String[] split2 = blues.split("\\.");
blues = split2[0];
List<String> list=new ArrayList<>();
list.add(course);
list.add(chapter);
list.add(blues);
return list;
}
public void traverseFolder1(String path) {
int fileNum = 0, folderNum = 0;
File file = new File(path);
LinkedList<File> rnameList = new LinkedList<>();
if (file.exists()) {
LinkedList<File> list = new LinkedList<File>();
File[] files = file.listFiles();
for (File file2 : files) {
if (file2.isDirectory()) {
list.add(file2);
rnameList.add(file2);
folderNum++;
} else {
rnameList.add(file2);
fileNum++;
}
}
File temp_file;
while (!list.isEmpty()) {
temp_file = list.removeFirst();
files = temp_file.listFiles();
for (File file2 : files) {
rnameList.add(file2);
if (file2.isDirectory()) {
list.add(file2);
folderNum++;
} else {
fileNum++;
}
}
}
} else {
System.out.println("文件不存在!");
}
System.out.println("文件夹共有:" + folderNum + ",文件共有:" + fileNum);
int msize = 0;
for (File file1 : rnameList) {
String absolutePath = file1.getAbsolutePath();
String timeLength = getVideoTime(absolutePath,"D:\\learn\\FFmpeg\\ffmpeg-N-102841-g041267b558-win64-lgpl-shared\\bin\\ffmpeg.exe");
if(timeLength.length()>0){
timeLength =timeLength.substring(0,timeLength.indexOf("."));
}
msize++;
}
}
private String rName(File file2) {
String absolutePath = file2.getAbsolutePath();
String[] split = absolutePath.split(File.pathSeparator);
String s = split[split.length - 1];
String replace = s.replace("(更多IT教程 微信352852792)", "");
if(s.equals(replace)){
return NO;
}
File file1 = new File(replace);
if(file2.renameTo(file1)){
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
return replace;
}
}
数据录入成功后的效果
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eE1EckoD-1650615602204)(C:\Users\29701\AppData\Roaming\Typora\typora-user-images\1649984062864.png)]
最后还有一个就是前期构建项目的时候遇到的小问题:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qadBEruP-1650615602206)(C:\Users\29701\AppData\Roaming\Typora\typora-user-images\1649984159309.png)]
mapper路径和上边的mapper路径冲突,spring容器前期构建的时候找不到mapper包下的bean解决办法修改为maqqer
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i1d20n1P-1650615602206)(C:\Users\29701\AppData\Roaming\Typora\typora-user-images\1649984317865.png)]
lace); if(file2.renameTo(file1)){ System.out.println(“修改成功”); }else { System.out.println(“修改失败”); } return replace; } }
数据录入成功后的效果
[外链图片转存中...(img-eE1EckoD-1650615602204)]
最后还有一个就是前期构建项目的时候遇到的小问题:
[外链图片转存中...(img-qadBEruP-1650615602206)]
mapper路径和上边的mapper路径冲突,spring容器前期构建的时候找不到mapper包下的bean解决办法修改为maqqer
[外链图片转存中...(img-i1d20n1P-1650615602206)]
mysql关键字加``解决
进行视频批量处理因为视频缺少h264加入h264生成新的文件后缀多.mp4
function recursive_list_dir(){ for file_or_dir in ls $1 do if [ -d
1
"
/
"
1"/"
1"/"file_or_dir ] then recursive_list_dir
1
"
/
"
1"/"
1"/"file_or_dir else file=
1
"
/
"
1"/"
1"/"file_or_dir
if [ "${file##*.}" = "mp4" ]
then
aa="${file##*/}"
if [ "${aa##*.}" = "mp4.mp4" ]
then
echo "ii"
else
docker run -it --name app_ffmpeg -v $PWD:/tmp/workdir jrottenberg/ffmpeg -i ${file:3} -vcodec h264 ${file:3}.mp4
docker rm -f app_ffmpeg
fi
fi
fi
done
} recursive_list_dir $1
|