About Audio socket

:satellite_antenna: Connecting to ARI WebSocket at ws://127.0.0.1:8080/ari/events?app=my_stasis_app&api_key=tcriber:myst
:white_check_mark: AudioSocket server listening on 127.0.0.1:4000
:satellite_antenna: Connected to ARI WebSocket.
:headphone: Connected audio stream from (β€˜127.0.0.1’, 35202)
:warning: Audio socket error: [Errno 104] Connection reset by peer
:cross_mark: Stream ended.
I got this error actully i want to stream audio from asterisk to python server for real time transcribe but i got this error please tell me how to resolve it?

You haven’t provided sufficient information. What troubleshooting or debugging have you done already? Have you confirmed your code is actually correct (I would wager it is AI generated so it should still be reviewed regardless)? What are the ARI requests that are happening? How are you initiating the audiosocket request? If using the external media ARI request, is it going to the correct place in Asterisk? What shows on the Asterisk console?

[incoming]
exten => +911204845652,1,NoOp(:telephone_receiver: Incoming Call: ${EXTEN} from ${CALLERID(all)})
same => n,Answer()
same => n,NoOp(Diversion: ${PJSIP_HEADER(read,Diversion)})
same => n,NoOp(History-Info: ${PJSIP_HEADER(read,History-Info)})
same => n,NoOp(To: ${PJSIP_HEADER(read,To)})
same => n,NoOp(Channel UNIQUEID: ${UNIQUEID})
same => n,Set(UUID=${UUID()})
same => n,NoOp(Using AudioSocket UUID: ${UUID})
same => n,AudioSocket(${UUID},127.0.0.1:4000)
same => n,Hangup()
this my extension conf file and below is python code
#!/usr/bin/env python3
import requests
import json
import threading
import socket
import time
import websocket
import os
import sys
import numpy as np
import io
from faster_whisper import WhisperModel

---------------- CONFIG ----------------

ARI_URL = β€œhttp://127.0.0.1:8088/ari”
ARI_USER = β€œtranscriber”
ARI_PASS = β€œmysecret”
STASIS_APP = β€œmy_stasis_app”

AUDIOSOCKET_HOST = β€œ127.0.0.1”
AUDIOSOCKET_PORT = 4000

choose a Whisper model size: tiny, base, small, medium, large-v2

WHISPER_MODEL_NAME = β€œsmall”
WHISPER_DEVICE = β€œcpu” # or β€œcuda” for GPU

---------------- LOAD WHISPER MODEL ----------------

print(f":counterclockwise_arrows_button: Loading Whisper model β€˜{WHISPER_MODEL_NAME}’ on {WHISPER_DEVICE} …")
model = WhisperModel(WHISPER_MODEL_NAME, device=WHISPER_DEVICE, compute_type=β€œint8”)
print(β€œ:white_check_mark: Whisper model loaded!”)

---------------- AUDIO SOCKET HANDLER ----------------

def handle_audio(conn, addr):
print(f":headphone: Connected audio stream from {addr}")
conn.settimeout(5.0)

# buffer for accumulating PCM samples (16-bit signed, mono)
audio_buffer = bytearray()

def transcribe_chunk(chunk):
    """Transcribe small PCM chunks in background."""
    try:
        # Convert raw PCM (16-bit, little-endian) to float32 numpy
        audio_np = np.frombuffer(chunk, dtype=np.int16).astype(np.float32) / 32768.0

        # Whisper expects 16 kHz audio
        segments, _ = model.transcribe(audio_np, language="en", beam_size=5)
        text = " ".join([seg.text.strip() for seg in segments])
        if text.strip():
            print("πŸ—£οΈ", text)
    except Exception as e:
        print("⚠️ Transcription error:", e)

def keep_alive():
    """Send silence periodically to keep Asterisk happy."""
    while True:
        try:
            conn.send(b'\x00' * 320)  # 20 ms silence
            time.sleep(1)
        except:
            break
threading.Thread(target=keep_alive, daemon=True).start()

# --- receive audio in chunks ---
while True:
    try:
        data = conn.recv(320)
        if not data:
            break
        audio_buffer.extend(data)

        # every ~1 sec (16000 samples = 2 bytes * 16000 = 32000 bytes)
        if len(audio_buffer) >= 32000:
            chunk = bytes(audio_buffer[:32000])
            audio_buffer = audio_buffer[32000:]
            threading.Thread(target=transcribe_chunk, args=(chunk,), daemon=True).start()

    except socket.timeout:
        continue
    except Exception as e:
        print("⚠️ Audio socket error:", e)
        break

print("❌ Stream ended.")
conn.close()

---------------- AUDIO SOCKET SERVER ----------------

def start_audiosocket_server():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((AUDIOSOCKET_HOST, AUDIOSOCKET_PORT))
s.listen(5)
print(f":white_check_mark: AudioSocket server listening on {AUDIOSOCKET_HOST}:{AUDIOSOCKET_PORT}")

while True:
    conn, addr = s.accept()
    threading.Thread(target=handle_audio, args=(conn, addr), daemon=True).start()

---------------- ARI HANDLERS ----------------

def on_incoming_call(channel_id):
print(f":telephone_receiver: Incoming call on channel {channel_id}")

external_media_url = f"{ARI_URL}/channels"
payload = {
    "endpoint": f"audiosocket:tcp://{AUDIOSOCKET_HOST}:{AUDIOSOCKET_PORT}?direction=send&timeout=0",
    "app": STASIS_APP,
    "appArgs": "audiosocket",
    "format": "slin16"
}

print("➑️ Creating external media channel...")
r = requests.post(external_media_url, auth=(ARI_USER, ARI_PASS), json=payload)
print(f"πŸ” ARI Response Status: {r.status_code}")
print(f"πŸ” ARI Response Body: {r.text}")

if r.status_code != 200:
    print("❌ Failed to create external media channel.")
    return

try:
    ext_chan = r.json()
    ext_id = ext_chan["id"]
    print(f"🎧 Created external media channel {ext_id}")
except Exception as e:
    print(f"❌ Error parsing ARI response: {e}")
    return

# Wait a moment before bridging
time.sleep(0.5)

bridge_id = f"bridge-{channel_id}"
bridge_url = f"{ARI_URL}/bridges/{bridge_id}"

requests.post(bridge_url, auth=(ARI_USER, ARI_PASS), json={"type": "mixing"})
requests.post(f"{bridge_url}/addChannel", auth=(ARI_USER, ARI_PASS),
              json={"channel": [channel_id, ext_id]})
print("πŸ”— Audio bridged to AudioSocket stream.")

---------------- ARI EVENT LISTENER ----------------

def listen_ari_events():
ws_url = f"ws://127.0.0.1:8088/ari/events?app={STASIS_APP}&api_key={ARI_USER}:{ARI_PASS}"
print(f":satellite_antenna: Connecting to ARI WebSocket at {ws_url}")
ws = websocket.create_connection(ws_url)
print(β€œ:satellite_antenna: Connected to ARI WebSocket.”)

while True:
    try:
        msg = ws.recv()
        data = json.loads(msg)
        event = data.get("type")

        if event == "StasisStart":
            channel = data["channel"]["id"]
            on_incoming_call(channel)

    except KeyboardInterrupt:
        print("\nπŸ›‘ Stopping server.")
        ws.close()
        break
    except Exception as e:
        print("⚠️ WebSocket error:", e)
        time.sleep(2)
        try:
            ws = websocket.create_connection(ws_url)
        except:
            pass

---------------- MAIN ----------------

if name == β€œmain”:
threading.Thread(target=start_audiosocket_server, daemon=True).start()
listen_ari_events()