JavaScript riproduce arraybuffer come audio. Hai bisogno di aiuto per risolvere "decodeaudiodata impossibile decodificare i dati audio"
Ho un server WebSocket .net core che riceve audio in streaming live dal client A, quindi ho bisogno di trasmettere questo audio live al client B (Browser). Quindi ho ricevuto l'array di byte dal client A e ho inviato l'array di byte al client B (Browser) * L'array di byte è corretto in quanto posso convertirlo in .wav e riprodurlo senza problemi.
Nel client B (Browser), provo a decodificare il buffer dell'array nel buffer audio in modo che possa essere messo in output e riprodotto.
Il mediastreamhandler.SendArraySegToAllAsync è il punto in cui comincio a inviare l'array di byte dal server al client B. Uso per inviare a tutti il metodo 1st, in seguito verrà modificato e invierò i dati abbinando l'ID di connessione websocket.
private async Task Echo(HttpContext context, WebSocket webSocket)
{
Debug.WriteLine("Start Echo between Websocket server & client");
var buffer = new byte[1024 * 4];
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
await mediastreamhandler.SendArraySegToAllAsync(new ArraySegment<byte>(buffer, 0, result.Count));
}
Debug.WriteLine("Close Echo");
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
Quindi ricevo l'array di byte audio tramite websocket.onmessage in Javascript. Quindi passo l'array di byte per decodificare e riprodurre. Ma qui si dice "impossibile decodificare i dati". Mentre in Mozilla, diceva che il formato del contenuto era sconosciuto (devo riformattare l'array di byte che ricevo?) L'array di byte stesso va bene perché ho usato lo stesso byte per creare file .wav localmente e riprodurlo senza Qualche problema.
var ctx = new AudioContext();
function playSound(arrBuff) {
var myAudioBuffer;
var src = ctx.createBufferSource();
ctx.decodeAudioData(arrBuff, function (buffer) {
myAudioBuffer = buffer;
});
src.buffer = myAudioBuffer;
src.connect(ctx.destination);
src.start();
}
Quindi provo un altro metodo per decodificare e riprodurre l'audio, questa volta ha riprodotto alcuni suoni bianchi invece di riprodurre in streaming l'audio dal client A.
var ctx = new AudioContext();
function playSound(arrBuff) {
var myAudioBuffer;
var src = ctx.createBufferSource();
myAudioBuffer = ctx.createBuffer(1, arrBuff.byteLength, 8000);
var nowBuffering = myAudioBuffer.getChannelData(0);
for (var i = 0; i < arrBuff.byteLength; i++) {
nowBuffering[i] = arrBuff[i];
}
src.buffer = myAudioBuffer;
src.connect(ctx.destination);
src.start();
}
Penso di aver davvero bisogno di aiuto qui, ragazzi, cercando di riprodurre il buffer dell'array in settimane e ancora, non ho potuto ottenere alcuna svolta. Bloccato qui. Non sono sicuro di quello che ho fatto, potreste gentilmente guidarmi o dirmi un altro approccio a questo? Grazie mille in anticipo, davvero.
Risposte
decodeAudioData()richiede file completi, quindi non può essere utilizzato per decodificare blocchi parziali di dati quando vengono ricevuti da un websocket. Se puoi eseguire lo streaming di file audio Opus sul tuo websocket, puoi riprodurli con un decodificatore WebAssembly disponibile. Vedere:
- https://fetch-stream-audio.anthum.com/
- https://github.com/AnthumChris/fetch-stream-audio
Ho risolto il problema mesi fa, solo qui per pubblicare la mia soluzione.
Passaggi:
- Il server riceve la stringa del payload da Twilio
- Invia la stringa del payload dal server al client (browser).
public async Task SendMessageAsync(WebSocket socket, string message)
{
if (socket.State != WebSocketState.Open)
return;
await socket.SendAsync(buffer: new ArraySegment<byte>(array: Encoding.ASCII.GetBytes(message),
offset: 0,
count: message.Length),
messageType: WebSocketMessageType.Text,
endOfMessage: true,
cancellationToken: CancellationToken.None);
}
- Aggiungi wavheader alla stringa di payload sul lato client prima di riprodurre l'audio.
function playSound(payloadBase64) {
/* You can generate the wav header here --> https://codepen.io/mxfh/pen/mWLMrJ */
var Base64wavheader = "UklGRgAAAABXQVZFZm10IBIAAAAHAAEAQB8AAEAfAAABAAgAAABmYWN0BAAAAAAAAABkYXRh";
var audio = new Audio('data:audio/wav;base64,' + Base64wavheader + payloadBase64);
audio.play();
};