我有许多视频文件(flv/mp4),它们在播放中途改变分辨率(720p/1080p/640)。
我想使用类似 ffmpeg 的东西来自动检测分辨率的变化并将视频分成各自的场景,保持其现有的编码质量:无需重新编码的片段(Video1-scene1.flv,Video1-scene2.flv 等)。
我找到了各种方法来分割静音、场景变化、黑色场景,但没有像改变分辨率宽度这样简单的方法。
这些文件经常导致视频编辑器/修剪器崩溃,如果我只是将整个视频转换为 1080p,手动识别和删除低分辨率场景非常耗时。
该算法可能很简单,只需将当前帧与前一帧进行比较,如果它们的分辨率不同,则分割视频并开始新的片段。
有人可以帮忙吗?
示例文件(temporarily available)
: 示例.flv
以下是一些相关答案:
使用 FFmpeg 从视频文件中剪切部分从开始位置到结束位置
https://stackoverflow.com/questions/36074224/how-to-split-video-or-audio-by-silent-parts
在黑帧(场景变化)处自动将较大的 .mov 视频文件分割为较小的文件?
其他资源:
使用 Lord Neckbeard 的解决方案,我附上了最终在 Windows10 上运行的(不幸的是,非常手动)过程。也许它可以引发有关 ffmpeg 的其他想法。
(我为任何足够专业的人士发布了一个单独的问题:使这个过程自动化...)
将视频拖到包含以下内容的批处理文件中:
ffprobe -v 错误 -show_entries 帧=pkt_pts_time,宽度,高度 -select_streams v -of csv=p=0 %1 > allkeyframes.txt
(allkeyframes.txt 示例...)
13.652000,640,480
13.755000,640,480
13.597000,480,360
13.652000,480,360
将此文本粘贴到 POWERSHELL 中:
$o=""
$n=0
foreach($line in (Get-Content allkeyframes.txt)){
$nline = $line.Split(",")
$nline2=($nline[1]+$nline[2])
if ($nline2 -ne $preventry) {
$n0=$nline[0]
$o="$o,$n0"
$n=$n0
}
$preventry = $nline2
}
if ($o.length -gt 1){
echo $o.Remove(0,1) > resolutionchanges.txt
} else {
Write-Host "No resolution changes found" -ForegroundColor Red
}
(分辨率变化.txt:)
13.597000,25.618000,33.628000,45.598000
粘贴resolutionchanges.txt的内容并将“input.flv”更改为视频名称后,在命令窗口中输入以下内容(Win10拒绝我对此进行批处理的尝试):
ffmpeg -i 输入.flv -map 0 -c 复制 -segment_times 13.597000,25.618000,33.628000,45.598000 -reset_timestamps 1 -f 片段输出_%03d.flv
答案1
Lazyman 的解决方案是使用缩放过滤器以使每个输入符合所需的宽度 x 高度。
对于您提出的解决方案,您可以使用它ffprobe
来确定何时发生尺寸变化。
ffprobe -v error -show_entries frame=pkt_pts_time,width,height -select_streams v -of csv=p=0 input.flv
宽度和高度变化期间的示例输出摘录(key_frame、pkt_pts_time、width、height):
0,89.081000,480,640
0,89.281000,480,640
0,89.481000,480,640
1,89.568000,640,480
0,89.592000,640,480
0,89.632000,640,480
1,97.749000,480,640
尺寸变化可能会发生在关键帧上,如果需要流复制,则可以在此处进行剪切。如果您只想要关键帧,请添加该-skip_frame nokey
选项。
然后使用段复用器:
ffmpeg -i input.flv -map 0 -c copy -segment_times 89.568,97.749 -reset_timestamps 1 -f segment output_%03d.flv