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}")