0

I have a react application in which I am trying to let the user toggle between recording their face and their screen. I have it set up so that the video element correctly shows if I am using getDisplayMedia or getUserMedia. The problem is that the recorded video from the MediaRecorder only shows the video from getUserMedia even if I toggle. How do I get the recording of the getDisplayMedia content after clicking toggleRecording?

Here is a small demo of the problem: To replicate the problem follow these steps: 1) Click Record 2) Click Share Screen 3) Click Stop Recording 4) Play the recorded video at the bottom.

You will see that it is not capturing a recording of the screen.

Here is a codesandbox of the demo.

If needed here is the code from the codesandbox:

import React, { useState, useEffect, useRef } from "react";

export default function App() {
  const [isActive, setIsActive] = useState(false);
  const [mediaStream, setMediaStream] = useState(null);
  const [userFacing, setuserFacing] = useState(false);
  const [videoUrl, setvideoUrl] = useState("");
  const [chunks, setchunks] = useState([]);

  const videoRef = useRef();
  const liveStreamRecorder = useRef(null);
  let liveStream;

  const CAPTURE_OPTIONS = {
    audio: true,
    video: true
  };

  if (mediaStream && videoRef.current && !videoRef.current.srcObject) {
    videoRef.current.srcObject = mediaStream;
  }

  useEffect(() => {
    if (!mediaStream) {
      enableStream();
    } else {
      return function cleanup() {
        mediaStream.getVideoTracks().forEach((track) => {
          track.stop();
        });
      };
    }
  }, [mediaStream]);

  async function enableStream() {
    try {
      let stream = await navigator.mediaDevices.getUserMedia({
        video: true,
        audio: true
      });
      setMediaStream(stream);
    } catch (err) {
      console.log(err);
    }
  }

  // toggles the stream to active or inactive
  const toggle = () => {
    setIsActive(!isActive);
  };

  const startRecording = () => {
    toggle();
    recorderInit();
  };

  const recorderInit = () => {
    liveStream = videoRef.current.captureStream(30); // 30 FPS
    liveStreamRecorder.current = new MediaRecorder(liveStream, {
      mimeType: "video/webm;codecs=h264",
      videoBitsPerSecond: 3 * 1024 * 1024
    });
    liveStreamRecorder.current.ondataavailable = (e) => {
      chunks.push(e.data);
      console.log("send data", e.data);
    };
    liveStreamRecorder.current.start(1000);
  };

  const stopRecording = () => {
    liveStreamRecorder.current.stop();

    const recVideoBlob = new Blob(chunks, {
      type: "video/webm;codecs=h264"
    });
    // console.log('recVideo', recVideoBlob)
    const videoURL = window.URL.createObjectURL(recVideoBlob);
    setvideoUrl(videoURL);
  };

  const toggleRecording = async () => {
    let stream;
    !userFacing
      ? (stream = await navigator.mediaDevices.getDisplayMedia(CAPTURE_OPTIONS))
      : (stream = await navigator.mediaDevices.getUserMedia(CAPTURE_OPTIONS));
    setMediaStream(stream);

    videoRef.current.srcObject = stream;
    setuserFacing(!userFacing);
  };

  return (
    <div className="studio-container">
      <div id="container">
        <video
          width="640px"
          height="480px"
          ref={videoRef}
          autoPlay
          playsInline
          muted={true}
        />
        {/* VIDEO WILL APPEAR OF RECORDING AFTER PRESSING STOP RECORDING */}
        {videoUrl ? <video controls src={videoUrl} /> : null}
      </div>
      <div className="studio-bottom-button-container">
        {/* PRESS BUTTON TO START RECORDING AND THEN TO STOP RECORDING */}
        <button
          style={{ padding: ".5rem" }}
          onClick={!isActive ? startRecording : stopRecording}
        >
          {!isActive ? "Record" : "Stop Recording"}
        </button>

        {/* PRESS BUTTON TO SWITCH BETWEEN GETUSERMEDIA AND GETDISPLAYMEDIA */}
        <button
          style={{ marginLeft: ".5rem", padding: ".5rem" }}
          onClick={toggleRecording}
        >
          {!userFacing ? "Share Screen" : "Stop Sharing"}
        </button>
      </div>
    </div>
  );
}

Kaiido
  • 103,356
  • 8
  • 183
  • 231
Tosh Velaga
  • 85
  • 1
  • 11

0 Answers0