// Wait for the Cast framework to be available window.castReceiverManager = window.castReceiverManager || cast.framework.CastReceiverContext.getInstance(); const context = cast.framework.CastReceiverContext.getInstance(); const playerManager = context.getPlayerManager(); const video = document.getElementById('video'); // Initialize Shaka Player on the video element const shakaPlayer = new shaka.Player(video); // Optional Shaka configuration shakaPlayer.configure({ streaming: { rebufferingGoal: 15, }, }); // Listen for Shaka player errors shakaPlayer.addEventListener('error', (event) => { log('Shaka Player error:', event.detail); }); // Intercept LOAD requests playerManager.setMessageInterceptor( cast.framework.messages.MessageType.LOAD, async (loadRequestData) => { const url = loadRequestData.media.contentId; try { if (shakaPlayer.isLive() || shakaPlayer.getMediaElement()) { await shakaPlayer.unload(); } await shakaPlayer.load(url); playerManager.notifyPlayerStateChanged(cast.framework.PlaybackState.LOADING); return loadRequestData; } catch (error) { log('Failed to load media:', error); return null; } } ); // Sync native video events to CAF video.addEventListener('play', () => { playerManager.notifyPlayerStateChanged(cast.framework.PlaybackState.PLAYING); }); video.addEventListener('pause', () => { playerManager.notifyPlayerStateChanged(cast.framework.PlaybackState.PAUSED); }); video.addEventListener('seeking', () => { playerManager.notifySeekStarted(); }); video.addEventListener('seeked', () => { playerManager.notifySeekCompleted(); playerManager.setPlaybackPosition(video.currentTime); }); video.addEventListener('timeupdate', () => { playerManager.setPlaybackPosition(video.currentTime); }); video.addEventListener('waiting', () => { playerManager.setIsBuffering(true); }); video.addEventListener('playing', () => { playerManager.setIsBuffering(false); }); // Handle play, pause, and seek commands from sender playerManager.setMessageInterceptor(cast.framework.messages.MessageType.PLAY, () => { video.play(); }); playerManager.setMessageInterceptor(cast.framework.messages.MessageType.PAUSE, () => { video.pause(); }); playerManager.setMessageInterceptor(cast.framework.messages.MessageType.PAUSE, (newPosition) => { video.currentTime = newPosition; }); // Start the Cast receiver context context.start();