使用ffmpeg/mencoder/transcode等工具转储视频文件的最后一帧。

18
我想要提取视频(.mpg.avi或其他格式)中的最后一帧并将其转储到图像文件(.jpg.png或其他格式)中。使用的工具链是现代Linux 命令行,例如mencodertranscodeffmpeg&c.

祝好, 鲍勃。

5个回答

24

这不是一个完整的解决方案,但它将指引你走上正确的道路。

使用 ffprobe -show_streams IN.AVI 来获取视频输入中帧数的数量。然后

ffmpeg -i IN.AVI -vf "select='eq(n,LAST_FRAME_INDEX)'" -vframes 1 LAST_FRAME.PNG

当LAST_FRAME_INDEX是帧数减1时(帧从0开始编号),将输出最后一帧。


谢谢。真的帮了我很大的忙。我完全照着你的命令复制了,没有做任何更改。 - Dimitris Stefanidis
5
我用这些指令创建了一个 shell 脚本。 https://gist.github.com/NelsonMinar/b00693feecc3b6673e36 - Nelson
这难道不会解码所有帧,而寻求使用关键帧跳过大量视频吗? - Guig

4
我有一个mp4 / h264的 matroska 输入视频文件。但以上解决方案都对我无效。(虽然我确定它们适用于其他文件格式)。
结合 samrad 上面的答案 这个很棒的答案,我得到了这个可行的代码
input_fn='output.mp4'

image_fn='output.png'

rm -f $image_fn

frame_count=`ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 $input_fn`

ffmpeg -i $input_fn -vf "select='eq(n,$frame_count-1)'" -vframes 1 "$image_fn" 2> /dev/null

2
我无法使Nelson的解决方案起作用,但是这个对我有用。 https://gist.github.com/samelie/32ecbdd99e07b9d8806f 编辑(以防链接消失,这是shell脚本-bobbogo):
#!/bin/bash

fn="$1"
of=`echo $1 | sed s/mp4/jpg/`

lf=`ffprobe -show_streams "$fn" 2> /dev/null | grep nb_frames | head -1 | cut -d \= -f 2`
rm -f "$of"
let "lf = $lf - 1"
ffmpeg -i $fn -vf select=\'eq\(n,$lf\) -vframes 1 $of

不需要使用 grepheadcut,只需使用 ffprobe 即可完成。请参考此链接 - llogan
1
被踩了。如果你要发布一个脚本,它会删除原始视频(没有提示!)对于任何非mp4格式,尽管原始问题*明确列出了两种非mp4视频格式,至少写一个免责声明。用粗体标出来。这样你就不会害其他人了。 - thepiercingarrow

1

我看到没有人提到一个问题,如果文件中有重复帧,那么预期的帧数可能会出错。如果您计算帧数的方法导致图像提取命令返回空值,那么这可能是问题所在。

为解决此问题,我编写了一个简短的脚本。可在这里找到。


1
我发现我必须添加-vsync 2才能使其可靠地工作。这是我使用的完整命令:
ffmpeg -y -sseof -3 -i $file -vsync 2 -update 1 -vf scale=640:480 -q:v 1 /tmp/test.jpg

如果你写入一个NFS文件夹,那么结果将非常不一致。因此我会写入/tmp,然后在完成后复制文件。如果没有完成,我会对进程ID执行kill -9

它可以工作,但其他人应该摆脱 scale=640:480 - tommy.carstensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接