java使用ffmpeg进行视频处理

使用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);

        }

        /**
         *获取视频时间
         * @param video_path  视频路径
         * @param ffmpeg_path ffmpeg安装路径
         * @return
         */
        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;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wtong
 * @since 2022-04-13
 */
@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) {

//            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);



    }
    private  void dataEntry(List<String> stringList) {
//        System.out.println(stringList.get(4));
        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());
//        this.saveOrUpdate(course,queryWrapper);
        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());
//        statisticsService.saveOrUpdate(section,sectionQueryWrapper);
        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();
//        String s = dateAdded.toString();
//        Integer sp = Integer.parseInt(s);
//        lesson.setDateAdded(sp);
        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 static void main(String[] args) {
//        String path="F:\\BaiduNetdiskDownload\\mksz355 - 编程必备基础 计算机组成原理+操作系统+计算机网络";
            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);
//
//
//    }

    /**
     *获取视频时间
     * @param video_path  视频路径
     * @param ffmpeg_path ffmpeg安装路径
     * @return
     */
    public  String getVideoTime(String video_path, String ffmpeg_path) {
        //将命令行拼接到list集合中
        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()) {
                List<String > re=replace(video_path);
//                    System.out.println(re.toString());
                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 "";
    }


    /**
     * 字符串分割
     * @param video_path 需要分割的绝对路径
     * @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()) {
//                    System.out.println("文件夹:" + file2.getAbsolutePath());
                    list.add(file2);
                    rnameList.add(file2);
                    folderNum++;
                } else {
//                    System.out.println("文件1:" + file2.getAbsolutePath());
                    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()) {
//                        System.out.println("文件夹:" + file2.getAbsolutePath());
                        list.add(file2);
                        folderNum++;
                    } else {

//                        System.out.println("文件2:" + file2.getAbsolutePath());
                        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("."));
            }
//            System.out.println("视频时长:"+timeLength+"path"+absolutePath);
//            String result = rName(file1);
//            if(!result.equals(NO)){
//                traverseFolder1( path);
//                break;
//
//            }
            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;
    }
}

进行视频批量处理因为视频缺少h264加入h264生成新的文件后缀多.mp4



function recursive_list_dir(){
    for file_or_dir in `ls $1`
    do
        if [ -d $1"/"$file_or_dir ]
        then
            recursive_list_dir $1"/"$file_or_dir
        else
                file=$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
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值