@fishjam-cloud/react-client
Version:
React client library for Fishjam
47 lines (46 loc) • 1.98 kB
JavaScript
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 };
};