Circular creation of channels (ARI, Python)

Hi everyone,

I’m working on creating a Python-based client to manage calls, serving as a channel to my voice AI agent. I can successfully answer calls from a remote party, but I’m having trouble retrieving the audio stream to send to my Speech-To-Text engine.

After researching, I understand that I need to create a snoop channel that spies on the main channel, along with an external media channel bridged to the snoop channel.

However, when I try to implement this setup, I encounter a circular channel creation issue. I’ve tried to avoid the loop without success. Below is my code snippet (Python):

def on_message(ws, message):
    try:
        event = json.loads(message)
        logging.info(f"Received event: {event}")

        if event['type'] == 'StasisStart':
            channel = event['channel']

            if channel['id'] in processed_channels or "Snoop" in channel['name']:
                logging.info(f"Ignoring already processed or snoop channel: {channel['id']}")
                return

            processed_channels.add(channel['id'])
            logging.info(f"Processing new channel: {channel['id']}")

            # Answer the call
            answer_call(channel['id'])

            # Start external media and snoop
            external_channel_id = start_external_media()
            if not external_channel_id:
                logging.error("Failed to start external media.")
                return

            snoop_channel_id = create_snoop_channel(channel['id'])
            if not snoop_channel_id:
                logging.error("Failed to create snoop channel.")
                return

            # Create and populate bridge
            bridge_id = create_bridge()
            if bridge_id:
                add_channel_to_bridge(bridge_id, snoop_channel_id)
                add_channel_to_bridge(bridge_id, external_channel_id)
            else:
                logging.error("Failed to create bridge.")
    except Exception as e:
        logging.error(f"Error in on_message: {e}")

Additionally, to receive audio, I wrote a separate Python script that listens for RTP packets. However, this feels suboptimal. Does Asterisk provide a way to receive audio packets as media events directly, instead of using RTP listeners?

Any help or suggestions would be greatly appreciated!

Thanks,
Arkadi

It would be helpful if you actually showed what happened as well. The more information you provide and the less effort involved to try to deduce, the more likely people will help.

I’m not sure what you mean by “media events”. There is no websocket support for media, or other way to transport it aside from RTP and audiosocket (which is extended support, and TCP based).

I saw the check for the snoop channel on StasisStart, Are you doing the same for the External Media channel?

Thank you @mbradeen ! The issue was related to checking the external media channel, and it seems the loop issue is gone. However, I’m now facing another issue.

I am originating a call to Asterisk and saving the RTP packets (after decoding) to a file, but the file only contains silence (with the same duration as the call).

### What I Have Tried

**Verified Audio Format:
The audio format seems correct. Here is the relevant part from the SIP INVITE:

v=0  
o=- 188 3 IN IP4 10.208.0.2  
s=Asterisk  
c=IN IP4 10.208.0.2  
t=0 0  
m=audio 33792 RTP/AVP 0 101  
a=rtpmap:0 PCMU/8000  
a=rtpmap:101 telephone-event/8000  
a=fmtp:101 0-16  
a=ptime:20  
a=maxptime:150  
a=sendrecv  

Here is the external channel creation code:

def start_external_media():
    """Start an external media channel."""
    url = f"{ARI_URL}/ari/channels/externalMedia"
    data = {
        "app": APP_NAME,
        "external_host": f"{MEDIA_HOST}:{MEDIA_PORT}",
        "format": "ulaw"  # Ensure this matches PCMU (G.711) as per SIP SDP
    }
    logging.info(f"Opening external media with data: {data}")
    response = requests.post(url, auth=(USERNAME, PASSWORD), json=data)

    if response.status_code == 200:
        external_channel = response.json()
        logging.info(f"Started external media: {external_channel}")
        return external_channel['id']
    else:
        logging.error(f"Failed to start external media: {response.status_code} - {response.text}")
        return None

**Decoded the Audio from “ulaw” Format:
Below is my ulaw_to_pcm function used for decoding:

def ulaw_to_pcm(ulaw_byte):
    """Convert a single u-law byte to a PCM sample."""
    ulaw_byte = ~ulaw_byte
    sign = (ulaw_byte & 0x80)
    exponent = (ulaw_byte >> 4) & 0x07
    mantissa = ulaw_byte & 0x0F
    magnitude = ((0x21 | (mantissa << 1)) << exponent) - 33
    pcm_value = -magnitude if sign else magnitude
    logging.debug(f"u-law byte: {ulaw_byte}, PCM value: {pcm_value}")
    return pcm_value

Despite these efforts, the output audio file still contains only silence.


### Complete ARI Python Code
I’ve included my ARI Python code for reference below:

# Configuration details
ARI_URL = 'http://127.0.0.1:8088'
USERNAME = 'asterisk_channel'
PASSWORD = 'Onvego123'
APP_NAME = 'hello-world'
MEDIA_HOST = '127.0.0.1'
MEDIA_PORT = 9000

# Track processed channels globally
processed_channels = set()
logging.basicConfig(level=logging.INFO)

def on_message(ws, message):
    try:
        logging.info("\n--- New on_message execution ---")
        event = json.loads(message)
        logging.info(f"Received event: {event}")

        if event['type'] == 'StasisStart':
            channel = event['channel']
            channel_id = channel['id']
            channel_name = channel['name']

            # Ensure no redundant processing of channels
            if channel_id in processed_channels or "Snoop" in channel_name:
                logging.info(f"Ignoring already processed or snoop channel: {channel_id}")
                logging.info("--- Exit on_message: Ignoring channel ---\n")
                return

            processed_channels.add(channel_id)
            logging.info(f"Processing new channel: {channel_id}")

            # Answer the call
            answer_call(channel_id)

            # Start external media and add to processed channels
            external_channel_id = start_external_media()
            if not external_channel_id:
                logging.error("Failed to start external media.")
                logging.info("--- Exit on_message: Failed external media ---\n")
                return
            processed_channels.add(external_channel_id)

            # Create snoop channel and add to processed channels
            snoop_channel_id = create_snoop_channel(channel_id)
            if not snoop_channel_id:
                logging.error("Failed to create snoop channel.")
                logging.info("--- Exit on_message: Failed snoop channel ---\n")
                return
            processed_channels.add(snoop_channel_id)

            # Create and populate bridge
            bridge_id = create_bridge()
            if bridge_id:
                add_channel_to_bridge(bridge_id, snoop_channel_id)
                add_channel_to_bridge(bridge_id, external_channel_id)
            else:
                logging.error("Failed to create bridge.")
                logging.info("--- Exit on_message: Failed to create bridge ---\n")

        logging.info("--- End of on_message execution ---\n")
    except Exception as e:
        logging.error(f"Error in on_message: {e}")
        logging.info("--- Exit on_message: Exception occurred ---\n")

def start_external_media():
    """Start an external media channel."""
    url = f"{ARI_URL}/ari/channels/externalMedia"
    data = {
        "app": APP_NAME,
        "external_host": f"{MEDIA_HOST}:{MEDIA_PORT}",
        "format": "ulaw"  # Verify this matches PCMU (G.711) as per SIP SDP
    }
    logging.info(f"Opening external media with data: {data}")
    response = requests.post(url, auth=(USERNAME, PASSWORD), json=data)

    if response.status_code == 200:
        external_channel = response.json()
        logging.info(f"Started external media: {external_channel}")
        return external_channel['id']
    else:
        logging.error(f"Failed to start external media: {response.status_code} - {response.text}")
        return None

def create_snoop_channel(original_channel_id):
    """Create a snoop channel on the original channel."""
    url = f"{ARI_URL}/ari/channels/{original_channel_id}/snoop"
    data = {
        "app": APP_NAME,
        "spy": "both"
    }
    response = requests.post(url, auth=(USERNAME, PASSWORD), json=data)
    if response.status_code == 200:
        snoop_channel = response.json()
        logging.info(f"Snoop channel created: {snoop_channel}")
        return snoop_channel['id']
    else:
        logging.error(f"Failed to create snoop channel: {response.status_code} - {response.text}")
        return None

def answer_call(channel_id):
    """Answer the incoming call."""
    url = f"{ARI_URL}/ari/channels/{channel_id}/answer"
    response = requests.post(url, auth=(USERNAME, PASSWORD))
    if response.status_code == 204:
        logging.info(f"Answered call on channel: {channel_id}")
    else:
        logging.error(f"Failed to answer call: {response.status_code} - {response.text}")

def create_bridge():
    """Create a mixing bridge."""
    url = f"{ARI_URL}/ari/bridges"
    data = {"type": "mixing"}
    response = requests.post(url, auth=(USERNAME, PASSWORD), json=data)
    if response.status_code == 200:
        bridge = response.json()
        logging.info(f"Created bridge: {bridge}")
        return bridge['id']
    else:
        logging.error(f"Failed to create bridge: {response.status_code} - {response.text}")
        return None

def add_channel_to_bridge(bridge_id, channel_id):
    """Add a channel to the bridge."""
    url = f"{ARI_URL}/ari/bridges/{bridge_id}/addChannel"
    data = {"channel": channel_id}
    response = requests.post(url, auth=(USERNAME, PASSWORD), json=data)
    if response.status_code == 204:
        logging.info(f"Added channel {channel_id} to bridge {bridge_id}")
    else:
        logging.error(f"Failed to add channel to bridge: {response.status_code} - {response.text}")

def start_ari_ws():
    """Start the ARI WebSocket connection."""
    credentials = f"{USERNAME}:{PASSWORD}".encode('utf-8')
    auth_header = base64.b64encode(credentials).decode('utf-8')

    ws_url = f"ws://127.0.0.1:8088/ari/events?app={APP_NAME}&subscribeAll=true"
    ws = WebSocketApp(
        ws_url,
        on_message=on_message,
        on_error=lambda ws, err: logging.error(f"WebSocket error: {err}"),
        on_close=lambda ws, code, msg: logging.info("WebSocket connection closed"),
        header=[f"Authorization: Basic {auth_header}"]
    )
    ws.on_open = lambda ws: logging.info(f"WebSocket connected to ARI app '{APP_NAME}'")
    ws.run_forever()

if __name__ == "__main__":
    logging.info(f"Starting ARI client for app '{APP_NAME}'...")
    start_ari_ws()

### RTP Packet Capture Script
Here is the script I use to capture RTP packets, decode them, and save them to a WAV file:

HOST = "0.0.0.0"
PORT = 9000
BUFFER_SIZE = 2048
ALLOWED_IP = "127.0.0.1"

filename = f"rtp_capture_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.wav"
logging.basicConfig(level=logging.INFO)
logging.info(f"Saving RTP packets to: {filename}")

sample_rate = 8000
channels = 1
sample_width = 2

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((HOST, PORT))

with wave.open(filename, "wb") as wav_file:
    wav_file.setnchannels(channels)
    wav_file.setsampwidth(sample_width)
    wav_file.setframerate(sample_rate)

    try:
        while True:
            data, addr = sock.recvfrom(BUFFER_SIZE)
            if addr[0] == ALLOWED_IP:
                audio_data = data[12:]
                pcm_data = bytearray()
                for byte in audio_data:
                    pcm_sample = ulaw_to_pcm(byte)
                    pcm_data.extend(struct.pack('<h', pcm_sample))
                wav_file.writeframes(pcm_data)
            else:
                logging.info(f"Ignored packet from {addr}")
    except KeyboardInterrupt:
        logging.info("Capture stopped.")
    finally:
        sock.close()

### Attached Logs

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘StasisStart’, ‘timestamp’: ‘2024-10-18T12:20:26.473+0000’, ‘args’: , ‘channel’: {‘id’: ‘1729254026.56’, ‘name’: ‘PJSIP/siptrunk-0000000c’, ‘state’: ‘Ring’, ‘protocol_id’: ‘3283c6a7-07ee-123e-e3a7-d4bed9a8ae14’, ‘caller’: {‘name’: ‘XLf9rR5woMHW_FZ’, ‘number’: ‘+18443359250’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘from-trunk’, ‘exten’: ‘s’, ‘priority’: 2, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.472+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:Processing new channel: 1729254026.56
INFO:root:Answered call on channel: 1729254026.56
INFO:root:Opening external media with data: {‘app’: ‘hello-world’, ‘external_host’: ‘127.0.0.1:9000’, ‘format’: ‘ulaw’}
INFO:root:Started external media: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Down’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘AppDial2’, ‘app_data’: ‘(Outgoing Line)’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’, ‘channelvars’: {‘UNICASTRTP_LOCAL_PORT’: ‘20828’, ‘UNICASTRTP_LOCAL_ADDRESS’: ‘127.0.0.1’}}
INFO:root:Snoop channel created: {‘id’: ‘1729254026.58’, ‘name’: ‘Snoop/1729254026.56-0000000b’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘’, ‘app_data’: ‘’}, ‘creationtime’: ‘2024-10-18T12:20:26.679+0000’, ‘language’: ‘en’}
INFO:root:Created bridge: {‘id’: ‘370a8271-d17a-40e0-9e13-452394980833’, ‘technology’: ‘simple_bridge’, ‘bridge_type’: ‘mixing’, ‘bridge_class’: ‘stasis’, ‘creator’: ‘Stasis’, ‘name’: ‘’, ‘channels’: , ‘creationtime’: ‘2024-10-18T12:20:26.680+0000’, ‘video_mode’: ‘talker’}
INFO:root:Added channel 1729254026.58 to bridge 370a8271-d17a-40e0-9e13-452394980833
INFO:root:Added channel 1729254026.57 to bridge 370a8271-d17a-40e0-9e13-452394980833
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘ChannelStateChange’, ‘timestamp’: ‘2024-10-18T12:20:26.673+0000’, ‘channel’: {‘id’: ‘1729254026.56’, ‘name’: ‘PJSIP/siptrunk-0000000c’, ‘state’: ‘Up’, ‘protocol_id’: ‘3283c6a7-07ee-123e-e3a7-d4bed9a8ae14’, ‘caller’: {‘name’: ‘XLf9rR5woMHW_FZ’, ‘number’: ‘+18443359250’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘from-trunk’, ‘exten’: ‘s’, ‘priority’: 2, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.472+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘DeviceStateChanged’, ‘application’: ‘hello-world’, ‘timestamp’: ‘2024-10-18T12:20:26.673+0000’, ‘device_state’: {‘name’: ‘PJSIP/siptrunk’, ‘state’: ‘INUSE’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘ChannelCreated’, ‘timestamp’: ‘2024-10-18T12:20:26.677+0000’, ‘channel’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Down’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘’, ‘app_data’: ‘’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘variable’: ‘UNICASTRTP_LOCAL_ADDRESS’, ‘value’: ‘127.0.0.1’, ‘type’: ‘ChannelVarset’, ‘timestamp’: ‘2024-10-18T12:20:26.677+0000’, ‘channel’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Down’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘’, ‘app_data’: ‘’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘variable’: ‘UNICASTRTP_LOCAL_PORT’, ‘value’: ‘20828’, ‘type’: ‘ChannelVarset’, ‘timestamp’: ‘2024-10-18T12:20:26.677+0000’, ‘channel’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Down’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘’, ‘app_data’: ‘’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘ChannelDialplan’, ‘timestamp’: ‘2024-10-18T12:20:26.677+0000’, ‘dialplan_app’: ‘AppDial2’, ‘dialplan_app_data’: ‘(Outgoing Line)’, ‘channel’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Down’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘AppDial2’, ‘app_data’: ‘(Outgoing Line)’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘Dial’, ‘timestamp’: ‘2024-10-18T12:20:26.677+0000’, ‘dialstatus’: ‘’, ‘forward’: ‘’, ‘dialstring’: ‘127.0.0.1:9000’, ‘peer’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Down’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘AppDial2’, ‘app_data’: ‘(Outgoing Line)’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘ChannelStateChange’, ‘timestamp’: ‘2024-10-18T12:20:26.677+0000’, ‘channel’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘AppDial2’, ‘app_data’: ‘(Outgoing Line)’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘Dial’, ‘timestamp’: ‘2024-10-18T12:20:26.677+0000’, ‘dialstatus’: ‘ANSWER’, ‘forward’: ‘’, ‘dialstring’: ‘127.0.0.1:9000’, ‘peer’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘AppDial2’, ‘app_data’: ‘(Outgoing Line)’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘variable’: ‘STASISSTATUS’, ‘value’: ‘’, ‘type’: ‘ChannelVarset’, ‘timestamp’: ‘2024-10-18T12:20:26.677+0000’, ‘channel’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘StasisStart’, ‘timestamp’: ‘2024-10-18T12:20:26.677+0000’, ‘args’: , ‘channel’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:Ignoring already processed or snoop channel: 1729254026.57
INFO:root:— Exit on_message: Ignoring channel —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘ChannelCreated’, ‘timestamp’: ‘2024-10-18T12:20:26.679+0000’, ‘channel’: {‘id’: ‘1729254026.58’, ‘name’: ‘Snoop/1729254026.56-0000000b’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘’, ‘app_data’: ‘’}, ‘creationtime’: ‘2024-10-18T12:20:26.679+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘ChannelDialplan’, ‘timestamp’: ‘2024-10-18T12:20:26.679+0000’, ‘dialplan_app’: ‘Stasis’, ‘dialplan_app_data’: ‘hello-world’, ‘channel’: {‘id’: ‘1729254026.58’, ‘name’: ‘Snoop/1729254026.56-0000000b’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.679+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘variable’: ‘STASISSTATUS’, ‘value’: ‘’, ‘type’: ‘ChannelVarset’, ‘timestamp’: ‘2024-10-18T12:20:26.679+0000’, ‘channel’: {‘id’: ‘1729254026.58’, ‘name’: ‘Snoop/1729254026.56-0000000b’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.679+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘StasisStart’, ‘timestamp’: ‘2024-10-18T12:20:26.679+0000’, ‘args’: , ‘channel’: {‘id’: ‘1729254026.58’, ‘name’: ‘Snoop/1729254026.56-0000000b’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.679+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:Ignoring already processed or snoop channel: 1729254026.58
INFO:root:— Exit on_message: Ignoring channel —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘BridgeCreated’, ‘timestamp’: ‘2024-10-18T12:20:26.680+0000’, ‘bridge’: {‘id’: ‘370a8271-d17a-40e0-9e13-452394980833’, ‘technology’: ‘simple_bridge’, ‘bridge_type’: ‘mixing’, ‘bridge_class’: ‘stasis’, ‘creator’: ‘Stasis’, ‘name’: ‘’, ‘channels’: , ‘creationtime’: ‘2024-10-18T12:20:26.680+0000’, ‘video_mode’: ‘talker’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘ChannelEnteredBridge’, ‘timestamp’: ‘2024-10-18T12:20:26.699+0000’, ‘bridge’: {‘id’: ‘370a8271-d17a-40e0-9e13-452394980833’, ‘technology’: ‘simple_bridge’, ‘bridge_type’: ‘mixing’, ‘bridge_class’: ‘stasis’, ‘creator’: ‘Stasis’, ‘name’: ‘’, ‘channels’: [‘1729254026.58’], ‘creationtime’: ‘2024-10-18T12:20:26.680+0000’, ‘video_mode’: ‘talker’}, ‘channel’: {‘id’: ‘1729254026.58’, ‘name’: ‘Snoop/1729254026.56-0000000b’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.679+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘ChannelEnteredBridge’, ‘timestamp’: ‘2024-10-18T12:20:26.877+0000’, ‘bridge’: {‘id’: ‘370a8271-d17a-40e0-9e13-452394980833’, ‘technology’: ‘simple_bridge’, ‘bridge_type’: ‘mixing’, ‘bridge_class’: ‘stasis’, ‘creator’: ‘Stasis’, ‘name’: ‘’, ‘channels’: [‘1729254026.57’, ‘1729254026.58’], ‘creationtime’: ‘2024-10-18T12:20:26.680+0000’, ‘video_mode’: ‘talker’}, ‘channel’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘variable’: ‘BRIDGEPEER’, ‘value’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘type’: ‘ChannelVarset’, ‘timestamp’: ‘2024-10-18T12:20:26.877+0000’, ‘channel’: {‘id’: ‘1729254026.58’, ‘name’: ‘Snoop/1729254026.56-0000000b’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.679+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘variable’: ‘BRIDGEPEER’, ‘value’: ‘Snoop/1729254026.56-0000000b’, ‘type’: ‘ChannelVarset’, ‘timestamp’: ‘2024-10-18T12:20:26.877+0000’, ‘channel’: {‘id’: ‘1729254026.57’, ‘name’: ‘UnicastRTP/127.0.0.1:9000-0x7f2ba40c7390’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.677+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘ChannelHangupRequest’, ‘timestamp’: ‘2024-10-18T12:20:35.685+0000’, ‘channel’: {‘id’: ‘1729254026.56’, ‘name’: ‘PJSIP/siptrunk-0000000c’, ‘state’: ‘Up’, ‘protocol_id’: ‘3283c6a7-07ee-123e-e3a7-d4bed9a8ae14’, ‘caller’: {‘name’: ‘XLf9rR5woMHW_FZ’, ‘number’: ‘+18443359250’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘from-trunk’, ‘exten’: ‘s’, ‘priority’: 2, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.472+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘StasisEnd’, ‘timestamp’: ‘2024-10-18T12:20:35.685+0000’, ‘channel’: {‘id’: ‘1729254026.56’, ‘name’: ‘PJSIP/siptrunk-0000000c’, ‘state’: ‘Up’, ‘protocol_id’: ‘3283c6a7-07ee-123e-e3a7-d4bed9a8ae14’, ‘caller’: {‘name’: ‘XLf9rR5woMHW_FZ’, ‘number’: ‘+18443359250’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘from-trunk’, ‘exten’: ‘s’, ‘priority’: 2, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.472+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘variable’: ‘STASISSTATUS’, ‘value’: ‘SUCCESS’, ‘type’: ‘ChannelVarset’, ‘timestamp’: ‘2024-10-18T12:20:35.685+0000’, ‘channel’: {‘id’: ‘1729254026.56’, ‘name’: ‘PJSIP/siptrunk-0000000c’, ‘state’: ‘Up’, ‘protocol_id’: ‘3283c6a7-07ee-123e-e3a7-d4bed9a8ae14’, ‘caller’: {‘name’: ‘XLf9rR5woMHW_FZ’, ‘number’: ‘+18443359250’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘from-trunk’, ‘exten’: ‘s’, ‘priority’: 2, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.472+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘cause’: 16, ‘soft’: True, ‘type’: ‘ChannelHangupRequest’, ‘timestamp’: ‘2024-10-18T12:20:35.685+0000’, ‘channel’: {‘id’: ‘1729254026.56’, ‘name’: ‘PJSIP/siptrunk-0000000c’, ‘state’: ‘Up’, ‘protocol_id’: ‘3283c6a7-07ee-123e-e3a7-d4bed9a8ae14’, ‘caller’: {‘name’: ‘XLf9rR5woMHW_FZ’, ‘number’: ‘+18443359250’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘from-trunk’, ‘exten’: ‘s’, ‘priority’: 2, ‘app_name’: ‘’, ‘app_data’: ‘’}, ‘creationtime’: ‘2024-10-18T12:20:26.472+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘variable’: ‘BRIDGEPEER’, ‘value’: ‘’, ‘type’: ‘ChannelVarset’, ‘timestamp’: ‘2024-10-18T12:20:35.699+0000’, ‘channel’: {‘id’: ‘1729254026.58’, ‘name’: ‘Snoop/1729254026.56-0000000b’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.679+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —

INFO:root:
— New on_message execution —
INFO:root:Received event: {‘type’: ‘ChannelLeftBridge’, ‘timestamp’: ‘2024-10-18T12:20:35.699+0000’, ‘bridge’: {‘id’: ‘370a8271-d17a-40e0-9e13-452394980833’, ‘technology’: ‘simple_bridge’, ‘bridge_type’: ‘mixing’, ‘bridge_class’: ‘stasis’, ‘creator’: ‘Stasis’, ‘name’: ‘’, ‘channels’: [‘1729254026.57’], ‘creationtime’: ‘2024-10-18T12:20:26.680+0000’, ‘video_mode’: ‘talker’}, ‘channel’: {‘id’: ‘1729254026.58’, ‘name’: ‘Snoop/1729254026.56-0000000b’, ‘state’: ‘Up’, ‘protocol_id’: ‘’, ‘caller’: {‘name’: ‘’, ‘number’: ‘’}, ‘connected’: {‘name’: ‘’, ‘number’: ‘’}, ‘accountcode’: ‘’, ‘dialplan’: {‘context’: ‘default’, ‘exten’: ‘s’, ‘priority’: 1, ‘app_name’: ‘Stasis’, ‘app_data’: ‘hello-world’}, ‘creationtime’: ‘2024-10-18T12:20:26.679+0000’, ‘language’: ‘en’}, ‘asterisk_id’: ‘42:01:0a:d0:00:02’, ‘application’: ‘hello-world’}
INFO:root:— End of on_message execution —
`

I would appreciate any guidance on what could be causing the silence issue.

Thank you!

I would start with 2 things -

  1. Sanity checking the audio path - ie take a tcpdump/wireshark trace and make sure that the audio is actually reaching Asterisk and being forwarded on the External Media Channel. The External Media stream is RTP and can be analyzed as such.
  2. Check the Asterisk log to make sure that the channels and bridge structure are correct.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.