JavaScript 将 arraybuffer 作为音频播放。需要帮助解决 "decodeaudiodata unable to decode audio data"
JavaScript play arraybuffer as audio. Need help to solve "decodeaudiodata unable to decode audio data"
我有一个 .net 核心 WebSocket 服务器,它从客户端 A 接收实时流音频,然后我需要将这个实时音频流式传输到客户端 B(浏览器)。所以我从客户端 A 收到了字节数组,并将字节数组发送给客户端 B(浏览器)*字节数组是正确的,因为我可以将它转换为 .wav 并毫无问题地播放它。
在客户端B(浏览器)中,我尝试将数组缓冲区解码为音频缓冲区,以便可以将其放入输出和播放。
mediastreamhandler.SendArraySegToAllAsync是我开始从服务器向客户端B发送字节数组的地方。我使用发送到所有方法1,稍后将修改并通过匹配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();
}
我想我真的需要这里的一些帮助,试图在几周内完成数组缓冲区,但仍然没有任何突破。卡在这里。不确定我做了什么,你们能指导我或告诉我任何其他方法吗?非常感谢,真的很认真。
decodeAudioData()
需要完整的文件,因此它不能用于解码从 websocket 接收到的部分数据块。如果您可以通过 websocket 流式传输 Opus 音频文件,则可以使用可用的 WebAssembly 解码器进行播放。参见:
我几个月前就解决了这个问题,现在就post我的解决方案。
步骤:
- 服务器从 Twilio 接收负载字符串
- 从服务器向客户端(浏览器)发送负载字符串。
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);
}
- 在播放音频之前在客户端将 wavheader 添加到负载字符串。
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();
};
我有一个 .net 核心 WebSocket 服务器,它从客户端 A 接收实时流音频,然后我需要将这个实时音频流式传输到客户端 B(浏览器)。所以我从客户端 A 收到了字节数组,并将字节数组发送给客户端 B(浏览器)*字节数组是正确的,因为我可以将它转换为 .wav 并毫无问题地播放它。
在客户端B(浏览器)中,我尝试将数组缓冲区解码为音频缓冲区,以便可以将其放入输出和播放。
mediastreamhandler.SendArraySegToAllAsync是我开始从服务器向客户端B发送字节数组的地方。我使用发送到所有方法1,稍后将修改并通过匹配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();
}
我想我真的需要这里的一些帮助,试图在几周内完成数组缓冲区,但仍然没有任何突破。卡在这里。不确定我做了什么,你们能指导我或告诉我任何其他方法吗?非常感谢,真的很认真。
decodeAudioData()
需要完整的文件,因此它不能用于解码从 websocket 接收到的部分数据块。如果您可以通过 websocket 流式传输 Opus 音频文件,则可以使用可用的 WebAssembly 解码器进行播放。参见:
我几个月前就解决了这个问题,现在就post我的解决方案。
步骤:
- 服务器从 Twilio 接收负载字符串
- 从服务器向客户端(浏览器)发送负载字符串。
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);
}
- 在播放音频之前在客户端将 wavheader 添加到负载字符串。
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();
};