Icecast Server/Streaming WebM to Icecast with FFmpeg

From XiphWiki
Revision as of 12:43, 12 November 2015 by Remjey (talk | contribs)
Jump to navigation Jump to search


What is FFmpeg?

FFmpeg is a very versatile command-line tool to decode, capture, encode or modify audio and video media. It supports being a source for several streaming servers including Icecast. The resulting stream can be read from a simple HTML5 video tag in Firefox and Chrome.

Streaming a live webcam with sound

This configuration is a Linux example and must be adapted for your hardware and operating system. As explained in next section, -cluster_time_limit should always have a value (in milliseconds) greater than the value of -g divided by the framerate times 1000. If your framerate is 30 and -g is 150, then -cluster_time_limit should be greater than 5000 (which is (150 ÷ 30) × 1000 milliseconds).

ffmpeg \
  -f v4l2 -video_size 640x480 -framerate 30 -i /dev/video0 \
  -f alsa -i default \
  -f webm -cluster_size_limit 2M -cluster_time_limit 5100 -content_type video/webm \
  -c:a libvorbis -b:a 96K \
  -c:v libvpx -b:v 1.5M -crf 30 -g 150 -deadline good -threads 4 \
  icecast://user:password@server:port/stream_name

The value of -cluster_size_limit must be set to a very high value that will never be reached. In this configuration, 5100 milliseconds of throughput at the maximum bandwidth shouldn’t make more than 1MB so 2M is okay.

Choosing a value for -g

The value of the -g parameter is a compromise between latency and bandwidth. A higher value will save bandwidth and increase latency. However, a huge value will have little benefits for the bandwidth while causing very high latency. It is advised to use a 5 to 10 seconds GOP period. The -g parameters takes a number of frames as his value, so if you have a framerate of 30 want a GOP period of 5 seconds, you can set -g to 150 (which is 5 × 30). Don’t forget to update -cluster_time_limit.

What it takes to make FFmpeg generate a compatible WebM stream

WebM streams are made of clusters, each one containing a number of frames of every track (video, audio, subtitles…). Icecast will synchronise each clients’ stream with a cluster. As of writing this, Firefox and Chrome will fail to play a stream when the first cluster received after connecting to a stream contains no key frame. FFmpeg creates small clusters by default, so the probability of a cluster containing a key frame is low, thus the browser will often fail to open the stream. One could increase the number of key frames, but that would cause high bandwidth usage and low quality video. The trick is making FFmpeg generate larger clusters with an adequate maximum period between key frames so that each cluster contains at least one key frame.