Icecast Server/Streaming WebM to Icecast with FFmpeg

From XiphWiki
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 \

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 sets the maximum period betwoon two key frames. Its value should be a compromise between latency and bandwidth, because key frames occupy more space whilst being of lower quality because they don’t use the previous images as reference. However periodic key frames are necessary to bootstrap the video decoder when a client connects to the stream after the beginning.

A higher value of the -g parameter will save bandwidth and increase latency. However, a value too high 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 its value, so if you have a framerate of 30 and 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.