【问题标题】:GStreamer: Multiple RTMP sources, Picture in Picture to mux on a Jetson Nano, then to be used with RTMP pipeline with BelaboxGStreamer:多个 RTMP 源,画中画在 Jetson Nano 上复用,然后与带有 Belabox 的 RTMP 管道一起使用
【发布时间】:2022-04-07 22:57:24
【问题描述】:

我的目标是在画中画合成中拥有 (2) 个 RTMP 源,将其编码为 h265 mpegts,仅从 cam1 rtmp 源混合音频,然后将其发送到应用程序;

这就是我在脑海中的看法,但我可能错了:

[已确认] 正在工作(在设备上)画中画管道:

使用的设备:Camlink 4k (Sony Action Cam FDR-x3000) 和 Logitech c920

v4l2src device=/dev/video0 ! nvvidconv ! queue ! comp.sink_0
v4l2src device=/dev/video1 ! video/x-raw, width=800, height=448, framerate=30/1, format=YUY2 !
videobox left=-4 right=-4 top=-4 bottom=-4 ! nvvidconv ! queue ! comp.sink_1
 
nvcompositor name=comp sink_0::width=1920 sink_0::height=1080 sink_1::width=640 sink_1::height=360 sink_1::xpos=1266 sink_1::ypos=706 !
queue ! identity name=v_delay signal-handoffs=TRUE ! nvvidconv interpolation-method=5 !
nvv4l2h265enc control-rate=1 qp-range=\"28,50:0,38:0,50\" iframeinterval=60 preset-level=4 maxperf-enable=true EnableTwopassCBR=true insert-sps-pps=true name=venc_bps !
h265parse config-interval=-1 ! queue max-size-time=10000000000 max-size-buffers=1000 max-size-bytes=41943040 !
mpegtsmux name=mux ! appsink name=appsink
 
alsasrc device=hw:2 ! identity name=a_delay signal-handoffs=TRUE ! volume volume=1.0 !
audioconvert ! opusenc bitrate=320000 ! opusparse ! queue ! mux.

[已确认] 工作 RTMP 管道:

使用的设备:Samsung s10e 使用 Larix Broadcaster 通过 RTMP 流式传输 x264

rtmpsrc location=rtmp://127.0.0.1/live/cam1 ! 
flvdemux name=demux 

demux.video ! identity name=v_delay signal-handoffs=TRUE ! h264parse ! nvv4l2decoder ! nvvidconv ! 
textoverlay text=\'\' valignment=top halignment=right font-desc=\"Sans, 10\" name=overlay ! queue ! 
videorate ! video/x-raw,framerate=60/1 !
nvvidconv interpolation-method=5 ! 
nvv4l2h265enc control-rate=1 qp-range=\"28,50:0,38:0,50\" iframeinterval=60 preset-level=4 maxperf-enable=true EnableTwopassCBR=true insert-sps-pps=true name=venc_bps ! 
h265parse config-interval=-1 ! queue max-size-time=10000000000 max-size-buffers=1000 max-size-bytes=41943040 ! mux. 

demux.audio ! aacparse ! avdec_aac ! identity name=a_delay signal-handoffs=TRUE ! volume volume=1.0 ! 
audioconvert ! opusenc bitrate=128000 ! opusparse ! queue max-size-time=10000000000 max-size-buffers=1000 ! mux. 

mpegtsmux name=mux ! 
appsink name=appsink

我所有的尝试都失败了;

这些是我的尝试:

尝试1:

rtmpsrc name=cam1 location=rtmp://127.0.0.1/live/cam1 ! flvdemux name=demux0 ! queue ! demux0.video ! identity name=v_delay signal-handoffs=TRUE ! h264parse ! nvv4l2decoder ! nvvidconv ! queue ! comp.sink_0 
rtmpsrc name=cam2 location=rtmp://127.0.0.1/live/cam2 ! flvdemux name=demux1 ! queue ! demux1.video ! identity signal-handoffs=TRUE ! h264parse ! nvv4l2decoder ! nvvidconv ! queue ! comp.sink_1 

nvcompositor name=comp sink_0::xpos=0 sink_0::ypos=0 sink_0::width=1920 sink_0::height=1080 sink_1::xpos=0 sink_1::ypos=240 sink_1::width=320 sink_1::height=240 ! 
videorate ! video/x-raw,framerate=60/1 ! 
nvvidconv interpolation-method=5 ! 

nvv4l2h265enc control-rate=1 qp-range=\"28,50:0,38:0,50\" iframeinterval=60 preset-level=4 maxperf-enable=true EnableTwopassCBR=true insert-sps-pps=true name=venc_bps ! 
h265parse config-interval=-1 ! queue max-size-time=10000000000 max-size-buffers=1000 max-size-bytes=41943040 ! mux. 

demux0. ! queue ! audio/mpeg ! decodebin ! audioconvert ! audioresample ! autoaudiosink 

mpegtsmux name=mux ! 
appsink name=appsink

尝试2:

rtmpsrc name=cam1 location=rtmp://127.0.0.1/live/cam1 ! 
flvdemux name=demux0
demux0.video ! identity name=v_delay0 signal-handoffs=TRUE ! h264parse ! nvv4l2decoder ! nvvidconv ! queue ! comp.sink_0

rtmpsrc name=cam2 location=rtmp://127.0.0.1/live/cam2 ! 
flvdemux name=demux1
demux1.video ! identity name=v_delay1 signal-handoffs=TRUE ! h264parse ! nvv4l2decoder ! videobox left=-4 right=-4 top=-4 bottom=-4 ! nvvidconv ! queue ! comp.sink_1

nvcompositor name=comp sink_0::width=1920 sink_0::height=1080 sink_1::width=640 sink_1::height=360 sink_1::xpos=10 sink_1::ypos=10 ! 
queue ! identity name=v_delay0 signal-handoffs=TRUE ! nvvidconv interpolation-method=5 ! 
queue ! identity name=v_delay1 signal-handoffs=TRUE ! nvvidconv interpolation-method=5 ! 
nvv4l2h265enc control-rate=1 qp-range=\"28,50:0,38:0,50\" iframeinterval=60 preset-level=4 maxperf-enable=true EnableTwopassCBR=true insert-sps-pps=true name=venc_bps ! 
h265parse config-interval=-1 ! queue max-size-time=10000000000 max-size-buffers=1000 max-size-bytes=41943040 ! 
mpegtsmux name=mux ! appsink name=appsink

demux0.audio ! aacparse ! avdec_aac ! identity name=a_delay signal-handoffs=TRUE ! volume volume=1.0 ! 
audioconvert ! opusenc bitrate=320000 ! opusparse ! queue max-size-time=10000000000 max-size-buffers=1000 ! mux. 

当前 GStreamer 配置:


更新 1:我尝试了@SeB\ 的解决方案,但没有奏效:

以下是一些显示该过程的屏幕截图:

端口 4953 上的 videotestsrc:

端口 4954 上的 videotestsrc:

完整的测试管道:


更新 2:解决方案:

通过利用@SeB\'s answer并稍微修改一下,我能够将两个 rtmpsrc\'s 组合在一起,然后以不同的密钥将其发送到同一个 rtmp 服务器,并使用随附的 rtmp 管道与belacoder。

在我的测试过程中,这仅适用于遵循 belabox 教程,而不是使用预制图像。

这是我使用的管道:

gst-launch-1.0 -v \\
 rtmpsrc location=rtmp://127.0.0.1/live/cam1 ! flvdemux name=demux0 \\
   demux0. ! queue ! video/x-h264 ! h264parse ! nvv4l2decoder ! nvvidconv ! \'video/x-raw(memory:NVMM),format=RGBA,width=1920,height=1080,pixel-aspect-ratio=1/1\' ! identity ! queue ! comp.sink_0 \\
   demux0. ! queue ! audio/mpeg ! mux. \\
 rtmpsrc location=rtmp://127.0.0.1/live/cam2 ! flvdemux name=demux1 \\
   demux1. ! queue ! video/x-h264 ! h264parse ! nvv4l2decoder ! nvvidconv ! video/x-raw,format=YUY2,width=800,height=448,pixel-aspect-ratio=1/1 ! videobox left=-4 right=-4 top=-4 bottom=-4 ! nvvidconv ! \'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1\' ! identity ! queue ! comp.sink_1 \\
 nvcompositor name=comp sink_0::xpos=0 sink_0::ypos=0 sink_0::width=1920 sink_0::height=1080 sink_0::zorder=1 sink_1::xpos=0 sink_1::ypos=0 sink_1::width=808,sink_1::height=456 sink_1::zorder=2 ! \'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1\' ! nvvidconv ! \'video/x-raw(memory:NVMM),format=NV12\' \\
   ! nvv4l2h264enc control-rate=1 qp-range=\"28,50:0,38:0,50\" iframeinterval=60 preset-level=4 maxperf-enable=true EnableTwopassCBR=true insert-sps-pps=true name=venc_bps ! h264parse config-interval=-1 ! queue max-size-time=10000000000 max-size-buffers=1000 max-size-bytes=41943040 ! mux. \\
 flvmux name=mux ! rtmpsink location=\'location=rtmp://127.0.0.1/live/cam3 live=1\'

然后我刚刚编辑了belacoder附带的rtmp管道以从/cam3中提取。

在这里,它通过 SRTLA 使用 belaUI + belacoder 在 OBS Studio 中工作:

这是我在 belaUI/belacoder 中使用的管道:

rtmpsrc location=rtmp://127.0.0.1/live/cam3 ! 
flvdemux name=demux 

demux.video ! identity name=v_delay signal-handoffs=TRUE ! h264parse ! nvv4l2decoder ! nvvidconv ! 
textoverlay text=\'\' valignment=top halignment=right font-desc=\"Sans, 10\" name=overlay ! queue ! 
nvvidconv interpolation-method=5 ! 
nvv4l2h265enc control-rate=1 qp-range=\"28,50:0,38:0,50\" iframeinterval=60 preset-level=4 maxperf-enable=true EnableTwopassCBR=true insert-sps-pps=true name=venc_bps ! 
h265parse config-interval=-1 ! queue max-size-time=10000000000 max-size-buffers=1000 max-size-bytes=41943040 ! mux. 

demux.audio ! aacparse ! avdec_aac ! identity name=a_delay signal-handoffs=TRUE ! volume volume=1.0 ! 
audioconvert ! voaacenc bitrate=128000 ! aacparse ! queue max-size-time=10000000000 max-size-buffers=1000 ! mux. 

mpegtsmux name=mux ! 
appsink name=appsink

我的设置对于我在 belabox (Jetson-nano) 上运行的 rtmp 服务器是唯一的,所以请记住这一点。

这是在 belaUI 中选择的最终管道:

一旦你选择了它,你所要做的就是点击开始,你可以利用连接到 belabox 的所有互联网连接:

请记住,这真的很挑剔,如果您的一个 rtmps 源废话它会破坏整个管道,因此当所有 rtmp 源都在本地环境中并且您将 gts-launch 管道作为服务运行时,这最有效。

如果您想了解有关开源 DIY 项目 belabox 的更多信息或想联系我,请查看我的个人资料链接 @https://stackoverflow.com/users/3331416/b3ck

    标签: gstreamer rtmp nvidia-jetson nvidia-jetson-nano


    【解决方案1】:

    刚刚尝试模拟您的来源(我没有 RTMP 服务器,但应该直接尝试适应):

    # Cam 1 1920x1080@30fps with audio
    gst-launch-1.0 -e videotestsrc ! video/x-raw,format=NV12,width=320,height=240,framerate=30/1 ! nvvidconv ! 'video/x-raw(memory:NVMM),format=NV12,width=1920,height=1080,pixel-aspect-ratio=1/1' ! nvv4l2h264enc ! h264parse ! queue ! flvmux name=mux    audiotestsrc ! audioconvert ! voaacenc ! queue ! mux.   mux. ! tcpserversink port=4953
    
    # Cam2 with 800x448@30fps
    gst-launch-1.0 -e videotestsrc pattern=ball ! video/x-raw,format=NV12,width=320,height=240,framerate=30/1 ! nvvidconv ! 'video/x-raw(memory:NVMM),format=NV12,width=800,height=448,pixel-aspect-ratio=1/1' ! nvv4l2h264enc ! h264parse ! queue ! flvmux ! tcpserversink port=4954
    

    然后,这应该输出视频和音频:

    gst-launch-1.0 -v \
     tcpclientsrc port=4953 ! flvdemux name=demux0 ! h264parse ! nvv4l2decoder ! nvvidconv ! 'video/x-raw(memory:NVMM),format=RGBA,width=1920,height=1080,pixel-aspect-ratio=1/1' ! identity ! queue ! comp.sink_0 \
     tcpclientsrc port=4954 ! flvdemux name=demux1 ! h264parse ! nvv4l2decoder ! nvvidconv ! video/x-raw,format=YUY2,width=800,height=448,pixel-aspect-ratio=1/1 !  nvvidconv ! 'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1' ! identity ! queue ! comp.sink_1 \
     nvcompositor name=comp sink_0::xpos=0 sink_0::ypos=0 sink_0::width=1920 sink_0::height=1080 sink_0::zorder=1 sink_1::xpos=0 sink_1::ypos=0 sink_1::width=800,sink_1::height=448 sink_1::zorder=2 ! 'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1' ! nvvidconv ! autovideosink \
     demux0. ! queue ! audio/mpeg ! decodebin ! audioconvert ! audioresample ! autoaudiosink
    

    如果没问题,您可以对合成视频进行 H265 编码(请注意,在此处添加视频框,第二帧现在将具有 808x456 大小)并转发 mpeg 音频:

    gst-launch-1.0 -v \
     tcpclientsrc port=4953 ! flvdemux name=demux0 \
       demux0. ! queue ! video/x-h264 ! h264parse ! nvv4l2decoder ! nvvidconv ! 'video/x-raw(memory:NVMM),format=RGBA,width=1920,height=1080,pixel-aspect-ratio=1/1' ! identity ! queue ! comp.sink_0 \
       demux0. ! queue ! audio/mpeg ! tsmux. \
     tcpclientsrc port=4954 ! flvdemux name=demux1 \
       demux1. ! queue ! video/x-h264 ! h264parse ! nvv4l2decoder ! nvvidconv ! video/x-raw,format=YUY2,width=800,height=448,pixel-aspect-ratio=1/1 ! videobox left=-4 right=-4 top=-4 bottom=-4 ! nvvidconv ! 'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1' ! identity ! queue ! comp.sink_1 \
     nvcompositor name=comp sink_0::xpos=0 sink_0::ypos=0 sink_0::width=1920 sink_0::height=1080 sink_0::zorder=1 sink_1::xpos=0 sink_1::ypos=0 sink_1::width=808,sink_1::height=456 sink_1::zorder=2 ! 'video/x-raw(memory:NVMM),format=RGBA,pixel-aspect-ratio=1/1' ! nvvidconv ! 'video/x-raw(memory:NVMM),format=NV12' \
       ! nvv4l2h265enc control-rate=1 qp-range="28,50:0,38:0,50" iframeinterval=60 preset-level=4 maxperf-enable=true EnableTwopassCBR=true insert-sps-pps=true name=venc_bps ! h265parse config-interval=-1 ! queue max-size-time=10000000000 max-size-buffers=1000 max-size-bytes=41943040 ! tsmux. \
     mpegtsmux name=tsmux ! appsink name=appsink
    
    

    【讨论】:

    • 非常感谢,我尝试了您的解决方案,这是我的应用程序遇到的错误,日志太大,无法在此处发布,请查看此 pastebin:pastebin.com/TwJe2pYY 我还在我的原始答案中添加了我的工作显示我尝试过的内容以及随之而来的错误。
    • 编辑了我的答案。您可以重试。
    • 仍然出现错误:i.imgur.com/cKpmMGS.png
    • 嗯....我没有在我的管道中看到涉及 uri 属性...您尝试过我的确切管道吗?我可以使用 L4T R32.6.1 在 Jetson AGX Xavier 上确认这些工作。
    • 是的,我使用了您的确切管道,我使用的是 Jetson Nano
    猜你喜欢
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多