Escrevi um código em python utilizando a biblioteca aiortc, o código recebe no on_track o áudio envio pelo navegador e reproduzir o áudio diretamente no python. No código atual, o áudio fica com ruído. import argparse import asyncio import logging from aiohttp import web from aiortc import MediaStreamTrack, RTCPeerConnection, RTCSessionDescription from aiortc.contrib.media import MediaRecorder import os import aiohttp_cors import uuid import json import pyaudio # Biblioteca para reprodução de áudio em tempo real com PyAudio from av import AudioFrame ROOT = os.path.dirname(__file__) logger = logging.getLogger("pc") pcs = set() # Inicializa o PyAudio audio = pyaudio.PyAudio() # Configuração do PyAudio # Parâmetros do stream de áudio FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 44100 CHUNK = 1024 # Função para abrir o stream de áudio def open_stream(): return audio.open( format=FORMAT, channels=CHANNELS, rate=RATE, output=True, frames_per_buffer=CHUNK ) async def offer(request): params = await request.json() offer = RTCSessionDescription(sdp=params["sdp"], type=params["type"]) pc = RTCPeerConnection() pc_id = "PeerConnection(%s)" % uuid.uuid4() pcs.add(pc) recorder = MediaRecorder('temp.wav') def log_info(msg, *args): logger.info(pc_id + " " + msg, *args) log_info("Created for %s", request.remote) @pc.on("datachannel") def on_datachannel(channel): @channel.on("message") def on_message(message): if (message.startswith('command:')): command = message[8:] log_info("Command received: %s", command) if (command == "move_forward"): log_info("Move Forward") if isinstance(message, str) and message.startswith("ping"): channel.send("pong" + message[4:]) @pc.on("connectionstatechange") async def on_connectionstatechange(): log_info("Connection state is %s", pc.connectionState) if pc.connectionState == "failed": await pc.close() pcs.discard(pc) @pc.on("track") async def on_track(track): log_info("Track %s received", track.kind) if (track.kind == "audio"): log_info("Audio received") # Cria o stream de áudio # Cria o stream de áudio stream = open_stream() @track.on("ended") async def on_ended(): log_info("Track %s ended", track.kind) stream.stop_stream() stream.close() async def play_audio(): while True: try: # Recebe um frame de áudio frame = await track.recv() # Obtenha os dados brutos do frame samples = frame.to_ndarray() # Ajuste o formato conforme necessário # Envia os dados para o stream de áudio stream.write(samples.tobytes()) except Exception as e: log_info(f"Exception in play_audio: {e}") break asyncio.create_task(play_audio()) # handle offer await pc.setRemoteDescription(offer) await recorder.start() # send answer answer = await pc.createAnswer() await pc.setLocalDescription(answer) return web.Response( content_type="application/json", text=json.dumps( {"sdp": pc.localDescription.sdp, "type": pc.localDescription.type} ), ) async def on_shutdown(app): # close peer connections coros = [pc.close() for pc in pcs] await asyncio.gather(*coros) pcs.clear() if __name__ == "__main__": parser = argparse.ArgumentParser( description="WebRTC audio / video / data-channels demo" ) parser.add_argument( "--host", default="0.0.0.0", help="Host for HTTP server (default: 0.0.0.0)" ) parser.add_argument( "--port", type=int, default=8080, help="Port for HTTP server (default: 8080)" ) parser.add_argument("--verbose", "-v", action="count") args = parser.parse_args() if args.verbose: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) app = web.Application() cors = aiohttp_cors.setup(app) app.on_shutdown.append(on_shutdown) resource = cors.add(app.router.add_resource("/offer")) route = cors.add( resource.add_route("POST", offer), { "*": aiohttp_cors.ResourceOptions( allow_credentials=True, expose_headers=("X-Custom-Server-Header",), allow_headers=("X-Requested-With", "Content-Type"), max_age=3600, ) }) #app.router.add_post("/offer", offer) web.run_app( app, access_log=None, host=args.host, port=args.port ) Continue reading...