kurento提供了一组测试RTP的client应用。里面提供了一组gstreamer的脚本。因为推流的逻辑差不多所以就拿来魔改了一下。主要是增加视频本地播放功能验证pipeline传输是否正常。
need to do:
- 解析h264裸流
- 去掉音频传输
- 增加本地同步播放
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提供了这个功能可供我们直接使用
需要做的也是三步
在脚本目录下新建dot文件夹
设置环境变量
1
| GST_DEBUG_DUMP_DOT_DIR=./dot
|
运行脚本的时候在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,然后看图就好了。下面给一张预览图,因为宽度非常大所以可能看不清,所以自己生成自己的来看吧
