【发布时间】:2020-12-24 17:05:14
【问题描述】:
我的项目的目标是能够操纵原始音频数据,例如这个问题:Play raw audio with JavaScript。有五个步骤:
- 录制音频
- 将生成的
blob转换为ArrayBuffer - 使用
DataView处理音频数据的ArrayBuffer(例如,使其速度提高一倍或提高两倍)。 - 转换回 blob
- 播放经过处理的音频
当我将音频数据块转换为ArrayBuffer,并将ArrayBuffer 转换为Int8Array 以便我可以查看数据时,它看起来像这样(我只显示前几个值,而不是整件事):
[26,69,-33,-93,-97,66,-122,-127,1,66,-9,-127,1,66,-14,-127,4,66,-13,-127,8,66,-126,-124,119,101,98,109,66,-121,-127,4,66,-123,-127,2,24,83,-128,103,1,-1,-1,-1,-1,-1,-1,-1,21,73,-87,102,-103,42,-41,-79,-125,15,66,64,77,-128,-122,67,104,114,111,109,101,87,65,-122,67,104,114,111,109,101,22,84,-82,107,-65,-82,-67,-41,-127,1,115,-59,-121,-103,-103,-9,91,-16,59,77,-125,-127,2,-122,-122,65,95,79,80,85,83,99,-94,-109,79,112,117,115,72,101,97,100,1,1,0,0,-128,-69,0,0,0,0,0,-31,-115,-75,-124,71,59,-128,0,-97,-127,1,98,100,-127,32,31,67,-74,117,1,-1,-1,-1,-1,-1,-1,-1,-25,-127,0,-93,65,52,-127,0,0,-128,-5,-125,2,-60,-1,-2,127,-4,102,-43,102,31,98,87,-112,-55,-17,-20,-88,89,39,108,97,84,44,38,-113,61,36,122,7,39,61,27,-103,-91,-23,80,64,36,9,-4,-51,-127,12,109,38,100,99,-101,-18,74,124,108,59,71,81,23,-30,93...]
由于似乎不可能从Int8Array 回到ArrayBuffer,并最终回到可以作为音频播放的Blob,我决定使用DataView 来操纵@ 987654336@.
当我根本不更改 ArrayBuffer 时,它可以成功地将其转换回 blob 并转换回音频。但是,当我尝试将 ArrayBuffer 更改为 DataView 时,出现以下错误:
index.html:1
Uncaught (in promise) DOMException: Failed to load because no supported source was found.
在线查看后,该错误似乎是某种CORS问题,但这没有意义,因为当我不更改ArrayBuffer时它可以工作。问题是否与数据类型有关?
这是我的整个 JavaScript:
let AudioContext = window.AudioContext || window.webkitAudioContext;
var mediaRecorder;
function start(){ //start recording
audio = navigator.mediaDevices.getUserMedia({
audio: true,
video: false
}).then(record);
}
function record(stream) {
mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start(); //start recording
mediaRecorder.addEventListener("dataavailable", event => {
event.data.arrayBuffer().then(processAudio); //event.data is a blob, converts it into an arrayBuffer
});
}
function processAudio(buffer){
var view = new DataView(buffer); //to change the ArrayBuffer
var array = new Int8Array(buffer); //this typed array contains all of the audio data
view.setInt16(0, 1); //when I comment out this line and don't change the ArrayBuffer at all, it works.
var newBlob = new Blob([buffer]); //convert back into blob
var newAud = document.createElement("audio"); //create audio element to play the recording
newAud.src = URL.createObjectURL(newBlob);
newAud.play();
document.body.appendChild(newAud);
}
function done(){ mediaRecorder.stop(); }
我还想提一下,当我尝试绘制 Int8Array 时,我得到如下图所示的随机静态:
我很确定它应该是 8 位编码,因为 ArrayBuffer 的字节长度并不总是两个的倍数。
感谢任何帮助。
【问题讨论】:
标签: javascript audio blob arraybuffer