Lightweight, Live Video in a Webpage with GStreamer and WebRTC

WebRTC is the hottest thing going right now, and allows you to receive live, secure video over RTP right to the browser. It’s videoconferencing without the need for any plugins or software (other than your browser). Better yet, as long as your audio/video is encoded correctly, it doesn’t have to be another person, but a song or movie in your own, private on-demand service.

Currently, Firefox, Chrome, and Opera are the browsers that support this. Unfortunately, you’ll have to shelf your love for Microsoft (who naturally vied for their own, alternative standard), for now.

There are a few different layers and components that are required in order for a developer to take advantage of this, however. This includes an ICE server (which wraps one or more STUN or TURN servers), a data connection to your webserver, whether it’s Ajax, WebSockets, SSE, or something else, properly encoded video (exclusively using Google’s VP8 codec), and properly encoded audio (e.g. Opus)… All of which is encrypted as SRTP (secure RTP).

Any time spent understanding this would be well-worth it for a lot of engineers. If you want to get started, the top five or six books in Amazon’s results (as of this time) are enjoyable reads. Currently, the most authoritative reference is “WebRTC: APIs and RTCWEB Protocols of the HTML5 Real-Time Web“, which is written by two participants of the relevant W3C/IETF working groups.

However, if you decide that you want an easy-as-pie solution and no challenge whatsoever, try out the Janus WebRTC Gateway.


Janus is a C-based RTP bridge for WebRTC. The following are the components that you’ll need to implement:

  • RTP generator
  • Janus server
  • Webpage that displays the video using Janus’ relatively-simple javascript library
  • STUN/TURN server (this is optional during development, and there’s a default one configured).

For our example, we’ll do exactly what they’ve already provided the groundwork for:

  • Use the provided script to invoke GStreamer 1.0 to generate an audio and video test-pattern, encode it to RTP-wrapped VP8-encoded video and Opus-encoded audio, and send it via UDP to the IP/port that the Janus server will be listening to.
  • Use the default config and certificates provided in the Janus source-code to retransmit the RTP data as a WebRTC peer.
  • Use the provided test-webpage to engage the Janus server using the Janus Javascript library.

Yeah. It’s that simple.


We’re using Ubuntu 14.04 LTS.

  1. Install the dependencies:
    $ sudo apt-get install libmicrohttpd-dev libjansson-dev libnice-dev \
        libssl-dev libsrtp-dev libsofia-sip-ua-dev libglib2.0-dev \
        libopus-dev libogg-dev libini-config-dev libcollection-dev \
        pkg-config gengetopt
  2. Clone the project:
    $ git clone
    Cloning into 'janus-gateway'...
    remote: Reusing existing pack: 394, done.
    remote: Counting objects: 14, done.
    remote: Compressing objects: 100% (14/14), done.
    remote: Total 408 (delta 5), reused 0 (delta 0)
    Receiving objects: 100% (408/408), 733.31 KiB | 628.00 KiB/s, done.
    Resolving deltas: 100% (268/268), done.
    Checking connectivity... done.
  3. Build the project:
    $ cd janus-gateway
    $ ./

    This will display the help for the janus command upon success.

  4. Start GStreamer:
    $ cd plugins/streams/
    $ ./ 
    Setting pipeline to PAUSED ...
    Pipeline is PREROLLING ...
    Redistribute latency...
    Redistribute latency...
    Pipeline is PREROLLED ...
    Setting pipeline to PLAYING ...
    New clock: GstSystemClock
  5. In another window, run the Janus command without any parameters. This will use the default janus.cfg config.
    $ ./janus
  6. Either point your webserver to the html/ directory, or dump its contents into an existing web-accessible directory.
  7. Use the webpage you just hooked-up to see the video:
    1. Click on the “Demos” menu at the top of the page.
    2. Select the “Streaming” item.
    3. Click on the “Start” button (to the right of the title).
    4. Under the “Streams list” selector, select “Opus/VP8 live stream coming from gstreamer (live)”.
    5. Click the “Watch or Listen” button.
    6. Watch in wonderment.
      Janus WebRTC Gateway Screenshot

The possibilities are endless with the presentational simplicity of WebRTC, and a simple means by which to harness it.


4 thoughts on “Lightweight, Live Video in a Webpage with GStreamer and WebRTC

  1. Thanks for sharing! It’s an amazing software!

    I did successfully build these things up with your tutorial. I’m really happy with that. However, I’m trying to stream my raspberry pi camera video instead of gstreamer’s test video, but eventually fail (Chrome).

    I didn’t execute “”, instead, I run this command in pi:

    gst-launch-1.0 rpicamsrc bitrate=2000000 rotation=90 ! video/x-h264,width=1080,height=760,framerate=25/1 ! h264parse ! rtph264pay ! udpsink host=janus_ip port=5004

    After that the janus server shows
    [gstreamer-sample] New video stream! (ssrc=4089642855)

    Seems it has received the stream, great. And now I open demo page, start watch “Opus/VP8 live stream coming from gstreamer (live)”

    The janus server shows:
    [2938765189] There’s a message for JANUS Streaming plugin
    [2938765189] Creating ICE agent (controlling mode)
    [2938765189] Waiting for candidates-done callback…
    [2938765189] Waiting for candidates-done callback…
    [2938765189] Waiting for candidates-done callback…
    [2938765189] There’s a message for JANUS Streaming plugin
    [2938765189] — ICE Trickling is supported by the browser, waiting for remote candidates…
    [WARN] [2938765189] Unsupported transport tcp!
    ICE started and trickling, sending connectivity checks for candidates retrieved so far…
    No more remote candidates for handle 2938765189!
    [2938765189] The DTLS handshake has been completed
    WebRTC media is now available

    Then I could just see a black video, nothings in it. This message

    [WARN] [2938765189] Unsupported transport tcp!

    is strange since I’m streaming over udp, not tcp.

    I don’t know where things go wrong. I’ve tried using vp8enc but so far the raspberry pi package didn’t contains this plugin. Supposedly Chrome knows how to decode h.264 so this probably should not be a problem. And I also tried tcpclientsink but janus refuse to connect.

    If I set debug level grater than the default, it shows
    Rewind! (./plugins/streams/radio.alaw)

    Any helps would be very appreciated!!


Comments are closed.