Another method of MoH Streaming using only files and as Default

There are many solutions to do MoH Most use the streaming MoH and MPG123, none worked for me for two main reasons.

1: You cannot set a stream MoH as default (Yes I know you can edit the musiconhold_additional.conf but was uncomfortable with that as I didn’t want the freepbx web admin to overwrite my changed)
2: When I did Use streaming I got a large number of continuous errors stating WARNING res_musiconhold.c: poll() failed: Interupted system call

I wasn’t about to give up though as I was curious if Asterisk could handle the MoH wave files being updated in round robin fashion. I quick script hack and viola, I am listening to my local radio station streaming as files into the default MoH.

Now in all honesty I am very new to Asterisk and am mainly posting this for feedback as to the actual feasibility of what I propose.

First Asterisk will play all wav files in the moh (mohmp3) folder in order when sorted as alpha, and continue to loop through them until MoH is no longer required. It does this with no discernable gap (read silence) between each file.
Secondly, and file in it’s list that is not present will simply be skipped for the next file in the series.

What I needed was a little daemon to

  1. listen to a stream
  2. break the stream up into precise bits
  3. remove a specific wav file in a series
  4. replace that file with the latest stream data
  5. go back to listening

Part one is handled by this command. (I intentionally broke the links. I cant put functioning ones in since I am such a newb ;))

pbxuser@pbx1:~# avconv -I http#://2643.live.streamtheworld.com/KIROFMAAC -ar 8000 -ac 1 -sample_fmt s16 -acodec pcm_s16le -f s16le - | split -b 160000 -d -a 7 --filter=’/usr/local/bin/mohstreamer.sh $FILE’ strm- &

I used avconv only because it’s what I had installed that would read an AAC stream and output an 8000 sample per second, 16 bit mono linear headerless stream. You can use almost anything that can output that format, ffmpeg, aplay to read the sound card, mpg123 for mpeg streams, what ever.

The real trick was using split to break the stream up into 10 second (160000 byte) chunks and passing them to a shell script to handle to file writing operations. The -d and -a7 and strm- gives me a numbered $FILE name to pass to the shell script.

pbxuser@pbx1:~# cat /usr/local/bin/mohstreamer.sh
#/bin/sh

#let me know your getting the right info
echo FILENAME - $1

#Grab the last digit 0-9 and use it for my file counter
cnt=echo $1 | sed -s "s/.*\(.\)$/\1/"

# remove our target file
rm /var/lib/asterisk/moh/strm_$cnt.wav

# Use xxd (or binhex or uucode if their installed0 to write the binary wav file header for a second wav file
# This header is set specifically to 8000 Samples per Second 16 Bit Samples One channel and a total of
# 160000 samples (10 Seconds)
cat << EOF | xxd -r > /var/lib/asterisk/moh/strm_$cnt.tmp
0000000: 5249 4646 2471 0200 5741 5645 666d 7420 RIFF$q…WAVEfmt
0000010: 1000 0000 0100 0100 401f 0000 803e 0000 …@…>…
0000020: 0200 1000 6461 7461 0071 0200 …data.q…
EOF

# I prefer to use dd to throw data around but I was having some issues with it sooooo…
# dd of=/var/lib/asterisk/moh/strm_$cnt.tmp bs=16 count=10000 conv=notrunc

# Append our 160000 bytes of wav data to our header in our temp file
cat >> /var/lib/asterisk/moh/strm_$cnt.tmp

# Move our newly created wav file into place for Asterisk to find
mv /var/lib/asterisk/moh/strm_$cnt.tmp /var/lib/asterisk/moh/strm_$cnt.wav

# Continue being an overly chatty Shell script.
echo built strm_$cnt.wav

Now I know this may not be the best way to go but for the few calls I have here, and myself just sitting listening to my streaming radio extension “misc application -> terminate call -> place on hold forever” it has worked flawlessly. (Well at least for another three year when split runs out of numbers ;)) This worked much easier than reinstalling asterisk, trying to install asterisk and gamble whether my google voice connector will still work, or a complete recompile to fix whatever bug that was.

I’d would like to know if anyone can identify any caveats that I may have missed, that can cause problems with streaming in this manner. If no one finds any problems with this method I’ll see if I can recode this into something much cleaner, maybe python. I greatly appreciate any comments, the non flammable ones are preferred though.

Thank you
Eric

I should note that you REALLY want to make sure that your /var/lib/asterisk/moh folder is empty expect for the wave files created by the mohstreamer.sh script. Also the FreePBX administration Music on hold settings generally repopulates based on the contents of this directory. Asterisk should only need a reload when all ten files are created. I am currently at 5 hours listening to the stream with no glitches.

Hmmm, I bet if I do this as a python script I can make it mix in regular announcements while playing the stream.

I.E. Blah, blah, radio stuff, blah, We appreciate you’re patience, a representative will be with you shortly, blah blah blah more radio stuff.