javascriptreactjsasynchronouswebrtcmediastream

MediaStream throwing play() request was interrupted by a new load request


The browser throws this asynchronous error when I try to play my mediastream videotrack

Uncaught (in promise) DOMException: The play() request was interrupted by a new load request.

Here's my code:

import { useEffect, useRef, useState } from "react"
import { Link } from "react-router-dom";
import { Room } from "./Room";

export const Landing = () => {
    const [name, setName] = useState("");
    const [localAudioTrack, setLocalAudioTrack] = useState(null);
    const [localVideoTrack, setlocalVideoTrack] = useState(null);
    const videoRef = useRef(null);

    const [joined, setJoined] = useState(false);

    const getCam = async () => {
        const stream = await window.navigator.mediaDevices.getUserMedia({
            video: true,
            audio: true
        })
        // MediaStream
        const audioTrack = stream.getAudioTracks()[0]
        const videoTrack = stream.getVideoTracks()[0]
        setLocalAudioTrack(audioTrack);
        setlocalVideoTrack(videoTrack);
        if (!videoRef.current) {
            return;
        }
        videoRef.current.srcObject = new MediaStream([videoTrack])
        videoRef.current.play();
        // MediaStream
    }

    useEffect(() => {
        if (videoRef && videoRef.current) {
            getCam()
        }
    }, [videoRef]);

    if (!joined) {
            
    return <div>
            <video autoPlay ref={videoRef}></video>
            <input type="text" onChange={(e) => {
                setName(e.target.value);
            }}>
            </input>
            <button onClick={() => {
                setJoined(true);
            }}>Join</button>
        </div>
    }

    return <Room name={name} localAudioTrack={localAudioTrack} localVideoTrack={localVideoTrack} />
}

The link at the end of the exception mentions how to handle .play() but the browser says that this line is causing the error:

videoRef.current.srcObject = new MediaStream([videoTrack])

Solution

  • I fixed it by following the instructions on https://developer.chrome.com/blog/play-request-was-interrupted

    Since I was using autoPlay, I had to handle the .play() accordingly:

    let localPlayPromise = localVideoRef.current.play()
    if (localPlayPromise !== undefined) {
      localPlayPromise.then(_ => {
        // Automatic playback started!
        // Show playing UI.
      })
      .catch(error => {
        // Auto-play was prevented
        // Show paused UI.
      });
    }