GStreamer pipeline recipe: Stream file via RTP using rtpbin

This blog post was published 6 years ago and may or may not have aged well. While reading please keep in mind that it may no longer be accurate or even relevant.

Given an audio/video file encoded with …

ffmpeg -i in.webm -vcodec vp9 -acodec opus -b:v 200k -b:a 80k out.mkv

then the following GStreamer pipeline (I’m using version 1.13.1) will stream it via RTP using rtpbin to localhost ports 50000-50003:

gst-launch-1.0 -v \
rtpbin name=rtpbin \
filesrc location=out.mkv ! matroskademux name=demux \
demux.audio_0 ! rtpopuspay ! rtpbin.send_rtp_sink_0 \
demux.video_0 ! rtpvp9pay ! rtpbin.send_rtp_sink_1 \
rtpbin.send_rtp_src_0 ! udpsink host=127.0.0.1 port=50000 sync=true async=false \
rtpbin.send_rtcp_src_0 ! udpsink host=127.0.0.1 port=50001 sync=false async=false \
rtpbin.send_rtp_src_1 ! udpsink host=127.0.0.1 port=50002 sync=true async=false \
rtpbin.send_rtcp_src_1 ! udpsink host=127.0.0.1 port=50003 sync=false async=false

The receiver outputting the media to screen and speakers:

gst-launch-1.0 -v \
rtpbin name=rtpbin \
udpsrc address=127.0.0.1 port=50000 caps="application/x-rtp, media=audio, encoding-name=OPUS, clock-rate=48000" ! rtpbin.recv_rtp_sink_0 \
udpsrc address=127.0.0.1 port=50001 caps="application/x-rtcp" ! rtpbin.recv_rtcp_sink_0 \
udpsrc address=127.0.0.1 port=50002 caps="application/x-rtp, media=video, encoding-name=VP9, clock-rate=90000" ! rtpbin.recv_rtp_sink_1 \
udpsrc address=127.0.0.1 port=50003 caps="application/x-rtcp" ! rtpbin.recv_rtcp_sink_1 \
rtpbin. ! rtpopusdepay ! queue ! opusdec ! autoaudiosink sync=true \
rtpbin. ! rtpvp9depay ! queue ! avdec_vp9 ! autovideosink sync=true

Notes/Gotchas

  • The sender uses almost no CPU because the media is not transcoded.
  • Instead of vp9dec you can use avdec_vp9.
  • The sync attributes must be specified exactly as given.
  • When the sender is restarted while the client is running, the client terminates with the error streaming stopped, reason not-linked.
  • media, encoding-name and clock-rate attributes are required.
  • The encoding names specified in the receiver must match those of the sender.
  • It is not necessary to specify RTP payload numbers.
  • If on the receiver sync=false, audio and video are not in sync.
  • Above example only supports one receiver. To support multiple receivers, you can multicast the UDP packets to the loopback network device with the following modifications:
    • udpsink options: host=225.0.0.37 auto-multicast=true multicast-iface=lo ttl-mc=0 bind-address=127.0.0.1
    • udpsrc options: address=225.0.0.37 auto-multicast=true multicast-iface=lo ttl-mc=0 bind-address=127.0.0.1
    • Note: 225.0.0.37 is just an example multicast address. ttl-mc=0 is important, otherwise the packets will be forwarded across network boundaries. You should be careful with multicasting, and educate yourself before you try it.

Receiver without rtpbin

To receive without using rtpbin:

gst-launch-1.0 -v \
udpsrc address=127.0.0.1 port=50000 caps="application/x-rtp" ! queue ! rtpopusdepay ! queue ! opusdec ! autoaudiosink sync=true \
udpsrc address=127.0.0.1 port=50002 caps="application/x-rtp" ! queue ! rtpvp9depay ! queue ! vp9dec ! autovideosink sync=true

Here, the sender can be restarted without bringing the receiver down.

If you think you found a mistake in this blog post, or would like to suggest an improvement to this blog post, you can write me an e-mail to the address public dot michael at franzl dot name; as subject please use the prefix "Comment to blog post" and append the post title.
 
Copyright © 2023 Michael Franzl