0

The following javascript code records a sound and generates blob with audio every 0,5 second.
After recording has stopped the program plays 1-st blob - data[0].
I need the audio player to fire event after data[0] has played, and event handler will deliver the next portion to the audio player - data[1] (далее - data[2], data[3] etc.).
How can I modify the code and which objects should I use to do this ?
I know that I could pass all data[] array to the audio player, but I need a mechanism allowing the audio player to request next portions using events.

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);
});
LUN2
  • 75
  • 5

1 Answers1

0

I guess that's what your looking for ?

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);
});

You had some mistakes to correct :

  • When recorder call start event wich timeslice parameters, that will not fire the ondataavailable event. You need to stop the recorder to fire the event and create the blob.

  • You make a mistake on the recorder name's variable and the time on the settimeout function.

  • You recreate a audio player all times the recorder stop and never append it on the DOM.

Popwers
  • 46
  • 4
  • thank you for your answer. The main idea, that I have wanted to implement, is not to stop the recorder after every small time interval (in my example - timeSlice). When I call record.start(500) it will not be stopped after every 0,5 s - It will produce blob every 0,5 s, firing ondataavailable event. Your example assumes that the recorder will be stopped calling stop(), but I am looking for a way not to do it. – LUN2 Feb 04 '23 at 14:43
  • If you just want to stream the record in live, you just need to pass the `stream` to the `audio` element. I edit the source. – Popwers Feb 07 '23 at 06:25
  • I need to fill the stream you have proposed with data and does not know how to do it. The audio data come from the remote computer, which records them using MediaRecorder. So recording and playing are processes occured in the different computers. My remote computer gets blobs from network, but how can I convert it to stream, which you have proposed ? – LUN2 Feb 13 '23 at 19:37
  • @LUN2 you can look at this post, it seems to answer your problem : https://stackoverflow.com/questions/50333767/html5-video-streaming-video-with-blob-urls – Popwers Feb 21 '23 at 04:17