attempt to simplify ytm_client

This commit is contained in:
ChuckBuilds
2025-05-25 20:26:24 -05:00
parent 3ac436dc54
commit f053963f43
2 changed files with 48 additions and 47 deletions

View File

@@ -185,9 +185,22 @@ class MusicManager:
if not is_actually_playing_ytm and self.current_source == MusicSource.YTM:
self.current_source = MusicSource.NONE
logger.debug(f"[YTM Direct Update] Old Album Art URL: {old_album_art_url}, New Album Art URL: {new_album_art_url}")
if new_album_art_url != old_album_art_url:
logger.info("[YTM Direct Update] Album art URL changed. Clearing self.album_art_image to force re-fetch.")
self.album_art_image = None
self.last_album_art_url = new_album_art_url
elif not self.last_album_art_url and new_album_art_url: # Case where old was None, new is something
logger.info("[YTM Direct Update] New album art URL appeared (was None). Clearing self.album_art_image.")
self.album_art_image = None
self.last_album_art_url = new_album_art_url
elif new_album_art_url is None and old_album_art_url is not None:
logger.info("[YTM Direct Update] Album art URL disappeared (became None). Clearing image and URL.")
self.album_art_image = None
self.last_album_art_url = None
elif self.current_track_info and self.current_track_info.get('album_art_url') and not self.last_album_art_url:
self.last_album_art_url = self.current_track_info.get('album_art_url')
self.album_art_image = None # Ensure image is cleared if URL was just populated from None
display_title = self.current_track_info.get('title', 'None') if self.current_track_info else 'None'
logger.debug(f"YTM Direct Update: Track change detected. Source: {self.current_source.name}. Track: {display_title}")
@@ -279,7 +292,8 @@ class MusicManager:
is_playing_from_poll = True # YTM is now considered playing
logger.debug(f"Polling YTM: Active track - {ytm_track_data.get('track', {}).get('title')}")
else:
logging.debug("Polling YTM: No active track or player paused (or track data missing player info).")
# logger.debug("Polling YTM: No active track or player paused (or track data missing player info).") # Potentially noisy
pass # Keep it quiet if no track or paused via polling
except Exception as e:
logging.error(f"Error polling YTM: {e}")
elif self.preferred_source == "ytm" and self.ytm and not self.ytm.is_connected:
@@ -304,9 +318,22 @@ class MusicManager:
self.current_track_info = simplified_info_poll
self.current_source = polled_source
logger.debug(f"[Poll Update] Old Album Art URL: {old_album_art_url_poll}, New Album Art URL: {new_album_art_url_poll}")
if new_album_art_url_poll != old_album_art_url_poll:
logger.info("[Poll Update] Album art URL changed. Clearing self.album_art_image to force re-fetch.")
self.album_art_image = None
self.last_album_art_url = new_album_art_url_poll
elif not self.last_album_art_url and new_album_art_url_poll: # Case where old was None, new is something
logger.info("[Poll Update] New album art URL appeared (was None). Clearing self.album_art_image.")
self.album_art_image = None
self.last_album_art_url = new_album_art_url_poll
elif new_album_art_url_poll is None and old_album_art_url_poll is not None:
logger.info("[Poll Update] Album art URL disappeared (became None). Clearing image and URL.")
self.album_art_image = None
self.last_album_art_url = None
elif self.current_track_info and self.current_track_info.get('album_art_url') and not self.last_album_art_url:
self.last_album_art_url = self.current_track_info.get('album_art_url')
self.album_art_image = None # Ensure image is cleared if URL was just populated from None
display_title_poll = self.current_track_info.get('title', 'None') if self.current_track_info else 'None'
logger.debug(f"Poll Update: Track change detected. Source: {self.current_source.name}. Track: {display_title_poll}")
@@ -462,17 +489,17 @@ class MusicManager:
if not self.is_currently_showing_nothing_playing or force_clear:
if force_clear or not self.is_currently_showing_nothing_playing: # Ensure clear if forced or first time
self.display_manager.clear()
logger.debug("[MusicManager.display] Display cleared for 'Nothing Playing'.")
# logger.debug("[MusicManager.display] Display cleared for 'Nothing Playing'.") # Commented out
logger.debug(f"[MusicManager.display] Font for 'Nothing Playing': {self.display_manager.regular_font}, Type: {type(self.display_manager.regular_font)}")
# logger.debug(f"[MusicManager.display] Font for 'Nothing Playing': {self.display_manager.regular_font}, Type: {type(self.display_manager.regular_font)}") # Commented out
text_width = self.display_manager.get_text_width("Nothing Playing", self.display_manager.regular_font)
logger.debug(f"[MusicManager.display] Calculated text_width for 'Nothing Playing': {text_width}")
# logger.debug(f"[MusicManager.display] Calculated text_width for 'Nothing Playing': {text_width}") # Commented out
x_pos = (self.display_manager.matrix.width - text_width) // 2
y_pos = (self.display_manager.matrix.height // 2) - 4
logger.debug(f"[MusicManager.display] Drawing 'Nothing Playing' at x={x_pos}, y={y_pos}")
# logger.debug(f"[MusicManager.display] Drawing 'Nothing Playing' at x={x_pos}, y={y_pos}") # Commented out
self.display_manager.draw_text("Nothing Playing", x=x_pos, y=y_pos, font=self.display_manager.regular_font)
self.display_manager.update_display()
logger.debug("[MusicManager.display] 'Nothing Playing' text drawn and display updated.")
# logger.debug("[MusicManager.display] 'Nothing Playing' text drawn and display updated.") # Commented out
self.is_currently_showing_nothing_playing = True
with self.track_info_lock: # Protect writes to shared state

View File

@@ -35,8 +35,6 @@ class YTMClient:
self._data_lock = threading.Lock()
self._connection_event = threading.Event()
self.external_update_callback = update_callback
self.last_processed_key_data = None # Stores key fields of the last update that triggered a callback
self.previous_key_data_for_debug_logging = None # Helps reduce repetitive non-significant change logs
@self.sio.event(namespace='/api/v1/realtime')
def connect():
@@ -57,47 +55,23 @@ class YTMClient:
@self.sio.on('state-update', namespace='/api/v1/realtime')
def on_state_update(data):
logging.debug(f"Received state update from YTM Companion on /api/v1/realtime: {data.get('video',{}).get('title')}")
# --- TEMPORARY DIAGNOSTIC LOGGING ---
# --- END TEMPORARY DIAGNOSTIC LOGGING ---
# Always update the full last_known_track_data for polling purposes
with self._data_lock:
self.last_known_track_data = data
# Extract key fields for deciding if a significant change occurred
current_key_data = None
if data and isinstance(data, dict):
video_info = data.get('video', {})
player_info = data.get('player', {})
current_key_data = {
'title': video_info.get('title'),
'author': video_info.get('author'),
'album': video_info.get('album'), # Added album for more robust change detection
'trackState': player_info.get('trackState'),
'adPlaying': player_info.get('adPlaying', False)
}
title = data.get('video', {}).get('title', 'N/A') if isinstance(data, dict) else 'N/A'
logging.debug(f"YTM state update received. Title: {title}. Callback Exists: {self.external_update_callback is not None}")
significant_change_detected = False
if current_key_data:
logging.debug(f"[YTMClient Check] Current Key Data: {current_key_data}")
logging.debug(f"[YTMClient Check] Last Processed Key Data: {self.last_processed_key_data}")
if current_key_data and (self.last_processed_key_data != current_key_data):
significant_change_detected = True
self.last_processed_key_data = current_key_data # Update only on significant change
logging.debug(f"[YTMClient Decision] Significant Change: {significant_change_detected}, Callback Exists: {self.external_update_callback is not None}")
if significant_change_detected and self.external_update_callback:
logging.info(f"--> Attempting to call YTM external_update_callback for title: {current_key_data.get('title')}")
if self.external_update_callback:
logging.debug(f"--> Attempting to call YTM external_update_callback for title: {title}")
try:
# Pass the full 'data' object to the callback
self.external_update_callback(data)
except Exception as cb_ex:
logging.error(f"Error executing YTMClient external_update_callback: {cb_ex}")
elif not significant_change_detected and current_key_data:
if current_key_data != self.previous_key_data_for_debug_logging:
logging.debug(f"YTM state update received but no significant change to callback. Title: {current_key_data.get('title')}, State: {current_key_data.get('trackState')}")
self.previous_key_data_for_debug_logging = current_key_data
elif not current_key_data:
logging.debug("YTM state update received but current_key_data was None/empty.")
def load_config(self):
default_url = "http://localhost:9863"
@@ -120,7 +94,7 @@ class YTMClient:
except Exception as e:
logging.error(f"Error loading YTM_COMPANION_URL from main config {CONFIG_PATH}: {e}. Using default YTM URL.")
logging.info(f"YTM Companion URL set to: {self.base_url}")
logging.debug(f"YTM Companion URL set to: {self.base_url}")
if self.base_url and self.base_url.startswith("ws://"):
self.base_url = "http://" + self.base_url[5:]
@@ -137,17 +111,17 @@ class YTMClient:
if self.ytm_token:
logging.info(f"YTM Companion token loaded from {YTM_AUTH_CONFIG_PATH}.")
else:
logging.warning(f"YTM_COMPANION_TOKEN not found in {YTM_AUTH_CONFIG_PATH}. YTM features will be disabled until token is present.")
logging.warning(f"YTM_COMPANION_TOKEN not found in {YTM_AUTH_CONFIG_PATH}. YTM features may be limited or disabled.")
except json.JSONDecodeError:
logging.error(f"Error decoding JSON from YTM auth file {YTM_AUTH_CONFIG_PATH}. YTM features will be disabled.")
logging.error(f"Error decoding JSON from YTM auth file {YTM_AUTH_CONFIG_PATH}. YTM features may be limited or disabled.")
except Exception as e:
logging.error(f"Error loading YTM auth config {YTM_AUTH_CONFIG_PATH}: {e}. YTM features will be disabled.")
logging.error(f"Error loading YTM auth config {YTM_AUTH_CONFIG_PATH}: {e}. YTM features may be limited or disabled.")
else:
logging.warning(f"YTM auth file not found at {YTM_AUTH_CONFIG_PATH}. Run the authentication script to generate it. YTM features will be disabled.")
logging.warning(f"YTM auth file not found at {YTM_AUTH_CONFIG_PATH}. Run the authentication script to generate it. YTM features may be limited or disabled.")
def connect_client(self, timeout=10):
if not self.ytm_token:
logging.warning("No YTM token loaded. Cannot connect to Socket.IO. Run authentication script.")
logging.warning("No YTM token loaded. Cannot connect to YTM Socket.IO. Run authentication script.")
self.is_connected = False
return False
@@ -155,7 +129,7 @@ class YTMClient:
logging.debug("YTM client already connected.")
return True
logging.info(f"Attempting to connect to YTM Socket.IO server: {self.base_url} on namespace /api/v1/realtime")
logging.info(f"Attempting to connect to YTM Socket.IO server: {self.base_url}")
auth_payload = {"token": self.ytm_token}
try:
@@ -172,7 +146,7 @@ class YTMClient:
logging.warning(f"YTM Socket.IO connection event not received within {event_wait_timeout}s (connect timeout was {timeout}s).")
self.is_connected = False
return False
logging.info(f"YTM Socket.IO connection successful: {self.is_connected}")
# Connection success/failure is logged by connect/connect_error events
return self.is_connected
except socketio.exceptions.ConnectionError as e:
logging.error(f"YTM Socket.IO connection error: {e}")