使用 fps 过滤器的 ffmpeg 时间戳信息与 ffprobe 不一致
ffmpeg timestamp information using fps filter isn't aligned with ffprobe
我正在使用 ffmpeg 从使用过滤器 fps 的视频中提取图像(缩略图),这样我每 0.5 秒就会得到一张图像。这是我使用的命令:
ffmpeg -i video.mp4 -f image2 -filter:v fps=1/0.5 -y out_%3d.png
我想知道这些图像的时间戳,我发现 ffmpeg 的行为与 ffprobe 不同。
首先,我还没有找到将时间戳作为元数据(日志文件或其他)获取的方法,但我必须使用 ffmpeg 在图像本身中覆盖时间戳:
ffmpeg -i video.mp4 \
-vf "fps=fps=1/5,drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf: text='%{pts\:hms}': x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000000@1" \
out_with_timestamp_%03d.png
但是,使用 ffprobe 可以模拟使用相同的 fps 过滤器,并且 ffprobe 允许您从帧中获取一些信息。此命令应该模拟 ffmpeg 并提供一些元数据,您可以从中提取时间戳:
fprobe -hide_banner \
-i "movie=video.mp4,fps=fps=1/0.5[out0]" \
-f lavfi -show_frames -show_entries frame=pkt_pts_time -of csv=p=0
问题是ffmpeg打印到图像中的时间戳与ffprobe给出的时间戳不同,ffprobe给出的是错误的,而ffmpeg给出的是正确的。
ffmpeg 给出的时间戳在时间段的中间,而 ffprobe 给出的时间戳在 window.
的最开始
有什么方法可以使用 ffmpeg 从视频中提取缩略图及其时间戳吗?
您可以在此处找到能够重现此行为的所有步骤:
https://www.joseoc.com/en/video/ffmpeg/extract-images-from-video/#getting-the-timestamp-for-the-images
ffmpeg 和 ffprobe 产生相同的时间戳。
但是,您想知道源时间戳,之后您必须为此应用 fps 过滤器。 fps 过滤器的作用是从源流中删除 and/or 重复帧以生成恒定帧速率输出。它还以给定的速率重新生成平滑的时间戳。所以要早点画文字才能印出源TS
这是将源 TS 归档的粗略解决方法。
运行,
ffmpeg -i video.mp4 -vf "showinfo,fps=fps=1/5,showinfo" out_%03d.png 2> showinfo.log
showinfo.log,会有这样的行
[Parsed_showinfo_0 @ 000000000051fe40] n: 56 pts: 28672 pts_time:2.33333 pos: 159155 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:P checksum:E16BA92B plane_checksum:[DDD39061 7EA5EE0E B9642AAD] mean:[188 113 134 ] stdev:[35.2 24.8 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 57 pts: 29184 pts_time:2.375 pos: 161402 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:P checksum:A363FB5E plane_checksum:[9BBF72F4 87165D47 ADB32B23] mean:[188 113 134 ] stdev:[35.3 24.7 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 58 pts: 29696 pts_time:2.41667 pos: 173158 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:B checksum:5EE879C4 plane_checksum:[55EA6029 A578E90A 4F463082] mean:[188 113 134 ] stdev:[35.3 24.6 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 59 pts: 30208 pts_time:2.45833 pos: 170104 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:B checksum:EE8A0C3A plane_checksum:[A90276D4 620C6744 F5012E13] mean:[188 114 134 ] stdev:[35.4 24.5 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 60 pts: 30720 pts_time:2.5 pos: 175138 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:B checksum:8E112769 plane_checksum:[9A02FB68 1FF2EC88 1E573F5B] mean:[188 114 134 ] stdev:[35.5 24.4 6.3 ]
[Parsed_showinfo_2 @ 0000000004947540] n: 0 pts: 0 pts_time:0 pos: 170104 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:B checksum:EE8A0C3A plane_checksum:[A90276D4 620C6744 F5012E13] mean:[188 114 134 ] stdev:[35.4 24.5 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 61 pts: 31232 pts_time:2.54167 pos: 164026 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:P checksum:BB465233 plane_checksum:[EAEAE802 57E310BE 62275964] mean:[187 114 134 ] stdev:[35.7 24.4 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 62 pts: 31744 pts_time:2.58333 pos: 187333 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:B checksum:9D4E3B24 plane_checksum:[D5D19959 05A4FDBE 88B7A3EF] mean:[187 114 134 ] stdev:[35.8 24.4 6.3 ]
对于每个 Parsed_showinfo_2
行,您必须提取 pos
相同的 Parsed_showinfo_0
行。 Parsed_showinfo_0
中的pts_time
是你的源TS。
我正在使用 ffmpeg 从使用过滤器 fps 的视频中提取图像(缩略图),这样我每 0.5 秒就会得到一张图像。这是我使用的命令:
ffmpeg -i video.mp4 -f image2 -filter:v fps=1/0.5 -y out_%3d.png
我想知道这些图像的时间戳,我发现 ffmpeg 的行为与 ffprobe 不同。
首先,我还没有找到将时间戳作为元数据(日志文件或其他)获取的方法,但我必须使用 ffmpeg 在图像本身中覆盖时间戳:
ffmpeg -i video.mp4 \
-vf "fps=fps=1/5,drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf: text='%{pts\:hms}': x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000000@1" \
out_with_timestamp_%03d.png
但是,使用 ffprobe 可以模拟使用相同的 fps 过滤器,并且 ffprobe 允许您从帧中获取一些信息。此命令应该模拟 ffmpeg 并提供一些元数据,您可以从中提取时间戳:
fprobe -hide_banner \
-i "movie=video.mp4,fps=fps=1/0.5[out0]" \
-f lavfi -show_frames -show_entries frame=pkt_pts_time -of csv=p=0
问题是ffmpeg打印到图像中的时间戳与ffprobe给出的时间戳不同,ffprobe给出的是错误的,而ffmpeg给出的是正确的。
ffmpeg 给出的时间戳在时间段的中间,而 ffprobe 给出的时间戳在 window.
有什么方法可以使用 ffmpeg 从视频中提取缩略图及其时间戳吗?
您可以在此处找到能够重现此行为的所有步骤: https://www.joseoc.com/en/video/ffmpeg/extract-images-from-video/#getting-the-timestamp-for-the-images
ffmpeg 和 ffprobe 产生相同的时间戳。
但是,您想知道源时间戳,之后您必须为此应用 fps 过滤器。 fps 过滤器的作用是从源流中删除 and/or 重复帧以生成恒定帧速率输出。它还以给定的速率重新生成平滑的时间戳。所以要早点画文字才能印出源TS
这是将源 TS 归档的粗略解决方法。
运行,
ffmpeg -i video.mp4 -vf "showinfo,fps=fps=1/5,showinfo" out_%03d.png 2> showinfo.log
showinfo.log,会有这样的行
[Parsed_showinfo_0 @ 000000000051fe40] n: 56 pts: 28672 pts_time:2.33333 pos: 159155 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:P checksum:E16BA92B plane_checksum:[DDD39061 7EA5EE0E B9642AAD] mean:[188 113 134 ] stdev:[35.2 24.8 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 57 pts: 29184 pts_time:2.375 pos: 161402 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:P checksum:A363FB5E plane_checksum:[9BBF72F4 87165D47 ADB32B23] mean:[188 113 134 ] stdev:[35.3 24.7 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 58 pts: 29696 pts_time:2.41667 pos: 173158 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:B checksum:5EE879C4 plane_checksum:[55EA6029 A578E90A 4F463082] mean:[188 113 134 ] stdev:[35.3 24.6 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 59 pts: 30208 pts_time:2.45833 pos: 170104 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:B checksum:EE8A0C3A plane_checksum:[A90276D4 620C6744 F5012E13] mean:[188 114 134 ] stdev:[35.4 24.5 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 60 pts: 30720 pts_time:2.5 pos: 175138 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:B checksum:8E112769 plane_checksum:[9A02FB68 1FF2EC88 1E573F5B] mean:[188 114 134 ] stdev:[35.5 24.4 6.3 ]
[Parsed_showinfo_2 @ 0000000004947540] n: 0 pts: 0 pts_time:0 pos: 170104 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:B checksum:EE8A0C3A plane_checksum:[A90276D4 620C6744 F5012E13] mean:[188 114 134 ] stdev:[35.4 24.5 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 61 pts: 31232 pts_time:2.54167 pos: 164026 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:P checksum:BB465233 plane_checksum:[EAEAE802 57E310BE 62275964] mean:[187 114 134 ] stdev:[35.7 24.4 6.3 ]
[Parsed_showinfo_0 @ 000000000051fe40] n: 62 pts: 31744 pts_time:2.58333 pos: 187333 fmt:yuv420p sar:0/1 s:1280x720 i:P iskey:0 type:B checksum:9D4E3B24 plane_checksum:[D5D19959 05A4FDBE 88B7A3EF] mean:[187 114 134 ] stdev:[35.8 24.4 6.3 ]
对于每个 Parsed_showinfo_2
行,您必须提取 pos
相同的 Parsed_showinfo_0
行。 Parsed_showinfo_0
中的pts_time
是你的源TS。