Gstreamer:udpsink/udpsrc 与 tcpserversink/tcpclientsrc

Dav*_*ams 2 gstreamer

我对 gstreamer 非常陌生,但经过大量研究,我现在设法创建了自己的工作管道,通过 UDP 传输将网​​络摄像头从 Raspberry PI Zero 流式传输到 PC。我对自己的进步很满意!:)

但我正在努力创建一个 TCP 传输......

此管道在 UDP 上完美运行:(注意:使用测试视频源和 JPEG 编码进行了简化):

Server UDP (192.168.2.1):
gst-launch-1.0 videotestsrc is-live=true ! jpegenc ! rtpjpegpay  ! udpsink host=192.168.2.13  port=7001

Client UDP (192.168.2.13):
gst-launch-1.0 udpsrc port=7001 ! application/x-rtp,encoding-name=JPEG ! rtpjpegdepay ! jpegdec ! autovideosink
Run Code Online (Sandbox Code Playgroud)

...但是当我使用具有完全相同元素的 TCP 接收器/源时,我只收到错误消息。

使用tcpserversinktcpclientsrc修改后的管道:

Server TCP (192.168.2.1):
gst-launch-1.0 videotestsrc is-live=true ! jpegenc ! rtpjpegpay  ! tcpserversink port=7001

Client TCP (192.168.2.13):
gst-launch-1.0 tcpclientsrc host=192.168.2.1 port=7001 ! application/x-rtp,encoding-name=JPEG ! rtpjpegdepay ! jpegdec ! autovideosink
Run Code Online (Sandbox Code Playgroud)

尝试 1:tcpserversink 端口=7001

ERROR: Failed to connect to host '192.168.2.1:7001': No connection could be made because the target machine actively refused it.
Run Code Online (Sandbox Code Playgroud)

尝试 2:tcpserversink 主机=本地主机端口=7001

ERROR: from element /GstPipeline:pipeline0/GstTCPClientSrc:tcpclientsrc0: Could not open resource for reading.
Run Code Online (Sandbox Code Playgroud)

尝试 3:tcpserversink 主机=127.0.0.1 端口=7001

ERROR: from element /GstPipeline:pipeline0/GstTCPClientSrc:tcpclientsrc0: Could not open resource for reading.
Run Code Online (Sandbox Code Playgroud)

尝试 4:tcpserversink 主机=192.168.2.1 端口=7001

ERROR: from element /GstPipeline:pipeline0/GstTCPClientSrc:tcpclientsrc0: Internal data stream error.
Run Code Online (Sandbox Code Playgroud)

尝试 5:tcpserversink 主机=0.0.0.0 端口=7001

ERROR: from element /GstPipeline:pipeline0/GstTCPClientSrc:tcpclientsrc0: Internal data stream error.
Run Code Online (Sandbox Code Playgroud)

我想我应该能够在不破坏管道的情况下替换 src 和 sink 元素,所以我一定是遗漏了一些东西。

如果您对此有所了解,我将不胜感激。

aha*_*son 5

您可以通过以下两种方式之一解决它(至少)。第一个是在您的媒体类型的 rtp 负载程序之后添加 rtpstreampay 元素。

https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good/html/gst-plugins-good-plugins-rtpstreampay.html

服务器:

gst-launch-1.0 videotestsrc is-live=true \
    ! jpegenc \
    ! rtpjpegpay \
    ! rtpstreampay \
    ! tcpserversink port=7001
Run Code Online (Sandbox Code Playgroud)

客户:

gst-launch-1.0 tcpclientsrc port=7001 \
    ! application/x-rtp-stream,encoding-name=JPEG \
    ! rtpstreamdepay \
    ! rtpjpegdepay \
    ! jpegdec \
    ! autovideosink
Run Code Online (Sandbox Code Playgroud)

第二种方法是使用多路复用器而不是 rtp 有效载荷器,就像 matroskamux 这样非常通用的东西。

服务器:

gst-launch-1.0 videotestsrc is-live=true \
    ! jpegenc \
    ! matroskamux \
    ! tcpserversink port=7001
Run Code Online (Sandbox Code Playgroud)

客户:

gst-launch-1.0 tcpclientsrc port=7001 \
    ! matroskademux \
    ! jpegdec \
    ! autovideosink
Run Code Online (Sandbox Code Playgroud)

如果您想要进行客户端/服务器 rtp 连接,您可能还想查看 GstRtspServer。像这样的简单 Python 脚本将充当服务器。

rtspserver.py

import gi
gi.require_version('Gst','1.0')
gi.require_version('GstRtspServer','1.0')
from gi.repository import Gst, GObject, GstRtspServer

Gst.init(None)
mainloop = GObject.MainLoop()
server = GstRtspServer.RTSPServer()
factory = GstRtspServer.RTSPMediaFactory()
factory.set_launch((
    'videotestsrc is-live=true '
    '! jpegenc '
    '! rtpjpegpay name=pay0 pt=26'
))
# allow multiple connections
factory.set_shared(True)
mounts = server.get_mount_points()
mounts.add_factory('/live', factory)
server.attach(None)
mainloop.run()
Run Code Online (Sandbox Code Playgroud)

您可以使用这样的管道来查看输出。

gst-launch-1.0 \
    rtspsrc location=rtsp://localhost:8554/live latency=100 \
    ! rtpjpegdepay \
    ! jpegdec \
    ! autovideosink
Run Code Online (Sandbox Code Playgroud)