http://pi.gbaman.info/?p=150
http://blog.tkjelectronics.dk/2013/06 / how-to-stream-video-and-audio-from-a-raspberry-pi-with-no-latency / comment-page-1 /#comments
http://www.raspberrypi.org/forums /viewtopic.php?p=464522
(所有链接都使用来自
deb http://vontaene.de/raspbian-updates/ . main
的gstreamer-1.0。) /> 最初,我们必须将
raspivid
的输出通过管道传输到gst-launch-1.0
(请参见链接1)。然后(链接2)创建了正式的V4L2驱动程序,现在它是标准驱动程序允许仅使用gstreamer即可直接获得数据,而无需使用管道(请参阅towolf的文章»Sat Dec 07,2013 3:34 pm在链接2中的链接): br />
接收器:
gst-launch-1.0 -e v4l2src do-timestamp=true ! video/x-h264,width=640,height=480,framerate=30/1 ! h264parse ! rtph264pay config-interval=1 ! gdppay ! udpsink host=192.168.178.20 port=5000
如果我理解正确,那么两种方法都可以使用GPU进行H264解码,但是后者的效率更高,因为它不需要再经过内核,因为所涉及的进程之间没有管道。 >
现在我对此有一些疑问。
后者仍然是从相机有效获取H264的最新方法吗?我已经读过
gst-launch-1.0 -v udpsrc port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! fpsdisplaysink sync=false text-overlay=false
,它允许使用gstreamer管道,例如gst-omx
。这与仅使用... video/x-raw ! omxh264enc ! ...
有什么不同吗,还是更有效率?有什么区别?使用
video/x-h264
管道时,如何找出实际使用的gstreamer编码插件?与其他管道部分相比,这似乎只是指定我想要的格式,在此我显式命名了(代码)组件(例如video/x-h264 ...
或h264parse
)。在对链接1的答复中,MikaelLepistö提到“我从流媒体一侧删除了一个不必要的过滤器通道”,这意味着他将
fpsdisplaysink
和gdppay
切掉了。这些是做什么的?为什么需要它们?我真的可以剥离它们吗?他还提到,通过在接收端为
gdpdepay
指定caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96"
参数,他可以在流的中间开始/恢复流。这些上限实现了什么,为什么要选择这些特定的选项,我在哪里可以了解更多呢?当我做问题3和4中的建议(添加
udpsrc
,删除caps
和gdppay
)时,我的视频延迟会变得更糟(而且似乎不断累积,延迟随着时间的流逝而增加,几分钟后视频停止)!为什么会这样呢?我想获得使用原始命令获得的延迟,但是还具有可以随时加入流的功能。我已经读过RTSP + RTP通常结合使用TCP和UDP :TCP用于控制消息和其他必不可少的内容,而UDP用于实际视频数据传输。在上面的设置中,我实际上是在使用它,还是仅在使用UDP?对于gstreamer是否处理此问题,我有点不透明。
即使是这些问题中的任何一个,我也希望得到任何答案!
#1 楼
选项:raspivid -t 0 -o - | nc -k -l 1234
raspivid -t 0 -o - | cvlc stream:///dev/stdin --sout "#rtp{sdp=rtsp://:1234/}" :demux=h264
cvlc v4l2:///dev/video0 --v4l2-chroma h264 --sout '#rtp{sdp=rtsp://:1234/}'
raspivid -t 0 -o - | gst-launch-1.0 fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=SERVER_IP port=1234
gst-launch-1.0 -e v4l2src do-timestamp=true ! video/x-h264,width=640,height=480,framerate=30/1 ! h264parse ! rtph264pay config-interval=1 ! gdppay ! udpsink host=SERVER_IP port=1234
uv4l --driver raspicam
picam --alsadev hw:1,0
要考虑的事项
延迟[ms](有无要求客户端要求比服务器更高的fps)
CPU空闲[%](由
top -d 10
测量) CPU 1客户端[%]
RAM [MB](RES)
相同的编码设置
相同的功能
音频
重新连接
/> OS独立客户端(vlc,webrtc等)
比较:
1 2 3 4 5 6 7
latency 2000 5000 ? ? ? ? 1300
CPU ? 1.4 ? ? ? ? ?
CPU 1 ? 1.8 ? ? ? ? ?
RAM ? 14 ? ? ? ? ?
encoding ? ? ? ? ? ? ?
audio n ? ? ? ? y ?
reconnect y y ? ? ? y ?
any OS n y ? ? ? y ?
latency fps ? ? ? ? ? ? ?
评论
为什么此表中的所有值都为“?”?
–幼虫
18 Mar 19 '18 at 18:55
@larsks,因为没有人愿意测试并填写此“社区Wiki”上的数据
–user1133275
18 Mar 19 '18 at 23:51
#2 楼
将H264流传输到浏览器的唯一现代方法是使用UV4L:无延迟,无配置,可选音频,可选双向音频/视频。没有神奇的GStreamer酱,但是可以扩展其使用范围。评论
由于我想流式传输到服务器和可能的智能手机,因此不需要流式传输到浏览器。而且,浏览器可能对其施加了额外的限制(例如,除非您使用WebRTC,否则不要设置RTSP,可能不使用TCP,但这很奇怪)。但是UV4L看起来仍然很有希望。您能否链接到一个我可以阅读如何使用它/从其中获取数据以进行网络流传输的地方?
– nh2
16年1月15日在2:00
天哪,我想我找到了示例页面……这件事似乎能够做得到! RTMP,RTSP,HTTPS流,WebRTC,“实时对象检测和对象跟踪+人脸检测”-到底是什么?每个都有一些对uv4l的简单命令行标志?我的gstreamer管道现在看起来已经过时了!等不及要测试延迟时间了!
– nh2
16年1月15日在2:15
哦,不,它是封闭源:(这使它不符合我想到的家庭监视用途:(
– nh2
16年1月15日在2:30
它确实支持WebRTC,2向WebRTC。音频/视频的延迟约为200毫秒,音频的可能性较小
–prinxis
16 Jan 18 '23:54
@ nh2,链接似乎已断开,您对该示例页面有任何更新的位置吗?
– Punit Soni
16 Dec 30 '23:45
#3 楼
我很惊讶对此线程没有更多的操作,几个月来我一直在追踪这个问题的答案。我从Pi Camera(CSI)流到Janus服务器,我发现最好的管道是
v4l2src使用内存高效的bmc2835-v4l2模块并直接提取硬件压缩的h264视频。在pi为0的情况下,gst启动会消耗4%至10%的cpu,以30fps的速度播放1280x720。我也可以随时恢复流,而无需使用gdppay。确保运行rpi-update以获取mmal v4l2驱动程序。我的pi也为了保持稳定而进行了超频和过压处理,并且连续数天不间断地流过,请参阅此处。
我偶然发现了与OP相同的许多问题。最令人沮丧的是问题5-延迟随着时间累积,最终导致pi崩溃。解决方案是
sync=false
udpsink元素。 gstreamer文档没有太多有关该元素的信息,只是它禁用了时钟同步,但是经过一番流泪,我发现我现在可以流化数小时而不会累积延迟。我还遇到问题4,我无法恢复直播,也无法在直播开始后开始观看。解决方案是
config-interval
,它重新广播SPS和PPS帧。我想使用config-interval=1
在每一帧都打包这些文件,这使我可以随时拾取流。 /> gst-launch-1.0 v4l2src ! video/x-h264, width=$width, height=$height, framerate=$framerate/1 ! h264parse ! rtph264pay config-interval=1 pt=96 ! udpsink sync=false host=$host port=$port
但是我无法恢复流,如果在流传输时刷新页面,我将没有流。我认为这是由于SPS和PPS帧。如果有人知道如何用ffmpeg打包它们,我很想知道。
btw我也使用v4l2-ctl设置参数,ffmpeg似乎可以自动识别宽度和高度等设置,但对于gstreamer他们必须匹配硬件生产的产品
ffmpeg -f h264 -framerate $framerate -i /dev/video0 -vcodec copy -g 60 -r $framerate -f rtp rtp://$hostname:$port
评论
这并不能真正回答问题。如果您有其他问题,可以单击“提问”来提问。一旦您有足够的声誉,您也可以添加赏金以吸引更多对此问题的关注。 -来自评论
–道奇
20年1月22日在19:49
我认为是! OP要求以最现代,最有效的方式从pi进行流式传输。我发布的gstreamer管道就是这样。我还解释了OP在他的管道中丢失了什么,以及管道的关键要素是什么。我正在编辑我的响应以直接解决CPU负载,也许有帮助。
– Ben Olayinka
20 Jan 24'8:51
我(OP)认为答案是完全正确的,特别是考虑到它解决了累积延迟问题。谢谢!
– nh2
20年1月24日在20:47
#4 楼
1.)h264es通过网络流式传输(仅用于示例)在服务器上:
raspivid -v -a 524 -a 4 -a "rpi-0 %Y-%m-%d %X" -fps 15 -n -md 2 -ih -t 0 -l -o tcp://0.0.0.0:5001
在客户端上:
mplayer -nostop-xscreensaver -nolirc -fps 15 -vo xv -vf rotate=2,screenshot -xy 1200 -demuxer h264es ffmpeg://tcp://<rpi-ip-address>:5001
2 .. mjpeg在网络上流式传输(仅用于示例)
在服务器上:在客户端上:
/usr/local/bin/mjpg_streamer -o output_http.so -w ./www -i input_raspicam.so -x 1920 -y 1440 -fps 3
所有这些甚至都可以在RPi Zero W(配置为服务器)上使用
评论
嘿,谢谢您的回答,样本仅代表什么?
– nh2
17年12月15日在20:50
我想说的只是“一个例子”。您可以根据自己的需要进行调整。
–sparkie
17/12/15在22:20
评论
使用管道的想法在这种情况下制造任何问题都是B.S.您是否尝试过任何raspivid | cvlc方法?我没有很长时间或没有相机来使用它,但是用它来产生一个http流(可以在另一端带有vlc的Linux上查看)似乎还可以。@goldilocks我并不是说管道是一个“问题”,只是它没有必要并且有一些开销,就像cat文件| grep ...而不是grep ...文件。管道在内核之间增加了另一层复制,这很容易测量,尤其是在内存带宽较低的设备上。如果gstreamer可以直接读取设备文件,为什么不使用它呢?关于您的raspivid | cvlc建议:在切换到基于gstreamer的解决方案之前,我一直在使用它,它的延迟比gstreamer多3秒钟(我不知道为什么)。
是的,肯定有一些延迟。 WRT管道,我对“上下文”的观点是,这里不可能成为瓶颈-网络I / O将变慢几个数量级,依此类推。您是对的,不过,这可能会给CPU增加一点点时间。我只是不敢下注。以全分辨率运行时,cvlc会使用〜45%的速度,但是我认为,仅以该数据速率通过管道运行(再次记住,管道并没有降低速度)就几乎不会动针。如<5%。当然,如果您想尽可能高效地执行此操作并不完全无关紧要...
...我只是不想让其他任何人读到它的印象,就是在这里使用管道可能会导致延迟问题或其他问题。那是一条红鲱鱼。否则我可能错了;)
如果您追求的是效率,则可能需要包括在特定分辨率/帧频下各种方法观察到的总CPU使用率。我尝试过的唯一一个是raspivid | cvlc一,占40-50%。人们可能会更好地回答一个挑战,要求他们在特定数字上进行改进。现在,您在问很多原因,而没有解释为什么每个原因都很重要。