使用 FFMPEG 从开头到关键帧进行截断

使用 FFMPEG 从开头到关键帧进行截断

如何从视频开头到下一个关键帧之间剪切一段视频?我知道这个-ss选项

ffmpeg -y -noaccurate_seek -ss 00:00:30 -i "%%~ni.mp4" -avoid_negative_ts make_zero -acodec copy -vcodec copy "%%~ni_cut.mp4"

但使用它我应该知道下一个关键帧的大致位置。

更新以使事情更清楚:

我不需要视频的开头。我需要的是整个视频,而不是开头的这一小段。

更新 2:

好的。我需要做更多评论。请忽略这 30 秒。我想丢弃从关键帧 0(位置:距开始 0 秒)到关键帧 1 的片段。

答案1

部分选项旨在通过关键帧剪切视频。

下列邮政展示如何将文件分割成多个片段。
我以为添加-segment_list_size 1会创建一个片段,但不起作用……(该选项仅适用于列表文件)。

我最终使用批处理文件提出了一个临时解决方案。
建议的解决方案的概念是:

  • 将 FFmpeg 作为后台进程启动。
  • 在创建第二个段文件后终止该进程。
  • 删除多余的输出文件。

我知道实现的批处理文件不够好(我对批处理文件的了解太基础了)。


首先创建一个示例合成视频(带音频)文件进行测试:

ffmpeg -y -f lavfi -i testsrc=size=192x108:rate=1 -f lavfi -i sine=frequency=400 -f lavfi -i sine=frequency=1000 -filter_complex "[1:a][2:a]amix=inputs=2" -vcodec libx264 -g 10 -crf 17 -pix_fmt yuv420p -acodec aac -ar 22050 -t 500 in.mp4
  • rate=1将帧速率设置为 1Hz(用于测试目的)。
  • -g 10每 10 帧应用一次关键帧(用于测试目的)。

这是批处理文件:

if exist out01.mp4 del out01.mp4

:: 'Start FFmpeg process at the background
start ffmpeg -y -noaccurate_seek -ss 00:00:30 -i in.mp4 -c copy -f segment -reset_timestamps 1 -segment_list_size 1 out%%02d.mp4

:START

:: 'Break the loop only when the second file (out01.mp4) is created.
if not exist out01.mp4 goto START

:: 'Terminate FFmpeg process (there is going to be an issue when there is more than one FFmpeg process).
taskkill /F /IM ffmpeg.exe

:: 'Delete the redundant output files (may use a for loop or file pattern). Be carful not to delete out00.mp4
del out01.mp4
if exist out02.mp4 del out02.mp4
if exist out03.mp4 del out03.mp4
if exist out04.mp4 del out04.mp4
if exist out05.mp4 del out05.mp4
if exist out06.mp4 del out06.mp4
if exist out07.mp4 del out07.mp4
if exist out08.mp4 del out08.mp4
if exist out09.mp4 del out09.mp4
if exist out10.mp4 del out10.mp4

输出文件为out00.mp4(来自合成视频的 10 帧)。


更新:

切掉开头,保留其余部分 - 保留尾部:

您可以应用以下阶段:

  • 对文件进行分段并创建列表:

     ffmpeg -y -i in.mp4 -c copy -f segment -reset_timestamps 1 -segment_list list.txt -segment_list_type ffconcat out%04d.mp4
    
  • 删除第二行list.txt(我不知道如何使用批处理文件执行此操作)。
    或者,删除第一个文件,并echo在循环中使用命令(%%a在批处理文件和%a控制台中使用):

     del out0000.mp4
     echo ffconcat version 1.0 > list.txt
     for %%a in (out????.mp4) do echo file %%a >> list.txt
    
  • 应用 concat 解复用器连接各段:

     ffmpeg -y -f concat -safe 0 -i list.txt -c copy out.mp4
    

在上面的例子中out.mp4从第二帧开始10(第 0 帧是关键帧,第 10 帧是下一个关键帧)。

相关内容