MediaRecorder API 不考虑 WebAudio API AudioBufferSourceNodes 之间的暂停

问题描述 投票:0回答:1

我正在开发一个网络应用程序,用户可以与数字乐器 UI 交互以播放不同的音符,这些音符最终会传输到我的后端。我正在使用 Web Audio API 将正在播放的音符转换为 AudioBufferSourceNodes,并尝试将播放的音频传递到我的(MediaRecorder API)录音机正在监听的流,以便生成所有音频的最终录音播放注意到用户已经玩过。

最终录音包含所有演奏的音符,问题是它没有考虑节点之间的暂停。例如,如果用户播放持续 1 秒的音符,等待 5 秒,然后再次播放相同的音符...最终录音将在 2 秒的时间内依次播放这两个音符,而不是第一次播放音符,等待 5 秒,然后第二次播放音符。

这是我的 WebAudio API 和 MediaRecorder API 代码:

//initialize recording stream components
let chunks = [];
let context = new AudioContext();
let stream_destination = context.createMediaStreamDestination();
let recording = new MediaRecorder(stream_destination.stream);

recording.ondataavailable = event => {
    chunks.push(event.data) 
}

recording.onstop = () => {
    document.getElementById("recording").src = URL.createObjectURL(new Blob(chunks,{'type':'audio/mp3'}))
}

document.getElementById("start").addEventListener("click", () => { recording.start(1000); console.log("recording started"); })
document.getElementById("stop").addEventListener("click", () => { recording.stop(); console.log("recording stopped"); })


// play audio file to user and create sourceNode to add to MediaRecorder
document.getElementById('sound-button').addEventListener('click', () => {
    const audioFilePath = './media/temp1.mp3';
    const audio = new Audio(audioFilePath);
    audio.play();

    let request = new XMLHttpRequest();
    request.open("GET", audioFilePath, true);
    request.responseType = "arraybuffer";
    request.onload = () => {
        let audioData = request.response;
        context.decodeAudioData(
            audioData,
            (buf) => {
                // add the played buffer to buffer history
                recordedAudioBuffers.push(buf);
                console.log("buffer was succesfully added to buffer history. buffer history: " + JSON.stringify(recordedAudioBuffers));
                const sourceNode = new AudioBufferSourceNode(context, {buffer: buf})
                sourceNode.connect(stream_destination);
                sourceNode.start();
            }
        )
    }
    request.send();
});

最初,我认为我可以操纵 sourceNode.start() 方法的计时参数来达到我想要的结果,但仍然没有得到我想要的最终记录。

我还研究了是否可以在代表用户演奏的音符的源节点之间集成“空”源节点,以模拟我在最终录音中寻找的音符之间的停顿,但在研究了在线选项之后,这似乎不必要地使我的代码/实现变得复杂。

reactjs streaming audio-streaming web-audio-api web-mediarecorder
1个回答
0
投票

据我所知这只是 Firefox 中的一个问题。可以用无声的

ConstantSourceNode
来修复。

const constantSourceNode = new ConstantSourceNode(
    context,
    { offset: 0 }
);

constantSourceNode.connect(stream_destination);
constantSourceNode.start();
© www.soinside.com 2019 - 2024. All rights reserved.