Hi,
My goal is to play an audio file while listening for a specific list of digits.
If the digits pressed are not on this list the audio file should keep playing (but not start over).
If any one of the digits on my list is pressed I want the audio file playback to be interrupted.
For my ARI app (“mercury” in the snippet below) I use a golang I’m sure some here are aware of:
github.com/CyCoreSystems/ari
I tried using the Prompt() function in that import, but I had the same behavior as in the following code by simply subscribing to DTMF events:
dtmfSub := h.Subscribe(ari.Events.ChannelDtmfReceived)
defer dtmfSub.Cancel()
I define only 3 digits that should interrupt audio playback (1, 3, 5):
interruptDigits := map[string]bool{
"1": true,
"3": true,
"5": true,
}
At some point I play the audio file:
playback := play.Play(ctx, h, play.URI("sound:tts/d6fe29440ba3ac62606c8c3e5f93943e"))
and I process the digits I receive:
for {
select {
case <-ctx.Done():
log.Info("Context canceled, stopping app")
return
case e := <-dtmfSub.Events():
dtmfEvent := e.(*ari.ChannelDtmfReceived)
digit := dtmfEvent.Digit
log.Info("DTMF received", "digit", digit)
if interruptDigits[digit] {
log.Info("Interrupting playback due to digit", "digit", digit)
playback.Stop()
return
} else {
log.Info("Non-interrupting digit received; ignoring", "digit", digit)
// Do nothing, let the playback continue -- but it doesn't!!!
}
}
}
Now, when I run the app and I press ‘2’ during the audio playback I’m expecting the playback to keep going because the digit should be ignored.
However, the audio playback is interrupted…
My app’s log:
INFO[04-17|13:30:21] Connecting to ARI
INFO[04-17|13:30:21] Listening for new calls
INFO[04-17|13:32:33] Got stasis start channel=1744889553.341692
INFO[04-17|13:32:33] Running app channel=1744889553.341692
INFO[04-17|13:32:42] DTMF received digit=2
INFO[04-17|13:32:42] Non-interrupting digit received; ignoring digit=2
This is what I see in Asterisk CLI:
<--- Sending ARI event to 127.0.0.1:59632 --->
{"type":"PlaybackStarted","timestamp":"2025-04-17T13:32:33.868+0200","playback":{"id":"01js1rb8rj9t8t0kvkjnw294ss-pb","media_uri":"sound:tts/d6fe29440ba3ac62606c8c3e5f93943e","target_uri":"channel:1744889553.341692","language":"en","state":"playing"},"asterisk_id":"30:85:a9:8e:b9:a0","application":"mercury"}
-- <PJSIP/4155-00013d49> Playing 'tts/d6fe29440ba3ac62606c8c3e5f93943e.slin' (language 'en')
<--- Sending ARI event to 127.0.0.1:59632 --->
{"type":"ChannelDtmfReceived","timestamp":"2025-04-17T13:32:42.519+0200","digit":"2","duration_ms":100,"channel":{"id":"1744889553.341692","name":"PJSIP/4155-00013d49","state":"Up","caller":{"name":"VC1","number":"4155"},"connected":{"name":"","number":""},"accountcode":"","dialplan":{"context":"default","exten":"mercury","priority":4,"app_name":"Stasis","app_data":"\"mercury\""},"creationtime":"2025-04-17T13:32:33.479+0200","language":"en"},"asterisk_id":"30:85:a9:8e:b9:a0","application":"mercury"}
[Apr 17 13:32:42] NOTICE[2018][C-00015458]: res_stasis_playback.c:277 playback_final_update: 1744889553.341692: Playback stopped for sound:tts/d6fe29440ba3ac62606c8c3e5f93943e
<--- Sending ARI event to 127.0.0.1:59632 --->
{"type":"PlaybackFinished","timestamp":"2025-04-17T13:32:42.519+0200","playback":{"id":"01js1rb8rj9t8t0kvkjnw294ss-pb","media_uri":"sound:tts/d6fe29440ba3ac62606c8c3e5f93943e","target_uri":"channel:1744889553.341692","language":"en","state":"done"},"asterisk_id":"30:85:a9:8e:b9:a0","application":"mercury"}
So I see that Asterisk is stopping the playback. Why?
Is it expected behavior?
How can I debug this further so I can make sure the audio playback is not interrupted when the user presses a digit that is “not on the list”?
Also, when I press ‘2’ as in the example above the audio playback is interrupted, but the channel is still up. I can then press, say, ‘5’ and my app’s log shows this:
INFO[04-17|13:34:06] DTMF received digit=5
INFO[04-17|13:34:06] Interrupting playback due to digit digit=5
At this point, since ‘5’ is in my list the channel shuts down and my call is hung up.
Any ideas?
[EDIT]
A tcpdump shows that the ARI client sends this:
POST /ari/channels/1744972148.344797/play/01js473vp358c6tgbhwn7wvgh4-pb
with “media” value properly set to sound:tts/etc…
Asterisk replies with 201 Created (state: queued)
Then, as soon as I press ‘2’ in my example, I see that the ARI client sends the following right after receiving the DTMF event with value “2”:
DELETE /ari/playbacks/01js473vp358c6tgbhwn7wvgh4-pb
So I guess it’s obvious that it’s either a bug in the ARI client library or I’m not using it correctly. Asterisk isn’t stopping the playback on its own.
[EDIT]
Replacing play.Play with h.Play solved my problem (where h is *ari.ChannelHandle).