【问题标题】:ffmpeg - preserve time base and pts of all frames during transcodeffmpeg - 在转码期间保留所有帧的时基和 pts
【发布时间】:2021-03-10 17:39:23
【问题描述】:

上下文:

我有一个使用 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
...

【问题讨论】:

  • copytb 是布尔值,而不是映射。由于输出是 MP4,只需设置 -video_track_timescale X 其中 X 是输入流 TB。
  • 根据 ffmpeg,copytb 不是布尔值。
  • 当我使用 -video_track_timescale 1000(谢谢)时,它更接近匹配,但 pkt_pts_times 在所有情况下仍然不匹配
  • 添加-vsync 0
  • 也不行;转换后视频的pts时间还是不一样

标签: ffmpeg


【解决方案1】:

您需要设置 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 将其关闭。

【讨论】:

  • 谢谢!测试时我发现我也可以省略 -video_track_timescale 1000 参数。只需-vsync 0-enc_time_base -1 就足够了。
  • 这对您的目的不安全。如果源较低,MP4 多路复用器会将时间刻度升级到超过 10,000 的值。根据输入和输出时间尺度之间的比率,舍入可以改变一些时间戳。
猜你喜欢
  • 2014-01-21
  • 1970-01-01
  • 2017-12-22
  • 2021-07-08
  • 2014-11-08
  • 1970-01-01
  • 2018-05-12
  • 2017-09-29
  • 2021-11-23
相关资源
最近更新 更多