UNPKG

@fishjam-cloud/react-client

Version:
47 lines (46 loc) 1.98 kB
import { LivestreamError, publishLivestream } from "@fishjam-cloud/ts-client"; import { useCallback, useRef, useState } from "react"; import { useFishjamId } from "../contexts/fishjamId"; import { buildLivestreamWhipUrl } from "../utils/fishjamUrl"; const isLivestreamError = (err) => Object.values(LivestreamError).includes(err); /** * Hook for publishing a livestream, which can be then received with {@link useLivestreamViewer} * @category Livestream * @group Hooks */ export const useLivestreamStreamer = () => { const [error, setError] = useState(null); const [isConnected, setIsConnected] = useState(false); const fishjamId = useFishjamId(); const resultRef = useRef(null); const disconnect = useCallback(() => { resultRef.current?.stopPublishing(); resultRef.current = null; }, []); const onConnectionStateChange = useCallback((pc) => { if (isConnected && pc.connectionState !== "connected") disconnect(); setIsConnected(pc.connectionState === "connected"); }, [isConnected, disconnect]); const connect = useCallback(async ({ inputs: { video, audio }, token }, urlOverride) => { if (resultRef.current !== null) disconnect(); const videoTrack = video?.getVideoTracks().at(0); const audioTrack = audio?.getAudioTracks().at(0); const stream = new MediaStream([videoTrack, audioTrack].filter((v) => v != null)); try { const result = await publishLivestream(stream, urlOverride ?? buildLivestreamWhipUrl(fishjamId), token, { onConnectionStateChange, }); resultRef.current = result; setError(null); } catch (e) { if (isLivestreamError(e)) setError(e); else console.error(e); } }, [disconnect, onConnectionStateChange, fishjamId]); return { connect, disconnect, error, isConnected }; };