Icecast Server/Streaming WebM to Icecast with FFmpeg: Difference between revisions

From XiphWiki
Jump to navigation Jump to search
(Created page with "{{IcecastThirdParty}} == What is FFmpeg? == [http://ffmpeg.org/ FFmpeg] is a very versatile command-line tool to decode, capture, encode or modify audio and video media. It...")
 
No edit summary
 
(One intermediate revision by the same user not shown)
Line 7: Line 7:
== Streaming a live webcam with sound ==
== Streaming a live webcam with sound ==


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


<pre>
<pre>
ffmpeg \
ffmpeg \
   -f v4l2 -video_size 640x480 -framerate 15 -i /dev/video0 \
   -f v4l2 -video_size 640x480 -framerate 30 -i /dev/video0 \
   -f alsa -i default \
   -f alsa -i default \
   -f webm -cluster_size_limit 2M -cluster_time_limit 5K -content_type video/webm \
   -f webm -cluster_size_limit 2M -cluster_time_limit 5100 -content_type video/webm \
   -c:a libvorbis -b:a 96K \
   -c:a libvorbis -b:a 96K \
   -c:v libvpx -b:v 1.5M -crf 30 -g 70 -deadline good -threads 4 \
   -c:v libvpx -b:v 1.5M -crf 30 -g 150 -deadline good -threads 4 \
   icecast://user:password@server:port/stream_name
   icecast://user:password@server:port/stream_name
</pre>
</pre>
The value of <code>-cluster_size_limit</code> 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 <code>-g</code> 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 <code>-g</code> 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 <code>-g</code> 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 <code>-g</code> to 150 (which is 5 × 30). Don’t forget to update <code>-cluster_time_limit</code>.


== What it takes to make FFmpeg generate a compatible WebM stream ==
== 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 lacks a key frame. FFmpeg by default creates small clusters so the probability of a cluster containing a key frame is low. One could increase the number of key frames, but would suffer high bandwidth usage and low quality. The trick is making FFmpeg generate larger clusters and setting an adequate maximum period between key frames so that each cluster contains at least one key frame.
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.

Latest revision as of 13:52, 12 November 2015


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 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.