mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
attempt to simplify ytm_client
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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}")
|
||||
|
||||
Reference in New Issue
Block a user