@@ -12,10 +12,10 @@ import type { JoinPolicy, MediaTrack } from 'types';
1212 */
1313class CastAdapter {
1414 private static _instance : CastAdapter | null = null ;
15- private castContext : any | null = null ;
16- private chromeCast : any | null = null ;
17- private remotePlayer : any | null = null ;
18- private remotePlayerController : any | null = null ;
15+ private castContext : cast . framework . CastContext | null = null ;
16+ private chromeCast : typeof chrome . cast | null = null ;
17+ private remotePlayer : cast . framework . RemotePlayer | null = null ;
18+ private remotePlayerController : cast . framework . RemotePlayerController | null = null ;
1919 private isInitialized = false ;
2020 private castButtonId = 'cast-button-container' ;
2121 private sessionStateListener : ( ( event : any ) => void ) | null = null ;
@@ -39,7 +39,11 @@ class CastAdapter {
3939 * @param retryDelay - Delay between retries in milliseconds
4040 * @returns Promise resolving to the cast context if successful
4141 */
42- async load ( retryCount = 0 , maxRetries = 15 , retryDelay = 500 ) : Promise < any | null > {
42+ async load (
43+ retryCount = 0 ,
44+ maxRetries = 15 ,
45+ retryDelay = 500 ,
46+ ) : Promise < cast . framework . CastContext | null > {
4347 try {
4448 // Check if Cast API is already available
4549 if ( typeof window !== 'undefined' && window . cast && window . cast . framework ) {
@@ -108,7 +112,7 @@ class CastAdapter {
108112 async init (
109113 receiverId : string = DEFAULT_CAST_CONFIG . receiverId ,
110114 joinPolicy : keyof JoinPolicy = DEFAULT_CAST_CONFIG . joinPolicy ,
111- ) : Promise < any | undefined > {
115+ ) : Promise < cast . framework . CastContext | undefined > {
112116 try {
113117 if ( this . isInitialized ) {
114118 console . warn ( 'Cast framework is already initialized.' ) ;
@@ -162,12 +166,12 @@ class CastAdapter {
162166 * Get the Cast context, initializing it if necessary.
163167 * @returns The Cast context or null if not available
164168 */
165- private getCastContext ( ) : any | null {
169+ private getCastContext ( ) : cast . framework . CastContext | null {
166170 if ( ! this . castContext && typeof window !== 'undefined' ) {
167171 try {
168172 if ( isValidWindow && window . cast ?. framework ) {
169173 this . castContext = window . cast . framework . CastContext . getInstance ( ) ;
170- this . chromeCast = window . chrome . cast ;
174+ this . chromeCast = window . chrome ? .cast ?? null ;
171175 return this . castContext ;
172176 }
173177 console . warn ( 'Cast framework not loaded yet' ) ;
@@ -245,16 +249,18 @@ class CastAdapter {
245249 return ;
246250 }
247251
248- switch ( event . sessionState ) {
249- case window . cast . framework . SessionState . SESSION_STARTED :
250- this . onCastSessionStarted ( ) ;
251- break ;
252- case window . cast . framework . SessionState . SESSION_RESUMED :
253- this . onCastSessionResumed ( ) ;
254- break ;
255- case window . cast . framework . SessionState . SESSION_ENDED :
256- this . onCastSessionEnded ( ) ;
257- break ;
252+ if ( window . cast ?. framework ) {
253+ switch ( event . sessionState ) {
254+ case window . cast . framework . SessionState . SESSION_STARTED :
255+ this . onCastSessionStarted ( ) ;
256+ break ;
257+ case window . cast . framework . SessionState . SESSION_RESUMED :
258+ this . onCastSessionResumed ( ) ;
259+ break ;
260+ case window . cast . framework . SessionState . SESSION_ENDED :
261+ this . onCastSessionEnded ( ) ;
262+ break ;
263+ }
258264 }
259265 } ;
260266
@@ -274,10 +280,20 @@ class CastAdapter {
274280 if ( session ) {
275281 this . setupRemotePlayer ( ) ;
276282
277- // Notify state change
283+ // Get the receiver name (cast device name)
284+ const castDevice = session . getCastDevice ( ) ;
285+ const deviceName = castDevice ?. friendlyName || 'Cast Device' ;
286+
287+ // Notify state change with device name
278288 ChangeNotifier . notify ( 'CAST_STATE' , {
279289 isCasting : true ,
280290 castSession : session ,
291+ deviceName : deviceName ,
292+ } ) ;
293+
294+ // Also add device name to audio state
295+ ChangeNotifier . notify ( 'AUDIO_STATE' , {
296+ castDevice : deviceName ,
281297 } ) ;
282298
283299 // Load current track if available
@@ -299,10 +315,20 @@ class CastAdapter {
299315 if ( session ) {
300316 this . setupRemotePlayer ( ) ;
301317
302- // Notify state change
318+ // Get the receiver name (cast device name)
319+ const castDevice = session . getCastDevice ( ) ;
320+ const deviceName = castDevice ?. friendlyName || 'Cast Device' ;
321+
322+ // Notify state change with device name
303323 ChangeNotifier . notify ( 'CAST_STATE' , {
304324 isCasting : true ,
305325 castSession : session ,
326+ deviceName : deviceName ,
327+ } ) ;
328+
329+ // Also add device name to audio state
330+ ChangeNotifier . notify ( 'AUDIO_STATE' , {
331+ castDevice : deviceName ,
306332 } ) ;
307333 }
308334 }
@@ -320,14 +346,20 @@ class CastAdapter {
320346 ChangeNotifier . notify ( 'CAST_STATE' , {
321347 isCasting : false ,
322348 castSession : null ,
349+ deviceName : null ,
350+ } ) ;
351+
352+ // Remove cast device name from audio state
353+ ChangeNotifier . notify ( 'AUDIO_STATE' , {
354+ castDevice : '' ,
323355 } ) ;
324356 }
325357
326358 /**
327359 * Initialize the remote player and controller.
328360 */
329361 private initializeRemotePlayer ( ) : void {
330- if ( ( isValidWindow && ! window . cast ) || ! window . cast . framework ) {
362+ if ( ! isValidWindow || ! window . cast ? .framework ) {
331363 console . error ( 'Cast framework not available' ) ;
332364 return ;
333365 }
@@ -438,7 +470,7 @@ class CastAdapter {
438470 console . log ( 'Cast player state changed:' , this . remotePlayer ?. playerState ) ;
439471
440472 let playbackState : string | undefined ;
441- if ( ! isValidWindow ) {
473+ if ( ! isValidWindow || ! window . chrome ?. cast ) {
442474 console . log ( 'no valid window context, returning :: CAST::onPlayerStateChanged' ) ;
443475 return ;
444476 }
@@ -552,7 +584,7 @@ class CastAdapter {
552584 private onMediaInfoChanged ( ) : void {
553585 const session = this . getCastSession ( ) ;
554586 const mediaSession = session ?. getMediaSession ( ) ;
555- if ( mediaSession ) {
587+ if ( mediaSession ?. media ) {
556588 console . log ( 'Media info changed:' , mediaSession . media ) ;
557589 ChangeNotifier . notify ( 'AUDIO_STATE' , {
558590 mediaInfo : mediaSession . media ,
@@ -571,16 +603,18 @@ class CastAdapter {
571603 const queue = mediaSession ?. getQueueItems ( ) ;
572604
573605 if ( queue && currentItemId !== undefined ) {
574- const currentIndex = queue . findIndex ( ( item : any ) => item . itemId === currentItemId ) ;
606+ const currentIndex = queue . findIndex (
607+ ( item : chrome . cast . media . QueueItem ) => item . itemId === currentItemId ,
608+ ) ;
575609 const nextTrack = queue [ currentIndex + 1 ] ?. media ;
576610 if ( nextTrack ) {
577- console . log ( `Moving to next track in queue: ${ nextTrack . metadata . title } ` ) ;
611+ console . log ( `Moving to next track in queue: ${ nextTrack . metadata ? .title || 'Unknown' } ` ) ;
578612 ChangeNotifier . notify ( 'AUDIO_STATE' , {
579613 playbackState : PLAYBACK_STATE . PLAYING ,
580614 currentTrack : {
581- title : nextTrack . metadata . title ,
582- artist : nextTrack . metadata . artist ,
583- album : nextTrack . metadata . albumName ,
615+ title : nextTrack . metadata ? .title || 'Unknown Title' ,
616+ artist : nextTrack . metadata ? .artist || 'Unknown Artist' ,
617+ album : nextTrack . metadata ? .albumName || 'Unknown Album' ,
584618 source : nextTrack . contentId ,
585619 } ,
586620 } ) ;
@@ -657,7 +691,7 @@ class CastAdapter {
657691 * @param mediaTrack - The media track to cast
658692 * @returns The created media info object
659693 */
660- private createCastMedia ( mediaTrack : MediaTrack ) : any | null {
694+ private createCastMedia ( mediaTrack : MediaTrack ) : chrome . cast . media . MediaInfo | null {
661695 try {
662696 if ( ! this . chromeCast ) {
663697 console . error ( 'Chrome Cast API not available' ) ;
@@ -757,17 +791,20 @@ class CastAdapter {
757791 */
758792 loadQueue ( tracks : MediaTrack [ ] , startIndex = 0 ) : void {
759793 const session = this . getCastSession ( ) ;
760- if ( ! session ) {
794+ if ( ! session || ! this . chromeCast ) {
761795 console . error ( 'No active cast session' ) ;
762796 return ;
763797 }
764798
765- const queueItems = tracks . map ( ( track ) => {
766- const mediaInfo = this . createCastMedia ( track ) ;
767- return new this . chromeCast ! . media . QueueItem ( mediaInfo ) ;
768- } ) ;
799+ const queueItems = tracks
800+ . map ( ( track ) => {
801+ const mediaInfo = this . createCastMedia ( track ) ;
802+ if ( ! mediaInfo || ! this . chromeCast ) return null ;
803+ return new this . chromeCast . media . QueueItem ( mediaInfo ) ;
804+ } )
805+ . filter ( ( item ) : item is chrome . cast . media . QueueItem => item !== null ) ;
769806
770- const queueLoadRequest = new this . chromeCast ! . media . QueueLoadRequest ( queueItems ) ;
807+ const queueLoadRequest = new this . chromeCast . media . QueueLoadRequest ( queueItems ) ;
771808 queueLoadRequest . startIndex = startIndex ;
772809 queueLoadRequest . autoplay = true ;
773810
@@ -821,13 +858,13 @@ class CastAdapter {
821858
822859 // Create media info for the next track
823860 const mediaInfo = this . createCastMedia ( nextTrack ) ;
824- if ( ! mediaInfo ) {
861+ if ( ! mediaInfo || ! this . chromeCast ) {
825862 console . error ( 'Failed to create media info for next track' ) ;
826863 return ;
827864 }
828865
829866 // Create load request with autoplay
830- const request = new this . chromeCast ! . media . LoadRequest ( mediaInfo ) ;
867+ const request = new this . chromeCast . media . LoadRequest ( mediaInfo ) ;
831868 request . autoplay = true ;
832869
833870 // Load the next track
@@ -867,13 +904,13 @@ class CastAdapter {
867904
868905 // Create media info for the previous track
869906 const mediaInfo = this . createCastMedia ( previousTrack ) ;
870- if ( ! mediaInfo ) {
907+ if ( ! mediaInfo || ! this . chromeCast ) {
871908 console . error ( 'Failed to create media info for previous track' ) ;
872909 return ;
873910 }
874911
875912 // Create load request with autoplay
876- const request = new this . chromeCast ! . media . LoadRequest ( mediaInfo ) ;
913+ const request = new this . chromeCast . media . LoadRequest ( mediaInfo ) ;
877914 request . autoplay = true ;
878915
879916 // Load the previous track
@@ -915,12 +952,12 @@ class CastAdapter {
915952 }
916953
917954 const mediaInfo = this . createCastMedia ( track ) ;
918- if ( ! mediaInfo ) {
955+ if ( ! mediaInfo || ! this . chromeCast ) {
919956 reject ( new Error ( 'Failed to create media info' ) ) ;
920957 return ;
921958 }
922959
923- const request = new this . chromeCast ! . media . LoadRequest ( mediaInfo ) ;
960+ const request = new this . chromeCast . media . LoadRequest ( mediaInfo ) ;
924961 request . autoplay = autoPlay ;
925962
926963 session
@@ -1014,7 +1051,7 @@ class CastAdapter {
10141051 * Get the current cast session.
10151052 * @returns The current cast session or null if none exists
10161053 */
1017- getCastSession ( ) : any | null {
1054+ getCastSession ( ) : cast . framework . CastSession | null {
10181055 if ( ! this . castContext ) {
10191056 return null ;
10201057 }
@@ -1055,15 +1092,15 @@ class CastAdapter {
10551092 * Get the remote player instance.
10561093 * @returns The remote player instance
10571094 */
1058- getRemotePlayer ( ) : any | null {
1095+ getRemotePlayer ( ) : cast . framework . RemotePlayer | null {
10591096 return this . remotePlayer ;
10601097 }
10611098
10621099 /**
10631100 * Get the remote player controller.
10641101 * @returns The remote player controller
10651102 */
1066- getRemotePlayerController ( ) : any | null {
1103+ getRemotePlayerController ( ) : cast . framework . RemotePlayerController | null {
10671104 return this . remotePlayerController ;
10681105 }
10691106}
0 commit comments