IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> java使用ffmpeg进行视频处理 -> 正文阅读

[移动开发]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;
    }
}

数据录入成功后的效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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



  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-04-24 09:34:21  更:2022-04-24 09:35:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 0:03:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码