Estoy tratando de enviar un archivo de audio a través de un websocket y me di cuenta de que para hacerlo necesito convertir el archivo mp3 a un código Linear PCM de 16 bits, pero no encuentro la manera de hacerlo.
esto es lo que quiero hacer:
let mp3File = // the 16-bit pcm file ws.on('message', async(msg) => { if (typeof msg === "string") { } else if (recognizeStream) { recognizeStream.write(msg); } ws.send(mp3File) <== stream back the audio file }); });algunos antecedentes, la transmisión es una llamada telefónica (a través de vonage api), por lo que ny estaba conectado a la llamada telefónica y escuché la entrada del usuario, y luego, después de cierta lógica en mi servidor, quiero reproducir para el usuario un archivo mp3 que es un archivo local en mi servidor, a través de ws.send().
-----------actualizar--------
ahora, si envío los datos pcm de la transmisión (el audio sin procesar de la llamada telefónica) funciona (el servidor hace eco de la llamada telefónica), así que quiero convertir el archivo mp3 al mismo formato para poder enviarlo a través de ws. enviar().
-----------actualización 2--------
después de hacer mi archivo de audio en el formato correcto que es: " PCM lineal de 16 bits, con una frecuencia de muestreo de 8kHz o 16kHz y un tamaño de cuadro de 20ms "
estoy tratando de enviar el archivo a través del socket web pero no sé cómo hacerlo, tengo el archivo en la carpeta del proyecto pero no sé cómo enviarlo a través de websocket, busqué cómo hacerlo pero no encontré cualquier cosa.
Primero entendamos lo que esto significa:
PCM lineal de 16 bits, con una frecuencia de muestreo de 8 kHz o 16 kHz y un tamaño de cuadro de 20 ms
Están hablando de 2 cosas aquí:
Según el formato de audio, si elige "PCM lineal de 16 bits con una frecuencia de muestreo de 16K" implica:
Entonces, un fragmento de audio de 1 segundo contendrá bytes = (16000 * 2) = 32000 bytes, lo que significa que un cuadro de audio de 20 ms/0,02 s será equivalente a (32000 * 0,2) = 640 bytes
Se necesitan 2 cosas:
convertir mp3 a wav. Instale ffmpeg en su sistema y ejecute este comando
ffmpeg -i filename.mp3 -ar 16000 -sample_fmt s16 output.wav
Esto convierte su filename.mp3 de archivo.mp3 a output.wav , que será PCM lineal de 16 bits en una frecuencia de muestreo de 16K
En su código, cuando devuelve el audio, debe transmitirlo como fragmentos de 640 bytes, no los datos completos del archivo de una sola vez . Hay 3 opciones:
Estoy escribiendo este ejemplo usando el paquete websocket npm.
var fs = require('fs'); var binaryData = fs.readFileSync('output.wav'); var start = 44 // discard the wav header var chunkSize = 640 ... // ws is a websocket connection object connection.on('message', function(message) { if (message.type === 'utf8') { // handle a text message here } else if (message.type === 'binary') { // print length of audio sent by nexmo. will be 640 for 16K and 320 for 8K console.log('Received Binary Message of ' + message.binaryData.length + ' bytes'); if (start >= binaryData.length) { // slice a chunk and send toSend = binaryData.slice(start, start + chunkSize) start = start + chunkSize connection.sendBytes(toSend); console.log('Sent Binary Message of ' + toSend.length + ' bytes'); } } ... });Recuerde, habrá algo de retraso desde el momento en que envía el audio desde su servidor a nexmo y lo escucha en el otro lado. Puede variar desde medio segundo hasta incluso más dependiendo de la ubicación del centro de datos de Nexmo, del servidor donde ejecuta su código, la velocidad de la red, etc. He observado que está cerca de 0,5 segundos.