• Docs
  • Web SDK
  • Store States
  • Camera

Camera States

Lets you access the MediaStream or CamStream of the client. These values are exposed in the store for the client.

NOTE: Camera stream for the client is available directly on the store but for all the peers, their streams are available in the peers store, which can accessed using the usePeerTrack() hook.

Camera Store

type IMediaSlice = {
    mediaDevice: MediaDeviceInfo | null;
    stream: MediaStream | null;
    streamError: {
        type: IMediErrorType;
        blocked: boolean;
    } | null;
    deviceLoading: boolean;
    streamsArry: MediaStream[];
}

mediaDevice - The device that is currently being used for the stream.
stream - The stream that is currently being used.
streamError - The error that is thrown when the stream is not available.
deviceLoading - The loading state of the device.
streamsArry - The array of all the streams that are currently being used.

streamError

This is the error that is thrown when the stream is not available. The error has two properties, type and blocked. This may occur if the user is denied permission to access the camera or if the camera is not available.

NOTE: The blocked property is available if any of the error cases occur.

type - The type of error that is thrown.

  • NotAllowedError - The user has denied permission to access the camera.
  • NotFoundError - The camera is not available.
  • NotReadableError - The camera is already in use.
  • OverconstrainedError - The camera is not available.
  • SecurityError - The camera is not available.
  • AbortError - The camera is not available.
  • NotSupportedError - The camera is not available.
  • TypeError - The camera is not available.

Example

You can access the camera state using the useMeCamTrack hook.

import { useHuddleStore, useMeCamTrack } from "huddle01-client/hooks";
 
interface Props {
    peerId: string;
}
 
const Component = ({ peerId }) => {
    const isCamPaused = useHuddleStore(state => state.isCamPaused);
    const myCamStream = useMeCamTrack(peerId);
 
    const getStream = (_track: MediaStreamTrack) => {
        const stream = new MediaStream();
        stream.addTrack(_track);
        return stream;
    };
 
    useEffect(() => {
        const videoObj = videoRef.current;
 
        if (videoObj && myCamStream) {
        videoObj.load();
        videoObj.srcObject = getStream(myCamStream);
        videoObj.play().catch(err => {
            logger.error({
            message: 'Error playing video',
            meta: {
                err,
            },
            });
        });
        }
 
        if (isCamPaused && videoObj) {
        videoObj.pause();
        } else if (!isCamPaused && videoObj) {
        videoObj.play();
        }
 
        return () => {
            if (videoObj) {
                videoObj?.pause();
                videoObj.srcObject = null;
            }
        };
    }, [myCamStream, isCamPaused]);
 
    return (
        <div>
            {isCamPaused ? "Paused" : "Not Paused"}
            {isCamPaused ? <video
                ref={videoRef}
                id="peer-video-elem"
                muted
                autoPlay
                playsInline
            /> : null}
            ...
        <div />
    )
}
 

NOTE: Doing this will subscribe isCamPaused, myCamStream state to that component and will re-render the component when the state changes.
Pro Tip: You dont need to add useEffect to subscribe to the state and change certains states based on this, it is already done for you.