简体   繁体   English

播放实时音频流 - html5

[英]Play live audio stream - html5

I have a desktop application which streams raw PCM data to my browser over a websocket connection.我有一个桌面应用程序,它通过 websocket 连接将原始 PCM 数据流式传输到我的浏览器。 The stream looks like this ...\\\\x00\\\\x00\\\\x02\\\\x00\\\\x01\\\\x00\\\\x00\\\\x00\\\\x01\\\\x00\\\\xff\\\\xff\\\\xff\\\\xff\\\\... .流看起来像这样...\\\\x00\\\\x00\\\\x02\\\\x00\\\\x01\\\\x00\\\\x00\\\\x00\\\\x01\\\\x00\\\\xff\\\\xff\\\\xff\\\\xff\\\\...

The question is simple: can I play such a stream in HTML with the Web Audio API / WebRTC / ...?问题很简单:我可以使用 Web Audio API / WebRTC / ...播放这样的 HTML 流吗?

Any suggestions are very welcome!非常欢迎任何建议!

code edit代码编辑

This code plays noise, randomly generated:此代码播放噪音,随机生成:

function myPCMSource() { 
    return Math.random() * 2 - 3;
}

var audioContext;

try {
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    audioContext = new AudioContext();
} catch(e) {
    alert('Web Audio API is not supported in this browser');
}

var bufferSize = 4096;
var myPCMProcessingNode = audioContext.createScriptProcessor(bufferSize, 1, 1);
myPCMProcessingNode.onaudioprocess = function(e) {
    var output = e.outputBuffer.getChannelData(0);
    for (var i = 0; i < bufferSize; i++) {
     output[i] = myPCMSource(); 
 }
}

So changing the myPCMSource() to the websocket stream input, should make it work somehow.因此,将myPCMSource()更改为 websocket 流输入,应该可以使其以某种方式工作。 But it doesn't.但事实并非如此。 I don't get any errors, but the API is not playing any sound nor noise.我没有收到任何错误,但 API 没有播放任何声音或噪音。

Use a ScriptProcessorNode, but be aware that if there is too much load on the main thread (the thread that runs your javascript, draws the screen, etc.), it will glitch. 使用ScriptProcessorNode,但要注意,如果主线程(运行javascript,绘制屏幕的线程等)的负载太多,它将会出现故障。

Also, your PCM stream is probably in int16, and the Web Audio API works in terms of float32. 此外,您的PCM流可能在int16中,Web Audio API在float32方面工作。 Convert it like so: 像这样转换它:

output_float[i] = (input_int16[i] / 32767);

that is, go from a [0; 也就是说,从[0; 65535] range to a [-1.0; 65535]范围到[-1.0; 1.0] range. 1.0]范围。

EDIT I was using output_float[i] = (input_int16[i] / 32767 - 1); 编辑我使用的是output_float[i] = (input_int16[i] / 32767 - 1); , this article shows that you should use output_float[i] = (input_int16[i] / 32767); 本文表明你应该使用output_float[i] = (input_int16[i] / 32767); . Now it's working fine! 现在它工作正常!

Just for the record, the ScriptProcessorNode is deprecated .仅作记录, ScriptProcessorNode弃用 See the MDN article for details.有关详细信息,请参阅MDN 文章 The feature was replaced by AudioWorklets and the AudioWorkletNode interface .该功能被AudioWorkletsAudioWorkletNode 接口取代。

In short, a ScriptProcessorNode runs outside of the browser's internal audio thread, which creates at least on frame (128 samples) of latency.简而言之, ScriptProcessorNode在浏览器的内部音频线程之外运行,这会产生至少一帧(128 个样本)的延迟。 Worse, the ScriptProcessorNode often fails to respond quickly enough, if the thread is busy, so will just randomly drop the ball every so often.更糟糕的是,如果线程很忙, ScriptProcessorNode经常不能足够快地响应,所以会每隔一段时间随机丢球。

Worklets are basically task-specific workers that run in one of the browsers internal threads (paint, layout, audio etc). Worklet 基本上是特定于任务的工作人员,它们在浏览器内部线程之一(绘制、布局、音频等)中运行。 Audio worklets run in the audio thread, and implement the guts of custom audio nodes, which are then exposed through the WebAudio API as normal.音频工作集在音频线程中运行,并实现自定义音频节点的内脏,然后像往常一样通过 WebAudio API 公开。

Note: You are also able to run WebAssembly inside worklets to handle the processing.注意:您还可以在工作集中运行 WebAssembly 来处理处理。

The solution provided above is still useful, as the basic idea holds, but it would ideally use an audio worklet.上面提供的解决方案仍然有用,因为基本思想成立,但理想情况下它会使用音频工作集。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM