IdentificacionIA/audio_iot.py

77 lines
2.7 KiB
Python
Raw Normal View History

import asyncio
import websockets
import json
from pydub import AudioSegment
import os
# Configuración de tu Bocina IP
IP_BOCINA = "192.168.1.142"
PUERTO_WS = 81
async def _enviar_audio_ws(pcm_data):
url = f"ws://{IP_BOCINA}:{PUERTO_WS}"
chunk_size = 1024
try:
async with websockets.connect(url, ping_timeout=None) as websocket:
# Esperamos el mensaje de bienvenida
await websocket.recv()
chunks_enviados = 0
for i in range(0, len(pcm_data), chunk_size):
chunk = pcm_data[i:i + chunk_size]
await websocket.send(chunk)
chunks_enviados += 1
# ⚡ EL TRUCO MAESTRO: CONTROL DE FLUJO
if chunks_enviados % 10 == 0:
try:
# Python se pausa hasta que el ESP32 mande el "ACK"
await asyncio.wait_for(websocket.recv(), timeout=1.0)
except asyncio.TimeoutError:
pass # Si hay lag en la red, forzamos a seguir para no cortar
else:
await asyncio.sleep(0.002) # Micro-pausa entre paquetes individuales
# Le damos 1 segundo al ESP32 para reproducir los últimos datos en su memoria
await asyncio.sleep(1.0)
await websocket.send(json.dumps({"cmd": "STOP"}))
return True
except Exception as e:
print(f" Error conectando a la bocina IP {IP_BOCINA}: {e}")
return False
def enviar_archivos_bocina(lista_archivos):
"""
Recibe una lista de rutas de archivos MP3, los une en un solo track,
los convierte al formato del ESP32 y los transmite.
"""
if not lista_archivos:
return
try:
audio_final = AudioSegment.empty()
for archivo in lista_archivos:
if os.path.exists(archivo):
segmento = AudioSegment.from_file(archivo)
audio_final += segmento
audio_mono = audio_final.split_to_mono()[0]
# ⚡ 2. SUBIMOS LA CALIDAD (A 22050 Hz)
audio_final = audio_mono.set_frame_rate(22050).set_sample_width(2)
# 3. Quitamos el clipping (saturación).
# Como ya no estamos sumando canales, podemos dejarle más volumen. Le bajaremos solo 2 dB.
audio_final = audio_final - 2
# 4. Obtenemos los datos puros
pcm_data = audio_final.raw_data
# ⚡ 4. TRANSMITIMOS A LA BOCINA (¡Te faltaba esta parte!)
print(f" Transmitiendo audio a {IP_BOCINA}...")
asyncio.run(_enviar_audio_ws(pcm_data))
except Exception as e:
print(f"Error procesando el audio para la bocina: {e}")