返回列表 发帖

[文件操作] 批处理怎样通过ffmpeg实现将目录下不同片源视频同一帧输出图片对比呢?

本帖最后由 1139054012 于 2025-3-4 23:29 编辑

前提条件目录下视频时轴可能不同,需要根据第一个输出的图片来识别后续视频是否同一帧对比


这个是时轴相同,或前面时轴相同,最后多了几分不影响,输出同一帧视频的图片成功了
预览图
@echo off
setlocal enabledelayedexpansion
:: 设置参数
set "target_time=00:10:00"  :: 指定时间点(格式:HH:MM:SS)
set "output_dir=输出图片"  :: 输出目录
set "tolerance=0"  :: 图片相似度容差(0-1,值越小越严格)
set "scale_width=1920"  :: 输出图片宽度
set "scale_height=1080"  :: 输出图片高度
:: 创建输出目录
if not exist "%output_dir%" mkdir "%output_dir%"
:: 遍历当前目录下的所有视频文件
for %%f in (*.mkv *.mp4 *.avi *.mov) do (
    echo 正在处理文件: %%f
    set "output_file=%output_dir%\%%~nf.png"
    :: 提取指定时间点的帧并缩放
    ffmpeg -i "%%f" -ss %target_time% -vframes 1 -vf scale=%scale_width%:%scale_height% -q:v 2 "!output_file!" -y
    :: 检查图片是否有效
    if not exist "!output_file!" (
        echo 错误:无法提取帧,尝试调整时间轴...
        :: 尝试调整时间轴(向前或向后 1 秒)
        for /L %%i in (1,1,5) do (
            set "adjusted_time=00:10:0%%i"
            ffmpeg -i "%%f" -ss !adjusted_time! -vframes 1 -vf scale=%scale_width%:%scale_height% -q:v 2 "!output_file!" -y
            if exist "!output_file!" (
                echo 成功提取帧,调整时间为: !adjusted_time!
                goto :next_file
            )
        )
        echo 错误:无法提取帧,跳过文件: %%f
        goto :next_file
    )
    :: 对比图片内容(如果存在前一个文件的图片)
    if exist "prev_frame.png" (
        ffmpeg -i "prev_frame.png" -i "!output_file!" -lavfi "ssim=stats_file=ssim_log.txt" -f null -
        for /F "tokens=2 delims= " %%a in ('findstr "All" ssim_log.txt') do (
            set "similarity=%%a"
        )
        echo 图片相似度: !similarity!
        if !similarity! LSS %tolerance% (
            echo 图片不同,尝试调整时间轴...
            :: 尝试调整时间轴(向前或向后 1 秒)
            for /L %%i in (1,1,5) do (
                set "adjusted_time=00:10:0%%i"
                ffmpeg -i "%%f" -ss !adjusted_time! -vframes 1 -vf scale=%scale_width%:%scale_height% -q:v 2 "!output_file!" -y
                if exist "!output_file!" (
                    echo 成功提取帧,调整时间为: !adjusted_time!
                    goto :next_file
                )
            )
            echo 错误:无法提取帧,跳过文件: %%f
            goto :next_file
        )
    )
    :: 保存当前帧为前一个帧
    copy "!output_file!" "prev_frame.png" >nul
    :next_file
    echo ------------------------------
)
:: 清理临时文件
del "prev_frame.png" 2>nul
del "ssim_log.txt" 2>nul
echo 处理完成!所有帧已保存到目录: %output_dir%
pauseCOPY
换成片源时轴不同的后,第二张输出的图片并没有根据输出第一张图片输出相同的图

预览图

求助坛友怎么完美实现这个功能?
而且这段代码占用CPU也太高了,可以优化下不OTL


链接:https://pan.baidu.com/s/1nnfDyy0LqNbrAUcF9BXoXg
提取码:iaa7

把素材上传 不要让大家管中窥豹

TOP

回复 2# smss


  文件有些大,刚才正上传,已发链接在1楼

TOP

弄小一点 描述清楚具体想法 ffmpeg如果能实现 代码就能实现
问题表述不清即问题本身存在问题,DeepSeek是辅助,我们无法通过它的备注来得知揣测你的真实想法

TOP

拍摄视频 发个链接 一目了然 抖音 B站 我们都能去

TOP

本帖最后由 1139054012 于 2025-3-4 22:18 编辑

回复 4# smss


    https://www.bilibili.com/video/B ... e1af06af41b8b452b58

TOP

就是把网上把下的视频还原成原视频吗? 还是说如同一首歌 歌词对不上要调整对上? 依据什么呢

TOP

说了半天最后说是为了判断片源哪个更清晰 你直接扒它源碼 就比较了

TOP

本帖最后由 1139054012 于 2025-3-4 20:19 编辑

回复 7# smss


    对,主要根据指定时轴的第1个视频输出的图来进行后续对比,最后输出图片

TOP

回复 9# 1139054012 一定要比较大小的话可以分别截取一张 比较分辨率就可以

TOP

回复 10# smss


    其实不是比较分辨率,是看压制的效果哪个更好
目前这段代码只能固定时间轴来输出图片,  如果时轴相同,或者只是后面时轴不同的片源也就不影响,但前面时轴不同的话,后面输出的图片就不对应了,现在想知道能否实现这个功能

TOP

简单看了一下你给的代码,应该是要提取出不同视频中相似的图片吧。
不知道你说的“输出失败”是什么意思?如果有调试信息参考更好。
不过我猜应该是调整时间轴那部分有问题,而且如果不同视频的时间轴不同的话调整时间轴、比较图片挺耗时间的。
滤镜操作CPU消耗是挺大的,硬件加速也缓解不了什么,可以试试换其他缩放算法。

TOP

本帖最后由 1139054012 于 2025-3-4 23:15 编辑

回复 12# buyiyang


    是这样的

输出失败指的是
A.mkv 10:00 第一张图输出图片成功
B.mkv 时轴不同,A.MKV的10:00,可能在10:05才是同一帧

现在两个视频都输出了
A.mkv 10:00 图
B.mkv 10:00 图

现在希望获取的图是
A.mkv 10:00 图
B.mkv10:05图


另外那种算法可以缓解CPU压力,提高搜索效率呢?

TOP

@echo off
D:\软件\央视影音\ffmpeg.exe -i D:\视频\终结者5.mp4 -i D:\视频\逐影.mp4 -lavfi ssim -f null -
::D:\软件\央视影音\ffmpeg.exe -i D:\视频\终结者5.mp4 -i D:\视频\逐影.mp4 -lavfi psnr -f null -
pause
1.PSNR(峰值信噪比)输出结果为全视频的平均PSNR值,YUV三通道分别统计。
逐帧分析可添加 stats_file=psnr.log 生成日志文件
2. SSIM(结构相似性)
与PSNR类似,但更贴近人眼感知,需注意某些场景下SSIM可能与主观感受不一致(如暗场色块问题)
通过以上返回信息 足以比较 2个视频哪个好点 同时视频像素 用来比较和判断视频是720P 1080P 4K 8K完全够用
以下是输出信息
ffmpeg version N-111671-gc7ff0c3e4b Copyright (c) 2000-2023 the FFmpeg developers
  built with gcc 13.2.0 (Rev1, Built by MSYS2 project)
  configuration: --prefix=../ffmpeg_build --enable-shared --disable-doc --disable-avdevice --disable-encoders --disable-protocols --enable-protocol=file --enable-protocol=hls --enable-protocol=https --disable-debug --disable-iconv --disable-lzma --disable-zlib
  libavutil      58. 14.100 / 58. 14.100
  libavcodec     60. 22.100 / 60. 22.100
  libavformat    60. 10.100 / 60. 10.100
  libavfilter     9. 10.100 /  9. 10.100
  libswscale      7.  3.100 /  7.  3.100
  libswresample   4. 11.100 /  4. 11.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'D:\视频\终结者5.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.83.100
  Duration: 02:05:43.08, start: 0.000000, bitrate: 1300 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/unknown/unknown, progressive), 1920x804 [SAR 1:1 DAR 160:67], 1167 kb/s, 25 fps, 25 tbr, 12800 tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'D:\视频\逐影.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf58.45.100
  Duration: 00:05:37.72, start: 0.000000, bitrate: 68734 kb/s
  Stream #1:0[0x1](eng): Video: vp9 (Profile 0) (vp09 / 0x39307076), yuv420p(tv, bt709/unknown/unknown), 7680x4320, 68598 kb/s, SAR 1:1 DAR 16:9, 59.94 fps, 59.94 tbr, 16k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #1:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
[vost#0:0 @ 00000218a6fa1740] Automatic encoder selection failed Default encoder for format null (codec wrapped_avframe) is probably disabled. Please choose an encoder manually.
[vost#0:0 @ 00000218a6fa1740] Error selecting an encoder
Error opening output file -.
Error opening output files: Encoder not found COPY

TOP

仔细看了下你的代码,
逻辑方面,图片相似度的比较的两个字符串类型和格式不同,无法正确比较,tolerance变量要适应similarity
尤其调整时间轴部分的代码逻辑完全错误,需要重构,建议不同的功能使用call标签的方法解耦
语法方面,循环中使用goto会直接跳出循环,不会进入下一个循环。
效率方面,可以改用bilinear算法试试。

TOP

返回列表