主要包括三个命令行工具的使用:gst-discover,gst-inspect,gst-launch
查看某一文件的基本属性 gst-discoverer-1.0 those_years.mp4
查看目前gstreamer所有可用于构建pipeline的element gst-inspect-1.0
查看某一element的详细信息,包括properties和caps gst-inspect-1.0 v4l2src
查看某一so中包含的plugins gst-inspect-1.0 /usr/local/lib/gstreamer-1.0/libgstaudiomixer.so
一些常见的插件:
videoconvert 颜色空间转换,应该是yuv和rgb等格式的互转 videoscale 对 raw video 做尺寸缩放 rtph264pay 将编码了的x264 packets转换得到rtp数据包 decodebin 集成了demux+(a/v)decode 功能的超级element uridecodebin 集成了 filesrc/souphttpsrc/.. + decodebin 功能的超级element h264parse (看起来对于解包时候很有用,可以省去很多额外的参数让其自动解析,输出就是串行的 h264-packets) queue 队列,gstreamer创建多线程的一种方式,sink pad仅仅将数据放入队列,另外一个线程从队列中取出数据,并传递到下一个Element一些常见的命令行例子:
//测试,videotestsrc 和 audiotestsrc 可以输出未经编码的 video/audio frame gst-launch-1.0 videotestsrc pattern=0 ! xvimagesink gst-launch-1.0 audiotestsrc wave=6 ! audioconvert ! audioresample ! autoaudiosink //添加了caps filter的,gst-inspect videotestsrc可以查看videotestsrc的caps,这里给出其中的一个子集 gst-launch-1.0 videotestsrc ! 'video/x-raw,format=(string)YV12;video/x-raw,format=(string)BGR' ! xvimagesink //直接使用playbin无脑完成播放操作 gst-launch-1.0 playbin uri=file:///home/fang/Desktop/Titanic.ts //decodebin看起来自带了demux的功能,输出为audio/video frame //name可以用来多分支,还可以用name指定pad名,"decoder." 其实是将pad名缺省了 gst-launch-1.0 filesrc location=/home/fang/Desktop/Titanic.ts ! decodebin name=decoder \ decoder. ! queue ! audioconvert ! audioresample ! autoaudiosink \ decoder. ! videoconvert ! xvimagesink gst-launch-1.0 filesrc location=/home/fang/Desktop/Titanic.ts ! decodebin name=decoder \ decoder. ! queue ! audioconvert ! audioresample ! autoaudiosink \ decoder. ! queue ! videoconvert ! xvimagesink //这里多一个queue,貌似影响不大 //将 videotestsrc 产生的raw video data编码为h264数据后,封装为rtp数据通过udp传输出去 gst-launch-1.0 -ve videotestsrc \ ! videoconvert \ ! x264enc noise-reduction=10000 tune=zerolatency byte-stream=true threads=4 key-int-max=15 intra-refresh=true \ ! rtph264pay pt=96 \ ! udpsink host=localhost port=5000 //在接受端接受上面的数据 gst-launch-1.0 -ve udpsrc port=5000 ! application/x-rtp, media=video, clock-rate=90000, encoding-name=H264, payload=96 \ ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! ximagesink sync=false //格式转换,将ts文件中video以x264重新编码,audio以aac格式重新编码,得到test.avi作为输出 gst-launch-1.0 -v uridecodebin uri=file:///home/fang/Desktop/Titanic.ts name=decoder \ decoder. ! queue2 ! videoconvert ! x264enc ! avimux name=mux mux. ! filesink location="test.avi" \ decoder. ! queue2 ! audioconvert ! faac ! mux. //和上面一样的,只是写法更好一些 gst-launch-1.0 -v uridecodebin uri=file:///home/fang/Desktop/Titanic.ts name=decoder \ decoder. ! queue2 ! videoconvert ! x264enc ! avimux name=mux \ decoder. ! queue2 ! audioconvert ! faac ! mux. \ mux. ! filesink location="test.avi" //一边播放声音,一边可视化audio波形(验证可用) gst-launch-1.0 -v audiotestsrc freq=215.0 ! tee name=tee0 \ tee0. ! queue ! audioconvert ! audioresample ! autoaudiosink \ tee0. ! queue ! wavescope shader=0 style=1 ! videoconvert ! autovideosink
//边做格式转换边播放(理论上是没问题的,但不知为何没有test.avi输出??? tee插件有些问题??) #gst-launch-1.0 -v uridecodebin uri=file:///home/fang/Desktop/Titanic.ts name=decoder \ #decoder. ! tee name=tee0 \ #tee0. ! queue2 ! videoconvert ! videoscale ! ximagesink \ #tee0. ! queue2 ! videoconvert ! x264enc ! avimux name=mux \ #mux. ! filesink location="test.avi" \ #decoder. ! tee name=tee1 \ #tee1. ! queue2 ! audioconvert ! autoaudiosink \ #tee1. ! queue2 ! audioconvert ! faac ! mux.
//解析范式,能解析出多少就多少,例如下面 rtpbin name=rtpbin latency=100 就是一个解析范式,并没有立刻使用 //而是作为 uridecodebin 的其中一个tee的输出(rtpbin.send_rtp_sink_0)使用 。同时 rtpbin.send_rtp_src_0 ! ... //作为一个新起的范式被解析。下面的命令未经过验证 #gst-launch-1.0 -v rtpbin name=rtpbin latency=100 uridecodebin uri=file:///home/fang/Desktop/Titanic.ts name=decoder \ #decoder. ! tee name=tee0 \ #tee0. ! queue2 ! videoconvert ! videoscale ! ximagesink \ #tee0. ! queue2 ! videoconvert ! x264enc ! rtph264pay pt=96 ! queue2 ! rtpbin.send_rtp_sink_0 rtpbin.send_rtp_src_0 ! \ # queue2 ! udpsink host=192.168.1.1 port=5000 async=false \ #decoder. ! tee name=tee1 \ #tee1. ! queue2 ! audioconvert ! autoaudiosink \ #tee1. ! queue2 ! audioconvert ! faac ! rtpmp4apay pt=96 ! queue2 ! rtpbin.send_rtp_sink_1 rtpbin.send_rtp_src_1 ! \ # queue2 ! udpsink host=192.168.1.1 port=5003 async=false
//和上面一样的,只是写法更好一些 gst-launch-1.0 -v \ rtpbin name=rtpbin latency=100 \ uridecodebin uri=file:///home/fang/Desktop/Titanic.ts name=decoder \ decoder. ! tee name=tee0 \ tee0. ! queue2 ! videoconvert ! videoscale ! ximagesink \ tee0. ! queue2 ! videoconvert ! x264enc ! rtph264pay pt=96 ! queue2 ! rtpbin.send_rtp_sink_0 \ decoder. ! tee name=tee1 \ tee1. ! queue2 ! audioconvert ! autoaudiosink \ tee1. ! queue2 ! audioconvert ! faac ! rtpmp4apay pt=96 ! queue2 ! rtpbin.send_rtp_sink_1 \ rtpbin.send_rtp_src_0 ! queue2 ! udpsink host=192.168.1.1 port=5000 async=false \ rtpbin.send_rtp_src_1 ! queue2 ! udpsink host=192.168.1.1 port=5003 async=false
//接收端?未经过验证 #gst-launch-1.0 -v rtpbin name=rtpbin latency=100 \ #udpsrc caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H264,sprop-parameter-sets=(string)\"Z0LAH9kAtD2wEQAAAwABdzWUAA8YMkgA\\,aMuMsg\\=\\=\",ssrc=(uint)2094326868,payload=(int)96,clock-base=(uint)2855623946,seqnum-base=(uint)57709" \ #port=5000 ! queue ! rtpbin.recv_rtp_sink_0 rtpbin. ! rtph264depay ! tee name=teevideo \ #teevideo. ! avdec_h264 ! videoscale ! videoconvert ! autovideosink \ #teevideo. ! queue ! "video/x-h264,width=720,height=480,framerate=(fraction)25/1" ! avdec_h264 ! videoconvert ! avenc_mjpeg ! avimux name=mux \ #mux. ! filesink location="test.avi" \ #\ #udpsrc caps="application/x-rtp,media=(string)audio,clock-rate=(int)44100,encoding-name=(string)MP4A-LATM,cpresent=(string)0,config=(string)40002420,ssrc=(uint)277283185,payload=(int)96,clock-base=(uint)3973143737,seqnum-base=(uint)63683" \ #port=5003 ! queue ! rtpbin.recv_rtp_sink_1 rtpbin. ! rtpmp4adepay ! tee name=teeaudio \ #teeaudio. ! queue ! faad ! audioconvert ! autoaudiosink \ #teeaudio. ! queue ! aacparse ! mux.
关于摄像头:
//查看摄像头支持的 formats:apt-get install v4l-utils, v4l2-ctl --list-formats-ext ioctl: VIDIOC_ENUM_FMT Index : 0 Type : Video Capture Pixel Format: 'YUYV' Name : YUYV 4:2:2 Size: Discrete 640x480 Interval: Discrete 0.033s (30.000 fps) Size: Discrete 352x288 Interval: Discrete 0.033s (30.000 fps) Size: Discrete 320x240 Interval: Discrete 0.033s (30.000 fps) Size: Discrete 176x144 Interval: Discrete 0.033s (30.000 fps) Size: Discrete 160x120 Interval: Discrete 0.033s (30.000 fps) //使用gstreamer实时显示摄像头数据, gst-launch-1.0 -ve v4l2src ! video/x-raw,framerate=30/1 ! videoconvert ! autovideosink gst-launch-1.0 v4l2src ! video/x-raw,framerate=30/1 ! videoconvert ! autovideosink gst-launch-1.0 v4l2src ! 'video/x-raw,format=(string)YUY2,framerate=30/1' ! videoconvert ! autovideosink //caps filter限制越多,越容易出现 streaming stopped, reason not-negotiated (-4) gst-launch-1.0 v4l2src ! 'video/x-raw,format=(string)YUY2,framerate=30/1' ! videoconvert ! videoscale ! 'video/x-raw,width=1280,height=960' ! autovideosink //录制摄像头数据得到 out.264,可以使用ffplay正常播放 gst-launch-1.0 -ve v4l2src ! video/x-raw,framerate=30/1 ! videoconvert ! x264enc ! filesink location='./out.h264' //将摄像头数据经过x264编码后,封装为ts包,通过 udpsink 发送到127.0.0.1:5000 gst-launch-1.0 -ve v4l2src ! video/x-raw,framerate=30/1 \ ! videoconvert \ ! x264enc noise-reduction=10000 tune=zerolatency byte-stream=true threads=4 key-int-max=15 intra-refresh=true \ ! mpegtsmux \ ! udpsink host=localhost port=5000 //接收端显示从 udpsrc 拿到的数据(经过验证可以正常播放) gst-launch-1.0 -ve udpsrc port=5000 ! tsparse ! tsdemux ! h264parse ! avdec_h264 ! videoconvert ! ximagesink sync=false //同上,只是没有经过 mpegtsmux 变为ts包,而是打包成rtp数据 gst-launch-1.0 -ve v4l2src ! video/x-raw,framerate=30/1 \ ! videoconvert \ ! x264enc noise-reduction=10000 tune=zerolatency byte-stream=true threads=4 key-int-max=15 intra-refresh=true \ ! rtph264pay pt=96 \ ! udpsink host=localhost port=5000 //接收端显示从 udpsrc 拿到的数据(经过验证可以正常播放)。因为没有parse元素,所以需要指定'payload...'等很多参数 gst-launch-1.0 -ve udpsrc port=5000 ! application/x-rtp, media=video, clock-rate=90000, encoding-name=H264, payload=96 \ ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! ximagesink sync=false
以上使用的命令都可以在应用程序中通过 gst_parse_launch()这个api完成。 关于如何生成pipeline构件图,可以参看https://blog.csdn.net/u013554213/article/details/98078955. 总结一下就是:
sudo apt-get install graphviz export GST_DEBUG_DUMP_DOT_DIR=/home/fang/gstreamer/gst_pipeline_pngs gst-launch-1.0 ..... dot -Tpng /home/fang/gstreamer/gst_pipeline_pngs/xxx.PLAYING_PAUSED.dot >pipeline.png至于在code中生成pipeline图,zx_gst_player是将 GST_DEBUG_BIN_TO_DOT_FILE(xxx) 放在了 change_state函数ready_to_pause & paused_to_playing 中。运行时 GST_DEBUG_DUMP_DOT_DIR=/data/ zx_gst_player -p 0
https://gstreamer.freedesktop.org/dev/ https://gstreamer.freedesktop.org/documentation/tools/gst-launch.html?gi-language=c https://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/tests/examples/rtp?h=0.10 http://orangeamoy.com/2019/06/28/GStreamerAndDeepStream/ https://recomm.cnblogs.com/blogpost/9198471 https://www.cnblogs.com/dong1/p/10423743.html https://www.cnblogs.com/huty/p/8517326.html https://blog.csdn.net/u010312436/article/details/53668083