【问题标题】:Play live audio stream - html5播放实时音频流 - html5
【发布时间】:2014-06-01 22:18:04
【问题描述】:

我有一个桌面应用程序,它通过 websocket 连接将原始 PCM 数据流式传输到我的浏览器。流看起来像这样...\\x00\\x00\\x02\\x00\\x01\\x00\\x00\\x00\\x01\\x00\\xff\\xff\\xff\\xff\\...

问题很简单:我可以使用 Web Audio API / WebRTC / ... 播放这样的 HTML 流吗?

非常欢迎任何建议!

代码编辑

此代码播放噪音,随机生成:

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

因此,将 myPCMSource() 更改为 websocket 流输入,应该可以使其以某种方式工作。但事实并非如此。我没有收到任何错误,但 API 没有播放任何声音或噪音。

【问题讨论】:

  • 不确定是否有现成的解决方案。但是应该可以使用 WebAudioAPI 和它的 ScriptNode。也许我应该坐下来写一篇。您是否使用任何特定框架来发出 websocket 流?
  • 我的应用程序是用 Python 编写的,我使用的是 websocket-client 库。我还发现了这篇文章,有人试图实现同样的目标 (code.google.com/p/chromium/issues/detail?id=250989),但仍然没有成功

标签: html audio html5-audio web-audio-api


【解决方案1】:

使用 ScriptProcessorNode,但请注意,如果主线程(运行 javascript、绘制屏幕等的线程)负载过多,则会出现故障。

另外,您的 PCM 流可能是 int16 格式,而 Web Audio API 以 float32 格式工作。像这样转换它:

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

也就是说,从 [0; 65535] 范围为 [-1.0; 1.0] 范围。

编辑 我使用的是output_float[i] = (input_int16[i] / 32767 - 1);,这个article 表明你应该使用output_float[i] = (input_int16[i] / 32767);。现在一切正常!

【讨论】:

  • 好的,所以我正在尝试将我的流转换为字节数组,但它还不正确。我的转换值介于 1:0 和 -1:0 之间,但仍然存在 NaN。我正在使用(parseInt(str.substring(0, 8)), 16) / 32767) - 1; 进行转换。有什么想法吗?
  • 从你的 WebSocket 获取一个 ArrayBuffer,然后从中获取一个 Uint16Array:var input_int16 = new Uint16Array(event.data); 其中 event 是你从你的 websocket 获取的事件。然后使用我上面的转换代码。
【解决方案2】:

仅作记录,ScriptProcessorNode弃用。有关详细信息,请参阅the MDN article。该功能已被AudioWorkletsthe AudioWorkletNode interface 取代。

简而言之,ScriptProcessorNode 在浏览器的内部音频线程之外运行,这会产生至少一帧(128 个样本)的延迟。更糟糕的是,ScriptProcessorNode 经常响应不够快,如果线程很忙,所以会每隔一段时间随机掉球。

Worklet 基本上是特定于任务的工作程序,它们在浏览器内部线程之一(绘画、布局、音频等)中运行。音频工作集在音频线程中运行,并实现自定义音频节点的内脏,然后像往常一样通过 WebAudio API 公开。

注意:您还可以在工作集中运行 WebAssembly 来处理处理。

按照基本思想,上面提供的解决方案仍然有用,但理想情况下它会使用音频工作集。

【讨论】:

    猜你喜欢
    • 2012-11-09
    • 1970-01-01
    • 2016-12-15
    • 2012-05-22
    • 2012-07-27
    • 2018-09-02
    • 2019-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多