mirror of
https://github.com/matthew1000/gstreamer-cheat-sheet.git
synced 2024-11-22 00:10:59 +00:00
183 lines
5.9 KiB
Markdown
183 lines
5.9 KiB
Markdown
# RTMP (GStreamer command-line cheat sheet)
|
||
|
||
GStreamer can receive an RTMP stream from an RTMP server. It can also send an RTMP stream to an RTMP server.
|
||
|
||
If you need your own RTMP server, [the Nginx RTMP extension](https://github.com/arut/nginx-rtmp-module) works quite well though is no longer supported.
|
||
|
||
### Play an RTMP stream
|
||
|
||
To play from RTMP server, playbin can be used (as with files and HLS streams):
|
||
|
||
```
|
||
gst-launch-1.0 playbin uri=$RTMP_SRC
|
||
```
|
||
|
||
A test RTMP stream is available at `rtmp://184.72.239.149/vod/BigBuckBunny_115k.mov` which serves as a useful example:
|
||
|
||
```
|
||
gst-launch-1.0 playbin uri='rtmp://184.72.239.149/vod/BigBuckBunny_115k.mov'
|
||
```
|
||
|
||
Instead of using `playbin`, it's possible to get video only with `uridecodebin` then shown with `autovideosink`:
|
||
|
||
```
|
||
gst-launch-1.0 uridecodebin uri=$RTMP_SRC ! autovideosink
|
||
```
|
||
|
||
Or as a step further we can split out into the source and decode too. This does video:
|
||
|
||
```
|
||
gst-launch-1.0 rtmpsrc location=$RTMP_SRC ! decodebin ! autovideosink
|
||
```
|
||
|
||
and this does the audio:
|
||
|
||
```
|
||
gst-launch-1.0 rtmpsrc name=rtmpsrc location=$RTMP_SRC ! decodebin ! \
|
||
queue ! audioconvert ! autoaudiosink
|
||
```
|
||
|
||
We can vget flvdemux to pull out the audio:
|
||
|
||
```
|
||
gst-launch-1.0 rtmpsrc location=$RTMP_SRC ! \
|
||
flvdemux name=t t.audio ! decodebin ! autoaudiosink
|
||
```
|
||
|
||
Incidentally, all of these work with a direct *flv* file:
|
||
|
||
```
|
||
gst-launch-1.0 filesrc location="/Users/clarkm22/workspace/silver/assets/test.flv" ! \
|
||
flvdemux name=t t.audio ! decodebin ! autoaudiosink
|
||
```
|
||
|
||
If you want to use `flvdemux` to do the video, you need to capture the audio too or else it will fail. This example puts it in `fakesink` which is basically discarding it:
|
||
|
||
```
|
||
gst-launch-1.0 rtmpsrc location="$RTMP_SRC" ! \
|
||
flvdemux name=demux \
|
||
demux.audio ! queue ! decodebin ! fakesink \
|
||
demux.video ! queue ! decodebin ! autovideosink
|
||
```
|
||
|
||
You could then use this to capture the RTMP as an MP4, e.g.
|
||
|
||
```
|
||
gst-launch-1.0 -e rtmpsrc location="$RTMP_SRC" ! \
|
||
flvdemux name=demux \
|
||
demux.audio ! queue ! decodebin ! audioconvert ! faac bitrate=32000 ! mux. \
|
||
demux.video ! queue ! decodebin ! videoconvert ! video/x-raw,format=I420 ! x264enc speed-preset=superfast tune=zerolatency psy-tune=grain sync-lookahead=5 bitrate=480 key-int-max=50 ref=2 ! mux. \
|
||
mp4mux name=mux ! filesink location="out.mp4"
|
||
```
|
||
|
||
According to [this conversation](http://gstreamer-devel.966125.n4.nabble.com/flvdemux-working-sometimes-td4677796.html), the following also works, although personally I find it intermittent:
|
||
|
||
```
|
||
export QUEUE="queue max-size-time=0 max-size-bytes=0 max-size-buffers=0"
|
||
|
||
gst-launch-1.0 \
|
||
rtmpsrc location="$RTMP_SRC live=1" ! \
|
||
$QUEUE ! \
|
||
flvdemux name=demux ! \
|
||
$QUEUE ! \
|
||
aacparse ! \
|
||
avdec_aac ! \
|
||
autoaudiosink sync=0 demux.video ! \
|
||
$QUEUE ! \
|
||
h264parse ! \
|
||
avdec_h264 ! \
|
||
$QUEUE ! \
|
||
videoconvert ! \
|
||
autovideosink sync=0
|
||
```
|
||
|
||
### Adding an RTMP as picture-in-Picture
|
||
|
||
This overlays an RTMP source as a picture-in-picture on top of a local filesource (set as `$SRC`)
|
||
|
||
```
|
||
export QUEUE="queue max-size-time=0 max-size-bytes=0 max-size-buffers=0"
|
||
gst-launch-1.0 \
|
||
filesrc location="$SRC" ! \
|
||
decodebin ! videoconvert ! \
|
||
videoscale ! video/x-raw,width=640,height=360 ! \
|
||
compositor name=mix sink_0::alpha=1 sink_1::alpha=1 sink_1::xpos=50 sink_1::ypos=50 ! \
|
||
videoconvert ! autovideosink \
|
||
rtmpsrc location="$RTMP_SRC" ! \
|
||
flvdemux name=demux \
|
||
demux.audio ! $QUEUE ! decodebin ! autoaudiosink \
|
||
demux.video ! $QUEUE ! decodebin ! \
|
||
videoconvert ! \
|
||
videoscale ! video/x-raw,width=320,height=180! \
|
||
mix.
|
||
```
|
||
|
||
## Sending to an RTMP server
|
||
|
||
### Sending a test stream to an RTMP server
|
||
|
||
This will send a test video source:
|
||
|
||
```
|
||
gst-launch-1.0 videotestsrc is-live=true ! \
|
||
queue ! x264enc ! flvmux name=muxer ! rtmpsink location="$RTMP_DEST live=1"
|
||
```
|
||
|
||
This sends both video and audio as a test source:
|
||
|
||
```
|
||
gst-launch-1.0 videotestsrc is-live=true ! \
|
||
videoconvert ! x264enc bitrate=1000 tune=zerolatency ! video/x-h264 ! h264parse ! \
|
||
video/x-h264 ! queue ! flvmux name=mux ! \
|
||
rtmpsink location=$RTMP_DEST audiotestsrc is-live=true ! \
|
||
audioconvert ! audioresample ! audio/x-raw,rate=48000 ! \
|
||
voaacenc bitrate=96000 ! audio/mpeg ! aacparse ! audio/mpeg, mpegversion=4 ! mux.
|
||
```
|
||
|
||
### Send a file over RTMP
|
||
|
||
Audio & video:
|
||
|
||
```
|
||
gst-launch-1.0 filesrc location=$SRC ! \
|
||
qtdemux name=demux \
|
||
demux.video_0 ! queue ! \
|
||
decodebin ! videoconvert ! x264enc bitrate=1000 tune=zerolatency ! video/x-h264 ! h264parse ! \
|
||
video/x-h264 ! queue ! flvmux name=mux ! \
|
||
rtmpsink location=$RTMP_DEST \
|
||
demux.audio_0 ! queue ! decodebin ! audioconvert ! audioresample ! \
|
||
audio/x-raw,rate=48000 ! \
|
||
voaacenc bitrate=96000 ! audio/mpeg ! aacparse ! audio/mpeg, mpegversion=4 ! mux.
|
||
```
|
||
|
||
Just video:
|
||
|
||
```
|
||
gst-launch-1.0 filesrc location=$SRC ! \
|
||
qtdemux name=demux \
|
||
demux.video_0 ! queue ! \
|
||
decodebin ! videoconvert ! x264enc bitrate=1000 tune=zerolatency ! video/x-h264 ! h264parse ! \
|
||
video/x-h264 ! queue ! flvmux name=mux ! \
|
||
rtmpsink location=$RTMP_DEST
|
||
```
|
||
|
||
---
|
||
|
||
Can we work out why a bad RTMP brings down the other mix?
|
||
|
||
```
|
||
export QUEUE="queue max-size-time=0 max-size-bytes=0 max-size-buffers=0"
|
||
gst-launch-1.0 \
|
||
filesrc location="$SRC2" ! \
|
||
decodebin ! videoconvert ! \
|
||
videoscale ! video/x-raw,width=640,height=360 ! \
|
||
compositor name=mix sink_0::alpha=1 sink_1::alpha=1 sink_1::xpos=50 sink_1::ypos=50 ! \
|
||
videoconvert ! autovideosink \
|
||
rtmpsrc location="$RTMP_DEST" ! \
|
||
flvdemux name=demux \
|
||
demux.audio ! $QUEUE ! decodebin ! fakesink \
|
||
demux.video ! $QUEUE ! decodebin ! \
|
||
videoconvert ! \
|
||
videoscale ! video/x-raw,width=320,height=180! \
|
||
mix.
|
||
```
|