ffmpeg - 在转码期间保留所有帧的时基和点
ffmpeg - preserve time base and pts of all frames during transcode
上下文:
我有一个使用 HEVC 编码生成 mp4 的应用程序。我想将它们转换为 AVC,以便在基于浏览器的显示中使用。我想如何使用它的一个非常关键的部分是保留准确的 PTS 时间,因为这是我们将帧与视频中未包含的其他数据流相关联的方式。
问题:
如何使 ffmpeg 在转码过程中保留此信息?所有明显的标志似乎都没有效果,ffmpeg 只是做它想做的事。
$ ffprobe -show_streams original.mp4 2>/dev/null | grep time_base
codec_time_base=16666667/500000000
time_base=1/1000
这是我的转换命令:
$ ffmpeg -i original.mp4 -copyts -copytb 0 test.mp4
及其结果:
$ ffprobe -show_streams test.mp4 2>/dev/null | grep time_base
codec_time_base=1/60
time_base=1/15360
我希望 time_bases 匹配。执行 ffprobe -show_frames
时,帧的 PTS 也不匹配
编辑:
@Gyan 建议使用 -video_track_timescale,但这并没有得到我正在寻找的确切行为:
$ sdiff <(ffprobe -show_frames test.mp4 | grep pkt_pts_time) <(ffprobe -show_frames original.mp4 | grep pkt_pts_time)
pkt_pts_time=0.000000 pkt_pts_time=0.000000
pkt_pts_time=0.033000 pkt_pts_time=0.033000
pkt_pts_time=0.067000 | pkt_pts_time=0.066000
pkt_pts_time=0.100000 pkt_pts_time=0.100000
pkt_pts_time=0.133000 pkt_pts_time=0.133000
pkt_pts_time=0.167000 | pkt_pts_time=0.166000
pkt_pts_time=0.200000 pkt_pts_time=0.200000
pkt_pts_time=0.233000 pkt_pts_time=0.233000
pkt_pts_time=0.267000 | pkt_pts_time=0.266000
pkt_pts_time=0.300000 pkt_pts_time=0.300000
pkt_pts_time=0.333000 pkt_pts_time=0.333000
pkt_pts_time=0.367000 | pkt_pts_time=0.366000
pkt_pts_time=0.400000 pkt_pts_time=0.400000
pkt_pts_time=0.433000 pkt_pts_time=0.433000
pkt_pts_time=0.467000 pkt_pts_time=0.467000
pkt_pts_time=0.500000 pkt_pts_time=0.500000
pkt_pts_time=0.533000 | pkt_pts_time=0.532000
pkt_pts_time=0.567000 | pkt_pts_time=0.565000
pkt_pts_time=0.600000 | pkt_pts_time=0.598000
pkt_pts_time=0.633000 | pkt_pts_time=0.631000
pkt_pts_time=0.667000 | pkt_pts_time=0.665000
pkt_pts_time=0.700000 | pkt_pts_time=0.698000
...
您需要设置 3 个参数以获得相同的时间戳:-vsync 0
避免帧重复和时基调整,-enc_time_base -1
避免编码器层的时基调整,-video_track_timescale
与源时基的倒数。
ffmpeg -i original.mp4 -vsync 0 -enc_time_base -1 -video_track_timescale 1000 test.mp4
请注意,使用默认编码参数时,默认编码器(MP4 的 libx264)会启用 B 帧,因此帧将按解码顺序存储,这与呈现顺序不同。添加 -bf 0
以关闭此功能。
上下文:
我有一个使用 HEVC 编码生成 mp4 的应用程序。我想将它们转换为 AVC,以便在基于浏览器的显示中使用。我想如何使用它的一个非常关键的部分是保留准确的 PTS 时间,因为这是我们将帧与视频中未包含的其他数据流相关联的方式。
问题:
如何使 ffmpeg 在转码过程中保留此信息?所有明显的标志似乎都没有效果,ffmpeg 只是做它想做的事。
$ ffprobe -show_streams original.mp4 2>/dev/null | grep time_base
codec_time_base=16666667/500000000
time_base=1/1000
这是我的转换命令:
$ ffmpeg -i original.mp4 -copyts -copytb 0 test.mp4
及其结果:
$ ffprobe -show_streams test.mp4 2>/dev/null | grep time_base
codec_time_base=1/60
time_base=1/15360
我希望 time_bases 匹配。执行 ffprobe -show_frames
编辑: @Gyan 建议使用 -video_track_timescale,但这并没有得到我正在寻找的确切行为:
$ sdiff <(ffprobe -show_frames test.mp4 | grep pkt_pts_time) <(ffprobe -show_frames original.mp4 | grep pkt_pts_time)
pkt_pts_time=0.000000 pkt_pts_time=0.000000
pkt_pts_time=0.033000 pkt_pts_time=0.033000
pkt_pts_time=0.067000 | pkt_pts_time=0.066000
pkt_pts_time=0.100000 pkt_pts_time=0.100000
pkt_pts_time=0.133000 pkt_pts_time=0.133000
pkt_pts_time=0.167000 | pkt_pts_time=0.166000
pkt_pts_time=0.200000 pkt_pts_time=0.200000
pkt_pts_time=0.233000 pkt_pts_time=0.233000
pkt_pts_time=0.267000 | pkt_pts_time=0.266000
pkt_pts_time=0.300000 pkt_pts_time=0.300000
pkt_pts_time=0.333000 pkt_pts_time=0.333000
pkt_pts_time=0.367000 | pkt_pts_time=0.366000
pkt_pts_time=0.400000 pkt_pts_time=0.400000
pkt_pts_time=0.433000 pkt_pts_time=0.433000
pkt_pts_time=0.467000 pkt_pts_time=0.467000
pkt_pts_time=0.500000 pkt_pts_time=0.500000
pkt_pts_time=0.533000 | pkt_pts_time=0.532000
pkt_pts_time=0.567000 | pkt_pts_time=0.565000
pkt_pts_time=0.600000 | pkt_pts_time=0.598000
pkt_pts_time=0.633000 | pkt_pts_time=0.631000
pkt_pts_time=0.667000 | pkt_pts_time=0.665000
pkt_pts_time=0.700000 | pkt_pts_time=0.698000
...
您需要设置 3 个参数以获得相同的时间戳:-vsync 0
避免帧重复和时基调整,-enc_time_base -1
避免编码器层的时基调整,-video_track_timescale
与源时基的倒数。
ffmpeg -i original.mp4 -vsync 0 -enc_time_base -1 -video_track_timescale 1000 test.mp4
请注意,使用默认编码参数时,默认编码器(MP4 的 libx264)会启用 B 帧,因此帧将按解码顺序存储,这与呈现顺序不同。添加 -bf 0
以关闭此功能。