java检验mp4文件完整性的一个方法:使用ffmpeg

问题引入

最近笔者在写一个多线程下载视频文件的程序,打算让这个程序在我的空闲服务器上运行,但是几轮测试之后发现,有时候会存在下载的视频文件不完整的情况,这就导致了有些文件无法正常播放

问题排查

经过一周的排查后,排除了多线程下载代码部分的问题,已经确定是对方的资源服务器有时会抽风,导致获取到的数据并不是正确的数据,所以就导致了视频文件中部分内容错误,所以解决方法也很简单,就是在文件下载完成后,对文件完整性进行检验,如果文件无法正常播放就重新下载

mp4完整性检验

笔者在网上找了很久的方法,最终找到最有效的方法就是使用ffmpeg这个工具来帮助我们完成视频完整性的检验
参考这篇文章,使用指令
ffmpeg -i your_file.mp4 -v error -map 0:1 -f null -
如果有输出,就说明文件有错误,否则文件就是完整的

安装ffmpeg

首先需要在服务器上安装ffmpeg
在 https://johnvansickle.com/ffmpeg/ 链接中找到linux版本的ffmpeg编译完成的包
使用wget下载到服务器上
wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz
再通过tar命令解压
tar -xvf ffmpeg-release-amd64-static.tar.xz
把文件复制到/opt目录下
mv ffmpeg-release-amd64-static /opt/
最后添加PATH环境变量,用vim打开/etc/profile,添加如下内容
export PATH=$PATH:/opt/ffmpeg-5.1.1-amd64-static/
再在控制台中执行一次这条指令,使得PATH环境变量的更改立刻生效
最后测试一下,输入
ffmpeg
有输出
java检验mp4文件完整性的一个方法:使用ffmpeg_第1张图片
说明安装成功

java实现

java实现就是简单的使用Runtime来执行linux指令即可
但要注意,有一个坑,就是当文件路径有空格时,就只能使用String数组的方式来调用Runtime的exec
这里为了普适性,就采用String数组的方式来调用exec
具体代码如下

public static boolean checkMP4L2(String filePath){
        String[] cmd={"ffmpeg","-v","error","-i",filePath,"-map","0:1","-f","null","-"};
        //下面注释了的这一行,在绝对路径中包含空格时会导致检测失败,会提示文件不存在
//        String command="ffmpeg -v error -i "+filePath.replaceAll(" ","\" \"")+" -map 0:1 -f null -";
        try {
            Process process=Runtime.getRuntime().exec(cmd);
            InputStream is=process.getErrorStream();
            BufferedReader br=new BufferedReader(new InputStreamReader(is));

            String line=br.readLine();
            if(line==null)
                return true;
            log.trace("L2 check error message "+line+"  (for "+filePath+")");
            return false;
        }catch (Exception e){
            log.error("Failed to do l2 check for "+filePath,e);
            return false;
        }
    }

你可能感兴趣的:(瞎捣鼓,ffmpeg,java,开发语言,mp4检验)