queue = self._queues[queue_id]
queue.radio_source = []
queue.stream_finished = None
+ queue.end_of_track_reached = None
if queue.state != PlayerState.IDLE:
self.mass.create_task(self.stop(queue_id))
queue.current_index = None
"""
if queue := self.get(queue_id):
queue.stream_finished = None
+ queue.end_of_track_reached = None
# forward the actual stop command to the player provider
if player_provider := self.mass.players.get_player_provider(queue_id):
await player_provider.cmd_stop(queue_id)
next_index = self._get_next_index(queue_id, index, allow_repeat=False)
queue.flow_mode = player_needs_flow_mode and next_index is not None
queue.stream_finished = False
+ queue.end_of_track_reached = False
# get streamdetails - do this here to catch unavailable items early
queue_item.streamdetails = await get_stream_details(
self.mass, queue_item, seek_position=seek_position, fade_in=fade_in
# return early if nothing changed
if len(changed_keys) == 0:
return
+ # check if we've reached the end of (the current) track
+ if (
+ queue.current_item
+ and (duration := queue.current_item.duration)
+ and (duration - queue.elapsed_time) < 10
+ ):
+ queue.end_of_track_reached = True
+ elif prev_state["current_index"] != new_state["current_index"]:
+ queue.end_of_track_reached = False
+
# handle enqueuing of next item to play
if not queue.flow_mode or queue.stream_finished:
self._check_enqueue_next(player, queue, prev_state, new_state)
# we wait for the player to stop after it reaches the end of the track
if (
(not queue.flow_mode or queue.repeat_mode == RepeatMode.ALL)
+ # we have a couple of guards here to prevent the player starting
+ # playback again when its stopped outside of MA's control
and queue.stream_finished
+ and queue.end_of_track_reached
and queue.state == PlayerState.IDLE
):
queue.stream_finished = None
if TYPE_CHECKING:
from collections.abc import AsyncGenerator
- from hass_client.models import CompressedState, EntityStateEvent
+ from hass_client.models import CompressedState
from hass_client.models import Device as HassDevice
from hass_client.models import Entity as HassEntity
+ from hass_client.models import EntityStateEvent
from hass_client.models import State as HassState
from music_assistant.common.models.config_entries import ProviderConfig
CONF_ENFORCE_MP3 = "enforce_mp3"
+CONF_ENTRY_ENFORCE_MP3_DEFAULT_ENABLED = ConfigEntry.from_dict(
+ {**CONF_ENTRY_ENFORCE_MP3.to_dict(), "default_value": True}
+)
+
PLAYER_CONFIG_ENTRIES = (
CONF_ENTRY_CROSSFADE_FLOW_MODE_REQUIRED,
CONF_ENTRY_CROSSFADE_DURATION,
"media_content_id": media.uri,
"media_content_type": "music",
"enqueue": "replace",
+ "extra": {
+ "metadata": {
+ "title": media.title,
+ "artist": media.artist,
+ "metadataType": 3,
+ "album": media.album,
+ "albumName": media.album,
+ "duration": media.duration,
+ "images": [{"url": media.image_url}] if media.image_url else None,
+ "imageUrl": media.image_url,
+ }
+ },
},
target={"entity_id": player_id},
)
entity_id
for entity_id, entity in entity_registry.items()
if entity["platform"] == entity_registry_entry["platform"]
+ and state["entity_id"].startswith("media_player")
and entity_id != state["entity_id"]
]
hass_device = device_registry.get(entity_registry_entry["device_id"])