Using Asterisk To Play Icecast Streams
Hi all,
A long time ago I built an Asterisk system that plays IceCast streams via moh.
extensions.conf:
Exten => moh,1,Set(SIP_CODEC=ulaw)
Exten => moh,2,Answer Exten => moh,3,MusicONHold(test_new)
Exten => moh,4,Hangup
musiconhold.conf
; test_new
[test_new]
mode=custom application=/etc/mystreams/test_new.sh
test_new.sh
#!/bin/bash wget -q -T 120 -O – ‘http://myURL.com/my_test_stream’ |
/usr/local/bin/madplay -Q -o raw:- –mono -R 8000 -a -10 –
Over all this does work good however:
1) I want to be able to add a few hundred streams per box. Not all streams are being listed to at once. Once you add a MOH class to musiconhold.conf it stays up forever (which I can understand why). When trying realtime madplay wont be loaded until it’s called in the dial plan. After that it is in Asterisk until I restart asterisk. If we have 20-30 streams it’s OK
but once that grows it can bog down the machine.
2) I found that it for some reason the stream returns a 404 (it goes off line etc.) then 10-15% of one core gets locked up until the stream comes back online. The issue is that if a few streams have an issue then I am locking up one care. From debuging the scripts it seems Asterisk keeps calling my bash script over and over. In the full I get:
[2016-03-14 06:39:23] WARNING[12534] res_musiconhold.c: poll() failed:
Interrupted system call
[2016-03-14 06:39:23] WARNING[12534] res_musiconhold.c: poll() failed:
Interrupted system call I tried using realtime along with a script that would check each stream and if there was a 404 to delete it from MySQL. This did not help. Asterisk would keep repeating the above logs till Asterisk was restarted.
Is there any way to have Asterisk remove a class if it’s not in use? What would be the right way to go about building such a system?
EDIT: I found that adding a simple sleep 2 to my bash script would slow things down and if a stream went down it would lower the CPU usage by a lot.
TIA.
Dovid
3 thoughts on - Using Asterisk To Play Icecast Streams
Steve,
These are live streams of events so I can’t simply rip the audio. As I
mentioned at the end of my email putting in a sleep did help a bit however there are only so many streams Asterisk will grab nicely at once with out spiking the CPU. I also tinkered a bit with real time here is what I found:
1) If we have cachertclasses=no then Asterisk will only pull the stream if some one is listening to that particular class. the upside of this is that we only pull a stream if we need it. The down side is if say there are four people listening to StreamX then we have four separate connections to StreamX.
2) If we have cachertclasses=yes set then Asterisk then we have the opposite of #1. The stream will be pulled if some one starts listening to it. If anyone hangs up then we still keep pulling the stream so over time if every stream is touched then we will over load the CPU.
I guess I am trying to find a match between the two.
Could you setup a local instance of Icecast and point your PBX to it?
It’s been years since I did any streaming but I recall my icecast relay would only consume bandwith when it had listeners connected to it.
Then you wouldn’t have to worry about how many people were listening to a single channel as it’d only use the one incoming stream to icecast.
John,
I don’t care about the bandwidth. My issue is with the cost of running madplay each instance of madplay. If we have 1000 possible streams and madplay using 0.3 of a core per CPU is 3 full cores just to pull the streams. What I am looking for a is a hybrid where we use the behavior of cachertclasses=no but if there are more than one people on hold we use the same “pull” so we aren’t invoking madplay over and over.
Another option would be to create a revert ices to play a stream from an icecast server. Again my goal is to cut down on CPU usage where possible.