使用事件将音频 blob 传递到音频播放器 (js)

Using events to deliver audio blobs to audio player (js)

提问人:LUN2 提问时间:2/3/2023 更新时间:2/7/2023 访问量:75

问:

以下 javascript 代码录制一个声音,并每 0.5 秒生成一次带有音频的 blob。
录制停止后,程序将播放第 1 个 blob - data[0]。
我需要音频播放器在 data[0] 播放后触发事件,事件处理程序会将下一部分传递给音频播放器 - data[1](далее - data[2]、data[3] 等)。
如何修改代码以及应该使用哪些对象来执行此操作?
我知道我可以将所有data[]数组传递给音频播放器,但我需要一种机制,允许音频播放器使用事件请求下一部分。

navigator.mediaDevices.getUserMedia({audio:true})
.then(function onSuccess(stream) {
const recorder = new MediaRecorder(stream);

const data = [];
recorder.ondataavailable = (e) => {
data.push(e.data);
};
recorder.start(500); // willfire 'dataavailable ' event every 0,5 second

recorder.onstop = (e) => {
const audio = document.createElement('audio');
audio.src = window.URL.createObjectURL(new Blob( data[0] ));
}
setTimeout(() => {
rec.stop();
}, 5000);
})
.catch(function onError(error) {
console.log(error.message);
});
JavaScript 音频

评论


答:

0赞 Popwers 2/3/2023 #1

我想这就是你要找的?

navigator.mediaDevices
.getUserMedia({ audio: true })
.then(function onSuccess(stream) {
    // create the audio stream
    const audio = document.createElement('audio');
    audio.srcObject = stream; // Pass the audio stream
    audio.controls = true;
    audio.play();

    document.body.appendChild(audio);

    const recorder = new MediaRecorder(stream);
    const data = [];

    // Set event listener
    // ondataavailable will fire when you request stop(), requestData() or after all timeSlice you give to the start function.
    recorder.ondataavailable = e => data.push(e.data);

    // Start recording
    // Will generate blob every 500ms
    recorder.start(500);
})
.catch(function onError(error) {
    console.log(error.message);
});

你有一些错误需要纠正:

  • 记录器调用 start 事件 wich timeslice 参数时,不会触发 ondataavailable 事件。需要停止记录器才能触发事件并创建 Blob。

  • 您在记录器名称的变量和函数上的时间上犯了错误。settimeout

  • 每当录音机停止时,您都会重新创建音频播放器,并且永远不要将其附加到 DOM 上。

评论

0赞 LUN2 2/4/2023
谢谢你的回答。我想要实现的主要思想是不要在每个小的时间间隔后停止记录器(在我的示例中是 timeSlice)。当我调用 record.start(500) 时,它不会在每 0,5 秒后停止 - 它将每 0,5 秒生成一次 blob,触发 ondataavailable 事件。您的示例假设记录器将停止调用 stop(),但我正在寻找一种不这样做的方法。
0赞 Popwers 2/7/2023
如果您只想实时流式传输记录,则只需将 传递给元素即可。我编辑源代码。streamaudio
0赞 LUN2 2/14/2023
我需要用数据填充您提议的流,但不知道该怎么做。音频数据来自远程计算机,远程计算机使用 MediaRecorder 记录它们。因此,录制和播放是在不同的计算机中发生的过程。我的远程计算机从网络获取 blob,但我如何将其转换为您提出的流?
0赞 Popwers 2/21/2023
@LUN2你看这篇文章,它似乎回答了你的问题:stackoverflow.com/questions/50333767/......