首页 > 解决方案 > JavaScript 将 arraybuffer 作为音频播放。需要帮助解决“decodeaudiodata无法解码音频数据”

问题描述

我有一个 .net 核心 WebSocket 服务器,它从客户端 A 接收实时流音频,然后我需要将此实时音频流式传输到客户端 B(浏览器)。所以我从客户端 A 收到字节数组,并将字节数组发送到客户端 B(浏览器)*字节数组是正确的,因为我可以将其转换为 .wav 并毫无问题地播放。

在客户端 B(浏览器)中,我尝试将数组缓冲区解码为音频缓冲区,以便将其放入输出和播放。

mediastreamhandler.SendArraySegToAllAsync 是我开始将字节数组从服务器发送到客户端 B 的地方。我使用第一种方法发送到所有方法,稍后将通过匹配 websocket 连接 ID 进行修改并发送数据。

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

然后我通过 Javascript 中的 websocket.onmessage 接收音频字节数组。然后我将字节数组传递给解码和播放。但这里它说“无法解码数据”。在 Mozilla 中,它确实说内容格式未知(我需要重新格式化收到的字节数组吗?)字节数组本身很好,因为我使用相同的字节在本地创建 .wav 文件并播放它任何问题。

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();

    }

然后我尝试另一种方法来解码和播放音频,这一次,它播放了一些白噪声,而不是从客户端 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();

    }

我想我真的需要一些帮助,试图在几周内完成数组缓冲区,但仍然没有任何突破。卡在这里。不知道我做了什么,你们能指导我或告诉我任何其他方法吗?提前非常感谢,真的是认真的。

标签: javascriptwebsocketaudio-streamingweb-audio-apiaudiobuffer

解决方案


decodeAudioData()需要完整的文件,因此它不能用于解码从 websocket 接收的部分数据块。如果您可以通过 websocket 流式传输 Opus 音频文件,则可以使用可用的 WebAssembly 解码器进行播放。看:


推荐阅读