Skip to content

Commit

Permalink
Various fixes and code cleanup to the streaming logic (#1216)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelveldt authored Apr 10, 2024
1 parent 55fad8a commit c836c25
Show file tree
Hide file tree
Showing 23 changed files with 379 additions and 367 deletions.
13 changes: 13 additions & 0 deletions music_assistant/common/helpers/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ def try_parse_bool(possible_bool: Any) -> str:
return possible_bool in ["true", "True", "1", "on", "ON", 1]


def try_parse_duration(duration_str: str) -> float:
"""Try to parse a duration in seconds from a duration (HH:MM:SS) string."""
milliseconds = float("0." + duration_str.split(".")[-1]) if "." in duration_str else 0.0
duration_parts = duration_str.split(".")[0].split(",")[0].split(":")
if len(duration_parts) == 3:
seconds = sum(x * int(t) for x, t in zip([3600, 60, 1], duration_parts, strict=False))
elif len(duration_parts) == 2:
seconds = sum(x * int(t) for x, t in zip([60, 1], duration_parts, strict=False))
else:
seconds = int(duration_parts[0])
return seconds + milliseconds


def create_sort_name(input_str: str) -> str:
"""Create sort name/title from string."""
input_str = input_str.lower().strip()
Expand Down
3 changes: 1 addition & 2 deletions music_assistant/common/models/streamdetails.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class LoudnessMeasurement(DataClassDictMixin):
true_peak: float
lra: float
threshold: float
target_offset: float | None = None


@dataclass(kw_only=True)
Expand Down Expand Up @@ -50,8 +51,6 @@ class StreamDetails(DataClassDictMixin):
# can_seek: bool to indicate that the providers 'get_audio_stream' supports seeking of the item
can_seek: bool = True

# stream_type:

# the fields below will be set/controlled by the streamcontroller
seek_position: int = 0
fade_in: bool = False
Expand Down
2 changes: 1 addition & 1 deletion music_assistant/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

API_SCHEMA_VERSION: Final[int] = 24
MIN_SCHEMA_VERSION: Final[int] = 24
DB_SCHEMA_VERSION: Final[int] = 28
DB_SCHEMA_VERSION: Final[int] = 29

MASS_LOGGER_NAME: Final[str] = "music_assistant"

Expand Down
1 change: 1 addition & 0 deletions music_assistant/server/controllers/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ async def auto_cleanup(self) -> None:
if db_row["expires"] < cur_timestamp:
await self.delete(db_row["key"])
cleaned_records += 1
await asyncio.sleep(0) # yield to eventloop
if cleaned_records > 50:
self.logger.debug("Compacting database...")
await self.database.vacuum()
Expand Down
1 change: 1 addition & 0 deletions music_assistant/server/controllers/media/artists.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ async def add_item_to_library(
# overhead of grabbing the musicbrainz id upfront
library_item = await self.update_item_in_library(db_item.item_id, item)
break
await asyncio.sleep(0) # yield to eventloop
if not library_item:
# actually add (or update) the item in the library db
# use the lock to prevent a race condition of the same item being added twice
Expand Down
10 changes: 3 additions & 7 deletions music_assistant/server/controllers/media/playlists.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@
ProviderUnavailableError,
UnsupportedFeaturedException,
)
from music_assistant.common.models.media_items import (
ItemMapping,
Playlist,
PlaylistTrack,
Track,
)
from music_assistant.common.models.media_items import ItemMapping, Playlist, PlaylistTrack, Track
from music_assistant.constants import DB_TABLE_PLAYLISTS
from music_assistant.server.helpers.compare import compare_strings

Expand Down Expand Up @@ -93,7 +88,7 @@ async def add_item_to_library(self, item: Playlist, metadata_lookup: bool = True
library_item = await self._add_library_item(item)
# preload playlist tracks listing (do not load them in the db)
async for _ in self.tracks(item.item_id, item.provider):
pass
await asyncio.sleep(0) # yield to eventloop
# metadata lookup we need to do after adding it to the db
if metadata_lookup:
await self.mass.metadata.get_playlist_metadata(library_item)
Expand Down Expand Up @@ -228,6 +223,7 @@ async def add_playlist_track(self, db_playlist_id: str | int, track_uri: str) ->
if i.provider_instance == playlist_prov.provider_instance
}
)
await asyncio.sleep(0) # yield to eventloop
# check for duplicates
for track_prov in track.provider_mappings:
if (
Expand Down
1 change: 1 addition & 0 deletions music_assistant/server/controllers/media/tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ async def add_item_to_library(self, item: Track, metadata_lookup: bool = True) -
# existing item found: update it
library_item = await self.update_item_in_library(db_item.item_id, item)
break
await asyncio.sleep(0) # yield to eventloop
if not library_item:
# actually add a new item in the library db
# use the lock to prevent a race condition of the same item being added twice
Expand Down
1 change: 1 addition & 0 deletions music_assistant/server/controllers/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ async def get_playlist_metadata(self, playlist: Playlist) -> None:
if genre not in playlist_genres:
playlist_genres[genre] = 0
playlist_genres[genre] += 1
await asyncio.sleep(0) # yield to eventloop

playlist_genres_filtered = {
genre for genre, count in playlist_genres.items() if count > 5
Expand Down
4 changes: 3 additions & 1 deletion music_assistant/server/controllers/music.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ async def set_track_loudness(
"true_peak": loudness.true_peak,
"lra": loudness.lra,
"threshold": loudness.threshold,
"target_offset": loudness.target_offset,
},
allow_replace=True,
)
Expand Down Expand Up @@ -659,7 +660,7 @@ async def _setup_database(self) -> None:
await asyncio.to_thread(shutil.copyfile, db_path, db_path_backup)

# handle db migration from previous schema to this one
if prev_version == 27:
if prev_version in (27, 28):
self.logger.info(
"Performing database migration from %s to %s",
prev_version,
Expand Down Expand Up @@ -727,6 +728,7 @@ async def __create_database_tables(self) -> None:
true_peak REAL,
lra REAL,
threshold REAL,
target_offset REAL,
UNIQUE(item_id, provider));"""
)
await self.database.execute(
Expand Down
2 changes: 2 additions & 0 deletions music_assistant/server/controllers/player_queues.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import asyncio
import random
import time
from collections.abc import AsyncGenerator
Expand Down Expand Up @@ -325,6 +326,7 @@ async def play_media(
elif media_item.media_type == MediaType.PLAYLIST:
async for playlist_track in ctrl.tracks(media_item.item_id, media_item.provider):
tracks.append(playlist_track)
await asyncio.sleep(0) # yield to eventloop
await self.mass.music.mark_item_played(
media_item.media_type, media_item.item_id, media_item.provider
)
Expand Down
Loading

0 comments on commit c836c25

Please sign in to comment.