Skip to content

Live Streaming

Kinshuk Bairagi edited this page Jan 10, 2022 · 9 revisions

Live Streaming

Features

  • Real-time media streaming over an RTMP endpoint that can be played using any player supporting the RTMP stream.
  • Stereo Stream Support.
  • Supported for PCMA, PCMU, G711 Codecs.

Non Functional Requirements

  • The feature would be available on-demand and can be enabled/disabled using an HTTP API.
  • It can be enabled/disabled based on the SIP-Call UUID.
  • It may be possible to do this via alternate identifiers if passed in sip headers, but this would be a future development task.
  • Each call would have a unique RTMP URL while streaming, which would be provided in the enable/disable HTTP call.
  • There would be no transcoding done by the streaming service, and the receiver would have to transcode if any.

Approach

Orkaudio provides a Filter Interface. A Filter is a black box that takes media chunks as input and produces media chunks as output. It can be translating between two encodings (codec) or just procession the signal. Implementation for Filter can be written and plugged in via Orkaudio's configuration file.

LiveStreamFilter

LiveStreamFilter is an implementation of Orkaudio's Filter Interface. It captures the incoming audio chunks, processes them to stereo stream chunks, and ingests them to an RTMP server. For every live call, an object of LiveStreamFilter is instantiated. The RTMP server then exposes a unique RTMP URL [rtmp://:/live/] for each call that can be used to live-stream audio on any RTMP-supported player.

HLD

LLD

LiveStreamFilter Module Components

  • LiveStreamServer
  • LiveStreamSession
  • LiveStreamFilter

What is interleaved Audio?

Generally speaking, if you have 2 channels, let's call them L for left and R for right, and you want to transmit or store 20 samples, then:

Interleaved = LRLRLRLRLRLRLRLRLRLR

What is Audio Downmixing?

Downmixing refers to combining multiple audio channels into a single stereo output. Audio packets from both channels are received as a continuous mono stream. They are interleaved to convert from Mono channel buffer to Stereo/Multi-Channel buffer

Sample LiveStream Configuration

<!-- LiveStreamFilter Configuration -->
<CapturePortFilters>LiveStreamFilter</CapturePortFilters>
<!-- RTMP Endpoint to which the streams would be published. Refer to nginx config for example -->
<RTMPServerEndPoint>127.0.0.1:1935/live</RTMPServerEndPoint>
<!-- By default start streaming of all calls. use this judiciously -->
<LiveStreamAllCalls>true</LiveStreamAllCalls> 
<LiveStreamingServerPort>59160</LiveStreamingServerPort>
<!-- Maximum buffer per channel, when other channel is not available, 
when threshold is breached, the stream is emitted out with silent other channel -->
<LiveStreamingQueueFlushThreshold>500</LiveStreamingQueueFlushThreshold>
<!-- End of LiveStreamFilter Configuration -->

Sample NGINX Configuration

load_module modules/ngx_rtmp_module.so;

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

rtmp {
    server {
        listen 1935;
        chunk_size 4096;

        # Stream mode: one publisher, many subscribers
        application live {
            live on;
            record off;
        }
    }
}


# HTTP can be used for accessing RTMP stats
http {

    server {

        listen      9091;
        # This URL provides RTMP statistics in XML
        location /stat {
            rtmp_stat all;

            # Use this stylesheet to view XML as web page
            # in browser
            rtmp_stat_stylesheet rtmp_stat.xsl;
        }

        location /rtmp_stat.xsl {
            root /usr/lib/nginx/modules/;
        }
    }
}

API

  • Ping Check
$ curl http://{recorderIp}:59160/hi

{
    "message": "Hi!"
}
  • Start Stream
$ curl -X POST 'http://{recorderIp}:59160/livestream/start' \ 
   -H 'Content-Type: application/json' --data-raw '{ "nativeCallId":"139b90ff-36e4-44f1-a581-9184b3988bdf" }'

{
     "url": "rtmp://172.16.176.65:1935/live/139b90ff-36e4-44f1-a581-9184b3988bdf"
}
  • Stop Stream
$ curl -X POST 'http://{recorderIp}:59160/livestream/stop' \ 
   -H 'Content-Type: application/json' --data-raw '{ "nativeCallId":"98c5fac6-25fb-4f73-a224-31c6135cd679" }'
 
{
      "callId": "98c5fac6-25fb-4f73-a224-31c6135cd679",
      "status": "stopped"
}
  • Get List of Current Live Calls
$ curl  http://{recorderIp}:59160/livestream/livecalls
 
{
  "liveCalls": [
    "98c5fac6-25fb-4f73-a224-31c6135cd679"
  ]
}
  • Get List of Currently Streamed Calls
$ curl http://{recorderIp}:59160/livestream/streamcalls

{
  "streamCalls": [
    "98c5fac6-25fb-4f73-a224-31c6135cd679",
    "23fdd9cd-b048-4baa-8003-767d51a937b0"
  ]
}

Play Stream

You can use any player which supports rtmp stream and g711 codec to listen to the streams. We usually use ffplay to play the streams

ffplay rtmp://172.16.176.65:1935/live/139b90ff-36e4-44f1-a581-9184b3988bdf