- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在使用此命令从我的 RTSP 流中获取帧并从标准输出读取帧:
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 Media > Open Network Stream 播放它时:network_caching=300ms。
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.>
最佳答案
我做了一些关于减少视频延迟的研究。
我的 following answer证明相关的 FFmpeg 标志是 -probesize 32
和 -flags low_delay
.
上述标志与视频 相关解码器 侧(接收方)。
视频编码参数“发送器/编码器端”对于确定端到端延迟更为重要。
添加参数 -tune zerolatency
将编码器延迟降至最低,但所需的带宽要高得多(并且可能与互联网上的流媒体无关)。
我将把我的答案限制在解码延迟上,因为它似乎与您的问题主题更相关。
关于“知道其他人如何以低延迟获取视频帧”的主题是一个单独问题的主题(我不知道答案)。
为了比较 FFplay 和 FFmpeg(解码器)之间的延迟差异,我创建了一个“自包含”测试样本。
主要“原则”:
127.0.0.1
(本地主机)。imshow
用于显示视频。 import cv2
import numpy as np
import subprocess as sp
import shlex
rtsp_stream0 = 'rtsp://127.0.0.1:21415/live.stream' # Use localhost for testing
rtsp_stream1 = 'rtsp://127.0.0.1:31415/live.stream'
width = 256 # Use low resolution (for testing).
height = 144
fps = 30
# https://stackoverflow.com/questions/60462840/ffmpeg-delay-in-decoding-h264
ffmpeg_cmd = shlex.split(f'ffmpeg -nostdin -probesize 32 -flags low_delay -fflags nobuffer -rtsp_flags listen -rtsp_transport tcp -stimeout 1000000 -an -i {rtsp_stream0} -pix_fmt bgr24 -an -vcodec rawvideo -f rawvideo pipe:')
# FFplay command before updating the code (latency is still too high):
# ffplay_cmd = shlex.split(f'ffplay -probesize 32 -analyzeduration 0 -sync ext -fflags nobuffer -flags low_delay -avioflags direct -rtsp_flags listen -strict experimental -framedrop -rtsp_transport tcp -listen_timeout 1000000 {rtsp_stream1}')
# Updated FFplay command - adding "-vf setpts=0" (fixing the latency issue):
# https://stackoverflow.com/questions/16658873/how-to-minimize-the-delay-in-a-live-streaming-with-ffmpeg
ffplay_cmd = shlex.split(f'ffplay -probesize 32 -analyzeduration 0 -sync ext -fflags nobuffer -flags low_delay -avioflags direct -rtsp_flags listen -strict experimental -framedrop -vf setpts=0 -rtsp_transport tcp -listen_timeout 1000000 {rtsp_stream1}')
# Execute FFplay to used as reference
ffplay_process = sp.Popen(ffplay_cmd)
# Open sub-process that gets in_stream as input and uses stdout as an output PIPE.
process = sp.Popen(ffmpeg_cmd, stdout=sp.PIPE) #,stderr=sp.DEVNULL
# The following FFmpeg sub-process stream RTSP video.
# The video is synthetic video with frame counter (that counts every frame) at 30fps.
# The arguments of the encoder are almost default arguments - not tuned for low latency.
# drawtext filter with the n or frame_num function https://stackoverflow.com/questions/15364861/frame-number-overlay-with-ffmpeg
rtsp_streaming_process = sp.Popen(shlex.split(f'ffmpeg -re -f lavfi -i testsrc=size={width}x{height}:rate={fps} '
'-filter_complex "drawtext=fontfile=Arial.ttf: text=''%{frame_num}'': start_number=1: x=(w-tw)/2: y=h-(2*lh): fontcolor=black: fontsize=72: box=1: boxcolor=white: boxborderw=5",'
'split[v0][v1] ' # Split the input into [v0] and [v1]
'-vcodec libx264 -pix_fmt yuv420p -g 30 -rtsp_transport tcp -f rtsp -muxdelay 0.1 -bsf:v dump_extra '
f'-map "[v0]" -an {rtsp_stream0} '
'-vcodec libx264 -pix_fmt yuv420p -g 30 -rtsp_transport tcp -f rtsp -muxdelay 0.1 -bsf:v dump_extra '
f'-map "[v1]" -an {rtsp_stream1}'))
while True:
raw_frame = process.stdout.read(width*height*3)
if len(raw_frame) != (width*height*3):
print('Error reading frame!!!') # Break the loop in case of an error (too few bytes were read).
break
# Transform the byte read into a numpy array, and reshape it to video frame dimensions
frame = np.frombuffer(raw_frame, np.uint8)
frame = frame.reshape((height, width, 3))
# Show frame for testing
cv2.imshow('frame', frame)
key = cv2.waitKey(1)
if key == 27:
break
process.stdout.close()
process.wait()
ffplay_process.kill()
rtsp_streaming_process.kill()
cv2.destroyAllWindows()
-vf setpts=0
:
-vf setpts=0
到 FFplay 命令。
setpts
的重要性筛选。
-vf setpts=0
解决了延迟问题。
setpts
将所有视频时间戳重置为零的视频过滤器。
-vf setpts=0
FFplay 和 OpenCV 的延迟差不多:
import cv2
import numpy as np
import subprocess as sp
import shlex
rtsp_stream0 = 'rtsp://127.0.0.1:21415/live.stream' # Use localhost for testing
rtsp_stream1 = 'rtsp://127.0.0.1:31415/live.stream'
width = 256 # Use low resolution (for testing).
height = 144
fps = 30
# https://stackoverflow.com/questions/60462840/ffmpeg-delay-in-decoding-h264
ffmpeg_cmd = shlex.split(f'ffmpeg -nostdin -probesize 32 -flags low_delay -fflags nobuffer -rtsp_flags listen -rtsp_transport tcp -stimeout 1000000 -an -i {rtsp_stream0} -pix_fmt bgr24 -an -vcodec rawvideo -f rawvideo pipe:')
# https://stackoverflow.com/questions/16658873/how-to-minimize-the-delay-in-a-live-streaming-with-ffmpeg
#ffplay_cmd = shlex.split(f'ffplay -probesize 32 -analyzeduration 0 -sync ext -fflags nobuffer -flags low_delay -avioflags direct -rtsp_flags listen -strict experimental -framedrop -rtsp_transport tcp -listen_timeout 1000000 {rtsp_stream1}')
# https://github.com/mpv-player/mpv/issues/4213
mpv_cmd = shlex.split(f'mpv --demuxer-lavf-o=rtsp_flags=listen --rtsp-transport=tcp --profile=low-latency --no-cache --untimed --no-demuxer-thread --vd-lavc-threads=1 {rtsp_stream1}')
# Execute FFplay to used as reference
#ffplay_process = sp.Popen(ffplay_cmd)
# Execute mpv media player (as reference)
mpv_process = sp.Popen(mpv_cmd)
# Open sub-process that gets in_stream as input and uses stdout as an output PIPE.
process = sp.Popen(ffmpeg_cmd, stdout=sp.PIPE) #,stderr=sp.DEVNULL
# The following FFmpeg sub-process stream RTSP video.
# The video is synthetic video with frame counter (that counts every frame) at 30fps.
# The arguments of the encoder are almost default arguments - not tuned for low latency.
# drawtext filter with the n or frame_num function https://stackoverflow.com/questions/15364861/frame-number-overlay-with-ffmpeg
rtsp_streaming_process = sp.Popen(shlex.split(f'ffmpeg -re -f lavfi -i testsrc=size={width}x{height}:rate={fps} '
'-filter_complex "drawtext=fontfile=Arial.ttf: text=''%{frame_num}'': start_number=1: x=(w-tw)/2: y=h-(2*lh): fontcolor=black: fontsize=72: box=1: boxcolor=white: boxborderw=5",'
'split[v0][v1] ' # Split the input into [v0] and [v1]
'-vcodec libx264 -pix_fmt yuv420p -g 30 -rtsp_transport tcp -f rtsp -muxdelay 0.1 -bsf:v dump_extra '
f'-map "[v0]" -an {rtsp_stream0} '
'-vcodec libx264 -pix_fmt yuv420p -g 30 -rtsp_transport tcp -f rtsp -muxdelay 0.1 -bsf:v dump_extra '
f'-map "[v1]" -an {rtsp_stream1}'))
while True:
raw_frame = process.stdout.read(width*height*3)
if len(raw_frame) != (width*height*3):
print('Error reading frame!!!') # Break the loop in case of an error (too few bytes were read).
break
# Transform the byte read into a numpy array, and reshape it to video frame dimensions
frame = np.frombuffer(raw_frame, np.uint8)
frame = frame.reshape((height, width, 3))
# Show frame for testing
cv2.imshow('frame', frame)
key = cv2.waitKey(1)
if key == 27:
break
process.stdout.close()
process.wait()
#ffplay_process.kill()
mpv_process.kill()
rtsp_streaming_process.kill()
cv2.destroyAllWindows()
关于python - 以低延迟从 IP Camera 获取帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71746326/
给定的输入是192.168.3.78/27 输入可以是任意C类ip地址,以上ip为例进行尝试 预期输出应显示从 192.168.3.65 到 192.168.3.94 的所有 IP如下 192.168
您好,我是一名 javascript 菜鸟,正在为 IP 范围编写验证器。例如,1.1.1.1-2.2.2.2 是一个有效范围,但我想确保第一个 IP 不大于第二个 IP。 2.2.2.2-1.1.1
在 MySQL 数据库中存储多种 IP 类型的最佳方式是什么: - 单一 IP (123.123.123.123) - IP 范围 (123.123.123.1 - 123.123.123.121)
所以我有一个带有子网的 IP:8.8.8.0/24 我如何将其转换为 8.8.8.0 和 8.8.8.255(实际上是它们的 ip2long 结果) 在 PHP 和 JavaScript 中 最佳答案
我有 Windows7 作为我的基本操作系统。最重要的是,我在 Ubuntu 上安装了 Virtual Box。我希望 ubuntu 获得与我的基本操作系统(Win7)相同的 IP 地址。我如何实现这
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 9年前关闭。 Improve this q
阅读后List of IP Space used by Facebook : “真实”列表是最后一个答案,但我想知道 Igy(答案标记为解决方案)如何通过将连续的类添加到更大的类中来大幅缩小列表(通过
我正在开发一个 web 应用程序,我已经在我的本地主机中创建了这个项目,但是网络用户需要访问我的项目,我不想给他们一个不友好的 ip 地址,所以我想用户访问一个名称例子 http://myprojec
有人可以向我解释 Azure 在逻辑应用程序的出站 IP 地址之间不同的新方式之间的区别。 我认为文档在对该问题的正确解释方面非常精简。读起来听起来好像 IP 地址在逻辑应用程序中具有完全相同的作用。
我正在尝试熟悉一个项目中java中的数据报系统,目前,我们只使用UDP包。 为了发送消息,我们在 DatagramPacket 上设置目标 IP。 /* * The fields o
我有一个 Java 服务器,当我获得连接时,我需要检查 IP 是本地 IP 还是公共(public) IP。当它是我自己的本地 IP 时,我可以检测到它,但我在使用其他本地 IP 时遇到了一些问题。J
所以我在网上看到了很多例子,这些例子展示了如果你知道起始 IP 和结束 IP 如何获得完整的 IP,但我需要的是在提供后告诉我完整的 IP 范围带有起始 IP 和所需 IP 地址数的代码。 因此,例如
我创建了一个 python 项目,用于扫描 IP 范围(即 x.y.z.0/24)并返回在线主机列表。它将在线主机列表保存到仅包含 IP 的文件中(即 ['192.168.0.1'、'192.168.
如果用户的 ip 在某个 IP 范围之间,我正在使用重定向。但是,我正在使用多个 ip 范围,所以我想知道执行此操作的最佳方法。我目前正在使用它来重定向, 但是如果 IP 范围是 72.122.166
好的,现在是星期五下午,我度过了漫长的一周,希望能得到一些帮助!目前,我有一个 IP 范围列表,如下所示: List ipRanges = new List(); ipRanges.Add(new I
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
下面是我的 CloudFormation 模板的片段,用于将弹性 IP 地址与网络接口(interface)的主 IP 相关联: "MyInterfaceSelfEipAssociat
我在 Azure 上创建了 Python 函数,该函数调用外部 API 服务,该服务仅允许访问白名单 IP。 根据 Microsoft 文档 ( https://learn.microsoft.com
我在 Azure 上创建了 Python 函数,该函数调用外部 API 服务,该服务仅允许访问白名单 IP。 根据 Microsoft 文档 ( https://learn.microsoft.com
我在我的 CentOS 5 x86_64 中使用 IP 别名。为简化此示例:IP 地址 A 是 eth0 地址,IP 地址 B 是 eth0:0地址。我有 2 个 Apache 实例(版本 2.2.3
我是一名优秀的程序员,十分优秀!