一种快速检测Mp4是否损坏的方法

一种快速检测Mp4是否损坏的方法

由于项目上的需求,需要一种能快速检测MP4文件是否有效(即能正常播放)的方法。

网络上搜索到的绝大多数方案是使用ffmpeg或者ffprobe。以ffprobe为例:

ffprobe -v quiet -print_format json -show_format -show_streams -i '/root/**/test.mp4'

如果能查询到类似于下图的video信息,表示该MP4文件是可以正常播放的

ffprobe方案在绝大多数情况下都是正确的,但是在实际项目使用上,有时候莫名会检测不到上图的流结果。(即针对一个有效的MP4文件,有0.1%的可能会出现检测不到流信息。)

为了绝对的准确性,所以需要寻找另外一种方法进行再次检测。

网上找了一圈,发现了这个专利:https://patents.google.com/patent/CN104486614A/nl

该专利的核心思想是读取MP4文件里每个box的大小,然后相加起来。最终和文件的原始大小进行比较,如果相等,那么认为这个MP4文件是未损坏的

MP4文件格式我参考了这篇博文:https://www.cnblogs.com/chyingp/p/mp4-file-format.html

最终形成了下面这个检测方法:

package com.soyuan.mh.srs.util;

import java.io.*;
import java.nio.ByteBuffer;

public class Mp4Checker {

    public static boolean check(String filePath) {
        long total = 0;
        try (InputStream is = new FileInputStream(filePath)) {
            long realSize = new File(filePath).length();

            boolean readLarge = false;
            long size;
            byte[] buff = new byte[8];
            while (is.read(buff,0,buff.length) != -1) {
                ByteBuffer wrap = ByteBuffer.wrap(buff);
                if (readLarge) {
                    size = wrap.getLong();
                }else {
                    size = Integer.toUnsignedLong(wrap.getInt());
                }

                if (size == 0) {
                    break;
                }
                if (size == 1) {
                    //读取largeSize
                    readLarge = true;
                }else {
                    total += size;
                    long skip;
                    if (readLarge) {
                        skip = size - 16;//跳过size + type + largeSize
                    }else {
                        skip = size - 8;
                    }
                    if (skip > 0) {
                        is.skip(skip);
                    }
                    readLarge = false;
                }
            }
            return realSize==total?true:false;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}

测试结果:

20220308141023.mp4 合法: true
20220308141541.mp4 合法: false
20220308141120.mp4 合法: true
20220308141310.mp4 合法: true
20220308141502.mp4 合法: true
20220308141405.mp4 合法: true
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值