我目前使用这个命令从RTSP流中获取帧,并从stdout中读取帧:
ffmpeg -nostdin -rtsp_transport tcp -i <rtsp_stream> -pix_fmt bgr24 -an -vcodec rawvideo -f rawvideo -
但是,我希望获得与通过ffplay看到它时相同的延迟:
ffplay -fflags nobuffer -flags low_delay -tune zerolatency -framedrop -rtsp_transport tcp <rtsp_stream>
或者当我通过VLC媒体〉打开网络流播放时:network_caching = 300ms。
我想知道我可以在ffmpeg命令中使用哪些其他参数来获得与ffplay命令相当(或更好)的结果。
我参考了:How to dump raw RTSP stream to file?、Open CV RTSP camera buffer lag、How to pipe output from ffmpeg using python?、bad ffmpeg performace compared to ffplay and VLC、How to minimize the delay in a live streaming with ffmpeg
我目前的实施情况:
FFMPEG_CMD = "ffmpeg -nostdin -rtsp_transport tcp -i <rtsp_stream> -pix_fmt bgr24 -an -vcodec rawvideo -f rawvideo -".split(" ")
WIDTH = 2560
HEIGHT = 1440
process = subprocess.Popen(FFMPEG_CMD, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
while True:
raw_frame = process.stdout.read(WIDTH*HEIGHT*3)
frame = np.frombuffer(raw_frame, np.uint8)
frame = frame.reshape((HEIGHT, WIDTH, 3))
<do stuff with frame/ show frame etc.>
感谢阅读。ffmpeg
命令,我现在使用的延迟小于1s。
ffmpeg -nostdin -flags low_delay -rtsp_transport tcp -i <rtsp_stream> -pix_fmt bgr24 -an -vcodec rawvideo -f rawvideo -
根据答案中的建议实施:
import subprocess
import numpy as np
FFMPEG_CMD = "ffmpeg -nostdin -flags low_delay -rtsp_transport tcp -i <rtsp_stream> -pix_fmt bgr24 -an -vcodec rawvideo -f rawvideo -".split(" ")
WIDTH = 2560
HEIGHT = 1440
process = subprocess.Popen(FFMPEG_CMD, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
raw_frame = np.empty((HEIGHT, WIDTH, 3), np.uint8)
frame_bytes = memoryview(raw_frame).cast("B")
while process.poll() is None:
process.stdout.readinto(frame_bytes)
frame = raw_frame.reshape((HEIGHT, WIDTH, 3))
<do stuff with frame/ show frame etc.>
2条答案
按热度按时间ibrsph3r1#
我做了一些关于减少视频延迟的研究。
我的following answer演示了相关的FFmpeg标志是
-probesize 32
和-flags low_delay
。上述标志与视频解码器侧(接收器侧)有关。
视频编码参数"发送器/编码器侧"对于确定端到端延迟更重要。
添加参数
-tune zerolatency
可以将编码器延迟降至最低,但所需的带宽要高得多(可能与Internet上的流媒体无关)。我将把我的答案限制在解码延迟上,因为它似乎与您的问题主题更相关。
关于"知道其他人如何获得低延迟的视频帧"的主题是一个单独问题的主题(我不知道答案)。
为了比较FFplay和FFmpeg(解码器)之间的延迟差异,我创建了一个"自包含"测试示例。
主要"原则":
流视频是合成模式,帧计数器作为视频上的文本。
两个输出流应用相同的编码参数(仅端口不同)。
RTSP IP地址为
127.0.0.1
(本地主机)。(Note:我们可能会使用tee muxer而不是编码两次,但我从来没有尝试过)。
OpenCV
imshow
用于显示视频。代码示例(已更新):
添加
-vf setpts=0
之前的示例输出:样本输出(左侧为OpenCV,右侧为FFplay):
在将
-vf setpts=0
添加到FFplay命令之前,FFmpeg-OpenCV延迟似乎降低了6帧。注意:我花了一些时间才找到解决方案,我决定保留原帖子的结果,以显示添加
setpts
过滤器的重要性。更新:
添加
-vf setpts=0
解决了延迟问题。following post的最新回答建议添加
setpts
视频过滤器,将所有视频时间戳重置为零。这可能不是一个好主意与目前的音频流,但当最低的视频延迟是必需的,这是最好的解决方案,我可以找到。
添加
-vf setpts=0
后,FFplay和OpenCV的延迟大致相同:使用mpv media player重复测试:
(Note:在我找到FFplay解决方案之前似乎更相关)。
当应用this page中的所有mpv "延迟破解"时,mpv和OpenCV的延迟大致相同:
FFplay一定有解决的办法,但我找不到......
代码示例(使用mpv而不是FFplay):
mzmfm0qo2#
假设瓶颈确实在示例代码中的某个地方(而不是在
<do stuff with frame/ show frame etc.>
中),您可以尝试更新numpy array,而不是每次都创建一个: