Не в состоянии отправлять потоки из Asterisk Audio Socket на сервер Audio Socket PythonPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Не в состоянии отправлять потоки из Asterisk Audio Socket на сервер Audio Socket Python

Сообщение Anonymous »

Я добавил это в Asterisk conf < /p>

Код: Выделить всё

 same  => n(newIvr),Log(NOTICE, Start New IVR POC flow)
same  => n,AudioSocket(${UUID()},172.25.25.150:1579)
same  => n,Playback(goodbye)
same  => n,Hangup()
< /code>
и мой сервер Audio Socket Python < /p>
import sys
import threading
import time
import json
import os
import audioop
import wave
import logging
import signal
from google.cloud import speech
from google.protobuf.json_format import MessageToDict
from audiosocket import Audiosocket

logging.basicConfig(
stream=sys.stdout,
format='%(asctime)s [%(levelname)s] %(message)s',
level=logging.INFO
)
log = logging.getLogger()

# Configuration
port = 1579
audiosocket = Audiosocket(("0.0.0.0", port))
speech_client = speech.SpeechClient()

def graceful_shutdown(signum, frame):
log.info("🛑 Shutting down service due to signal...")
sys.exit(0)

signal.signal(signal.SIGTERM, graceful_shutdown)
signal.signal(signal.SIGINT, graceful_shutdown)

def save_raw_to_wav(call_uuid, raw_filename, wav_filename, sample_rate=8000):
try:
file_size = os.path.getsize(raw_filename)
if file_size == 0:
log.warning(f"[{call_uuid}] ⚠️ Raw file is empty, skipping WAV conversion")
return

with open(raw_filename, 'rb') as raw_file:
raw_data = raw_file.read()

duration_seconds = len(raw_data) / (sample_rate * 2)

if duration_seconds < 0.1:
log.warning(f"[{call_uuid}] ⚠️ Duration < 0.1s ({duration_seconds:.2f}s), skipping WAV conversion")
return

with wave.open(wav_filename, 'wb') as wav_file:
wav_file.setnchannels(1)
wav_file.setsampwidth(2)
wav_file.setframerate(sample_rate)
wav_file.writeframes(raw_data)

log.info(f"[{call_uuid}] ✅ WAV file saved: {wav_filename} ({duration_seconds:.2f} sec)")
except Exception as e:
log.error(f"[{call_uuid}] ❌ Error converting raw to WAV: {e}")

def handle_call(conn):
call_uuid = conn.uuid
log.info(f"[{call_uuid}] 🔔 Incoming connection with UUID: {call_uuid}")

audio_filename = f"{call_uuid}.raw"
try:
audio_file = open(audio_filename, "wb")
log.info(f"[{call_uuid}] 💾 Opened local raw audio file for writing: {audio_filename}")
except Exception as e:
log.error(f"[{call_uuid}] ❌ Failed to open file {audio_filename}: {e}")
audio_file = None

def audio_generator():
total_bytes = 0
last_data_time = time.time()
start_time = time.time()

while conn.connected:
data = conn.read()
now = time.time()

if not data:
if now - last_data_time > 2:
log.info(f"[{call_uuid}] 🤐 Detected silence > 2 seconds, stopping stream")
break
time.sleep(0.05)
continue

last_data_time = now
total_bytes += len(data)

# 🔥 Decode G.711 μ-law (8-bit) to 16-bit PCM
# decoded_data = audioop.ulaw2lin(data, 2)
decoded_data = data

if audio_file:
try:
audio_file.write(decoded_data)
except Exception as file_write_err:
log.error(f"[{call_uuid}] ❌ Error writing audio data: {file_write_err}")

log.info(f"[{call_uuid}] 🎧 Received {len(data)} bytes (total: {total_bytes})")
yield speech.StreamingRecognizeRequest(audio_content=decoded_data)

if now - start_time > 8:
log.info(f"[{call_uuid}] ⏰ Stream duration > 8s, stopping stream")
break

log.info(f"[{call_uuid}] 🛑 Finished streaming audio.  Total bytes: {total_bytes}")

config = speech.RecognitionConfig(
encoding=speech.RecognitionConfig.AudioEncoding.LINEAR16,
sample_rate_hertz=8000,
language_code="en-US",
)

streaming_config = speech.StreamingRecognitionConfig(
config=config,
interim_results=False  # Only final results
)

try:
log.info(f"[{call_uuid}] 🚀 Starting Google Speech API streaming")

responses = speech_client.streaming_recognize(
config=streaming_config,
requests=audio_generator()
)

responses_dict = [MessageToDict(responses) for response in responses]
log.info(f"[{call_uuid}] 🗂️ Full responses object:\n{json.dumps(responses_dict, indent=2)}")

# ✅ Process responses here directly without exhausting the generator
for response in responses:
log.info(f"[{call_uuid}] 🎙️ Got response from Google")
for result in response.results:
if result.is_final:
transcript = result.alternatives[0].transcript
log.info(f"[{call_uuid}] 📝 Final transcript: {transcript}")
print(f"[{call_uuid}] 🗣️ Final transcript: {transcript}")

except Exception as e:
log.error(f"[{call_uuid}] ❌ Google Speech API error: {e}")

finally:
if audio_file:
try:
audio_file.close()
log.info(f"[{call_uuid}] 💾 Closed raw audio file: {audio_filename}")
save_raw_to_wav(call_uuid, audio_filename, f"{call_uuid}.wav")
except Exception as e:
log.error(f"[{call_uuid}] ❌ Error closing file: {e}")

if conn:
try:
conn.hangup()
conn.close()
log.info(f"[{call_uuid}] ✅ Connection closed")
except Exception as close_err:
log.error(f"[{call_uuid}] ❌ Error closing connection: {close_err}")

log.info("🚦 Server started and listening for incoming connections")
while True:
try:
conn = audiosocket.listen()
time.sleep(0.3)
log.info("🔔 Received connection from audiosocket")
# print("conn.uuid:", getattr(conn, "uuid", "no uuid"))

threading.Thread(target=handle_call, args=(conn,), daemon=True).start()
except Exception as listener_err:
log.error(f"❌ Exception in main listener loop: {listener_err}")
import traceback
traceback.print_exc()
< /code>
и журналы < /p>
2025-06-06 12:53:53,404 [INFO] 🚦 Server started and listening for incoming connections
2025-06-06 12:53:58,886 [INFO] 🔔 Received connection from audiosocket
2025-06-06 12:53:58,887 [INFO] [40325ec25efd4bd3805f53576e581d13] 🔔 Incoming connection with UUID: 40325ec25efd4bd3805f53576e581d13
2025-06-06 12:53:58,951 [INFO] [40325ec25efd4bd3805f53576e581d13] 💾 Opened local raw audio file for writing: 40325ec25efd4bd3805f53576e581d13.raw
2025-06-06 12:53:58,952 [INFO] [40325ec25efd4bd3805f53576e581d13] 🚀 Starting Google Speech API streaming
2025-06-06 12:53:59,323 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 320)
2025-06-06 12:53:59,527 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 640)
2025-06-06 12:53:59,729 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 960)
2025-06-06 12:53:59,931 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 1280)
2025-06-06 12:54:00,132 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 1600)
2025-06-06 12:54:00,334 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 1920)
2025-06-06 12:54:00,536 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 2240)
2025-06-06 12:54:00,737 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 2560)
2025-06-06 12:54:00,939 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 2880)
2025-06-06 12:54:01,141 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 3200)
2025-06-06 12:54:01,348 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 3520)
2025-06-06 12:54:01,550 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 3840)
2025-06-06 12:54:01,753 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total:  4160)
2025-06-06 12:54:01,959 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 4480)
2025-06-06 12:54:02,164 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 4800)
2025-06-06 12:54:02,369 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 5120)
2025-06-06 12:54:02,572 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 5440)
2025-06-06 12:54:02,778 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 5760)
2025-06-06 12:54:02,985 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 6080)
2025-06-06 12:54:03,194 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 6400)
2025-06-06 12:54:03,404 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 6720)
2025-06-06 12:54:03,606 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 7040)
2025-06-06 12:54:03,808 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 7360)
2025-06-06 12:54:04,011 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 7680)
2025-06-06 12:54:04,213 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 8000)
2025-06-06 12:54:04,416 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 8320)
2025-06-06 12:54:04,619 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 8640)
2025-06-06 12:54:04,821 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 8960)
2025-06-06 12:54:05,044 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 9280)
2025-06-06 12:54:05,246 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 9600)
2025-06-06 12:54:05,447 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 9920)
2025-06-06 12:54:05,649 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 10240)
2025-06-06 12:54:05,851 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 10560)
2025-06-06 12:54:06,053 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 10880)
2025-06-06 12:54:06,255 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 11200)
2025-06-06 12:54:06,458 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 11520)
2025-06-06 12:54:06,659 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 11840)
2025-06-06 12:54:06,861 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 12160)
2025-06-06 12:54:07,063 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 12480)
2025-06-06 12:54:07,265 [INFO] [40325ec25efd4bd3805f53576e581d13] 🎧 Received 320 bytes (total: 12800)
2025-06-06 12:54:07,265 [INFO] [40325ec25efd4bd3805f53576e581d13] ⏰ Stream duration > 8s, stopping stream
2025-06-06 12:54:07,266 [INFO] [40325ec25efd4bd3805f53576e581d13] 🛑 Finished streaming audio. Total bytes: 12800
2025-06-06 12:54:07,483 [INFO] [40325ec25efd4bd3805f53576e581d13] 🗂️ Full responses object:
[]
2025-06-06 12:54:07,490 [INFO] [40325ec25efd4bd3805f53576e581d13] 💾 Closed raw audio file: 40325ec25efd4bd3805f53576e581d13.raw
2025-06-06 12:54:07,539 [INFO] [40325ec25efd4bd3805f53576e581d13] ✅ WAV file saved: 40325ec25efd4bd3805f53576e581d13.wav (0.80 sec)
2025-06-06 12:54:25,390 [ERROR] [40325ec25efd4bd3805f53576e581d13] ❌ Error closing connection: [Errno 9] Bad file descriptor
< /code>
Проблема заключается в том, что я не получаю никакого текстового ответа после потоковой передачи API Google речевого потока. Оба есть 13 КБ каждый раз, а 0 сек в WAV. Я попробовал в Интернете, преобразовав Raw в WAV, но во время преобразования показывает неверный файл RAW.decoded_data = audioop.ulaw2lin(data, 2)
Все еще такая же проблема
Я использую это аудиопооттрай>

Подробнее здесь: https://stackoverflow.com/questions/796 ... ket-server
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»