@@ -338,55 +338,64 @@ impl App {
338338 ) {
339339 let new_state = cmd_rx. recv ( ) . await . unwrap ( ) ;
340340
341- // report metadata to OS
341+ let now_playing = new_state. now_playing . clone ( ) ;
342+ let name = new_state. name . clone ( ) ;
343+ // Report initial metadata to OS
342344 send_os_media_controls_command (
343345 self . os_media_controls . as_mut ( ) ,
344346 os_media_controls:: Command :: SetMetadata ( souvlaki:: MediaMetadata {
345- title : ( !new_state . now_playing . is_empty ( ) ) . then_some ( & new_state . now_playing ) ,
346- album : ( !new_state . name . is_empty ( ) ) . then_some ( & new_state . name ) ,
347+ title : ( !now_playing. is_empty ( ) ) . then ( || now_playing. as_str ( ) ) ,
348+ album : ( !name. is_empty ( ) ) . then ( || name. as_str ( ) ) ,
347349 artist : None ,
348350 cover_url : None ,
349351 duration : None ,
350352 } ) ,
351353 ) ;
352- // report started playing to OS
354+ // Report started playing to OS
353355 send_os_media_controls_command (
354356 self . os_media_controls . as_mut ( ) ,
355357 os_media_controls:: Command :: Play ,
356358 ) ;
357- // report volume to OS
359+ // Report volume to OS
358360 send_os_media_controls_command (
359361 self . os_media_controls . as_mut ( ) ,
360362 os_media_controls:: Command :: SetVolume ( new_state. volume . volume_ratio ( ) as f64 ) ,
361363 ) ;
362364
363365 let new_state = Arc :: new ( Mutex :: new ( new_state) ) ;
364-
365366 let id = id. to_string ( ) ;
366367 let new_state_clone = new_state. clone ( ) ;
367368
368- thread:: spawn ( move || loop {
369+ // Background thread to update now_playing
370+ thread:: spawn ( move || {
369371 let rt = tokio:: runtime:: Runtime :: new ( ) . unwrap ( ) ;
370372 rt. block_on ( async {
371- let mut new_state = new_state_clone. lock ( ) . unwrap ( ) ;
372- // Get current playing if available, otherwise use state's value
373- new_state. now_playing = get_currently_playing ( & id) . await . unwrap_or_default ( ) ;
374- drop ( new_state) ;
375- std:: thread:: sleep ( Duration :: from_millis ( 10000 ) ) ;
373+ loop {
374+ let mut new_state = new_state_clone. lock ( ) . unwrap ( ) ;
375+ // Get current playing if available, otherwise use default
376+ let now_playing = get_currently_playing ( & id) . await . unwrap_or_default ( ) ;
377+ if new_state. now_playing != now_playing {
378+ new_state. now_playing = now_playing;
379+ }
380+ drop ( new_state) ;
381+ std:: thread:: sleep ( Duration :: from_millis ( 10000 ) ) ;
382+ }
376383 } ) ;
377384 } ) ;
378385
379386 let mut fps = 0 ;
380387 let mut framerate = 0 ;
381388 let mut last_poll = Instant :: now ( ) ;
389+ let mut last_metadata_update = Instant :: now ( ) ;
390+ let mut last_now_playing = String :: new ( ) ;
391+ const METADATA_UPDATE_INTERVAL : Duration = Duration :: from_secs ( 1 ) ; // Check every second
382392
383393 loop {
384394 let channels = if self . graph . pause {
385395 None
386396 } else {
387397 let Ok ( audio_frame) = self . frame_rx . recv ( ) else {
388- // other thread has closed so application has
389- // closed
398+ // other thread has closed so application has closed
390399 return ;
391400 } ;
392401 Some ( stream_to_matrix (
@@ -441,12 +450,33 @@ impl App {
441450 size. y += 8 ;
442451 }
443452 let chart = Chart :: new ( datasets. iter ( ) . map ( |x| x. into ( ) ) . collect ( ) )
444- . x_axis ( current_display. axis ( & self . graph , Dimension :: X ) ) // TODO allow to have axis sometimes?
453+ . x_axis ( current_display. axis ( & self . graph , Dimension :: X ) )
445454 . y_axis ( current_display. axis ( & self . graph , Dimension :: Y ) ) ;
446455 f. render_widget ( chart, size)
447456 }
448457 } )
449458 . unwrap ( ) ;
459+
460+ // Update metadata only if needed and at a controlled interval
461+ if last_metadata_update. elapsed ( ) >= METADATA_UPDATE_INTERVAL {
462+ let state = new_state. lock ( ) . unwrap ( ) ;
463+ if state. now_playing != last_now_playing {
464+ let now_playing = state. now_playing . clone ( ) ;
465+ let name = state. name . clone ( ) ;
466+ send_os_media_controls_command (
467+ self . os_media_controls . as_mut ( ) ,
468+ os_media_controls:: Command :: SetMetadata ( souvlaki:: MediaMetadata {
469+ title : ( !now_playing. is_empty ( ) ) . then_some ( now_playing. as_str ( ) ) ,
470+ album : ( !name. is_empty ( ) ) . then_some ( name. as_str ( ) ) ,
471+ artist : None ,
472+ cover_url : None ,
473+ duration : None ,
474+ } ) ,
475+ ) ;
476+ last_now_playing = state. now_playing . clone ( ) ;
477+ }
478+ last_metadata_update = Instant :: now ( ) ;
479+ }
450480 }
451481
452482 while let Some ( event) = self
@@ -481,7 +511,6 @@ impl App {
481511 }
482512 }
483513 }
484-
485514 fn current_display_mut ( & mut self ) -> Option < & mut dyn DisplayMode > {
486515 match self . mode {
487516 CurrentDisplayMode :: Oscilloscope => {
0 commit comments