web-audio-api - 如何从 JavaScript AudioAPI 获取连续的样本流
问题描述
我想从音频 API 中获取 JavaScript 中的连续样本流。我发现获取样本的唯一方法是通过 JavaScript 音频 API 中的 MediaRecorder 对象。
我这样设置我的录音机:
var options = {
mimeType: "audio/webm;codec=raw",
}
this.mediaRecorder = new MediaRecorder(stream, options);
this.mediaRecorder.ondataavailable = function (e) {
this.decodeChunk(e.data);
}.bind(this);
this.mediaRecorder.start(/*timeslice=*/ 100 /*ms*/);
这给了我每秒 10 次新数据的回调。到目前为止一切都很好。
数据被编码,所以我使用 audioCtx.decodeAudioData 来处理它:
let fileReader = new FileReader();
fileReader.onloadend = () => {
let encodedData = fileReader.result;
// console.log("Encoded length: " + encodedData.byteLength);
this.audioCtx.decodeAudioData(encodedData,
(decodedSamples) => {
let newSamples = decodedSamples.getChannelData(0)
.slice(this.firstChunkSize, decodedSamples.length);
// The callback which handles the decodedSamples goes here. All good.
if (this.firstChunkSize == 0) {
this.firstChunkSize = decodedSamples.length;
}
});
};
这一切都很好。
为文件阅读器设置数据很奇怪:
let blob;
if (!this.firstChunk) {
this.firstChunk = chunk;
blob = new Blob([chunk], { 'type': chunk.type });
} else {
blob = new Blob([this.firstChunk, chunk], { 'type': chunk.type });
}
fileReader.readAsArrayBuffer(blob);
第一个块工作得很好,但第二个和以后的块无法解码,除非我将它们与第一个块结合起来。我猜这里发生的事情是第一个块具有解码数据所需的标头。在第二次解码后,我从第一个块中删除了解码的样本。见this.firstChunkSize
上文。
这一切都没有错误地执行,但是我返回的音频在 10Hz 处具有类似颤音的效果。几个假设:
我的“firstChunkSize”和“splice”逻辑中有一些简单的错误
第一个块有一些标题,导致剩余数据以一种奇怪的方式解释。
创建音频源时,与某些选项有一些奇怪的交互(降噪?)
解决方案
你想要codecs=
,没有codec=
。
var options = {
mimeType: "audio/webm;codecs=pcm",
}
虽然MediaRecorder.isSupported
会返回 truecodec=
只是因为这个参数被忽略了。例如:
MediaRecorder.isTypeSupported("audio/webm;codec=pcm")
true
MediaRecorder.isTypeSupported("audio/webm;codecs=pcm")
true
MediaRecorder.isTypeSupported("audio/webm;codecs=asdfasd")
false
MediaRecorder.isTypeSupported("audio/webm;codec=asdfasd")
true
asdfasd
如果您指定而codec
不是codecs
.
推荐阅读
- spring - Cloud Foundry 更新/升级时 Spring Boot 应用程序自动重启
- python - ModuleNotFoundError:没有名为“win32serviceutil”的模块
- c++ - 出队不适用于从双链表继承的 Queue 类
- mysql - 我的 Django 管理字段未正确显示非 asccii 数据
- flutter - 如何在charts_flutter中更改条形图中条形的宽度?
- java - Spring Boot Admin - 持久化应用程序和事件
- azure - 如何在映射数据流的联接转换中写入 <= 条件
- java - 自定义测试结果监听器
- javascript - 添加具有相同类的新字段后验证输入字段
- swift - SwiftUI TupleView 和泛型,如何递归解析一些 View 和 Group 的元组