【问题标题】:Read RTSP Stream from UDP sink using Python OpenCV and GStreamer使用 Python OpenCV 和 GStreamer 从 UDP 接收器读取 RTSP 流
【发布时间】:2021-02-13 10:33:54
【问题描述】:

我们正在开发一种软​​件,用于使用 GStreamer 使用 RTSP 从两个不同的摄像机流式传输视频。为了简化采集过程,我们将 OpenCV 与 Python 3 结合使用。

问题是:我们想将流推送到 UDP 接收器,通过 LAN 将其作为 RTSP 流重新发布,然后在另一台 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

我想这与我们的管道有关,但我真的不明白它可能是什么。 任何帮助将不胜感激。提前致谢。

【问题讨论】:

    标签: python-3.x opencv video-streaming gstreamer rtsp


    【解决方案1】:

    你可以去掉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)
    

    【讨论】:

    • 感谢您的回答。我希望它会那么简单,但它实际上并没有奏效。它会抛出相同的错误消息。
    • 很抱歉听到这个消息。我的环境中没有opencv。所以我使用下面的命令通过udpsinkgst-launch-1.0 -e v4l2src device=/dev/video0 ! videoconvert ! x264enc tune=zerolatency speed-preset=superfast key-int-max=20 ! udpsink port=5000发送h264数据,然后使用./test-launch "udpsrc port=5000 ! h264parse ! rtph264pay name=pay0 pt=96 "通过udpsrc接收h264数据。之后,我使用 ffplay ffplay rtsp://127.0.0.1:8554/test 播放 rtsp,它可以工作。也许你应该提供更多关于 opencv 中的 test-launch 和 gstreamer 管道的日志
    【解决方案2】:

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

    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
    

    好的。仅证明可以通过 UDP 发送视频而无需 rtph264paytest-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"
        )
    

    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
    

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

    【讨论】:

      猜你喜欢
      • 2020-03-05
      • 2014-10-11
      • 1970-01-01
      • 2020-02-26
      • 2017-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      相关资源
      最近更新 更多