@@ -51,6 +51,46 @@ const Player = () => {
5151
5252
5353
54+ // Helper function to check if a URL is an MKV file
55+ const isMkvFile = ( url : string , filename ?: string ) : boolean => {
56+ if ( filename && filename . toLowerCase ( ) . endsWith ( '.mkv' ) ) return true
57+ const urlLower = url . toLowerCase ( )
58+ // Check URL path for .mkv extension
59+ try {
60+ const urlObj = new URL ( url . startsWith ( '/' ) ? `${ window . location . origin } ${ url } ` : url )
61+ if ( urlObj . pathname . toLowerCase ( ) . endsWith ( '.mkv' ) ) return true
62+ } catch { }
63+ // Fallback: check if URL contains .mkv
64+ return urlLower . includes ( '.mkv' )
65+ }
66+
67+ // Helper function to check if we're in Electron
68+ const isElectron = ( ) : boolean => {
69+ return typeof ( window as any ) . electronAPI !== 'undefined'
70+ }
71+
72+ // Helper function to open external player
73+ const openExternalPlayer = async ( url : string ) : Promise < boolean > => {
74+ if ( ! isElectron ( ) ) {
75+ console . log ( 'Not in Electron, skipping external player' )
76+ return false
77+ }
78+ try {
79+ const abs = url . startsWith ( '/' ) ? `${ window . location . origin } ${ url } ` : url
80+ const result = await ( window as any ) . electronAPI ?. openExternalPlayer ( abs )
81+ if ( result ?. ok ) {
82+ console . log ( `Opened in external player: ${ result . player } ` )
83+ return true
84+ } else {
85+ console . error ( 'Failed to open external player:' , result ?. error )
86+ return false
87+ }
88+ } catch ( e ) {
89+ console . error ( 'Error opening external player:' , e )
90+ return false
91+ }
92+ }
93+
5494 const pickSource = async ( s : SourceItem ) => {
5595 try {
5696 setResolvingId ( s . id )
@@ -65,37 +105,45 @@ const Player = () => {
65105 if ( r . status === 'ok' && r . directUrl ) {
66106 setCompatibilityInfo ( r )
67107
68- // Handle MKV externally via system player (mpv/vlc)
69- if ( r . format === 'mkv_native' && r . directUrl . includes ( '/api/stream/' ) ) {
70- const abs = r . directUrl . startsWith ( '/' ) ? `${ window . location . origin } ${ r . directUrl } ` : r . directUrl
71- // Ask main process to open the external player
72- try { await ( window as any ) . electronAPI ?. openExternalPlayer ( abs ) } catch { }
73- // Show overlay briefly before navigating home
74- setExternalOpening ( true )
75- setTimeout ( ( ) => { navigate ( '/' ) } , 1500 )
76- return
77- } else {
78- setSelectedUrl ( r . directUrl )
79- setFallbackUrl ( null )
80-
81- // Show compatibility warning for other limited formats
82- if ( r . compatibility && r . compatibility . browserSupport === 'limited' ) {
83- setShowCompatibilityAlert ( true )
108+ // Handle MKV externally via system player (mpv/vlc) when in Electron
109+ // Check if it's an MKV file by format, filename, or URL
110+ const isMkv = r . format === 'mkv_native' ||
111+ isMkvFile ( r . directUrl , r . filename ) ||
112+ ( r . compatibility ?. format === 'mkv' )
113+
114+ if ( isMkv && isElectron ( ) ) {
115+ const opened = await openExternalPlayer ( r . directUrl )
116+ if ( opened ) {
117+ // Show overlay briefly before navigating home
118+ setExternalOpening ( true )
119+ setTimeout ( ( ) => { navigate ( '/' ) } , 1500 )
120+ return
84121 }
122+ // If external player failed, fall through to try in-browser playback
123+ }
124+
125+ setSelectedUrl ( r . directUrl )
126+ setFallbackUrl ( r . fallbackUrl || null )
127+
128+ // Show compatibility warning for other limited formats
129+ if ( r . compatibility && r . compatibility . browserSupport === 'limited' ) {
130+ setShowCompatibilityAlert ( true )
85131 }
86132 } else {
87133 // Handle non-streamable response
88134 setVideoError ( r . message || r . reason || 'This source cannot be streamed' )
89135 setCompatibilityInfo ( r )
90136 }
91137 } else {
92- // Non-debrid direct link; if MKV, open externally
93- if ( s . url . toLowerCase ( ) . includes ( '.mkv' ) ) {
94- const abs = s . url . startsWith ( '/' ) ? `${ window . location . origin } ${ s . url } ` : s . url
95- try { await ( window as any ) . electronAPI ?. openExternalPlayer ( abs ) } catch { }
96- setExternalOpening ( true )
97- setTimeout ( ( ) => { navigate ( '/' ) } , 1500 )
98- return
138+ // Non-debrid direct link; if MKV and in Electron, open externally
139+ if ( isMkvFile ( s . url , s . name ) && isElectron ( ) ) {
140+ const opened = await openExternalPlayer ( s . url )
141+ if ( opened ) {
142+ setExternalOpening ( true )
143+ setTimeout ( ( ) => { navigate ( '/' ) } , 1500 )
144+ return
145+ }
146+ // If external player failed, fall through to try in-browser playback
99147 }
100148 setSelectedUrl ( s . url )
101149 }
0 commit comments