如何在给定时间使用 ffmpeg 为视频提取 1 个屏幕截图?
Posted
技术标签:
【中文标题】如何在给定时间使用 ffmpeg 为视频提取 1 个屏幕截图?【英文标题】:How to extract 1 screenshot for a video with ffmpeg at a given time? 【发布时间】:2015-02-18 12:28:23 【问题描述】:有许多教程和资料展示了如何使用 ffmpeg 从视频中提取多个屏幕截图。你设置-r,你甚至可以启动一定数量。
但我只想要 1 个屏幕截图,比如 01:23:45 英寸。或者 1 个 86% 英寸的屏幕截图。
ffmpegthumbnailer 可以实现这一切,但这是我不想依赖的另一个依赖项。我希望能够用 ffmpeg 做到这一点。
【问题讨论】:
【参考方案1】:使用-ss
选项:
ffmpeg -ss 01:23:45 -i input -frames:v 1 -q:v 2 output.jpg
对于 JPEG 输出,使用 -q:v
来控制输出质量。全范围是 1-31 的线性刻度,值越低,质量越高。 2-5 是一个不错的尝试范围。
select filter 为更复杂的需求提供了一种替代方法,例如仅选择某些帧类型,或每 100 个帧类型 1 个等。
在输入之前放置-ss
会更快。请参阅FFmpeg Wiki: Seeking 和ffmpeg
cli tool documentation 的这段摘录:
-ss
位置(输入/输出)当用作输入选项时(
-i
之前),在此输入文件中查找位置。请注意,在大多数格式中,无法搜索 确切地说,所以ffmpeg
将寻找之前最近的寻找点 位置。启用转码和-accurate_seek
时( 默认),搜索点和位置之间的这个额外段将 被解码并丢弃。进行流复制时或-noaccurate_seek
被使用,它将被保留。当用作输出选项时(在输出文件名之前),解码但丢弃输入,直到时间戳到达位置。
位置可以是秒或
hh:mm:ss[.xxx]
形式。
【讨论】:
这要快得多。太感谢了。将 -ss 放在首位会产生巨大的影响。 有什么办法可以得到指定时间后的第n帧? @GuntherPiez 我没有看到任何关于可能的工件的提及。 请注意,vframes
在(至少)版本 4.2.2 中已过时。根据手册“[vframes
] 是 '-frames:v
' 的过时别名,您应该改用它。”
完美快速运行。【参考方案2】:
FFMpeg 可以通过寻找给定的时间戳并准确提取一帧作为图像来做到这一点,例如:
ffmpeg -i input_file.mp4 -ss 01:23:45 -vframes 1 output.jpg
让我们解释一下选项:
-i input file the path to the input file
-ss 01:23:45 seek the position to the specified timestamp
-vframes 1 only handle one video frame
output.jpg output filename, should have a well-known extension
-ss
参数接受HH:MM:SS[.xxx]
形式的值或以秒为单位的数字。如果需要百分比,则需要事先计算视频时长。
【讨论】:
似乎按预期工作。我目前正在测试这是否与使用 ffmpegthumbnailer 的速度相同。 是的,这种方法超级慢。见peterbe.com/plog/fastest-way-to-take-screencaps-out-of-videos 尝试在 -i 之前使用 -ss 选项,因为它会跳过管道的解码部分。这可能会加快进程。 有没有办法以 PNG 格式输出到流而不是文件? @NickeManarin 是的..ffmpeg -ss 01:23:45 -i video.mp4 -c:v png -frames:v 1 image.jpg
。请注意,正如其他人所推荐的那样,我还将-ss
“seek”选项放在命令行上的输入文件中。以上是关于如何在给定时间使用 ffmpeg 为视频提取 1 个屏幕截图?的主要内容,如果未能解决你的问题,请参考以下文章