Hang up if no moh streaming?

My church has a video livestream on Sundays and I have it pushed to various platforms, including an rtmp server which then uses ffmpeg to push to an Icecast server encoded as audio only. Then I have an Asterisk server where when the caller calls in during a livestream, they immediately hear the livestream from the Icecast server. This is what I have to make that happen:

In pjsip.conf:

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0

[siptrunk-auth]
type=auth
auth_type=userpass
username=mysipusername
password=mysippassword

[siptrunk-aor]
type=aor
contact=sip:voip.provider.com
[siptrunk]
type=endpoint
transport=transport-udp
context=from-siptrunk
disallow=all
allow=ulaw
outbound_auth=siptrunk-auth
aors=siptrunk-aor

[siptrunk-registration]
type=registration
transport=transport-udp
outbound_auth=siptrunk-auth
server_uri=sip:voip.provider.com
client_uri=sip:mysipusername@voip.provider.com
contact_user=inbound-calls
retry_interval=60

[siptrunk-identify]
type=identify
match=voip.provider.com
endpoint=siptrunk

In extensions.conf

[from-siptrunk]
exten => inbound-calls,1,Verbose(1,Playing some music.)
same => n,Answer
same => n,MusicOnHold(ulawstream)
same => n,Hangup()

In musiconhold.conf:

[ulawstream]
mode=custom
application=/usr/sbin/moh.sh

In /usr/sbin/moh.sh:

#!/bin/bash

if -n "`ls /tmp/asterisk-moh-pipe.*`" ; then
rm /tmp/asterisk-moh-pipe.*
fi

PIPE="/tmp/asterisk-moh-pipe.$$"
mknod $PIPE p

/usr/sbin/mplayer https://my.icecastserver.com/live.mp3 -really-quiet -quiet -ao pcm:file$
rm $PIPE

I had to also install mplayer & edit the modules.conf file and uncomment res_musiconhold.so.

What I am trying to figure out is how to have it hang up if someone calls in and there is no Icecast stream happening, and also hang up when the Icecast stream ends. Is this possible? How would I accomplish this?

It seems to me that your current solution is overly complicated. The sample configuration file for MOH shows how to call an mp3 stream directly. You could reload the MOH configuration with different settings when the holy words start and end. There are a couple of ways to do that from outside Asterisk. It’s difficult to suggest something, as I don’t know what you are trying to exactly and what your environment offers.

I was using these instructions.

But I just found this today. Is this what you’re talking about? In musiconhold.conf:

[ulawstream]
mode=custom
application=/usr/bin/mplayer https://my.icecastserver.com/live.mp3 -quiet -ao pcm:file=/dev/stdout -af volume=5,resample=8000,channels=1,format=alaw

Beyond that, I don’t know. I am just learning and starting to understand bash scripting, so maybe I’ll play around with that. I am just not sure what I would need to change in extensions.conf to make it hang up when there is nothing streaming.

You don’t need bash, methinks. mpg123 works fine without any further scripts. That said, I can’t understand how this is going to work on the phone side. Usually, the number of channels is rather limited, unless you have something bigger.

mpg123 won’t work for me. I get a bazillion, neverending res_musiconhold.c:719 monmp3thread: poll() failed: Interrupted system call in the asterisk console, and don’t hear anything.

Yikes! All my problems went away after I switched to mpg123 (with some fine-tuned buffer settings + process control), but I guess that could depend on the characteristics of the source.

Interrupted system call indicates that your stream gets interrupted, which would have nothing to do with mpg123. You probably need to analyze your problem more thoroughly and any attempt to close the barn door after the horse has escaped will not be successful.

Interrupted system call is not an error, although it might indicate an underlying problem. Certain long running system calls can be interrupted by the delivery of signals to a process, and interrupted system call tells the user level code that it needs to re-issue the call to do the balance of the processing.

If the user level code doesn’t restart the system call, that would be a bug.

In this case, it would mean that res_musiconhold would have to restart the connection, but I don’t know how you can trigger that, except reloading the module which would also restart mpg123. My suggestion was to first look at the initial audio source.

I use mpg123 for various tasks including music/radio for restaurants and MOH in Asterisk systems. mpg123 has no problem with long runtimes, if the source is ok (but hardly any is).

I think you are confusing it with SIGPIPE. All that you need to do for EINTR is to re-issue the read(). The EINTR indicates that it didn’t really fail, but had to be terminated before it returned any data.

Maybe, but how can res_musiconhold take care of that? Either you look at the source code, or you try to detect problems somehow from the outside and that implies that sometimes only reloading the module helps.

So if I was to switch to mpg123, how would I implement that?

I have done experimentations where I use mplayer directly in musiconhold.conf (no script) and I actually have the same error as I described. It seems that I must have the $PIPE as voip-info describes, which means I need to do this via a script.

I’m pretty new to this.

The first think I would do is to upgrade to a current version of Asterisk, as there are 90 additional lines of code ahead of the line that produces this message in the current development version.

I don’t know which version you are using, so I don’t know what to compare to work out if this has already been addressed.

It looks like ast_poll doesn’t handle EINTR. That is either because it isn’t supposed to be used in a context where EINTR is possible, or because the caller is expected to handle it.

In the latter case, as poll seems to be being used for its timer side effect, the code probably needs to work out how much of time interval is left and re-issue ast_poll for the balance.

If EINTR isn’t expected to happen at all, the code should block the signal that is causing it. That probably means first making sure that the signal gets logged, so as to know what has to be blocked.

Detailed analysis might reveal that there is a signal that is not expected in the rest of asterisk, but is relevant here. Typically the signal handler should set a flag which is tested when handling EINTR, with the poll being restarted if it isn’t set, or a clear diagnostic message being produced if it is set.

I’d need a much more detailed study of the code, and ideally information on what signal was interrupting the system call, to go into any more detail. I guess the most likely ones are SIGPIPE (which is likely to indicate that the stream has ended) and SIGALARM, which would require further analysis.

I’m in the opposite boat; I attempted to use an icecast stream as moh and only got it to work using the script method. Then again I’m pretty sure I never got mpg123 to properly pull from icecast to start with; not to mention it was easier to use ogg on the icecast.

I don’t think there is a direct option to disconnect if moh dies. In my cases every time the icecast stream would fail moh would just sit there, silent.

Off the top of my head…the very roundabout way I would do this is have whatever you’re using to go from rtmp to mp3 run inside a script that, when finished, would call asterisk to put an entry in it’s internal database; you then check for that entry in your dialplan and use a gotoif. The script would also have to call asterisk to send the command to delete that db entry.

You could also probably do this with a complex agl script.

Just to be sure that the problem is not the icecast stream and/or mpg123, you could listen to the speaker for a while before bringing everything to Asterisk.

I’m running Asterisk 16.22.

Just to be sure that the problem is not the icecast stream and/or mpg123, you could listen to the speaker for a while before bringing everything to Asterisk.

The problem is not icecast. I can play the stream fine in my browser. I can even hear the stream fine in asterisk… but once I end the stream, then I can’t get it to recover (when starting a new stream) unless I stop Asterisk, uninstall mplayer, reinstall mplayer, and start Asterisk again. And even then, sometimes I can’t get it to recover until randomly later.

Off the top of my head…the very roundabout way I would do this is have whatever you’re using to go from rtmp to mp3 run inside a script that, when finished, would call asterisk to put an entry in it’s internal database; you then check for that entry in your dialplan and use a gotoif. The script would also have to call asterisk to send the command to delete that db entry.

Definitely way over my head right now.

Update. Using madplay ended up solving one of my problems. Stream resumes with no issues.

So now I just need to figure out how to get asterisk to hang up when the stream ends. I get the warning res_musiconhold.c:809 monmp3thread: poll() failed: Interrupted system call when the stream ends, so maybe there is some way to build a script where if that warning comes up in asterisk console, asterisk hangs up?

I think I’m seeing the problem here. You are using a mechanism designed for recorded audio on demand, for a real time audio feed that isn’t always present. I think Asterisk is simply replaying the audio every time it completes, as it would do with a recording. When it isn’t present, it completes immediately.

I think the message your are receiving is the result of rather bad logging of the SIGPIPE event that happens when the stream stops.

MoH is really intended for background streams. I’m not sure if you are really using it for background, or whether the stream is the primary content.

For primary content, in principle you should be using Playback, which will only play the stream once, but I haven’t investigated its ability to use a stream, rather than a file, as a source.

If you really need something for genuine music on hold, or it is impossible to do foreground media properly, looking for that message is relying on something that could easily change. The easiest approach might involve more complicated shell scripting such that the playback is followed a very long wait, doing nothing, or streaming silence, but down the same pipe. However, if you want things to hangup when the audio ceases, that isn’t how MoH is intended to be used, and you really need a foreground stream.

Incidentally, I haven’t checked the Ts and Cs on your sources, but are you sure that your use is permitted, and you aren’t breaching any performing rights. Most streaming services are intended for individual, personal, use.