import {faSquare, faThLarge, faUserFriends} from '@fortawesome/free-solid-svg-icons'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {Room, RoomEvent, setLogLevel, VideoPresets} from 'livekit-client'; import {DisplayContext, DisplayOptions, LiveKitRoom} from '@livekit/react-components'; import {useState} from 'react'; import 'react-aspect-ratio/aspect-ratio.css'; import {useNavigate, useLocation} from 'react-router-dom'; // 新增代码 let currentRoom: Room; export const RoomPage = () => { const [numParticipants, setNumParticipants] = useState(0); const [displayOptions, setDisplayOptions] = useState({ stageLayout: 'grid', showStats: false, }); const navigate = useNavigate(); const query = new URLSearchParams(useLocation().search); const url = query.get('url'); const token = query.get('token'); const recorder = query.get('recorder'); if (!url || !token) { return
url and token are required
; } const onLeave = () => { navigate('/'); }; const updateParticipantSize = (room: Room) => { setNumParticipants(room.participants.size + 1); }; const onParticipantDisconnected = (room: Room) => { updateParticipantSize(room); /* Special rule for recorder */ if (recorder && parseInt(recorder, 10) === 1 && room.participants.size === 0) { console.log('END_RECORDING'); } }; const updateOptions = (options: DisplayOptions) => { setDisplayOptions({ ...displayOptions, ...options, }); }; // 新增代码开始 const encoder = new TextEncoder(); const decoder = new TextDecoder(); const enterText = () => { const textField = document.getElementById('entry') as HTMLInputElement; const chat = document.getElementById('chat') as HTMLDivElement; if (textField.value.trim()) { textField.focus(); const msg = encoder.encode(textField.value); currentRoom.localParticipant.publishData(msg, 0); chat.innerHTML += `
${currentRoom.localParticipant.identity} (me): ${textField.value}
`; chat.scrollTop = chat.scrollHeight; textField.value = ''; } }; const handleData = (msg: Uint8Array, participant?: any) => { const chat = document.getElementById('chat') as HTMLDivElement; const str = decoder.decode(msg); let from = 'server'; if (participant) { from = participant.identity; } chat.innerHTML += `
${from}: ${str}
`; chat.scrollTop = chat.scrollHeight; }; const closeChat = () => { const chatArea: any = document.getElementById('chat-area'); chatArea.style.display = 'none'; } const handleKeydown = (e: any) => { if (e.target.value.trim() && e.key === 'Enter') { enterText() } } // 新增代码结束 return (

Zoom Video

updateOptions({showStats: e.target.checked})} />
{numParticipants}
{ setLogLevel('debug'); onConnected(room, query); room.on(RoomEvent.ParticipantConnected, () => updateParticipantSize(room)); room.on(RoomEvent.ParticipantDisconnected, () => onParticipantDisconnected(room)); room.on(RoomEvent.DataReceived, handleData); updateParticipantSize(room); }} roomOptions={{ adaptiveStream: isSet(query, 'adaptiveStream'), dynacast: isSet(query, 'dynacast'), publishDefaults: { simulcast: isSet(query, 'simulcast'), }, videoCaptureDefaults: { resolution: VideoPresets.h720.resolution, }, }} onLeave={onLeave} />
{ currentRoom &&

Chat

x
handleKeydown(event)}/>
}
); }; async function onConnected(room: Room, query: URLSearchParams) { // make it easier to debug // (window as any).currentRoom = room; // 新增代码 currentRoom = room; if (isSet(query, 'audioEnabled')) { const audioDeviceId = query.get('audioDeviceId'); if (audioDeviceId && room.options.audioCaptureDefaults) { room.options.audioCaptureDefaults.deviceId = audioDeviceId; } await room.localParticipant.setMicrophoneEnabled(true); } if (isSet(query, 'videoEnabled')) { const videoDeviceId = query.get('videoDeviceId'); if (videoDeviceId && room.options.videoCaptureDefaults) { room.options.videoCaptureDefaults.deviceId = videoDeviceId; } await room.localParticipant.setCameraEnabled(true); } } function isSet(query: URLSearchParams, key: string): boolean { return query.get(key) === '1' || query.get(key) === 'true'; }