MUSIC_SRC_TV,
)
+from music_assistant.models.player import PlayerSource
+
# Configuration Keys
CONF_NETWORK_SCAN = "network_scan"
CONF_HOUSEHOLD_ID = "household_id"
PlayerFeature.VOLUME_SET,
PlayerFeature.ENQUEUE,
PlayerFeature.GAPLESS_PLAYBACK,
+ PlayerFeature.SELECT_SOURCE,
)
# Source Mapping
}
LINEIN_SOURCES = (MUSIC_SRC_TV, MUSIC_SRC_LINE_IN)
+LINEIN_SOURCE_IDS = (SOURCE_TV, SOURCE_LINEIN)
+
+PLAYER_SOURCE_MAP = {
+ SOURCE_LINEIN: PlayerSource(
+ id=SOURCE_LINEIN,
+ name="Line-in",
+ passive=False,
+ can_play_pause=False,
+ can_next_previous=False,
+ can_seek=False,
+ ),
+ SOURCE_TV: PlayerSource(
+ id=SOURCE_TV,
+ name="TV",
+ passive=False,
+ can_play_pause=False,
+ can_next_previous=False,
+ can_seek=False,
+ ),
+ SOURCE_AIRPLAY: PlayerSource(
+ id=SOURCE_AIRPLAY,
+ name="AirPlay",
+ passive=True,
+ can_play_pause=True,
+ can_next_previous=True,
+ can_seek=True,
+ ),
+ SOURCE_SPOTIFY_CONNECT: PlayerSource(
+ id=SOURCE_SPOTIFY_CONNECT,
+ name="Spotify Connect",
+ passive=True,
+ can_play_pause=True,
+ can_next_previous=True,
+ can_seek=True,
+ ),
+}
# Playback State Mapping
PLAYBACK_STATE_MAP = {
from .constants import (
DURATION_SECONDS,
+ LINEIN_SOURCE_IDS,
LINEIN_SOURCES,
NEVER_TIME,
PLAYER_FEATURES,
+ PLAYER_SOURCE_MAP,
POSITION_SECONDS,
RESUB_COOLDOWN_SECONDS,
SONOS_STATE_TRANSITIONING,
self.player_id,
)
return
- await asyncio.to_thread(self.soco.stop)
+ if self._attr_active_source in LINEIN_SOURCE_IDS:
+ # Play an invalid URI to force stop line-in sources
+ with contextlib.suppress(SoCoException):
+ await asyncio.to_thread(self.soco.play_uri, "")
+ else:
+ await asyncio.to_thread(self.soco.stop)
self.mass.call_later(2, self.poll)
self.update_state()
uri = track_info["uri"]
audio_source = self.soco.music_source_from_uri(uri)
- if SOURCE_MAPPING.get(audio_source) and audio_source in LINEIN_SOURCES:
+ if (source_id := SOURCE_MAPPING.get(audio_source)) and audio_source in LINEIN_SOURCES:
self._attr_elapsed_time = None
self._attr_elapsed_time_last_updated = None
+ self._attr_active_source = source_id
+ self._attr_current_media = None
+ if source_id not in [x.id for x in self._attr_source_list]:
+ self._attr_source_list.append(PLAYER_SOURCE_MAP[source_id])
return
current_media = PlayerMedia(
image_url=track_info.get("album_art"),
)
self._attr_current_media = current_media
+ self._attr_active_source = None
self._update_media_position(track_info, force_update=update_position)
def _update_media_position(