我已经看到许多关于视频 PTS 值不从零开始的问题,或者询问如何使它们从零开始。我知道使用 ffmpeg 我可以做一些事情ffmpeg -i <video> -vf="setpts=PTS-STARTPTS" <output>
来解决这种事情
但是,据我了解,PTS 值不必从零开始。例如,如果您加入直播,那么很可能它已经持续了一个小时,并且 PTS 已经在 3600000+ 左右,但您的视频播放器忠实地显示了一切。因此,如果我故意创建一个 PTS 值从当前挂钟时间开始的视频,我希望不会有问题。
我想使用 ffmpeg 发送实时流,但将当前时间嵌入到流中。这既可以用于在直播时计算延迟时间,也可以在以后确定流最初播出的时间。根据我对 PTS 的理解,像这样简单的事情应该可以工作:
ffmpeg -i video.flv -vf="setpts=RTCTIME" rtmp://<output>
但是,当我尝试此操作时,ffmpeg 输出以下内容:
frame= 93 fps= 20 q=-1.0 Lsize= 9434kB time=535020:39:58.70 bitrate= 0.0kbits/s speed=1.35e+11x
请注意“时间”、比特率(0.0kbits)和速度(135000000000x !!!)的极大值
起初我认为问题可能是我的时基,所以我尝试了以下方法:
ffmpeg -i video.flv -vf="settb=1/1K,setpts=RTCTIME/1K" rtmp://<output>
这以毫秒为单位(1 PTS = 1 ms),但我遇到了同样的问题(大量时间、零比特率和巨大速度)
我对 PTS 有误解吗?是否不允许从非零值开始?还是我只是做错了什么?
更新
在查看@Gyan 的答案后,我将命令格式化如下:
ffmpeg -re -i video.flv -vf="settb=1/1K, setpts=(RTCTIME-RTCSTART)/1K" -output_ts_offset $(date +%s.%N) rtmp://<output>
这样,PTS 值将匹配到“自流开始以来的毫秒数”,并将被流的开始时间抵消(理论上使 PTS = 服务器上的时间戳)
这看起来编码更好:
frame= 590 fps=7.2 q=22.0 size= 25330kB time=00:01:21.71 bitrate=2539.5kbits/s dup=0 drop=1350 speed= 1x
比特率现在是正确的,时间是准确的,而且速度也没有离谱。不过,每秒帧数仍然有点偏(源视频是 24 fps,但它报告每秒 7.2 帧)
当我尝试从另一端观看流时,视频与音频不同步,并以大约两倍正常速度播放了一段时间,然后视频冻结,音频继续没有它
此外,当我将流转储到文件 ( ffmpeg -i rtmp://<output> dump.mp4
) 并使用 ffprobe () 查看 PTS 时间戳时,ffprobe -show_entries packet=codec_type,pts dump.mp4 | grep "video" -B 1 -A 2
时间戳似乎根本没有显示服务器时间:
...
--
[PACKET]
codec_type=video
pts=131072
[/PACKET]
[PACKET]
codec_type=video
pts=130048
[/PACKET]
--
[PACKET]
codec_type=video
pts=129536
[/PACKET]
[PACKET]
codec_type=video
pts=130560
[/PACKET]
--
[PACKET]
codec_type=video
pts=131584
[/PACKET]
问题只是与 RTMP 不兼容吗?
更新 2
我已经删除了视频过滤器,现在我的编码如下:
ffmpeg -re -i video.flv -output_ts_offset $(date +%s.%N) rtmp://<output>
这是正确编码:
frame= 910 fps= 23 q=25.0 size= 12027kB time=00:00:38.97 bitrate=2528.2kbits/s speed=0.981x
为了验证 PTS 值是否正确,我将输出转储到文件中,如下所示:
ffmpeg -i rtmp://<output> -copyts -write_tmcd 0 dump.mp4
我尝试将其保存为dump.flv
(因为它是 RTMP)但是这引发了错误:
[flv @ 0x5600f24b4620] Audio codec mp3 not compatible with flv
这有点奇怪,因为视频不是 mp3 编码的(它是 speex)——但无论如何。
转储此文件时,反复弹出以下错误:
frame= 1 fps=0.0 q=0.0 size= 0kB time=00:00:09.21 bitrate= 0.0kbits/s dup=0 dr
43090023 frame duplication too large, skipping
43090027 frame duplication too large, skipping
Last message repeated 3 times
43090031 frame duplication too large, skipping
Last message repeated 3 times
43090035 frame duplication too large, skipping
在 VLC 中播放生成的视频会播放音频流,但不显示视频。然后,我尝试通过ffprobe
查看视频 PTS 值来探测此视频:
ffprobe -show_entries packet=codec_type,pts dump.mp4 | grep "video" -B 1 -A 2
这仅返回一个视频帧,其 PTS 并不像我预期的那样大:
[PACKET]
codec_type=video
pts=1020
[/PACKET]
这是一项异常艰巨的任务