WebRTC Video Chat
Relevant source files
The following files were used as context for generating this wiki page:The WebRTC Video Chat system provides real-time video and audio communication for players at the poker table. It is designed to enhance the interactive experience by allowing players to see and hear each other during gameplay. The system is built around a centralized React Context and a custom hook (useWebRTC) that manages media streams, player state, and user controls.
The core functionality includes initializing the local user's camera and microphone, managing a collection of players and their associated media streams, and providing UI components for displaying video feeds and controlling media devices. The WebRTCProvider wraps the entire application, making the video chat state and functions globally accessible to any component that needs them.
Architecture
The system uses a provider pattern, with WebRTCProvider at the root of the component tree. This provider manages all WebRTC-related state and logic. Components throughout the application can access this state and the associated functions by using the useWebRTC custom hook.
This diagram illustrates the high-level architecture, showing how the provider supplies data to various consumer components.
Core Logic: useWebRTC Hook
The useWebRTC hook is the brain of the video chat system. It is responsible for state management, media device access, and player management.
Sources: hooks/use-webrtc.tsx
State Management
The hook manages the following state variables, which are distributed through the WebRTCContext.
| State Variable | Type | Description |
|---|---|---|
localStream | MediaStream | null | The local user's media stream from their camera and microphone. |
players | Map<string, Player> | A map of all players in the session, including the local user. |
isVideoEnabled | boolean | The current enabled/disabled state of the local user's video track. |
isAudioEnabled | boolean | The current enabled/disabled state of the local user's audio track. |
isMediaInitialized | boolean | A flag indicating if the media initialization process has completed. |
mediaError | string | null | Stores any error message that occurred during media initialization. |
Sources: hooks/use-webrtc.tsx:14-22, hooks/use-webrtc.tsx:31-37
Player Data Structure
Each player is represented by a Player object with a defined structure.
Sources: hooks/use-webrtc.tsx:5-12
Media Initialization
The initializeMedia function is called on component mount to request access to the user's camera and microphone.
The flow is as follows:
- It checks if initialization has already been attempted or completed to prevent redundant calls.
- It verifies that the
navigator.mediaDevicesAPI is available. If not, it sets an error and adds demo players. - It calls
navigator.mediaDevices.getUserMediato request video and audio streams with specific constraints. - On success, it sets the
localStream, adds the local player to theplayersmap, and then adds simulated remote players for demonstration purposes. - On failure (e.g., user denies permission), it sets an error message, adds the local player without a stream, and still adds demo players.
This flowchart shows the logic of the initializeMedia function.
Sources: hooks/use-webrtc.tsx:41-109
Note: The current implementation uses a placeholder function addDemoPlayers to simulate other players in the room. The logic for establishing real RTCPeerConnections with a signaling server is not present in the analyzed files, though a peerConnectionsRef exists, suggesting it is planned.
Sources: hooks/use-webrtc.tsx:38, 111-133
Core Functions
The context provides several functions to interact with the WebRTC state.
| Function | Description |
|---|---|
toggleVideo() | Toggles the enabled state of the local video track and updates the isVideoEnabled state. |
toggleAudio() | Toggles the enabled state of the local audio track and updates the isAudioEnabled state. |
addPlayer() | Adds a new remote player to the players map. |
removePlayer() | Removes a player from the players map and cleans up their associated RTCPeerConnection. |
initializeMedia() | Initiates the process of acquiring the local user's media stream. |
Sources: hooks/use-webrtc.tsx:135-175, hooks/use-webrtc.tsx:177-201
UI Components
Several React components consume the useWebRTC hook to build the user-facing video chat interface.
VideoPlayer
This component is responsible for rendering a single player's video feed.
- Props: It accepts
stream,name,isLocal,videoEnabled, andaudioEnabled. - Functionality:
- If a
streamis available andvideoEnabledis true, it renders a<video>element. AuseEffecthook attaches the stream to the video element'ssrcObject. - The video is muted for the local player (
muted={muted || isLocal}) to prevent audio feedback. - If video is unavailable, it displays a placeholder with the player's name and an avatar icon.
- It shows
VideoOffandMicOfficons at the bottom of the player if the respective tracks are disabled.
- If a
Sources: components/video-player.tsx
VideoControls
This component provides buttons for the local user to control their own media devices.
- It renders two buttons: one for toggling the camera and one for the microphone.
- It uses the
toggleVideoandtoggleAudiofunctions from theuseWebRTChook. - The button icons (
Video/VideoOff,Mic/MicOff) and styles change dynamically based on theisVideoEnabledandisAudioEnabledstate values.
// components/video-controls.tsx:11-26
<Button
size="icon"
variant={isVideoEnabled ? "secondary" : "destructive"}
onClick={toggleVideo}
// ...
>
{isVideoEnabled ? <Video ... /> : <VideoOff ... />}
</Button>
<Button
size="icon"
variant={isAudioEnabled ? "secondary" : "destructive"}
onClick={toggleAudio}
// ...
>
{isAudioEnabled ? <Mic ... /> : <MicOff ... />}
</Button>
Sources: components/video-controls.tsx:7-28
Component Interaction Flow
The following sequence diagram shows how a user interacting with VideoControls triggers a state change that is reflected in the VideoPlayer.
PlayerPosition Integration
The PlayerPosition component integrates the VideoPlayer into the main poker table UI. It fetches the full list of players from useWebRTC, finds the specific player for its position via playerId, and renders a VideoPlayer with the correct stream and status properties. This demonstrates how the decoupled useWebRTC hook allows different parts of the UI to easily access and display video chat information.
Sources: components/player-position.tsx:16-17, 68-75
Summary
The WebRTC Video Chat feature is a client-side implementation designed for real-time communication in the poker game. It is architected around a central useWebRTC hook and WebRTCProvider, which manage media streams and player state. While the core logic for local media management and state toggling is robust, the peer-to-peer connection aspect is currently simulated with demo players, indicating that a signaling server and RTCPeerConnection management are future steps for a fully functional multi-user chat. The system is well-integrated into the UI through components like VideoPlayer, VideoControls, and PlayerPosition.