繁体   English   中英

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

[英]Read RTSP Stream from UDP sink using Python OpenCV and GStreamer

我们正在开发一种软​​件,可以使用 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, 0, 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数据,test-launch接收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, 0, 1, (640, 480), True)

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

如何在 Python 上使用 RTSP 和 Gstreamer 流式传输 PC 网络摄像头

将 OpenCV 帧写入 Gstreamer RTSP 服务器管道

它实际上显示了这些问题的具体性,这就是为什么我决定在这里分享我的想法。 它现在不是完美的解决方案,但它“有点”有效。

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

首先,我退后videotestsrc在 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

好的。 它仅证明可以通过 UDP 发送视频而无需rtph264pay ,该视频由test-launch接收,并使用 RTP 打包为 RTSP 重新发送。

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

 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"
    )

Python 代码的其余部分是相同的,除了video_writer ,它使用正确的帧宽度和高度进行了更新:

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

其他管道( IntercessorReceiver )保持不变。 有了这个,我可以检索一些非常单色的图像(它们完全是灰色或绿色),但至少我可以检索到一些东西。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM