3

I have a react app configured as such:

// landingpage.js

const {mediaStream, setMediaStream} = useContext(StreamContext);

useEffect(() => {
  navigator.mediaDevices.getUserMedia({ video: true, audio: true })
  .then((stream) => {
    const video = document.querySelector('video');
    video.srcObject = stream;
    video.onloadedmetadata = () => {
      video.play();
      setMediaStream(stream.clone());
    }
  }).catch here...;
}, []);

const toggleVideo = () => {
  ...
  const video = document.querySelector('video');
  const stream = video.srcObject;
  tracks.forEach((track) => {
    if (track.kind === 'video') {
      track.enabled = !track.enabled;
      setMediaStream(stream.clone());
    }
  });
  ...
}

// same thing for toggleAudio

The landing page seems to work fine, onloadedmetadata event gets fired and the video plays with audio. But when I take the stream.clone() and go to another page, and then srcObject to a video element there, weird behavior happens:

// Redirected to a new page, newpage.js
const { mediaStream, setMediaStream } = useContext(StreamContext);

useEffect(() => {
  if (mediaStream) {
    const video = document.querySelector('video');
    video.srcObject = mediaStream;
    video.onloadedmetadata = () => {
      // This event isn't captured if video track is not enabled
      // I also confirmed that this block runs if video track is enabled
      // I've tried video.addEventListener with 'loadedmetadata' and 'loadeddata' instead, but it didn't work for me
      video.play();
    };
  }
}, [])

In this page, if I had set enabled false for the video track, then audio does not autoplay, no audio, even though tracks are not muted. If videotrack was enabled true, then audio and video works. Here's how the media stream tracks look like:

MediaStreamTrack
contentHint: ""
enabled: true
id: ...
kind: "audio"
label: ...
muted: false
onended: null
onmute: null
onoverconstrained: null
onunmute: null
readyState: "live"

MediaStreamTrack
contentHint: ""
enabled: false
id: ...
kind: "video"
label: ...
muted: false
onended: null
onmute: null
onoverconstrained: null
onunmute: null
readyState: "live"

I expected the clone to autoplay in a new page seamlessly, however, if video was toggled off, it doesn't seem to autoplay the audio.

What I'm noticing is that onloadedmetadata event doesn't get fired in this new page if video track is not enabled.

This problem seems to occur in Safari, but not in Chrome and Firefox.

Joseph K.
  • 1,055
  • 3
  • 23
  • 46
  • have you checked `react-hooks/exhaustive-deps` lint warning? it seems like dependency error. – gnujoow Jul 13 '20 at 09:56
  • @gnujoow Yeah, I have `"react-hooks/exhaustive-deps": "warn"` in my eslintrc rules. Is there something specific I should look at? – Joseph K. Jul 14 '20 at 03:38

0 Answers0