Closed MihaiSandor closed 7 months ago
@Ulexus, I managed to add this after I answered the call, but for some reason, it enters an infinite loop and Asterisk keeps sending the StasisStart
event, even though I should get the stream back to the TCP Server.
id := uuid.Must(uuid.NewV1()).String()
_, err = h.ExternalMedia(ari.ExternalMediaOptions{
ChannelID: id,
App: ariClient.ApplicationName(),
ExternalHost: "test:9000",
Format: "slin16",
Encapsulation: "audiosocket",
Transport: "tcp",
ConnectionType: "client",
Direction: "both",
Data: id,
Variables: map[string]string{
"AUDIOSOCKET_ID": id,
},
})
if err != nil {
log.Printf("Failed to get external media %v", err)
return
}
I am trying to have full control over the backend application, which is why I want to keep the extensions.conf
minimal. The extensions.conf
looks like this:
[mycontext]
include => voipms-inbound
[voipms-inbound]
exten => s,1,NoOp(Call received for extension s)
same => n,Stasis(myapp)
exten => _X!,1,Stasis(myapp)
Here are some logs from Asterisk Server:
[Mar 13 14:03:24] WARNING[3161]: app.c:1941 __ast_play_and_record: No audio available on AudioSocket/test:9000-728fd0b8-e142-11ee-a15d-9600031994bb??
[Mar 13 14:03:24] -- User hung up
[Mar 13 14:03:24] -- x=0, open writing: /var/spool/asterisk/recording/01hrw1zz35fvhm61cnrz2gn7kg-rc format: wav, 0x7f8684205630
[Mar 13 14:03:24] WARNING[3162]: app.c:1941 __ast_play_and_record: No audio available on AudioSocket/test:9000-7290cb97-e142-11ee-a15d-9600031994bb??
[Mar 13 14:03:24] -- User hung up
[Mar 13 14:03:24] -- Called test:9000/74f52185-e142-11ee-a15d-9600031994bb
[Mar 13 14:03:24] -- x=0, open writing: /var/spool/asterisk/recording/01hrw1zz3a3aqwg18qdn0e3q7s-rc format: wav, 0x55ac1ff88300
[Mar 13 14:03:24] -- AudioSocket/test:9000-74f52185-e142-11ee-a15d-9600031994bb answered
[Mar 13 14:03:24] -- Called test:9000/74f60149-e142-11ee-a15d-9600031994bb
[Mar 13 14:03:24] -- AudioSocket/test:9000-74f60149-e142-11ee-a15d-9600031994bb answered
[Mar 13 14:03:24] WARNING[3165]: app.c:1941 __ast_play_and_record: No audio available on AudioSocket/test:9000-7291b111-e142-11ee-a15d-9600031994bb??
[Mar 13 14:03:24] -- User hung up
[Mar 13 14:03:24] -- x=0, open writing: /var/spool/asterisk/recording/01hrw1zz3h1nvyn8xxzhnc337m-rc format: wav, 0x7f8650635490
[Mar 13 14:03:24] -- Called test:9000/74f71422-e142-11ee-a15d-9600031994bb
[Mar 13 14:03:24] -- AudioSocket/test:9000-74f71422-e142-11ee-a15d-9600031994bb answered
[Mar 13 14:03:24] -- x=0, open writing: /var/spool/asterisk/recording/01hrw1zz3q2rbrx8jbr36gsc61-rc format: wav, 0x7f865c3866e0
[Mar 13 14:03:24] WARNING[3166]: app.c:1941 __ast_play_and_record: No audio available on AudioSocket/test:9000-72926c20-e142-11ee-a15d-9600031994bb??
[Mar 13 14:03:24] -- User hung up
[Mar 13 14:03:24] -- Called test:9000/74f80a39-e142-11ee-a15d-9600031994bb
[Mar 13 14:03:24] -- AudioSocket/test:9000-74f80a39-e142-11ee-a15d-9600031994bb answered
[Mar 13 14:03:24] -- x=0, open writing: /var/spool/asterisk/recording/01hrw1zz3y66jt383z241t2fqy-rc format: wav, 0x7f8664231910
[Mar 13 14:03:24] WARNING[3169]: app.c:1941 __ast_play_and_record: No audio available on AudioSocket/test:9000-729354e5-e142-11ee-a15d-9600031994bb??
[Mar 13 14:03:24] -- User hung up
[Mar 13 14:03:24] WARNING[3171]: app.c:1941 __ast_play_and_record: No audio available on AudioSocket/test:9000-7295a6f0-e142-11ee-a15d-9600031994bb??
[Mar 13 14:03:24] -- User hung up
[Mar 13 14:03:24] -- Called test:9000/74faa9c9-e142-11ee-a15d-9600031994bb
[Mar 13 14:03:24] -- AudioSocket/test:9000-74faa9c9-e142-11ee-a15d-9600031994bb answered
[Mar 13 14:03:24] WARNING[3173]: app.c:1941 __ast_play_and_record: No audio available on AudioSocket/test:9000-7296caa0-e142-11ee-a15d-9600031994bb??
[Mar 13 14:03:24] -- User hung up
[Mar 13 14:03:24] WARNING[3175]: app.c:1941 __ast_play_and_record: No audio available on AudioSocket/test:9000-7297c552-e142-11ee-a15d-9600031994bb??
[Mar 13 14:03:24] -- User hung up
@MihaiSandor I also see the loop. It's happening because ExternalMedia
is calling ApplicationName
with the same application name, so it just loops. I see that's happening in the example code as well and not sure how to address it.
Were you able to workaround it?
@MihaiSandor I also see the loop. It's happening because
ExternalMedia
is callingApplicationName
with the same application name, so it just loops. I see that's happening in the example code as well and not sure how to address it.Were you able to workaround it?
@alon7, Yes. I did this hack:
func isUUID(uuid string) bool {
r, err := regexp.Compile(`^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`)
if err != nil {
log.Println("Error compiling regex:", err)
return false
}
return r.MatchString(uuid)
}
func answerCalls() {
log.Println("Listening for new calls")
sub := ariClient.Bus().Subscribe(nil, "StasisStart")
defer sub.Cancel()
for {
select {
case e := <-sub.Events():
v := e.(*ari.StasisStart)
h := ariClient.Channel().Get(v.Key(ari.ChannelKey, v.Channel.ID))
if isUUID(h.ID()) {
log.Printf("Ignoring ExternalMedia StasisStart event for channel %s", h.ID())
continue
}
go handleCall(h)
}
}
}
Thanks @MihaiSandor ill try it soon!
Yeah, I generally set a channel variable on the newly-created channel indicating it is related to an existing channel already in ARI, and should thus be handled differently. Your workaround is also fine, but it would be better to use something a little more direct than just testing whether a new channel ID is a UUID.
Another option I have used is to pre-register the new channel ID upon creation, popping it into a redis cache, and checking new channels against that.
In your case, since you are setting AUDIOSOCKET_ID
, you could just check for that variable on new calls.
Makes sense @Ulexus. How come it works in your example without ignoring it?
That's actually a really good question... I see I'm passing "noop" as the args (another method I've used to have it ignore)... but I'm not actually evaluating that anywhere that I see. Looks like a bug. :)
Thanks @Ulexus!
Hello @Ulexus,
I am currently working on an application using the ARI (Asterisk REST Interface) that involves handling voice calls in real-time. My goal is to enhance the interactivity of voice calls by directly integrating real-time microphone input from the call handler side and streaming it to the call recipient. Additionally, I aim to capture the audio stream from the call recipient and output it through the call handler's speakers. This setup is intended to enable a live and interactive audio exchange between the call handler and the recipient.
To achieve this, I am interested in dynamically adding an AudioSocket endpoint to the dialplan within the context of a Stasis Application, after a call has been answered. Here is a snippet of code illustrating where I want to integrate this functionality:
However, I am uncertain about the feasibility and correct approach to dynamically add an AudioSocket application invocation to the dialplan for an ongoing call within a Stasis Application. Specifically, I am looking to understand:
github.com/CyCoreSystems/ari/v6
)?The primary objective is to create a seamless real-time voice exchange between the call handler and recipient, enhancing the interactive capabilities of voice applications built on Asterisk and ARI.
Thank you for your time and assistance. Any insights, guidance, or references to relevant documentation would be greatly appreciated.