Skip to content

Instantly share code, notes, and snippets.

@keiya
Last active April 22, 2024 06:43
Show Gist options
  • Save keiya/c8a5cbd4fe2594ddbb3390d9cf7dcac9 to your computer and use it in GitHub Desktop.
Save keiya/c8a5cbd4fe2594ddbb3390d9cf7dcac9 to your computer and use it in GitHub Desktop.
How to broadcast to Icecast2 by using ffmpeg (FLAC,Opus,Vorbis,AAC,MP3/Windows, Mac)

FFMpeg to Icecast2 Streaming Samples

Examples usage of various codecs with FFMpeg.

Samples

  • flac.sh : An Icecast Source Client
    • for Windows (Cygwin is required)
    • and macOS (brew install ffmpeg)
  • another_examples.sh : Samples
    • FFMpeg can push to Icecast2 in various formats: Opus/Vorbis/AAC/MP3
    • this script shows optimal format, container and codec combinations.
    • Recommended settings for stable streaming with good quality:
      • HE-AAC (aac_he): 48k-64k
      • HE-AACv2 (aac_he_v2): 32k-48k
      • LC-AAC VBR 3-4
        • Higer is good quality, increases bitrate
        • if you want to use CBR, set 96k-128k. (not recommended)
      • Opus VBR 48k-64k
        • CBR is not recommended
      • Vorbis q3
        • Higer is good quality, increases bitrate
      • MP3 V6-V4
        • Lower is good quality, increases bitrate
        • if you want to use CBR, set 128k-160k

Reference

# SAMPLE: encode to another formats
name=stream
# AACs
# AAC streams must be pushed as ADTS stream (-f adts)
# ==== HE-AAC (SBR+PS) @ CBR 48kbps ====
-c:a libfdk_aac -profile:a aac_he_v2 -ab 48k
-content_type 'audio/aac'
-vn -f adts icecast://source:PASSWORD@icecast:8001/$name_aac
# ==== LC-AAC @ VBR 4 ~110kbps ====
# -c:a libfdk_aac -vbr 4
# -content_type 'audio/aac'
# -vn -f adts icecast://source:PASSWORD@icecast:8001/$name_lcaac
# Xiph.org's Ogg Variant
# ==== Ogg Opus @VBR64k ====
# -c:a libopus -vbr on -b:a 64k
# -content_type 'audio/ogg'
# -vn -f opus icecast://source:PASSWORD@icecast:8001/$name_opus
# ==== Ogg Vorbis @ q3 ~112kbps ====
# -codec:a libvorbis -qscale:a 3
# -content_type 'audio/ogg'
# -vn -f ogg icecast://source:PASSWORD@icecast:8001/$name_vorbis
# ==== LAME MP3 @ V6 ~112kbps ====
# -codec:a libmp3lame -qscale:a 6
# -content_type 'audio/mpeg'
# -vn -f mp3 icecast://source:PASSWORD@icecast:8001/$name_mp3
# SAMPLE: FLAC streaming on Windows & Mac
# Input device on Windows
# you should find DShow device name by:
# ffmpeg.exe -list_devices true -f dshow -i dummy
input="dshow"
device="audio=@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{D50ABAB1-D542-4F19-BB77-D12FADCAB889}"
# Input device on macOS
# setup a default device at System Preferences > Sound > Input
# input="avfoundation"
# device="none:default"
channels=2
samplerate=48000
codec="flac"
# above 12 is not recommended
# if you have a slow hardware, set lower value.
level=10
while true
do
./ffmpeg -f $input \
-i $device \
-ar $samplerate \
-ac $channels \
-c:a $codec -compression_level $level \
-f ogg \
-content_type 'application/ogg' \
icecast://source:PASSWORD@HOSTNAME:8001/STREAM_NAME
sleep 1
done
@keiya
Copy link
Author

keiya commented Mar 26, 2022

I think the following are the minimum requirements for listening on a HiFi system:

Opus 96kbps
LC-AAC 160kbps
(HE-AAC is not suitable for strict music listening due to its SBR high frequencies)
Vorbis 160kbps
MP3 256kbps

Anything more than this is useless in many cases, as it is difficult to discern without a fairly good ear.

@edenzul
Copy link

edenzul commented Mar 26, 2022

@keiya Thanks alot for your prompt reply!

actually I am tuning icecast2 server in my LAN with goal to reduce delay between source and output voice. at first I thought if I can reduce the source bitrate then I can reduce size of data transmitted which can reduce latency.
in my case the voice quality is does'nt matter, as long as the end point can recognize the conversation then it is fine, maybe like AM radio quality.

I tested opus and libspeex like command below, it can transmit as lowest as 8kbps and still recognizeable.

ffmpeg -ac 1 -f alsa -i hw:0,0 -c:a libopus -vbr on -b:a 8k -content_type 'audio/ogg' -vn -f opus icecast://source:PASSWORD@HOSTNAME:8000/STREAM_NAME

ffmpeg -ac 1 -f alsa -i hw:0,0 -c:a libspeex -b:a 8k -content_type 'audio/ogg' -vn -f spx icecast://source:PASSWORD@HOSTNAME:8000/STREAM_NAME

however the delay still same.. around 16 seconds between source and output.
audio player in output side is VLC.

@keiya
Copy link
Author

keiya commented Mar 27, 2022

@edenzul

I have been trying the same idea for the same motivation and wrote about my findings in this Gist.

As it turns out, reducing latency with Icecast2 is probably not easy.
Even if you reduce the VLC buffer as shown in the image, there will still be latency, and synchronization will drift.
image

Opus and Speex have much less delay in encoding and decoding, but the delay is not only caused by encoding and decoding, but also by the buffers on Icecast2 and VLC.

( https://wiki.hydrogenaud.io/index.php?title=Opus#Lower_latency_versus_quality.2Fbitrate_trade-off )

Icecast2 and VLC are implemented with an approach that requires stable sound quality, which is incompatible with low latency applications. VoIP-related software such as Discord or mumble would be better for that application.

I have not used them, but there is a software called VBAN or SonoBus.

There are other open standards, but I don't have much information on them.
https://en.wikipedia.org/wiki/Audio_over_Ethernet#Layer-3_protocols

@StevenGangaram
Copy link

Hi I have this ultra strange issue, but I am using this command to stream to icecast, when I try to load the stream on my browser on another computer it doesn't play at all, but as soon as I close the ffmpeg script it plays for a short period and dies. Am I missing a setting?

ffmpeg -f "dshow" -i "audio=@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{C813B450-CA6A-45E5-9155-8E7EB6F5AEB2}" -c:a aac -b:a 320k -content_type 'audio/aac' -vn -f adts icecast://source:hackme@localhost:8000/WQXR-A

@mrx23dot
Copy link

Any idea why streaming stops between 2songs?
I'm using latest ices2/icecast2+ opus VBR on local LAN, still VLC strugles between songs.
Tried big/small buffers, no difference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment