1

I am trying to create individual chunks of a MediaRecorder stream and be able to play each chunk individually as it is recording. To clarify my question I have a sample website

website image of chunks

Here's the code, I create a block object whenever I receive the dataavailable event. This event is fired because I pass in a timesplit argument into mediaRecorder.start(2000) so that the event is fired after collecting 2 seconds of data.

const container = document.querySelector(".container");
let count = 0;

function Block(chunk, index) {
  const div = document.createElement("div");
  div.className = "block";
  div.onclick = () => {
    const audioUrl = URL.createObjectURL(chunk);
    const audio = new Audio(audioUrl);
    audio.play();
  };
  div.innerText = index;
  container.append(div);
}

const recordAudio = async () => {
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
  const mediaRecorder = new MediaRecorder(stream);

  mediaRecorder.addEventListener("dataavailable", (event) => {
    new Block(event.data, count);
    count += 1;
  });

  mediaRecorder.start(2000);
};

recordAudio();

Out of all the chunks, only the first chunk can be played. How to I play the other chunks?

update 1 I tried grouping the chunks together and I created a helper function to do that that you can try in the console.

If I group the first chunk and any other chunk, the audio becomes playable. For example, play(3) will create a blob of the first chunk (index 0) and the chunk at index 3.

play function in console

Here's the play function (allChunks is an array containing all the audio chunks)

const play = (idx) => {
  const audioBlob = new Blob([allChunks[0], allChunks[idx]]);
  const audioUrl = URL.createObjectURL(audioBlob);
  const audio = new Audio(audioUrl);
  audio.play();
};

I'm suspecting that the first audio chunk contains meta tags that if I added to the other audio chunks, I would be able to play them individually.

Update 2 To test out my theory to the above, when users click on a block I created a fileReader object so I can see the chunk data.

  div.onclick = () => {
    const audioUrl = URL.createObjectURL(chunk);
    const audio = new Audio(audioUrl);
    audio.play();

    const reader = new FileReader();
    reader.readAsDataURL(chunk);
    reader.onload = () => {
      console.log(reader.result);
    };
  };

The playable chunk and non-playable chunk looks like very similar base64 encoded strings.

enter image description here

songz
  • 2,082
  • 1
  • 14
  • 18
  • Start multiple recorders if you want multiple files. – Kaiido Aug 12 '20 at 22:45
  • @songz I am going down this same path in an effort to create 1-second long video clips using the timeslice param with 0 jumps in-between, did you end up arriving at a solution? – Louie Anderson Aug 28 '20 at 03:23

0 Answers0