Where to Find Hold Music (and How to Stream It Live)
Where to Find Hold Music (and How to Stream It Live)
Every Asterisk install ships with the same five Creative Commons tracks from 2013. They are fine. They are also what every other Asterisk install on earth sounds like. If you want something different, you can either find better audio files and serve them locally, or pipe a live internet radio stream through mpg123.
On this page
What ships with Asterisk
The asterisk-moh-opsound package has five instrumental tracks, all Creative Commons Attribution-ShareAlike 3.0:
| Track | Artist |
|---|---|
| macroform-cold_day | Paul Shuler (Macroform) |
| macroform-robot_dity | Paul Shuler (Macroform) |
| macroform-the_simplicity | Paul Shuler (Macroform) |
| manolo_camp-morning_coffee | Manolo Camp |
| reno_project-system | Reno Project |
They live in /var/lib/asterisk/moh/ on package installs (sometimes /usr/share/asterisk/moh/, depending on the distro). All nine codec formats are available from the Asterisk downloads page. Nothing wrong with them. Your callers have just heard them before.
Free and royalty-free sources
If you want different music, you need audio that is actually licensed for use in a phone system. That is not the same as music that is free to listen to. Playing a Spotify playlist or a YouTube rip as hold music is a copyright violation, even if nobody is likely to come after you for it.
No attribution required:
-
Pixabay Music has a dedicated "on hold" category. The Pixabay license allows commercial use without attribution. Downloads are MP3, so you will need to convert them.
-
Free Music Archive has a big library under various Creative Commons licenses. Filter for CC0 (public domain) if you want zero strings attached. Start with the ambient and instrumental categories.
Attribution required (CC-BY):
-
ccMixter is a Creative Commons remix community. Decent instrumental and ambient tracks. Check each track's license individually.
-
Chosic aggregates CC-licensed music with genre filtering.
Paid (but properly licensed for MOH):
-
MelodyLoops sells royalty-free tracks tagged for hold music. Per-track pricing.
-
AudioHub is royalty-free and not registered with any performing rights organizations, so no separate ASCAP/BMI/SESAC license.
-
Easy On Hold is a managed service. They give you HTTP streams you consume with mpg123 and they deal with the licensing. If you want someone else to handle the "on hold, your call is important to us" messaging, this is what that looks like.
Watch out for CC-BY-NC (NonCommercial) licenses. Hold music for a company counts as commercial use, even if you are not selling the music. Stick to CC0, CC-BY, or tracks explicitly licensed for commercial use.
Converting downloaded audio for Asterisk
Whatever you download, it needs to be converted to formats Asterisk can play natively. The best setup provides files in multiple codecs so Asterisk can match the caller's channel without transcoding:
# Convert an MP3 to 8kHz mono WAV (universal fallback)
sox input.mp3 -r 8000 -c 1 -b 16 output.wav
# Also generate ulaw and alaw for G.711 endpoints
sox input.mp3 -r 8000 -c 1 -t ul output.ulaw
sox input.mp3 -r 8000 -c 1 -t al output.alaw
# Optional: telephone bandpass filter for cleaner sound
sox input.mp3 -r 8000 -c 1 -t ul output.ulaw lowpass 3400 highpass 300
That bandpass filter (300 Hz to 3400 Hz) cuts frequencies the telephone network cannot carry anyway. It sounds a bit cleaner on the receiving end because the codec is not wasting bits on inaudible content.
Drop the converted files into your MOH directory, make sure Asterisk can read them, and reload:
cp *.wav *.ulaw *.alaw /var/lib/asterisk/moh/
chown -R asterisk:asterisk /var/lib/asterisk/moh/
asterisk -rx "moh reload"
asterisk -rx "moh show files"
If you have disabled module autoloading in modules.conf, load the format modules for the codecs you are using (for example format_wav.so, format_ulaw.so, format_alaw.so) before res_musiconhold.so, or Asterisk will skip the files it cannot decode.
See Music on Hold with Native Formats for batch conversion and multi-codec setups.
Using a custom directory with mode = files
If you want to keep custom hold music separate from the default tracks, point a new class at a different directory:
[default]
mode = files
directory = /var/lib/asterisk/moh
[custom-hold]
mode = files
directory = /var/lib/asterisk/moh-custom
random = yes
random = yes shuffles the tracks instead of playing them in filename order. Create the directory and set permissions before reloading:
mkdir -p /var/lib/asterisk/moh-custom
chown asterisk:asterisk /var/lib/asterisk/moh-custom
# copy converted files here
asterisk -rx "moh reload"
asterisk -rx "moh show classes"
A healthy moh show classes output looks like this:
Class: custom-hold
Mode: files
Directory: /var/lib/asterisk/moh-custom
File: /var/lib/asterisk/moh-custom/track01.ulaw
File: /var/lib/asterisk/moh-custom/track01.wav
If the directory is empty or the files are not readable by the asterisk user, the class appears in the list but with no files under it. Asterisk will play silence.
Streaming live audio with mpg123
Back up your configuration files
Before editing any Asterisk configuration file, make a backup copy:
bash
sudo cp /etc/asterisk/musiconhold.conf /etc/asterisk/musiconhold.conf.bak.$(date +%s)
If a typo prevents Asterisk from reloading, you can restore the working version immediately.
Instead of local files, you can pipe a live internet radio stream into Asterisk's MOH system. You do this with mode = custom in musiconhold.conf, which runs an external command and reads its audio output on stdout.
Install mpg123
# Debian/Ubuntu
apt install mpg123
# RHEL/CentOS/Rocky
dnf install mpg123
Make sure you get the real mpg123, not mpg321. Despite being marketed as a drop-in replacement, mpg321 cannot downsample to 8000 Hz. Useless for this.
Test the stream before touching Asterisk
Before editing any config, verify that mpg123 can actually connect, decode, and resample the stream. Run this as the asterisk user (or root) and listen for two seconds of raw audio on stdout:
timeout 2 /usr/bin/mpg123 -q -s --mono -r 8000 -f 8192 https://ice5.somafm.com/groovesalad-128-mp3 | wc -c
A working stream produces around 32000 bytes (2 seconds at 8000 samples/sec, 2 bytes/sample). If the output is 0 or the command hangs without producing output, the URL is unreachable or mpg123 cannot decode it. Fix this before touching musiconhold.conf.
Configure musiconhold.conf
[stream-ambient]
mode = custom
application = /usr/bin/mpg123 -q -s --mono -r 8000 -f 8192 -b 2048 https://ice5.somafm.com/groovesalad-128-mp3
The mpg123 flags:
| Flag | Purpose |
|---|---|
-q |
Quiet mode. No console output. |
-s |
Write raw audio to stdout (Asterisk reads this). |
--mono |
Force mono. Telephone audio is single-channel. |
-r 8000 |
Resample to 8000 Hz. Without this, mpg123 outputs at 44100 Hz and Asterisk cannot use it. |
-f 8192 |
Volume scale (1 to 32768). 8192 is a reasonable starting point. |
-b 2048 |
Output buffer in KB. Helps on flaky connections. |
Reload:
asterisk -rx "moh reload"
asterisk -rx "moh show classes"
A streaming class shows Mode: custom and the full application command. If the stream is active, the mpg123 process is already running at this point. You can confirm with ps aux | grep mpg123.
Assign the stream to a queue or endpoint
In the dialplan:
; Use in a queue
exten => 100,1,Answer()
same => n,Set(CHANNEL(musicclass)=stream-ambient)
same => n,Queue(support,,,,120)
same => n,Hangup()
After changing extensions.conf, run asterisk -rx "dialplan reload" (or core reload) before testing.
Or set it as the default for an endpoint in pjsip.conf:
[1001](endpoint-internal)
moh_suggest = stream-ambient
Then reload PJSIP:
asterisk -rx "pjsip reload"
Things that will bite you
Each mode = custom class spawns its mpg123 process when Asterisk starts and keeps streaming whether or not anyone is on hold. Five streaming classes means five streams running 24/7 consuming bandwidth.
After a restart, it can take up to two minutes for the stream buffer to fill. Callers on hold during that window hear silence.
If the stream URL goes down, mpg123 dies. Asterisk logs errors and respawns the process, but the retry interval is long (about 500 seconds by default), so callers can be left in silence for many minutes until the stream recovers. There is no fallback to another class or to local files. For anything production, local files are more dependable.
If you want faster reconnection, wrap mpg123 in a loop script and point Asterisk at that instead:
#!/bin/bash
# /usr/local/bin/moh-stream.sh
while true; do
/usr/bin/mpg123 -q -s --mono -r 8000 -f 8192 -b 2048 "$1"
sleep 2
done
[stream-ambient]
mode = custom
application = /usr/local/bin/moh-stream.sh https://ice5.somafm.com/groovesalad-128-mp3
Make it executable: chmod +x /usr/local/bin/moh-stream.sh. Now mpg123 restarts within two seconds of the stream dropping instead of waiting 500 seconds. The two-second sleep prevents a tight loop that would spin the CPU if the URL is permanently unreachable.
The -f 8192 volume value is just a starting point. Some streams are louder than others, and some phones amplify the signal on top of that. Test with real calls on real phones. Mobile phones especially tend to be sensitive to hot audio.
CPU-wise, real-time MP3 decoding is noticeable on a Raspberry Pi or a tiny VM. On anything resembling a real server, it is not a concern.
Example streams
Licensing
Most internet radio stations are licensed for personal listening only. Using them as commercial hold music may violate their terms and copyright law. The streams below show up in every Asterisk forum thread about MOH, but "everybody does it" is not a legal defense. For a production business system, use royalty-free files or a licensed service like Easy On Hold.
SomaFM is listener-supported and ad-free, which is why it keeps showing up in these configs:
; Ambient/downtempo
[soma-groovesalad]
mode = custom
application = /usr/bin/mpg123 -q -s --mono -r 8000 -f 8192 -b 2048 https://ice5.somafm.com/groovesalad-128-mp3
; Atmospheric/drone
[soma-dronezone]
mode = custom
application = /usr/bin/mpg123 -q -s --mono -r 8000 -f 8192 -b 2048 https://ice5.somafm.com/dronezone-128-mp3
; Mellow electronic
[soma-spacestation]
mode = custom
application = /usr/bin/mpg123 -q -s --mono -r 8000 -f 8192 -b 2048 https://ice5.somafm.com/spacestation-128-mp3
Icecast streams tend to work more reliably with mpg123 than Shoutcast ones.
Which approach to use
Local files (mode = files) |
Streaming (mode = custom) |
|
|---|---|---|
| Reliability | No external dependencies. | Depends on the stream staying up. |
| CPU | Near zero. | Continuous MP3 decoding. |
| Bandwidth | None after upload. | Continuous. |
| Variety | Whatever you uploaded. | An entire radio station. |
| Licensing | You picked the files, you know. | Murky. Stream ToS may prohibit it. |
| Best for | Production, anything compliance-sensitive. | Home labs, internal office PBX, personal use. |
For anything that has to stay up, use local files. Grab a few royalty-free tracks from Pixabay, convert them, drop in a couple codec variants, done. Streaming is more fun (who does not want Groove Salad piped into their PBX?), but when the stream dies at 2am and your overnight queue goes silent, you will wish you had just uploaded some WAV files.
User Notes
Know a tip or gotcha for this topic? Share it below and help others.
Contribute a note
Share a tip, gotcha, or practical example. Keep it under 2000 characters. No questions (use the Asterisk community forums for support). Wrap code in backticks.