// Enhanced polyfill for navigator.mediaDevices if (typeof navigator !== 'undefined') { // Ensure mediaDevices exists if (!navigator.mediaDevices) { (navigator as any).mediaDevices = {}; } // Polyfill getUserMedia if not available if (!navigator.mediaDevices.getUserMedia) { navigator.mediaDevices.getUserMedia = function(constraints) { // Try to find any available getUserMedia implementation const getUserMedia = (navigator as any).getUserMedia || (navigator as any).webkitGetUserMedia || (navigator as any).mozGetUserMedia || (navigator as any).msGetUserMedia; if (!getUserMedia) { // If no getUserMedia is available, create a comprehensive mock MediaStream console.warn('getUserMedia is not supported in this browser. Video/audio features will be disabled.'); // Create a more complete mock MediaStream const mockTrack = { id: 'mock-track', kind: 'video', label: 'Mock Track', enabled: true, muted: false, readyState: 'live', addEventListener: function() {}, removeEventListener: function() {}, dispatchEvent: function() { return true; }, stop: function() {}, clone: function() { return this; }, getCapabilities: function() { return {}; }, getConstraints: function() { return {}; }, getSettings: function() { return {}; }, applyConstraints: function() { return Promise.resolve(); } }; const mockStream = { id: 'mock-stream', active: true, getTracks: () => [mockTrack], getVideoTracks: () => constraints?.video ? [mockTrack] : [], getAudioTracks: () => constraints?.audio ? [mockTrack] : [], addEventListener: function() {}, removeEventListener: function() {}, dispatchEvent: function() { return true; }, addTrack: function() {}, removeTrack: function() {}, clone: function() { return this; }, stop: function() { this.active = false; } }; return Promise.resolve(mockStream as any); } // Wrap the legacy getUserMedia with a Promise return new Promise(function(resolve, reject) { getUserMedia.call(navigator, constraints, resolve, reject); }); }; } // Polyfill enumerateDevices if not available if (!navigator.mediaDevices.enumerateDevices) { navigator.mediaDevices.enumerateDevices = function() { return Promise.resolve([]); }; } // Polyfill getDisplayMedia if not available if (!navigator.mediaDevices.getDisplayMedia) { navigator.mediaDevices.getDisplayMedia = function(constraints) { console.warn('getDisplayMedia is not supported in this browser. Screen sharing will be disabled.'); return Promise.reject(new Error('getDisplayMedia is not supported')); }; } } import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import Page from './app/page'; import { PageClientImpl } from './app/rooms/[roomName]/PageClientImpl'; function Router() { const path = window.location.pathname; // Check if we're on a room page const roomMatch = path.match(/^\/rooms\/(.+)$/); if (roomMatch) { const roomName = roomMatch[1]; const searchParams = new URLSearchParams(window.location.search); // Extract query parameters const region = searchParams.get('region') || undefined; const hq = searchParams.get('hq') === 'true'; const codec = searchParams.get('codec') || 'vp9'; // Use the client component directly return ( ); } // Default to home page return ; } function render(container: HTMLElement) { const root = createRoot(container); root.render( ); } // Export the LiveKitMeet object const LiveKitMeet = { render, }; // Make it available globally if (typeof window !== 'undefined') { (window as any).LiveKitMeet = LiveKitMeet; } // Also export for module systems export default LiveKitMeet;