@@ -229,13 +229,12 @@ export function Player({
229229 const prop = sameSource ( propMedia ) ;
230230
231231 // Prefer a playable fileUrl; keep context/provisional as metadata shell.
232- // Previously `url` made us drop contextMedia, so re-extract after a long idle
233- // showed "Unknown" even when last-session/context still had real titles.
232+ // Prefer context over provisional so history-seeded titles/covers win the merge primary.
234233 const playable =
235234 ( prop ?. fileUrl ? prop : null ) ||
236235 ( extracted ?. fileUrl ? extracted : null ) ||
237236 ( context ?. fileUrl ? context : null ) ;
238- const shell = playable || prop || extracted || provisionalMedia || context ;
237+ const shell = playable || prop || extracted || context || provisionalMedia ;
239238 if ( ! shell ) return null ;
240239
241240 const ytId = getYouTubeId ( shell . sourceUrl || url || "" ) ;
@@ -345,8 +344,17 @@ export function Player({
345344 setExtractedMedia ( null ) ;
346345 setPlaybackError ( null ) ;
347346 setStreamState ( { status : "idle" } ) ;
348- // Drop stale context media so old cover/progress cannot linger
349- if ( url ) setMedia ( null ) ;
347+ // Keep media already seeded for this URL (history replay). Only drop unrelated tracks.
348+ if ( url ) {
349+ setMedia ( ( prev ) => {
350+ if ( ! prev ) return null ;
351+ if ( prev . sourceUrl === url ) return prev ;
352+ const prevId = getYouTubeId ( prev . sourceUrl ) ?? prev . metadata . id ;
353+ const nextId = getYouTubeId ( url ) ;
354+ if ( prevId && nextId && prevId === nextId ) return prev ;
355+ return null ;
356+ } ) ;
357+ }
350358 } , [ url , setMedia ] ) ;
351359
352360 // Reset autoplay gate whenever the playable file changes
@@ -359,15 +367,32 @@ export function Player({
359367 if ( extractedMedia || streamStarted . current ) return ;
360368 if ( ! url ) return ;
361369 streamStarted . current = true ;
370+
371+ // History/cache open already seeded a playable blob — reuse it instead of
372+ // re-resolving the cache with id-only metadata (which becomes Unknown).
373+ const seeded =
374+ contextMedia ?. fileUrl &&
375+ ( contextMedia . sourceUrl === url ||
376+ ( getYouTubeId ( contextMedia . sourceUrl ) &&
377+ getYouTubeId ( contextMedia . sourceUrl ) === getYouTubeId ( url ) ) )
378+ ? contextMedia
379+ : null ;
380+
362381 // Defer so we don't sync-setState inside the effect body (React Compiler lint).
363- const timer = window . setTimeout ( ( ) => startStream ( ) , 0 ) ;
382+ const timer = window . setTimeout ( ( ) => {
383+ if ( seeded ) {
384+ setExtractedMedia ( seeded ) ;
385+ return ;
386+ }
387+ startStream ( ) ;
388+ } , 0 ) ;
364389 return ( ) => {
365390 window . clearTimeout ( timer ) ;
366391 extractAbortRef . current ?. abort ( ) ;
367392 extractAbortRef . current = null ;
368393 streamStarted . current = false ;
369394 } ;
370- } , [ url , extractedMedia , startStream ] ) ;
395+ } , [ url , extractedMedia , startStream , contextMedia ] ) ;
371396
372397 // Measure bottom chrome for mini-player clip height
373398 useEffect ( ( ) => {
@@ -395,21 +420,14 @@ export function Player({
395420 } , [ isMini , barHeight ] ) ;
396421
397422 // Sync playable extracted media into app context (last-session + shared state).
398- // Keep a ref of context so we can merge prior titles without depending on it
399- // (depending would re-fire this effect after every setMedia).
400- const contextMediaRef = useRef ( contextMedia ) ;
401- useEffect ( ( ) => {
402- contextMediaRef . current = contextMedia ;
403- } , [ contextMedia ] ) ;
423+ // Titles/covers come from extract + stashed search/history meta (peekSearchMeta).
404424 useEffect ( ( ) => {
405425 if ( ! extractedMedia ?. fileUrl ) return ;
406- const prior = contextMediaRef . current ;
407426 const ytId = getYouTubeId ( extractedMedia . sourceUrl ) ;
408427 setMedia ( {
409428 ...extractedMedia ,
410429 metadata : mergeTrackMetadata (
411430 extractedMedia . metadata ,
412- prior ?. sourceUrl === extractedMedia . sourceUrl ? prior . metadata : undefined ,
413431 ytId ? peekSearchMeta ( ytId ) : undefined ,
414432 ) ,
415433 } ) ;
0 commit comments