Re: [mediacapture-record] MediaRecorder needs to define effect of adding / removing tracks in its input MediaStream (#4)

@Pehrsons In an attempt to create a version of https://github.com/guest271314/MediaFragmentRecorder which outputs the same result at both Mozilla Firefox and Chromium/Chrome substituted using `canvas.catureStream()`, `AudioContext.createMediaElementSource`, `AudioContext.createMediaStreamDestination()`, `requestAnimationFrame()` with `MediaRecorder()`. 

However, the code now outputs the roughly the expected result at Chromium/Chrome (save for audio clipping) though not at Mozilla Firefox, where the video does not contain all captured images, video playback stalls, and the audio has gaps. Encountered this issue once before though unfortunately no longer have access to the OS where ran and saved the tests.

If you find the time, for interop, can you run the code at both Chromium/Chrome and Mozilla Firefox and provide any feedback as to what the issue could be?

```
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <h1>click</h1>
  <script>
    const start = document.querySelector("h1");
    const canvas = document.createElement("canvas");
    const video = document.createElement("video");
    document.body.appendChild(video);
    const ctx = canvas.getContext("2d");
    const canvasStream = canvas.captureStream();
    const width = 320;
    const height = 240;
    canvas.width = video.width = width;
    canvas.height = video.height = height;
    video.autoplay = true;
    const recorder = new MediaRecorder(canvasStream);
    let raf;
    recorder.addEventListener("dataavailable", e => {
      console.log(e.data);
      const display = document.createElement("video");
      display.width = width;
      display.height = height;
      display.controls = true;
      document.body.appendChild(display);
      display.src = URL.createObjectURL(e.data);
    });
    recorder.addEventListener("stop", e => {
      console.log(e);
    });
    recorder.addEventListener("resume", e => {
      console.log(e);
      if (raf) cancelAnimationFrame(raf);
      raf = requestAnimationFrame(draw)
    });
    recorder.addEventListener("start", e => {
      console.log(e);
      if (raf) cancelAnimationFrame(raf);
      raf = requestAnimationFrame(draw)
    });
    recorder.addEventListener("pause", e => {
      console.log(e);
      cancelAnimationFrame(raf)
    });
    const ac = new AudioContext();
    const draw = _ => {
      if (raf) cancelAnimationFrame(raf);
      if (!video.paused) {
        ctx.clearRect(0, 0, width, height);
        ctx.drawImage(video, 0, 0, width, height);
        raf = requestAnimationFrame(draw)
      } else {
        cancelAnimationFrame(raf)
      }
    }

    const urls = [{
      src: "https://upload.wikimedia.org/wikipedia/commons/a/a4/Xacti-AC8EX-Sample_video-001.ogv",
      from: 0,
      to: 4
    }, {
      src: "https://mirrors.creativecommons.org/movingimages/webm/ScienceCommonsJesseDylan_240p.webm#t=10,20"
    }, {
      from: 55,
      to: 60,
      src: "https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4"
    }, {
      from: 0,
      to: 5,
      src: "https://raw.githubusercontent.com/w3c/web-platform-tests/master/media-source/mp4/test.mp4"
    }, {
      from: 0,
      to: 5,
      src: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"
    }, {
      from: 0,
      to: 5,
      src: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4"
    }, {
      src: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerMeltdowns.mp4#t=0,6.5"
    }];
    start.addEventListener("click", async e => {
      try {
        await ac.resume();
        console.log(ac);
        const source = ac.createMediaElementSource(video);
        const destination = ac.createMediaStreamDestination();
        source.connect(ac.destination);
        source.connect(destination);
        canvasStream.addTrack(destination.stream.getAudioTracks()[0]);
        await urls.reduce(async(promise, {
          src, from, to
        }) => {
          await promise;

          return await new Promise(async resolve => {
            const url = new URL(src);
            if (url.hash.length) {
              [from, to] = url.hash.match(/\d+|\d+\.\d+/g);
            }
            const request = await fetch(src);
            const blobURL = `${URL.createObjectURL(await request.blob())}#t=${from},${to}`;
            video.addEventListener("playing", e => {

              console.log(e);
              if (recorder.state === "inactive") {
                recorder.start();
              }
              if (recorder.state === "paused") {
                recorder.resume();
              }
            }, {
              once: true
            });
            video.addEventListener("pause", e => {
              recorder.pause();
              resolve()
            }, {
              once: true
            });
            video.load();
            video.src = blobURL;
          });
        }, Promise.resolve());
        recorder.stop();
      } catch (e) {
        console.error(e, e.stack);
      }
    }, {
      once: true
    });
  </script>
</body>

</html>
```

-- 
GitHub Notification of comment by guest271314
Please view or discuss this issue at https://github.com/w3c/mediacapture-record/issues/4#issuecomment-475908878 using your GitHub account

Received on Saturday, 23 March 2019 22:08:29 UTC