Little Deamon.

gstreamer-RTP测试脚本

字数统计: 941阅读时长: 4 min
2019/04/05 Share

kurento提供了一组测试RTP的client应用。里面提供了一组gstreamer的脚本。因为推流的逻辑差不多所以就拿来魔改了一下。主要是增加视频本地播放功能验证pipeline传输是否正常。

need to do:

  1. 解析h264裸流
  2. 去掉音频传输
  3. 增加本地同步播放
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
PEER_A={KMS_AUDIO_PORT} PEER_V={KMS_VIDEO_PORT} PEER_IP={KMS_PUBLIC_IP} \
SELF_PATH="{PATH_TO_VIDEO_FILE}" \
SELF_A=5006 SELF_ASSRC=445566 \
SELF_V=5004 SELF_VSSRC=112233 \
bash -c 'gst-launch-1.0 -e \
rtpbin name=r sdes="application/x-rtp-source-sdes,cname=(string)\"user\@example.com\"" \
filesrc location="$SELF_PATH" ! decodebin name=d \
d. ! queue ! audioconvert ! opusenc \
! rtpopuspay ! "application/x-rtp,payload=(int)96,clock-rate=(int)48000,ssrc=(uint)$SELF_ASSRC" \
! r.send_rtp_sink_0 \
d. ! queue ! videoconvert ! x264enc tune=zerolatency \
! rtph264pay ! "application/x-rtp,payload=(int)103,clock-rate=(int)90000,ssrc=(uint)$SELF_VSSRC" \
! r.send_rtp_sink_1 \
r.send_rtp_src_0 ! udpsink host=$PEER_IP port=$PEER_A bind-port=$SELF_A \
r.send_rtcp_src_0 ! udpsink host=$PEER_IP port=$((PEER_A+1)) bind-port=$((SELF_A+1)) sync=false async=false \
udpsrc port=$((SELF_A+1)) ! r.recv_rtcp_sink_0 \
r.send_rtp_src_1 ! udpsink host=$PEER_IP port=$PEER_V bind-port=$SELF_V \
r.send_rtcp_src_1 ! udpsink host=$PEER_IP port=$((PEER_V+1)) bind-port=$((SELF_V+1)) sync=false async=false \
udpsrc port=$((SELF_V+1)) ! tee name=t \
t. ! queue ! r.recv_rtcp_sink_1 \
t. ! queue ! fakesink dump=true async=false'

这是原本的脚本,基于gst-launch,感叹号左右连接的是两个element,反斜杠是换行符号,没有别的特殊意义。

h264解析与去除音频通道

我们不再需要decodebin,而是需要一个h264parse来解析h264裸流。所以相应去掉的还有decodebin连接的queue以及后面的音频通道。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
PEER_V={KMS_VIDEO_PORT} PEER_IP={KMS_PUBLIC_IP} \
SELF_PATH="{PATH_TO_VIDEO_FILE}" \
SELF_A=5006 SELF_ASSRC=445566 \
SELF_V=5004 SELF_VSSRC=112233 \
bash -c 'gst-launch-1.5 -e \
rtpbin name=r sdes="application/x-rtp-source-sdes,cname=(string)\"user\@example.com\"" \
filesrc location="$SELF_PATH" ! h264parse \
! rtph264pay ! "application/x-rtp,payload=(int)103,clock-rate=(int)90000,ssrc=(uint)$SELF_VSSRC" \
! r.send_rtp_sink_0 \
r.send_rtp_src_0 ! udpsink host=$PEER_IP port=$PEER_V bind-port=$SELF_V \
r.send_rtcp_src_0 ! udpsink host=$PEER_IP port=$((PEER_V+1)) bind-port=$((SELF_V+1)) sync=false async=false \
udpsrc port=$((SELF_V+1)) ! tee name=t \
t. ! queue ! r.recv_rtcp_sink_1 \
t. ! queue ! fakesink dump=true async=false'

本地同步播放

使用gstreamer的tee插件,新建本地的播放通道

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
PEER_V={KMS_VIDEO_PORT} PEER_IP={KMS_PUBLIC_IP} \
SELF_PATH="{PATH_TO_VIDEO_FILE}" \
SELF_A=5006 SELF_ASSRC=445566 \
SELF_V=5004 SELF_VSSRC=112233 \
bash -c 'gst-launch-1.5 -e \
rtpbin name=r \
filesrc location="$SELF_PATH" ! h264parse \
! rtph264pay ! "application/x-rtp,payload=(int)103,clock-rate=(int)90000,ssrc=(uint)$SELF_VSSRC" \
! tee name=echo \
echo. ! queue ! r.send_rtp_sink_0 \
r.send_rtp_src_0 ! udpsink host=$PEER_IP port=$PEER_V bind-port=$SELF_V \
r.send_rtcp_src_0 ! udpsink host=$PEER_IP port=$((PEER_V+1)) bind-port=$((SELF_V+1)) sync=false async=false \
udpsrc port=$((SELF_V+1)) ! tee name=t \
t. ! queue ! r.recv_rtcp_sink_1 \
t. ! queue ! fakesink dump=true async=false \
echo. ! queue ! rtph264depay ! capsfilter caps="video/x-h264" ! h264parse ! avdec_h264 \
! videoconvert ! videoscale ! video/x-raw ! ximagesink '

最终实现效果

可视化gstreamer pipeline

我们尝尝需要将pipeline可视化来方便调试和 (写文档 ,gstreamer提供了这个功能可供我们直接使用
需要做的也是三步

  1. 在脚本目录下新建dot文件夹

  2. 设置环境变量

    1
    GST_DEBUG_DUMP_DOT_DIR=./dot
  3. 运行脚本的时候在gstreamer前加上 GST_DEBUG_DUMP_DOT_DIR=./dot,我们可以整合到我们的脚本中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    PEER_V={KMS_VIDEO_PORT} PEER_IP={KMS_PUBLIC_IP} \
    SELF_PATH="{PATH_TO_VIDEO_FILE}" \
    SELF_A=5006 SELF_ASSRC=445566 \
    SELF_V=5004 SELF_VSSRC=112233 \
    bash -c 'GST_DEBUG_DUMP_DOT_DIR=./dot gst-launch-1.5 -e \
    rtpbin name=r \
    filesrc location="$SELF_PATH" ! h264parse \
    ! rtph264pay ! "application/x-rtp,payload=(int)103,clock-rate=(int)90000,ssrc=(uint)$SELF_VSSRC" \
    ! tee name=echo \
    echo. ! queue ! r.send_rtp_sink_0 \
    r.send_rtp_src_0 ! udpsink host=$PEER_IP port=$PEER_V bind-port=$SELF_V \
    r.send_rtcp_src_0 ! udpsink host=$PEER_IP port=$((PEER_V+1)) bind-port=$((SELF_V+1)) sync=false async=false \
    udpsrc port=$((SELF_V+1)) ! tee name=t \
    t. ! queue ! r.recv_rtcp_sink_1 \
    t. ! queue ! fakesink dump=true async=false \
    echo. ! queue ! rtph264depay ! capsfilter caps="video/x-h264" ! h264parse ! avdec_h264 \
    ! videoconvert ! videoscale ! video/x-raw ! ximagesink '

运行脚本后我们可以在dot目录中找到很多dot文件,找到后缀为PAUSED_PLAYING的dot文件,使用

1
dot -Tpng xxxxxxxx-gst-launch.PAUSED_PLAYING.dot > pipeline.png

将xxxxxxxx-gst-launch.PAUSED_PLAYING.dot输出到pipeline.png,然后看图就好了。下面给一张预览图,因为宽度非常大所以可能看不清,所以自己生成自己的来看吧

CATALOG
  1. 1. need to do:
  2. 2. h264解析与去除音频通道
  3. 3. 本地同步播放
  4. 4. 最终实现效果
  5. 5. 可视化gstreamer pipeline