I'm using channels.externalMedia in my Asterisk ARI application to stream audio to a UDP listener at 127.0.0.1:12345 and process it with an OpenAI real-time model. The issue I'm facing is that when I play a raw audio file back to the caller using channels

I’m using channels.externalMedia in my Asterisk ARI application to stream audio to a UDP listener at 127.0.0.1:12345 and process it with an OpenAI real-time model. The issue I’m facing is that when I play a raw audio file back to the caller using channels.play, at that time stops receiving audio chunks from the externalMedia channel. This seems to indicate a problem with handling concurrent audio reception and playback, or a limitation in how Asterisk or the script manages the audio flow.

I’m looking for help to analyze this issue, identify the root cause, and find a solution to ensure that audio chunks from externalMedia continue to be received while playing the audio file. I’m using Asterisk 21.0.0 and the aioari library with Python.

You can’t do two things at once on a channel such as having it bridged and play audio to it. You have to use a Snoop channel to passively receive audio or inject audio into the channel.

So using the Snoop channels, i can able to do this things right after the implementing Snoop channels ?

I’m currently building a bot using Asterisk with ARI and ExternalMedia. My setup streams real-time audio from the ExternalMedia source to an OpenAI real-time model.

The challenge I’m facing is with interruptions. When OpenAI generates an audio response, I use channels.play to play it back. However, the channels.play action appears to be blocking. This prevents my ExternalMedia channel from sending any new audio chunks while the response is playing.

Because the incoming audio is blocked, I can’t detect if the user is trying to interrupt the bot. To handle interruptions properly, I need to continuously process the incoming audio from ExternalMedia, even when the bot is speaking.

What changes do I need to make to my approach to allow for real-time interruption handling? Is there a non-blocking way to play the audio response while still receiving the audio stream.

Yes.

Snoop channels[1] allow you to receive audio from a channel no matter what it is doing, or inject audio into the channel no matter what it is doing. You would play audio to the Snoop channel, which would then inject it. The main channel would remain in the bridge.

[1] Channels - Asterisk Documentation

i am doing like this

        # Create external media channel for audio streaming
        logger.info("[ARI] Creating external media channel...")
        ext_channel = await client.channels.externalMedia(
            app=APP_NAME,
            external_host=EXTERNAL_HOST,
            transport='udp',
            connection_type='rtp',
            format=FORMAT
        )
        call_handler.ext_channel = ext_channel
        logger.info(f"[ARI] External media channel created: {ext_channel.id}")

        # Create bridge with default type and use non-blocking playback approach
        logger.info("[ARI] Creating bridge...")
        bridge = await client.bridges.create()  # Use default bridge type
        call_handler.bridge = bridge
        
        # Add main channel and external media channel to bridge
        await bridge.addChannel(channel=[channel.id, ext_channel.id])
        logger.info(f"[ARI] Channels bridged - audio streaming active for {call_uuid}")

and i am playing file like this
playback = await self.channel.play(media=f'sound:{play_file}')

So i need to remove the externalMedia or need both the externalMedia and Snoop?

External media sends media to your ARI application to be used. You want that, or else it would defeat the entire purpose of what you’re doing.

Snoop does what I’ve said before.

You would use both.

I would highly suggest experimenting with Snoop channels to understand them, what they do, and how they work.

If you’re using AI to write this without understanding what everything is actually doing, then you’re going to run into problems.

How can i play or inject the audio using the snoop?

I’m not going to provide you written code to do so. I’ve given you the link to the Snoop channel creation, and as it creates a channel you would just play back a file to it.

It’s up to you to learn better about the pieces, and to put them together.

I will definitely do that and I’m eager for these solutions to resolve my issues.

As yet, AI does not provide a shortcut around actually understanding software architecture and doing investigative work.

2 Likes