使用 GStreamer 打包现有的 h264 流并通过网络将其发送到 VLC

Use GStreamer to pack existing h264 stream and send it over network to VLC

我正在尝试使用 raspividgstreamer cli 通过网络从 Raspberry PI 摄像头流式传输。我希望能够在客户端上使用 VLC "open network stream" 查看流。

这与问题 GStreamer rtp stream to vlc 有关,但我的并不完全相同。我的想法是利用 raspivid 的现有 h264 输出,而不是对我的 PI 相机的原始输出进行编码,将其多路复用到适当的容器中并通过 TCP 或 UDP 发送。

我能够使用此管道成功地将 raspivid 的 h264 输出捕获到 mp4 文件(具有正确的 fps 和长度信息):

raspivid -n -w 1280 -h 720 -fps 24 -b 4500000 -a 12 -t 30000 -o - | \
gst-launch-1.0 -v fdsrc ! video/x-h264, width=1280, height=720, framerate=24/1 ! \ 
h264parse ! mp4mux ! filesink location="videofile.mp4"

但是,当我尝试通过网络流式传输此内容时:

raspivid -n -w 1280 -h 720 -fps 24 -b 4500000 -a 12 -t 0 -o - | \
gst-launch-1.0 -v fdsrc ! video/x-h264, width=1280, height=720, framerate=24/1 ! \
h264parse ! mpegtsmux ! rtpmp2tpay ! udpsink host=192.168.1.20 port=5000

...并尝试在 VLC 上使用 rtp://192.168.1.20:5000 打开流,它报告错误。

编辑:好的,我错误地认为 udpsink 侦听传入连接。然而,在将管道的最后一部分更改为使用我客户端的 IP 地址 ! udpsink host=192.168.1.77 port=5000 并尝试在 VLC 上使用 udp://@:5000 打开它后,播放器没有显示任何内容(PI 和接收计算机都是在同一个 LAN 上,我可以在客户端上看到传入的网络流量)。

有谁知道如何正确构建一个 gstreamer 管道来通过网络传输现有的 h264 流,可以在客户端上由 vanilla VLC 播放?

假设这是由于缺少 SPS/PPS 数据。例如。如果您先启动 VLC,然后启动 Raspberry PI 上的视频管道,它可能会起作用。默认情况下,SPS/PPS headers 很可能只在流的开头发送一次。

如果接收器错过 SPS/PPS headers 它将无法解码 H.264 流。我想这可以通过使用 h264parse.

config-interval=-1 属性 来解决

使用该选项 SPS/PPS 数据应该在每个 IDR-frame 之前发送,这应该每隔几秒发生一次 - 取决于编码器。

另一件事是您不需要使用 rtpmp2tpay 块。直接通过 UDP 发送 MPEG TS 就足够了。

话虽如此,管道应该是这样的:

raspivid -n -w 1280 -h 720 -fps 24 -b 4500000 -a 12 -t 0 -o - | \
gst-launch-1.0 -v fdsrc ! \
video/x-h264, width=1280, height=720, framerate=24/1 ! \
h264parse config-interval=-1 ! mpegtsmux ! udpsink host=192.168.1.77 port=5000

192.168.1.77 是客户端 运行 VLC 在 udp://@5000 的 IP 地址。此外,请确保 没有防火墙 阻止传入客户端的 UDP 流量(尤其是 Windows 防火墙)。