【问题标题】:Relay RTP Stream with NodeJS使用 NodeJS 中继 RTP 流
【发布时间】:2025-12-04 11:25:01
【问题描述】:

我正在尝试使用 NodeJS 将 RTP 数据包从 Raspberry Pi 中继到我的 Macbook Air。

这是我用来在 Raspberry Pi 上创建视频源的 gstreamer 命令:

gst-launch-1.0 rpicamsrc bitrate=1000000 \
    ! 'video/x-h264,width=640,height=480' \
    ! h264parse \
    ! queue \
    ! rtph264pay config-interval=1 pt=96 \
    ! gdppay \
    ! udpsink host=10.0.0.157 port=3333

然后我通过 NodeJS 从我的 Mac 上的 Raspberry Pi 接收数据报,并使用以下代码将它们转发到我的 Mac 上的端口 5000:

var udp = require('dgram');
var server = udp.createSocket('udp4');

server.on('message',function(msg,info){
    server.send(msg,5000,'0.0.0.0', function(){

    });
});

server.bind(3333);

这是我在 mac 上运行的 gstreamer 命令,用于在端口 5000 上接收 RTP 数据报流:

gst-launch-1.0 udpsrc port=5000 \
    ! gdpdepay \
    ! rtph264depay \
    ! avdec_h264 \
    ! videoconvert \
    ! osxvideosink sync=false

流工作正常,直接从 Raspberry Pi 到端口 5000 上的 gstreamer,但是,当我尝试使用 NodeJS 应用程序作为中介转发数据包时,我从 Mac 上的 gstreamer 收到以下错误:

ERROR: from element /GstPipeline:pipeline0/GstGDPDepay:gdpdepay0: Could not decode stream.
Additional debug info:
gstgdpdepay.c(490): gst_gdp_depay_chain (): /GstPipeline:pipeline0/GstGDPDepay:gdpdepay0:
Received a buffer without first receiving caps

有没有一种方法可以让我使用 NodeJS 作为中介来将 RTP 数据包转发到 gstreamer 客户端?

【问题讨论】:

    标签: javascript node.js raspberry-pi gstreamer


    【解决方案1】:

    通过更改启动服务器/RTP 流的顺序,我能够通过 NodeJS 成功中继来自 Raspberry Pi 的 RTP 流。

    Gstreamer 抛出错误 Received a buffer without first receiving caps,因为我在启动 NodeJS UDP 中继服务器之前启动了 Raspberry Pi 视频流。 Gstreamer 使用称为“Caps Negotation”的过程来确定“optimal solution for the complete pipeline”。此过程发生在客户端播放流之前。当 Raspberry Pi 流在 NodeJS 中继服务器之前启动时,gstreamer 客户端会错过 caps 协商过程并且不知道如何处理数据缓冲区。

    这个设置函数的操作顺序如下:

    (1) 在客户端机器上启动 gstreamer:

    gst-launch-1.0 udpsrc port=5000 \
        ! gdpdepay \
        ! rtph264depay \
        ! avdec_h264 \
        ! videoconvert \
        ! osxvideosink sync=false
    

    (2) 在客户端机器上启动 NodeJS 中继服务器:

    var udp = require('dgram');
    var server = udp.createSocket('udp4');
    
    server.on('message',function(msg,info){
        server.send(msg,5000,'0.0.0.0', function(){
    
        });
    });
    

    (3) 在树莓派上启动视频流

    gst-launch-1.0 rpicamsrc bitrate=1000000 \
        ! 'video/x-h264,width=640,height=480' \
        ! h264parse \
        ! queue \
        ! rtph264pay config-interval=1 pt=96 \
        ! gdppay \
        ! udpsink host=[CLIENT_MACHINE_IP_HERE] port=3333
    

    【讨论】: