Live Streaming with Flux

Introduction

Live streaming is a quite complex environment, this guide will try to introduce the user to Live streaming using the LSCube suite in a simple and pragmatic way.
The guide consists of three parts:

  • Live Streaming Audio Only Content
  • Live Streaming Audio and Video Content
  • Reliable Live Streaming

Live streaming Audio Only Content

Live streaming inside Feng is currently performed using posix message queues.

To perform live Streaming first of all is necessary to expose the shared resources to the world with a .sd files
For example we might want to stream a simple AUDIO content by itself, then we create a simple .sd file and place it inside the avroot of feng, let's call it “my_radio.sd”

my_radio.sd:

stream
        file_name mq:///audio
        encoding_name MPA
stream_end

Now we have told to feng to reproduce the content of the shared memory named audio.rtp when my_radio.sd is requested.
With this setup we are asking feng to play the content of the message queue named /audio as a live source specifying that the content of the stream has been encoded with MPA (mpeg audio).
If you are using dynamic payload, H264 or AAC for example, you must specify by yourself the payload_type, clock_rate and fmtp for the stream that you are producing. Feng is able to autodetect live data only for static payload types and has been tested only with MPA and MPV.

Now we must actually put the content of our stream inside the message queue.
This can be performed using Flux. Flux has the mq output filter that can write RTP packets inside a define message queue.
We tell Flux to get packets arriving from port 2900 on UDP protocol and copy them without changing them into the /audio posix message queue which is the same from which we told feng to serve the content (remember to check that feng has access rights for the posix message queue) by launching the following command:

flux -c udp://2900*copy*mq:///audio

notice: you may have a queue limit too low set, in order to raise it you may use either ulimit -q unlimited or set it through other specific ways (e.g though pam_limits).

Flux will also create the message queue if it doesn't exist and will destroy it after closing Flux (which can be terminated by simply pressing CTRL+C)

Now we have configured everything that is necessary on our server to expose the RTSP resource and serve it, we just need to actually produce the content to serve. This can be performed with any tool able to generate RTP packets (like ffmpeg or VLC) and send them through the UDP protocol in our case.
Let's try to do it using VLC:

* Run VLC
* Choose the Media->Streaming menu
* Choose any Audio File to be streamed
* Flag the “RTP” option from the “Outputs” box
* Enter the IP address of the machine where Flux and Feng are running in the first enabled “Address” entry field
* Set as “Audio Port” the value 2900 which is the we told to Flux to read from
* Choose the “Audio Codec” Tab
* Flag the “Audio” check and let any option to its default value (MPEG Audio, 128kb/s bitrate and 2channels)
* Click the Stream button and just let VLC produce the content

Now we can listen to our Audio stream simply by connecting with any RTSP+RTP player (like VLC itself) to our stream.
Just open the url rtsp://server_address/my_radio.sd inside VLC and you should be listening to your song Live.

To really make this a live stream we would need to rewrite the timestamps of the stream to serve it as it has been produced NOW, this can be performed by simply launching flux with the live parser instead of the copy one.
Having Flux run with the live parser will also permit to us to change on the fly the audio file that we are streaming without having to restart Flux, Feng or the client itself as the new audio file will be presented as it was still a piece of the previous one.

Live Streaming Audio+Video Content

Streaming an audio and video content is just like streaming two separated audio and video content.
The only thing that will change is that we have to tell feng to serve them togheter.
How to serve the live content is specified inside the .sd file as we saw before, so to serve an audio and video stream paired we just have to specify both of them inside our .sd file

my_tv.sd:

stream
        file_name mq:///audio
        encoding_name MPA
stream_end
stream
        file_name mq:///video
        encoding_name MPV
stream_end

Also we have to tell Flux to inject both the audio and video streams inside the shared memories audio.rtp and video.rtp this can be performed by configuring two chains:

flux -c udp://2900*live*mq:///audio -c udp://2902*live*mq:///video

Note also that we changed the parser from copy to live.
This is to ask to Flux to sync the timestamps of the two streams.
Flux will sync the timestamps of every stream inside chains generated from the same process.

After feeding your stream to ports 2900 for audio packets and 2902 for video packets from VLC or FFMPEG you will be able to view your video from rtsp://server_address/my_tv.sd

Reliable Live Streaming

Until now all the examples used UDP protocol to send the stream data to the server as this is how the RTP producers like ffmpeg and VLC now send RTP packets. But UDP protocol isn't the best option to serve the main stream from which every stream of the users will be duplicated, if we lost a packet or if we have misordering every user will suffer the same problem even if his communication channel is perfect.

To solve this problem Flux introduced support for transmission of RTP packets over TCP.
Using TCP we will introduce a bit of latency but we will have the guarantee that our packets will arrive and will arrive in the right order.

We will solve this problem in a quite straightforward way
We will setup a Flux on the server to receive the TCP packets and serve them to Feng
We will just tell our producer to send the packets to localhost to remove network problems
We will setup a Flux to receive those packets and resend them over TCP

First of all we must configure the Flux that will receive the packets from TCP and will give them to feng (remember to run this on the server where feng is running)

flux -c tcp://1900*copy*mq:///audio -c tcp://1902*copy*mq:///video

This instance of Flux will just wait for TCP connections from another flux on port 1900 and 1902 and will inject every packet that will receive inside Feng.
Then we will setup our local Flux (remember to also change your producer to send packets to localhost instead of directly to the server)

flux -c udp://2900*live*tcp://server_address:1900 -c udp://2902*live*tcp://server_address:1902

This Flux will try to connect to the other Flux on the server with the TCP protocol, will receive packets from the local source, will sync the timestamps as required as it is a live stream and will resend them to the remote Flux.

This way we will have only reliable network channels between our procuder and the Feng server as we will send over UDP to localhost which is supposed to be problems free and we will send over TCP to the remote server having the TCP protocol to mitigate network problems and Flux to automatically recover from timeouts and link problems.