微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Python OpenCV和GStreamer从UDP接收器读取RTSP流

如何解决使用Python OpenCV和GStreamer从UDP接收器读取RTSP流

我们正在开发一种软​​件,用于使用GStreamer使用RTSP传输来自两个不同摄像机的视频。为了简化获取过程,我们将OpenCV与Python 3配合使用。

问题是:我们想将流推送到UDP接收器,然后将其作为RTSP流通过LAN重新发布,而不是在另一台PC上读取。但是我们无法使它正常工作。

这是获取摄像机图像并以udpsink开始流式传输的Python代码在这种情况下,我们正在访问本地网络摄像头,以便任何人都可以直接测试代码

import cv2
import time
from multiprocessing import Process

def send():
    video_writer = cv2.VideoWriter(
        'appsrc ! '
        'videoconvert ! '
        'x264enc tune=zerolatency speed-preset=superfast ! '
        'rtph264pay ! '
        'udpsink host=127.0.0.1 port=5000',cv2.CAP_GSTREAMER,1,(640,480),True)

    video_getter = cv2.VideoCapture(0)

    while True:

        if video_getter.isOpened():
            ret,frame = video_getter.read()
            video_writer.write(frame)
            # cv2.imshow('send',data_to_stream)
            time.sleep(0.1)   

if __name__ == '__main__':
    s = Process(target=send)
    s.start()
    s.join()
    cv2.destroyAllWindows()

运行此命令时,我们只会收到一个警告:

[ WARN:0] global ../modules/videoio/src/cap_gstreamer.cpp (935) open OpenCV | GStreamer warning: Cannot query video position: status=0,value=-1,duration=-1

然后,我们尝试使用GStreamer中的examples/test-launch通过LAN重新将流作为RTSP重新发布

./test-launch " udpsrc port=5000 ! h264parse ! rtph264pay name=pay0 pt=96"

除了认消息外,这没有其他错误

stream ready at rtsp://127.0.0.1:8554/test

然后VLC无法在此地址打开流。

                     ~$ vlc -v rtsp://127.0.0.1:8554/test
VLC media player 3.0.11 Vetinari (revision 3.0.11-0-gdc0c5ced72)
[000055f5dacf3b10] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
Qt: Session management error: None of the authentication protocols specified are supported
[00007f5ea40010f0] live555 demux error: Failed to connect with rtsp://127.0.0.1:8554/test
[00007f5ea4003120] satip stream error: Failed to setup RTSP session

我想这与我们的管道有关,但是我真的不知道它可能是什么。 任何帮助将不胜感激。预先感谢。

解决方法

您可以在VideoWriter中删除rtph264pay,然后python脚本发送h264数据,并进行测试启动以接收h264数据,先进行rtp打包,然后再进行rtsp。

因此VideoWriter应该是:

video_writer = cv2.VideoWriter(
    'appsrc ! '
    'videoconvert ! '
    'x264enc tune=zerolatency speed-preset=superfast ! '
    'udpsink host=127.0.0.1 port=5000',cv2.CAP_GSTREAMER,1,(640,480),True)
,

我注意到与该主题相关的大多数问题最终都是由他们自己的作者回答的,就像这两个问题

How to Stream PC Webcam with RTSP and Gstreamer on Python

Write OpenCV frames into Gstreamer RTSP server pipeline

它实际上显示了这些问题的具体程度,这就是为什么我决定在这里分享我的想法的原因。目前,这并不是一个完美的解决方案,但它是一种“可行的”方法。

感谢kqmh00的支持,因为它给了我一些见识。

首先,我退后一步,在Python之外使用videotestsrc尝试了一个更简单的示例。经过几次尝试,这些是有效的管道

发件人

gst-launch-1.0 videotestsrc is-live=true ! video/x-raw ! videoconvert ! x264enc tune=zerolatency speed-preset=superfast ! udpsink host=127.0.0.1 port=30000

代祷

./test-launch "udpsrc port=30000 ! h264parse ! rtph264pay name=pay0 pt=96"

接收器

vlc -v rtsp://127.0.0.1:8854/test

好的。它仅证明了可以通过不带rtph264pay的UDP发送视频,test-launch会接收该视频,并以RTP打包格式将其重新发送为RTSP。

接下来,我再次尝试了Python。搜索类似的问题后,我发现this one启发了我正在使用的实际管道,即:

 pipeline = (
        "appsrc format=GST_FORMAT_TIME ! "
        "video/x-raw,format=BGR,width=1280,height=720 ! "
        "videoconvert ! "
        "video/x-raw,format=I420 ! "
        "x264enc tune=zerolatency speed-preset=superfast byte-stream=true threads=2 ! "
        "video/x-h264,stream-format=(string)byte-stream ! "
        "mpegtsmux alignment=7 ! "
        "udpsink host=127.0.0.1 port=30000"
    )

video_writer之外,其余的Python代码都是相同的,它们已使用正确的框架宽度和高度进行了更新:

   video_writer = cv2.VideoWriter(
        pipeline,(1280,720),True)

其他管道( Intercessor Receiver )保持不变。这样,我就可以检索一些漂亮的单色图像(它们完全是灰色或绿色),但是至少我可以检索到一些东西。

VLC 会引发很多错误,例如

[h264 @ 0x7ff8e0001da0] Invalid NAL unit 0,skipping.
[h264 @ 0x7ff8e0001da0] top block unavailable for requested intra mode -1
[h264 @ 0x7ff8e0001da0] error while decoding MB 1 0,bytestream 112420

可能是缺少某些设置或必须明确设置某些属性。我会继续挖掘,但随时可以在此处添加任何可能的改进。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。