import { RoomAudioRenderer, TrackLoop, TrackRefContext, useConnectionState, useTracks, VideoTrack, } from "@livekit/components-react"; import { PublicUserItem } from "@openim/wasm-client-sdk/lib/types/entity"; import { Spin } from "antd"; import clsx from "clsx"; import { ConnectionState, LocalParticipant, Participant, ParticipantEvent, Track, } from "livekit-client"; import { useEffect, useRef, useState } from "react"; import callingMp3 from "@/assets/audios/calling.mp3"; import OIMAvatar from "@/components/OIMAvatar"; import { CustomType } from "@/constants"; import { AuthData, InviteData } from "./data"; import { RtcControl } from "./RtcControl"; const localVideoClasses = "absolute right-3 top-3 !w-[100px] !h-[150px] rounded-md z-10"; const remoteVideoClasses = "absolute top-0 z-0"; interface IRtcLayoutProps { connect: boolean; isConnected: boolean; isRecv: boolean; inviteData?: InviteData; closeOverlay: () => void; sendCustomSignal: (recvID: string, customType: CustomType) => Promise; connectRtc: (data?: AuthData) => void; } export const RtcLayout = ({ connect, isConnected, isRecv, inviteData, connectRtc, sendCustomSignal, closeOverlay, }: IRtcLayoutProps) => { const isVideoCall = inviteData?.invitation?.mediaType === "video"; const tracks = useTracks([Track.Source.Camera]); const remoteParticipant = tracks.find((track) => !isLocal(track.participant)); const isWaiting = !connect && !isConnected; const [isRemoteVideoMuted, setIsRemoteVideoMuted] = useState(false); const callingRef = useRef(null); const connectState = useConnectionState(); useEffect(() => { if (!remoteParticipant?.participant.identity) return; const trackMuteUpdate = () => { setIsRemoteVideoMuted(!remoteParticipant?.participant.isCameraEnabled); }; remoteParticipant?.participant.on(ParticipantEvent.TrackMuted, trackMuteUpdate); remoteParticipant?.participant.on(ParticipantEvent.TrackUnmuted, trackMuteUpdate); trackMuteUpdate(); }, [remoteParticipant?.participant.identity]); const renderContent = () => { if (!isWaiting && isVideoCall && !isRemoteVideoMuted) return null; return ( ); }; useEffect(() => { if (isWaiting) { handlePlay(); } else { handlePause(); } }, [isWaiting]); const handlePlay = () => { if (callingRef.current) { callingRef.current.play(); } }; const handlePause = () => { if (callingRef.current) { callingRef.current.pause(); } }; return (
{renderContent()}
{isConnected && ( {(track) => track && ( ) } )}
); }; interface ISingleProfileProps { isWaiting: boolean; userInfo?: PublicUserItem; } const SingleProfile = ({ isWaiting, userInfo }: ISingleProfileProps) => { return (
{userInfo?.nickname}
); }; const isLocal = (p: Participant) => { return p instanceof LocalParticipant; };