用python比较两个mp4是否实质相同

下面这个脚本会使用 ffmpeg 和 ffprobe 检查两个视频文件在以下方面是否"实质相同":


✅ 检查内容:

  1. 分辨率(宽高)
  2. 帧率
  3. 视频总帧数
  4. 音频轨道数量和采样率
  5. 视频时长
  6. 视频帧哈希(可选) --- 对比前 N 帧的图像感知哈希,判断是否完全一致(更精确)

🧰 脚本需求:

确保已安装:

bash 复制代码
sudo apt install ffmpeg
pip install imagehash Pillow

🐍 Python 脚本如下:

python 复制代码
import subprocess
import json
import imagehash
from PIL import Image
import os

def ffprobe_info(path):
    cmd = [
        'ffprobe', '-v', 'error', '-show_entries',
        'format=duration', '-show_streams',
        '-of', 'json', path
    ]
    output = subprocess.check_output(cmd)
    return json.loads(output)

def extract_frame(path, frame_num, output_path):
    cmd = [
        'ffmpeg', '-y', '-i', path,
        '-vf', f'select=eq(n\,{frame_num})',
        '-vframes', '1', output_path
    ]
    subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

def compare_hashes(file1, file2, frames_to_check=5):
    for i in range(frames_to_check):
        extract_frame(file1, i * 10, 'frame1.jpg')
        extract_frame(file2, i * 10, 'frame2.jpg')
        try:
            h1 = imagehash.average_hash(Image.open('frame1.jpg'))
            h2 = imagehash.average_hash(Image.open('frame2.jpg'))
            if h1 != h2:
                print(f"[❌] Frame {i*10} differs: {h1} vs {h2}")
                return False
        except Exception as e:
            print(f"[⚠️] Error comparing frame {i*10}: {e}")
            return False
    print("[✅] Frame hashes match.")
    return True

def compare_videos(src, dst):
    info1 = ffprobe_info(src)
    info2 = ffprobe_info(dst)

    def get_val(info, stream_type, key):
        for stream in info['streams']:
            if stream['codec_type'] == stream_type:
                return stream.get(key)
        return None

    comparisons = [
        ('Resolution', f"{get_val(info1, 'video', 'width')}x{get_val(info1, 'video', 'height')}",
         f"{get_val(info2, 'video', 'width')}x{get_val(info2, 'video', 'height')}"),
        ('Frame rate', get_val(info1, 'video', 'r_frame_rate'),
         get_val(info2, 'video', 'r_frame_rate')),
        ('Audio rate', get_val(info1, 'audio', 'sample_rate'),
         get_val(info2, 'audio', 'sample_rate')),
        ('Duration (s)', round(float(info1['format']['duration']), 2),
         round(float(info2['format']['duration']), 2)),
    ]

    all_match = True
    for name, val1, val2 in comparisons:
        match = "✅" if val1 == val2 else "❌"
        print(f"[{match}] {name}: {val1} vs {val2}")
        if val1 != val2:
            all_match = False

    print("\n🔍 Checking frame visual hashes (first few frames)...")
    if not compare_hashes(src, dst):
        all_match = False

    if all_match:
        print("\n🎉 视频文件在核心内容上完全一致")
    else:
        print("\n⚠️ 视频存在差异")

    # 清理临时文件
    os.remove('frame1.jpg') if os.path.exists('frame1.jpg') else None
    os.remove('frame2.jpg') if os.path.exists('frame2.jpg') else None

# 使用示例
compare_videos("yanhuorenjia_12_src.mp4", "yanhuorenjia_12_dst.mp4")

💡 说明:

  • 它会提取每个视频的前 5 帧(间隔取)做图像哈希对比,适合检查是否重新编码或压缩。
  • 如果帧、音频、时长、分辨率都一样且图像一致,那可以认为视频实质相同。
  • 支持大视频,速度也不错。
相关推荐
第九序言T8 小时前
Python 数据处理进阶(十八)批量处理同结构文件:一个文件夹一次跑完
开发语言·python·自动化·pandas·数据处理
Java后端的Ai之路8 小时前
CAS并发控制-从CPU指令到企业级乐观锁
vue.js·人工智能·python·cas·乐观锁
qq_426003968 小时前
UI自动化高频次登录login限流解决方案
python·ui·自动化
Sakura_j_h_9 小时前
EasyEDA PCB 快速设计Skills
c++·python·github
龙亘川9 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
程序喵大人9 小时前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
quantdash_cc10 小时前
如何验证历史行情的交易日期是否完整覆盖研究区间?
python·数据分析·pandas·量化交易·股票数据·quantdash
I Am a robert girl10 小时前
当智能体学会“串通”:从长程交互中读懂涌现式合谋
python·多智能体系统·多智能体协作·llm agent·涌现式合谋·对齐问题·激励机制设计
Raas10010 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
小豆庄10 小时前
视频敏感信息脱敏:本地推理与云端API的工程取舍
阿里云·ai·视频·纹理贴图