使用 GStreamer 打包现有的 h264 流并通过网络将其发送到 VLC
Use GStreamer to pack existing h264 stream and send it over network to VLC
我正在尝试使用 raspivid 和 gstreamer 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 防火墙)。
我正在尝试使用 raspivid 和 gstreamer 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 防火墙)。