Having used Broadsoft’s BroadWorks for many years I can’t tell you how many times I’ve been asked “How can callers hear different music each time they are placed on hold?” This is something the BroadWorks platform does not easily provide for end customers. Every time a caller is placed on hold, they hear the beginning of whatever song or sequence of songs is configured for that business.
While music on hold is something that most callers may not find particularly entertaining, what if we could have listeners hear a variety of songs, and just “tune-in” to wherever the music sequence is (as if you just turned the radio on, or resumed playing your iPod)? That’s when the light bulb lit up – we can use Asterisk complement the Broadworks platform and provide a flexible music on hold server!
Asterisk is an open source implementation of a PBX created by Digium. When I think of Asterisk, I think of it as the canvas that enables the artist creatively express their vision. Asterisk provides a framework for us to develop custom telephony applications within our telephony network while Broadworks is the workhorse that provides carrier class VoIP service levels.
What’s needed to get the job done?
- Server running Asterisk
- Fixed IP address on Asterisk Server
- DRM-Free Music files (can be MP3, WAV, or internet streaming URL)
- About an hour to set up everything
Step 1: Install Asterisk
Install Asterisk on your server. There are many ways this can be done, depending on your OS choice. We will be using the SIP protocol to communicate to your Asterisk server. Make sure your firewall allows port 5060/udp into your Asterisk server. Start Asterisk, most binary installations provide a system script for starting/stopping Asterisk.
Step 2: Setup Asterisk/BroadWorks SIP Peering
Set up a SIP peer in Asterisk sip.conf. You should use the hostname of either your BroadWorks Application Server DNS, or your session border controller (depending on BWorks network). See example below.
Code
/etc/asterisk/sip.conf
[broadworks]
type=peer
host=broadworks-as.yourdomain.net
dtmfmode=auto
insecure=port
context=music-on-hold
Step 3: Asterisk Dial Plan
Code
/etc/asterisk/extensions.conf
[music-on-hold]
; Music On Hold Inbound Context from BroadWorks
exten => music1,1,Set(CHANNEL(musicclass)=music1)
exten => music1,n,Answer
exten => music1,n,MusicOnHold(music1)
exten => music1,n,HangUp
The above code is an example you’ll want to add to your Asterisk extensions.conf file. [music-on-hold] is the name of your Asterisk Dial Plan Context, which must match the SIP context= parameter from Step 2. Extensions can be numbers, words, or a combination of the two. For simplicity, I’ve used the extension music1. If you want to create multiple configurations for Music On Hold, you’ll want an extension created for each music configuration (up next).
Step 4: Asterisk Music On Hold
The musiconhold.conf configuration file defines the various music configurations. In the above example I used extension music1 and routed it to music class music1.
Code
/etc/asterisk/musiconhold.conf
[music1]
; Music On Hold for BroadWorks
mode=custom
application=/usr/bin/mpg123 -q -r 8000 -f 8192 -b 2048 --mono -s --list /var/lib/asterisk/moh/music1/music1.pls
The music on hold class example uses the music1 name and a custom mode. The custom mode gives us the ability to specify a music playlist. This allows you to define how the various files get played. If you don’t want to manage the playlist, you can have the server generate the list automatically using a script and the crontab for automatic updates.
The audio files in my example are saved in the directory /var/lib/asterisk/moh/music1/ This is also the same folder where the playlist file is saved. You can copy your files to the server whichever way works best for you. Most systems have FTP and SFTP/SCP available for remote file copying.
I thought an FTP server would handle this well, and other admins can easily use FTP to manage all the music files. To do this, I first created a user that has a custom home-directory. The home-directory is the same directory I configured for music1 music on hold class /var/lib/asterisk/moh/music1/
Code
groupadd music1
useradd -c "Music1 User - MOH" -d /var/lib/asterisk/moh/music1/ -s /bin/false -g music1 music1
passwd music1
chown -R music1:music1 ~music1
chmod -R g=rwxs ~music1
The above commands create a local user called music1 and assigned home-directory is that of the music1 music on hold class. Then we set the password (this is an interactive step that prompts for password). Following the password are file ownership and permissions (just in case directories already exist and are pre-populated).
Code
ls /var/lib/asterisk/moh/music1/
Bach Brandenburg Concerto 1 (1st movement).mp3
Bach Brandenburg Concerto 1 (2nd movement).mp3
Bach Brandenburg Concerto 1 (3rd movement).mp3
Bach Brandenburg Concerto 1 (4th movement).mp3
Bach Brandenburg Concerto 2 (1st movement).mp3
Bach Brandenburg Concerto 2 (2nd movement).mp3
Bach Brandenburg Concerto 2 (3rd movement).mp3
Ever Softer Grows My Slumber.mp3
Mendelssohn Fingels Cave Overture.mp3
Mendelssohn Wedding March (from Midsummer Nights Dream).mp3
music1.pls
Restart Asterisk if you haven’t by now, It needs to re-read the configuration files.
Code
/etc/init.d/asterisk restart
Step 5: Custom Asterisk Server Script for Music On Hold Playlist Files
I wrote a script that looks for files and inserts their names into a playlist file, that way I can organize my music files by sub-folders. The sub-folders (optional) allows me arrange my music files into folders however I see fit.
Code
/etc/asterisk/moh-scrub-playlists.sh
#!/bin/bash
#
# Collect the list of folders
# This could also be static via config file
#
# ./$0
#
moh_parent=/var/lib/asterisk/moh
for cheeseburger in `find ${moh_parent} -maxdepth 1 -type d -print | grep -v ${moh_parent}
do
group_name=`echo ${cheeseburger} | awk -F/ '{print $NF}'`
# First Level "Group"
find ${moh_parent}/${group_name} -maxdepth 1 -type f -not -name '*.pls' -print > ${moh_parent}/${group_name}/${group_name}.pls
#
# Look for sub-dirs "Department"
#
cd ${moh_parent}/${group_name} && for hamburger in `find ${moh_parent}/${group_name}/* -maxdepth 1 -type d -print`
do
moh_stub=`echo ${hamburger} | awk -F/ '{print $NF}'`
find ${moh_parent}/${group_name}/${moh_stub} -type f -not -name '*.pls' -print > ${moh_parent}/${group_name}/${moh_stub}/${moh_stub}.pls
done
done
Save the script to /etc/asterisk/moh-scrub-playlists.sh. To automate the script process we use crontab:
Code
as root user: crontab -e
#
# Music On Hold Auto-Reload Cron
# -Jessie Bryan 09/15/2010
#
#
*/15 * * * * (/etc/asterisk/moh-scrub-playlists.sh ; sleep 1 ; /usr/sbin/asterisk -r -x "reload res_musiconhold.so") > /dev/null 2>&1
The above crontab entry will run the moh-scrub-playlists.sh script four times an hour, then tell the Asterisk server to reload the music on hold driver. Once you have calls on the Asterisk server, the server will not disconnect any connected callers while the Asterisk reload process runs.
Step 6: Configuring BroadWorks to use Asterisk for Music On Hold
Step 7: Wrapping Up
So that’s it! Asterisk is using it’s built-in Music On Hold application to playback audio files that you uploaded. BroadWorks is configured to play this music each time a caller is placed on hold. The caller will hear music playing from where Asterisk is currently at in the playlist.