播放实时音频流 - 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的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Soundcloud api 获取流到 html5 音频播放器?