How to implement micro button and camera button like video call app?

39 views Asked by At

I'm learning to create a video call app, I want to do the media devices setting part (turn on/off camera and microphone) but it didn't work as expected.

My code is

"use client"
import React from 'react'
import styles from './MediaDevices.module.css'

const MediaDevices = () => {
    const setMicro =  async (e: React.SyntheticEvent) => {
        const localVideo = document.getElementById("localVideo") as HTMLVideoElement;
        // micro is on
        if ((document.getElementById("setMicro") as HTMLImageElement).src === "http://localhost:3000/icon-micro.png") {
            // change micro button
            (document.getElementById("setMicro") as HTMLImageElement).src = "http://localhost:3000/icon-micro-off.png";
            // Stop the media stream (turn off the camera)
            const stream = localVideo.srcObject as MediaStream;
            if (stream) {
                const tracks = stream.getAudioTracks();
                tracks.forEach(track => track.stop());
            }

            // Set the srcObject of the video element to null
            localVideo.srcObject = null;
            console.log("micro is off");
        // micro is off
        } else {
            (document.getElementById("setMicro") as HTMLImageElement).src = "http://localhost:3000/icon-micro.png";
            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
            localVideo.srcObject = stream;
            console.log("micro is on");
        }
    }

    
    const setCamera = async (e: React.SyntheticEvent) => {
        const localVideo = document.getElementById("localVideo") as HTMLVideoElement;
        // camera is on
        if ((document.getElementById("setCamera") as HTMLImageElement).src === "http://localhost:3000/icon-video-camera.png") {
            // change camera button
            (document.getElementById("setCamera") as HTMLImageElement).src = "http://localhost:3000/icon-video-camera-off.png";
            // Stop the media stream (turn off the camera)
            const stream = localVideo.srcObject as MediaStream;
            if (stream) {
                const tracks = stream.getVideoTracks();
                tracks.forEach(track => track.stop());
            }

            // Set the srcObject of the video element to null
            localVideo.srcObject = null;
            console.log("camera is off");
        // camera is off
        } else {
            (document.getElementById("setCamera") as HTMLImageElement).src = "http://localhost:3000/icon-video-camera.png";
            const stream = await navigator.mediaDevices.getUserMedia({ video: true });
            localVideo.srcObject = stream;
            console.log("camera is on");
        }
    }

    return (
        <>
            <div className={styles.cameraContainer}>
                <video id="localVideo" autoPlay playsInline controls={false}></video>
            </div>
            <div>
                <button onClick={setMicro} className='btn !btn-circle btn-outline mx-1'>
                    <img id="setMicro" src="icon-micro-off.png" alt="icon-micro" className={styles.icon}/>
                </button>
                <button onClick={setCamera} className='btn !btn-circle btn-outline mx-1'>
                    <img id="setCamera" src="icon-video-camera-off.png" alt="icon-camera" className={styles.icon}/>
                </button>
            </div>
        </>
    )
}

export default MediaDevices

If I only try setCamera/setMicro it works, but if I try both of them it didn't produce the result as expected.

Any tip to fix this? Thanks

0

There are 0 answers