播放实时音频流 - html5

Posted

技术标签:

【中文标题】播放实时音频流 - html5【英文标题】:Play live audio stream - 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),但仍然没有成功 【参考方案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。该功能已被AudioWorklets 和the AudioWorkletNode interface 取代。

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

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

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

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

【讨论】:

以上是关于播放实时音频流 - html5的主要内容,如果未能解决你的问题,请参考以下文章

如何从实时流中播放音频

如何禁用音频(流)html5元素的自动播放

如何使用 Soundcloud api 获取流到 html5 音频播放器?

实时音频流到移动设备 - 动态播放速度

ExoPlayer 无法播放 Adob​​e 实时流编码器流式传输的音频/视频 (RTMP)

WebRTC 实时音频流/广播 [关闭]