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

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


✅ 检查内容:

  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 帧(间隔取)做图像哈希对比,适合检查是否重新编码或压缩。
  • 如果帧、音频、时长、分辨率都一样且图像一致,那可以认为视频实质相同。
  • 支持大视频,速度也不错。
相关推荐
zhifanxu8 分钟前
Android开发常用Kotlin高级语法
android·开发语言·kotlin
困惑阿三9 分钟前
解决 iTerm2 中 nvm 不生效的问题(Mac 环境)
开发语言·前端·macos·bash
hongjianMa29 分钟前
【论文阅读】User Diverse Preference Modeling by Multimodal Attentive Metric Learning
论文阅读·python·推荐系统·多模态推荐
一切顺势而行34 分钟前
rabbitmq 使用过程中遇到的问题
java·开发语言·jenkins
乖乖der38 分钟前
python同步mysql数据
开发语言·python·mysql
woho7788991 小时前
伊吖学C笔记(4、循环、自定义函数、二级菜单)
c语言·开发语言·笔记
编码小笨猪1 小时前
[ Qt ] | QPushButton常见用法
开发语言·qt
L下自成蹊L1 小时前
4. Qt对话框(2)
开发语言·qt·对话框·登录对话框
向宇it1 小时前
【unity游戏开发——编辑器扩展】EditorApplication公共类处理编辑器生命周期事件、播放模式控制以及各种编辑器状态查询
开发语言·ui·unity·编辑器·游戏引擎
渐消散2 小时前
人工智障玩游戏
python