Stream raw vorbis audio over UDP or TCP with GStreamer


I have posted before about streaming a vorbis audio stream using TCP, muxed as WebM, so that the container header provides the necessary information regarding the audio stream to the receiver. I have also posted about streaming raw audio using RTP over UDP. All that works fine, but I wanted to try doing the same using just UDP or TCP, without resorting to a container format or other protocol.

Using UDP

The receiver starts the pipeline first, so it can receive the right headers:

gst-launch -v udpsrc port=9001 ! vorbisdec ! audioconvert ! alsasink sync=false

The sender then starts a pipeline thus:

gst-launch -v autoaudiosrc ! audioconvert ! audioresample ! vorbisenc ! multiudpsink client="localhost:9001,localhost:9002"

I have used a multiudpsink to demonstrate that it is possible to stream to multiple receivers. If you don’t have a sound input device, you may try using the audiotestsrc. The neat thing about using UDP is that the sender can be stopped and started again, without affecting the receiver. Note the use of sync property in the alsasink element. If you set it to true, the audio stops playing after a while or does not begin playing.

If you initiate the receiver pipeline after the sender, you’ll see a message such as:

ERROR: from element /GstPipeline:pipeline0/GstVorbisDec:vorbisdec0: Could not decode stream.
Additional debug info:
gstvorbisdec.c(976): vorbis_handle_data_packet (): /GstPipeline:pipeline0/GstVorbisDec:vorbisdec0:

Using TCP

Now, one would think that replacing the udpsrc and udpsink above, with tcpserversrc and tcpclientsink respectively, would work just fine. Unfortunately, that is not so. I haven’t arrived at a good explanation for it yet. I suspect it has to do with caps, so I use gdppay and gdpdepay in the pipeline below. Any GStreamer plugin hacker who can explain this difference between UDP and TCP is welcome to comment below.

The receiver can run a pipeline such as:

gst-launch -v tcpserversrc port=9001 ! gdpdepay ! vorbisdec ! audioconvert ! alsasink sync=false

The sender can then start sending the audio stream, using a pipeline such as:

gst-launch -v autoaudiosrc ! audioconvert ! audioresample ! vorbisenc ! gdppay ! tcpclientsink port=9001

One immediate advantage of using gdp with TCP, the sender can stream data using a tcpserversink, which can be received by multiple clients using tcpclientsrc. So, you are able to start the sender before the receiver.

The TCP pipelines above will not work with UDP. On executing the sender pipeline, the receiver prints a message such as

gstgdpdepay.c(416): gst_gdp_depay_chain (): /GstPipeline:pipeline0/GstGDPDepay:gdpdepay0:
Received a buffer without first receiving caps

I have absolutely no idea why.

3 thoughts on “Stream raw vorbis audio over UDP or TCP with GStreamer

    1. I’d think because tcpserversrc essentially establishes a TCP connection with the first tcpclientsink that starts streaming to it. After that connection is closed, it wouldn’t make much sense for tcpserversrc to go on.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s