music-assistant-server.git
29 hours agoAdd MLB provider dev
Kit Rhett Aultman [Wed, 8 Apr 2026 16:54:04 +0000 (12:54 -0400)]
Add MLB provider

Audio games from MLB.tv.  Yes, please.

6 weeks agoNotify UI when DLNA player has gone offline to mark it unavailable. (#3251)
Marvin Schenkel [Thu, 26 Feb 2026 15:54:41 +0000 (16:54 +0100)]
Notify UI when DLNA player has gone offline to mark it unavailable. (#3251)

6 weeks agoFix sendspin metadata sending wrong progress when paused (#3250)
Paulus Schoutsen [Thu, 26 Feb 2026 15:30:41 +0000 (10:30 -0500)]
Fix sendspin metadata sending wrong progress when paused (#3250)

* Fix sendspin metadata sending wrong progress when paused

Two issues caused the progress bar in sendspin clients to show wildly
incorrect values (e.g. 795:54 / 04:23) after reconnecting to a paused
stream:

1. playback_speed was hardcoded to 1000 (normal) and never set to 0
   when paused, so the server kept advancing progress.

2. Used PlayerMedia.corrected_elapsed_time which always interpolates
   elapsed time regardless of playback state (adding hours of wall-
   clock time while paused).  Switched to Player.corrected_elapsed_time
   which only interpolates during PLAYING.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(sendspin): preserve metadata progress when paused

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Maxim Raznatovski <nda.mr43@gmail.com>
6 weeks agoTry using .github/copilot-instructions.md.
Marvin Schenkel [Thu, 26 Feb 2026 11:56:11 +0000 (12:56 +0100)]
Try using .github/copilot-instructions.md.

6 weeks agoTry with inline content.
Marvin Schenkel [Thu, 26 Feb 2026 11:22:00 +0000 (12:22 +0100)]
Try with inline content.

6 weeks agoAdd Github Copilot instruction for PR reviews
Marvin Schenkel [Thu, 26 Feb 2026 11:03:53 +0000 (12:03 +0100)]
Add Github Copilot instruction for PR reviews

6 weeks agoAdd review-pr skill with reusable review standards.
Marvin Schenkel [Thu, 26 Feb 2026 11:01:05 +0000 (12:01 +0100)]
Add review-pr skill with reusable review standards.

6 weeks agoForce bufsize=0 on subprocess
Marcel van der Veldt [Thu, 26 Feb 2026 09:43:04 +0000 (10:43 +0100)]
Force bufsize=0 on subprocess

Which should already be the default, but just in case

6 weeks agoUpdate to `aiosendspin` 4.2.0 and fix a couple of issues (#3249)
Maxim Raznatovski [Thu, 26 Feb 2026 09:32:50 +0000 (10:32 +0100)]
Update to `aiosendspin` 4.2.0 and fix a couple of issues (#3249)

6 weeks agoFix state of syncgroup player
Marcel van der Veldt [Thu, 26 Feb 2026 09:30:24 +0000 (10:30 +0100)]
Fix state of syncgroup player

6 weeks agoFix power control on play
Marcel van der Veldt [Thu, 26 Feb 2026 09:27:34 +0000 (10:27 +0100)]
Fix power control on play

6 weeks agoFix Qobuz provider using HTTP instead of HTTPS for all API calls (#3246)
David Bishop [Thu, 26 Feb 2026 08:04:03 +0000 (00:04 -0800)]
Fix Qobuz provider using HTTP instead of HTTPS for all API calls (#3246)

- Switch both _get_data and _post_data URLs from http:// to https://
- Remove ssl=False on POST requests that was disabling TLS verification

Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
6 weeks agoAdd manual mediaitem linking to genre (#3248)
Jozef Kruszynski [Thu, 26 Feb 2026 08:02:18 +0000 (09:02 +0100)]
Add manual mediaitem linking to genre (#3248)

feat(genres): manual mediaitem linking to genre

6 weeks agoSet audio format on Bandcamp track ProviderMapping (#3213)
David Bishop [Thu, 26 Feb 2026 07:58:26 +0000 (23:58 -0800)]
Set audio format on Bandcamp track ProviderMapping (#3213)

* Set audio format and fetch fresh streaming URLs for Bandcamp

Extract _fetch_api_track from get_track so get_stream_details can
bypass the 30-day cache and always retrieve a fresh streaming URL.
Set AudioFormat (content_type, bit_rate) on both StreamDetails and
ProviderMapping instead of stashing the URL in metadata.links.

Also: guard split_id against malformed IDs, handle
BandcampMustBeLoggedInError explicitly, and fix album_from_api
for albums with no release_date.

Tests cover _fetch_api_track paths, streaming URL priority/format
selection, library async generators, split_id validation, and
error mapping.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Bandcamp provider for unauthenticated use

- Remove early return in search() that required identity token;
  the Bandcamp search API works without authentication.
- Handle non-integer media IDs in genre lookup gracefully; provider-
  only items (e.g. Bandcamp compound IDs) can't have genre mappings
  so return an empty list instead of crashing with ValueError.
- Update comment to reflect that unauthenticated mode supports both
  search and streaming, not just search.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------

Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
6 weeks ago⬆️ Update music-assistant-frontend to 2.17.99 (#3245)
music-assistant-machine [Thu, 26 Feb 2026 02:33:52 +0000 (03:33 +0100)]
⬆️ Update music-assistant-frontend to 2.17.99 (#3245)

Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
6 weeks agoFix really strange bug with airplay
Marcel van der Veldt [Thu, 26 Feb 2026 01:21:59 +0000 (02:21 +0100)]
Fix really strange bug with airplay

6 weeks agoSmall tweak to sonos regarding the airplay grouping bug
Marcel van der Veldt [Wed, 25 Feb 2026 22:04:34 +0000 (23:04 +0100)]
Small tweak to sonos regarding the airplay grouping bug

6 weeks agoPrefer active output protocol first when grouping members
Marcel van der Veldt [Wed, 25 Feb 2026 21:43:44 +0000 (22:43 +0100)]
Prefer active output protocol first when grouping members

6 weeks agoAdd handle_play_action to stop as well
Marcel van der Veldt [Wed, 25 Feb 2026 21:43:14 +0000 (22:43 +0100)]
Add handle_play_action to stop as well

6 weeks agoAdd members filter to syncgroup
Marcel van der Veldt [Wed, 25 Feb 2026 21:30:36 +0000 (22:30 +0100)]
Add members filter to syncgroup

6 weeks agoSort list of players to sync with in syncgroup player config
Marcel van der Veldt [Wed, 25 Feb 2026 21:08:01 +0000 (22:08 +0100)]
Sort list of players to sync with in syncgroup player config

6 weeks agoFix: prevent static members from unjoining a syncgroup
Marcel van der Veldt [Wed, 25 Feb 2026 21:05:50 +0000 (22:05 +0100)]
Fix: prevent static members from unjoining a syncgroup

6 weeks agoFix error in snapcast control script
Marcel van der Veldt [Wed, 25 Feb 2026 20:42:44 +0000 (21:42 +0100)]
Fix error in snapcast control script

6 weeks agofix(genres): remove genres from playlog during restore (#3244)
Jozef Kruszynski [Wed, 25 Feb 2026 20:01:21 +0000 (21:01 +0100)]
fix(genres): remove genres from playlog during restore (#3244)

6 weeks agoAdd generic short code authentication system (#3078)
apophisnow [Wed, 25 Feb 2026 17:57:51 +0000 (09:57 -0800)]
Add generic short code authentication system (#3078)

* feat: add generic short code authentication system

Add a reusable short code authentication system that any provider can use
for QR code login, device pairing, or similar flows.

Changes:
- Add join_codes database table (schema v6)
- Add generate_join_code(user_id, provider_name, ...) method
- Add exchange_join_code() to convert codes to JWT tokens
- Add auth/code public API endpoint
- Add revoke_join_codes() for cleanup
- Update login.html to handle ?join= parameter
- Add provider_name parameter to JWT token encoding

Providers can implement short code auth flows like:

    code, expires = await auth.generate_join_code(
        user_id=my_user.user_id,
        provider_name="my_provider",
        expires_in_hours=24,
    )

The provider_name is stored in the join code and passed to the JWT token,
allowing providers to identify their authenticated sessions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: Revise db migration

* test: add comprehensive tests for join code authentication

Add tests covering the short code authentication system:
- generate_join_code: basic functionality, invalid user handling
- exchange_join_code: success, case-insensitivity, expired codes,
  max_uses limits, unlimited uses, provider_name in JWT claims
- revoke_join_codes: per-user revocation, revoke all codes
- authenticate_with_join_code API: success and error cases

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Update music_assistant/controllers/webserver/auth.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/helpers/resources/login.html

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/controllers/webserver/auth.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/controllers/webserver/auth.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: Simplify join code schema

* chore: Update join code test

* fix: Fix revoke_join_codes() to use correct db count function

* fix: Simplify revoke_join_codes and add provider handling

* fix: Avoid useless rename

* fix: Handle rare collision edge case

* fix: Fix return type

* fix: Use named params

* fix: Rename prevents already defined error

* Add input validation to generate_join_code.

* Fix unhandled RunTimeError.

* Limit short codes to users with guest role only.

* Log security events.

* Rename endpoint and add endpoints to list and revoke codes.

* Make at least one parameter of revoke_join_codes required to prevent accidental deletion of all codes.

* Schedule cleanup of expired join codes once a day.

* Minor cleanup.

* Fixes for active source and current media with linked protocols

* Fix DSP not applying for AirPlay and Sendspin players (#3191)

* OpenSubsonic: Use server provided version tag if present (#3200)

* Fix use playerid for http profile

* ⬆️ Update music-assistant-frontend to 2.17.92 (#3203)

Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
* Expand PIN based auth in airplay 2 (#3165)

* add LG details

* Make pin based auth work in other devices

* remove reference to apple tv and macos in check

* remove unused constant and adjust airplay2 filter

* also apply pairing check to raop

* add unit test

* Revert MIN_SCHEMA_VERSION to maintain HA compatability.

* Add comments to schema version constants

* Fix some more issues with syncgroups

* Fix HEOS source switching back to Local Music after starting stream (#3206)

* Fix group mute for protocol-synced players (#3205)

* Handle HEAD requests on root route (#3204)

* Fix announcements typo

* Some small code quality changes to DLNA Provider

* Small simplification for GroupPlayer

* Fix Sonos S2 announcement 404 error on cloud queue context endpoint (#3208)

* Snapcast: Fixes for hard switching of group leaders (#3209)

* Gracefully skip files/folders with emoji names on SMB mounts (#3183)

* Add API to handle playback speed (#3198)

* Simplify can_group_with logic

* Airplay2-configurable-latency (#3210)

* Validate queue item ID in Sonos pause path (#3194)

* Add some additional guards to asyncprocess

* Add a bunch of extra error handling and logging for flow streams

* Properly cleanup stream buffers

* ⬆️ Update music-assistant-frontend to 2.17.93 (#3214)

Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
* Fix bluesound volume jumping back after volume_set.

* Speed-up core startup a bit

* More gracefully handle DLNA errors

* Lock set_members to avoid concurrent actions

* Fix issue with subprocess pips closing

* Fix ungroup command

* Add note in docstring

* Auto ungroup when trying to form syncgroup with already synced player

* Fix accessing player.state.synced_to

* Fix playback speed handling on queue item and not on queue

* Fix for _cleanup_player_memberships

* Fix race condition with enqueue_next_media on SyncGroup

* Fix some edge cases with AirPlay DACP commands

* Fix set_members with lock

* Fix player not available in HA at startup

* Fix fully_played should return boolean

* Auto translate commands directed at protocol player id to visible parent

* Some minor tweaks to handling prevent-playback of airplay

* Speedup core controller startup

* Pre-compile Python bytecode in Dockerimage for faster startup

* Speedup is_hass_supervisor check

* Fix _cleanup_player_memberships and _handle_set_members

* Fix player config not fully persisting

* ⬆️ Update music-assistant-frontend to 2.17.94 (#3218)

Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
* Bandcamp: validate login on init when credentials are configured (#3215)

Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix bluesound volume jumping back after volume_set.

* Use ImageType.THUMB for Bandcamp artwork images (#3212)

Bandcamp artwork is square, not landscape. All other music providers
in the codebase use THUMB for standard album and artist art.

Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Fix inverted track_number condition in Bandcamp converter (#3211)

The condition checked output.track_number instead of track.track_number,
meaning track numbers from the API were only applied when the output
already had a non-None default.

Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Clear internal HEOS queue before playing (#3219)

* Update Alexa player provider (#3167)

* Update Alexa player provider

* Remove redundant try catch

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Address PR comments

* Remove ActionUnavailble catches

* Remove extra catch alls and add _on_player_media_updated

* Remove catch all

* Bump AlexaPy

* Fix _upload_metadata when media is not available

---------

Co-authored-by: Sameer Alam <alams154@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Fix race condition in player register flow wrt config

* Fix select output protocol already in play_index to avoid race on flow mode

* Fail job on test failures

* Fix Radioparadise image URL (#3220)

The change to the documentation repo moved the images

* Fix flow mode determination

* Fix player tests

* Add genre icons and SVG handling to imageproxy (#3223)

* Add genre icons and SVG handling to imageproxy

* Cleanup

* ⬆️ Update music-assistant-frontend to 2.17.95 (#3222)

Co-authored-by: stvncode <25082266+stvncode@users.noreply.github.com>
Co-authored-by: Marvin Schenkel <marvinschenkel@gmail.com>
* Fix static members of sync group

* Fix last small issues with syncgroup

* Fix issue with clearing output protocol during track changes

* Use mass.call_later.

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Marvin Schenkel <marvinschenkel@gmail.com>
Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
Co-authored-by: Maxim Raznatovski <nda.mr43@gmail.com>
Co-authored-by: Eric Munson <eric@munsonfam.org>
Co-authored-by: music-assistant-machine <141749843+music-assistant-machine@users.noreply.github.com>
Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
Co-authored-by: hmonteiro <1819451+hmonteiro@users.noreply.github.com>
Co-authored-by: Tom Matheussen <13683094+Tommatheussen@users.noreply.github.com>
Co-authored-by: scyto <alex@alexbal.com>
Co-authored-by: David Bishop <teancom@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Mischa Siekmann <45062894+gnumpi@users.noreply.github.com>
Co-authored-by: OzGav <gavnosp@hotmail.com>
Co-authored-by: Andy Kelk <andy@andykelk.net>
Co-authored-by: Brad Keifer <15224368+bradkeifer@users.noreply.github.com>
Co-authored-by: Bob Butler <bob@robertjbutler.com>
Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Sameer Alam <31905246+alams154@users.noreply.github.com>
Co-authored-by: Sameer Alam <alams154@users.noreply.github.com>
Co-authored-by: stvncode <25082266+stvncode@users.noreply.github.com>
6 weeks ago⬆️ Update music-assistant-frontend to 2.17.98 (#3243)
music-assistant-machine [Wed, 25 Feb 2026 17:22:09 +0000 (18:22 +0100)]
⬆️ Update music-assistant-frontend to 2.17.98 (#3243)

Co-authored-by: MarvinSchenkel <17671719+MarvinSchenkel@users.noreply.github.com>
6 weeks agoAllow user-configured shairport-sync instances on the same host to be discovered...
Copilot [Wed, 25 Feb 2026 16:11:01 +0000 (17:11 +0100)]
Allow user-configured shairport-sync instances on the same host to be discovered as AirPlay players (#3221)

* Initial plan

* fix: only filter local ShairportSync instances matching MA's own AirPlay Receiver ports

Co-authored-by: MarvinSchenkel <17671719+MarvinSchenkel@users.noreply.github.com>
---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: MarvinSchenkel <17671719+MarvinSchenkel@users.noreply.github.com>
6 weeks agoFix PlayerQueue debounce logic for next/previous command
Marcel van der Veldt [Wed, 25 Feb 2026 13:58:36 +0000 (14:58 +0100)]
Fix PlayerQueue debounce logic for next/previous command

6 weeks agoRevert "Add debug logs to streamscontroller to debug smart fades sometimes skipping."
Marvin Schenkel [Wed, 25 Feb 2026 13:39:17 +0000 (14:39 +0100)]
Revert "Add debug logs to streamscontroller to debug smart fades sometimes skipping."

This reverts commit 09a80bd2e8657a95d557c3c470d98c08b9f7a966.

6 weeks agoFix smart fades sometimes skipping a fadeout abruptly.
Marvin Schenkel [Wed, 25 Feb 2026 13:36:44 +0000 (14:36 +0100)]
Fix smart fades sometimes skipping a fadeout abruptly.

6 weeks agoAdd play action in progress signal
Marcel van der Veldt [Wed, 25 Feb 2026 13:24:46 +0000 (14:24 +0100)]
Add play action in progress signal

To inform frontend that a play media action is processing

6 weeks agoFix: fire event if playerfeatures/controls updated
Marcel van der Veldt [Wed, 25 Feb 2026 12:34:40 +0000 (13:34 +0100)]
Fix: fire event if playerfeatures/controls updated

to ensure HA updates its supported features as well

6 weeks agoMerge branch 'dev' of https://github.com/music-assistant/server into dev
Marcel van der Veldt [Wed, 25 Feb 2026 11:53:27 +0000 (12:53 +0100)]
Merge branch 'dev' of https://github.com/music-assistant/server into dev

6 weeks agoWait for providers to load at startup
Marcel van der Veldt [Wed, 25 Feb 2026 11:53:17 +0000 (12:53 +0100)]
Wait for providers to load at startup

6 weeks agofeat(genres): add merge genres functionality (#3236)
Jozef Kruszynski [Wed, 25 Feb 2026 11:04:09 +0000 (12:04 +0100)]
feat(genres): add merge genres functionality (#3236)

* feat(genres): add merge genres functionality

* feat(genres): add empty genre filtering

* fix(genres): review comments

6 weeks agoFix language and genre mapping for Spotify podcasts and audiobooks (#3231)
OzGav [Wed, 25 Feb 2026 10:57:52 +0000 (20:57 +1000)]
Fix language and genre mapping for Spotify podcasts and audiobooks (#3231)

6 weeks agoAdd CoreState reporting to ServerInfo
Marcel van der Veldt [Wed, 25 Feb 2026 10:53:05 +0000 (11:53 +0100)]
Add CoreState reporting to ServerInfo

6 weeks agoAdd active_playlist to queue extra attributes
Marcel van der Veldt [Wed, 25 Feb 2026 10:25:08 +0000 (11:25 +0100)]
Add active_playlist to queue extra attributes

6 weeks ago⬆️ Update music-assistant-models to 1.1.102 (#3241)
music-assistant-machine [Wed, 25 Feb 2026 10:13:00 +0000 (11:13 +0100)]
⬆️ Update music-assistant-models to 1.1.102 (#3241)

Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
6 weeks ago⬆️ Update music-assistant-models to 1.1.100 (#3239)
music-assistant-machine [Wed, 25 Feb 2026 08:50:00 +0000 (09:50 +0100)]
⬆️ Update music-assistant-models to 1.1.100 (#3239)

* ⬆️ Update music-assistant-models to 1.1.100

* update test snapshots

---------

Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
6 weeks ago⬆️ Update music-assistant-frontend to 2.17.97 (#3238)
music-assistant-machine [Wed, 25 Feb 2026 03:48:19 +0000 (04:48 +0100)]
⬆️ Update music-assistant-frontend to 2.17.97 (#3238)

Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
6 weeks agoAdd readme to syncgroup provider
Marcel van der Veldt [Tue, 24 Feb 2026 22:31:33 +0000 (23:31 +0100)]
Add readme to syncgroup provider

6 weeks agoPrefer human readable protocol name in log
Marcel van der Veldt [Tue, 24 Feb 2026 22:31:17 +0000 (23:31 +0100)]
Prefer human readable protocol name in log

6 weeks agoFix double restart of playback when switching output protocol
Marcel van der Veldt [Tue, 24 Feb 2026 20:55:48 +0000 (21:55 +0100)]
Fix double restart of playback when switching output protocol

6 weeks agoFix access to actual (protocol)player from within get_queue_item_stream_with_smartfade
Marcel van der Veldt [Tue, 24 Feb 2026 18:44:22 +0000 (19:44 +0100)]
Fix access to actual (protocol)player from within get_queue_item_stream_with_smartfade

6 weeks agoFix: Resolve stream_url also for enqueue next media
Marcel van der Veldt [Tue, 24 Feb 2026 18:37:58 +0000 (19:37 +0100)]
Fix: Resolve stream_url also for enqueue next media

6 weeks agoFix for player power command recursive loop
Marcel van der Veldt [Tue, 24 Feb 2026 18:31:04 +0000 (19:31 +0100)]
Fix for player power command recursive loop

6 weeks agoFix various issues with protocol linking and syncgroups
Marcel van der Veldt [Tue, 24 Feb 2026 18:09:35 +0000 (19:09 +0100)]
Fix various issues with protocol linking and syncgroups

6 weeks agoMerge branch 'dev' of https://github.com/music-assistant/server into dev
Marvin Schenkel [Tue, 24 Feb 2026 14:13:17 +0000 (15:13 +0100)]
Merge branch 'dev' of https://github.com/music-assistant/server into dev

6 weeks agoSmart fades: Add debug logs to investigate sometimes skipping crossfades.
Marvin Schenkel [Tue, 24 Feb 2026 14:13:11 +0000 (15:13 +0100)]
Smart fades: Add debug logs to investigate sometimes skipping crossfades.

6 weeks agoAdd custom URL endpoint for listenbrainz scrobble (#3228)
relic664 [Tue, 24 Feb 2026 14:11:30 +0000 (09:11 -0500)]
Add custom URL endpoint for listenbrainz scrobble (#3228)

* add custom URL for listenbrainz scrobble

Bump  to 0.7.0 for custom URL specification, add the proper handling for a custom listenbrainz scrobble endpoint

* minor change

hide API base URL under advanced, streamline  constructo

6 weeks agoFix multi disc audiobook (#3182)
OzGav [Tue, 24 Feb 2026 10:11:17 +0000 (20:11 +1000)]
Fix multi disc audiobook (#3182)

6 weeks agoMerge branch 'dev' of https://github.com/music-assistant/server into dev
Marcel van der Veldt [Tue, 24 Feb 2026 09:16:43 +0000 (10:16 +0100)]
Merge branch 'dev' of https://github.com/music-assistant/server into dev

6 weeks agoUpdated Artwork handling on AriaCast Receiver (#3226)
Lorenzo Imbastari [Tue, 24 Feb 2026 08:25:31 +0000 (09:25 +0100)]
Updated Artwork handling on AriaCast Receiver (#3226)

* Add AriaCast Receiver plugin for Music Assistant

- Implemented AriaCast Receiver plugin to stream audio from Android devices to Music Assistant players.
- Added README.md with features, installation, configuration, and usage instructions.
- Created configuration classes for audio and server settings.
- Developed metadata handling for AriaCast streams.
- Implemented UDP discovery and WebSocket server for audio and metadata streaming.
- Added helper functions for local IP retrieval and artwork downloading.
- Included SVG icon for the plugin.
- Updated manifest.json with documentation link and requirements.

* Update README to simplify installation instructions

Removed installation instructions and updated configuration step for clarity.

* fixed mypy and pre-commit problems for my provider

* Delete music_assistant/providers/ariacast_receiver/README.md

* fixed pre-commit problems x2

* fixed icon

* Merge remote-tracking branch 'origin/dev' into dev

* Fixed Metadata and media controls after refactoring

* copilot notes addressing

* Addressing more copilot notes

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Addressing last notes

* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: address code review feedback for ariacast_receiver

* fix(ariacast): add playback ready event for audio/player sync

- Add _playback_ready event to coordinate audio handler and player stream
- Audio handler waits up to 2s for player to become ready after starting playback
- get_audio_stream signals ready when it starts consuming frames
- Clear ready state on cleanup in _clear_active_player and stream end

This reduces audio frame loss during player setup by synchronizing
the audio receiver with the player's readiness to consume frames.

* Add multi-platform AriaCast receiver binaries (darwin/linux amd64/arm64/arm)

* renamed receiver name

* no redownload if same artwork

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/manifest.json

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix: use shared http_session for ariacast websocket connection

* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix in previous copilot commit messing up the way pipe was read (no loop)

* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fixel last comments

* Change multi_instance setting to false

* Addressed latest comments after review

- Switched from pipe to stdout
- Dropped linux arm
- Moved _get_binary_path() to helpers.py

* Implemented stderr logging, robust WebSocket connection retries, improved artwork handling, and player switching control.

Updated Manifest

* Fix after PlayerController renamed all to all_players and players.get to get_player()

* Update music_assistant/providers/ariacast_receiver/__init__.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update music_assistant/providers/ariacast_receiver/__init__.py

Added suggested track change comments

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update documentation URL in manifest.json

* Added README for the binary of AriaCast Receiver

* updated receiver for artwork

* final fixes

* addressed copilot comment

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
6 weeks agoTreat narrators as a distinguishing field to prevent merging different recordings...
hayupadhyaya [Tue, 24 Feb 2026 08:17:11 +0000 (03:17 -0500)]
Treat narrators as a distinguishing field to prevent merging different recordings (#3230)

fix(audiobooks): treat narrators as a distinguishing field to prevent merging different recordings

Audiobooks with the same title and author but different narrators
(e.g. the same Harry Potter title read by Stephen Fry and Jim Dale)
were being merged into a single library item. This caused:
- Only one narrator to be retained in the merged item
- Chapter lists from all recordings to be concatenated, producing
  incorrect (doubled) chapter counts
- No way for clients to retrieve per-recording metadata via the API

Fix: in compare_audiobook(), add a narrator check before the author
comparison. When both items have narrators and no narrators are shared,
return False so they are treated as distinct recordings.

This change is safe for the single-narrator case: if either item has no
narrator metadata, the check is skipped and existing behaviour is
unchanged.

Co-authored-by: hayupadhyaya <hayupadhyaya@users.noreply.github.com>
6 weeks agoSubsonic: Reorder image metadata for artists (#3227)
Eric Munson [Tue, 24 Feb 2026 07:28:07 +0000 (02:28 -0500)]
Subsonic: Reorder image metadata for artists (#3227)

I am seeing a number of places where MA is asking the subsonic server
for images using the full URL to lastfm. Reorder the insertion of images
in these parsers to place the subsonic image first incase this
encourages MA to use that entry instead.

Signed-off-by: Eric B Munson <eric@munsonfam.org>
6 weeks agoYandex_music: Add FLAC lossless playback refactor, Lyrics support, Сurated collection...
Mikhail Nevskiy [Tue, 24 Feb 2026 07:26:15 +0000 (10:26 +0300)]
Yandex_music: Add FLAC lossless playback refactor, Lyrics support, Сurated collections, Extended recommendations etc (#3147)

* Yandex Music: Add configurable My Wave settings

Add 6 new configuration options for Yandex Music provider:
- My Wave maximum tracks (default: 150) - Control total number of tracks fetched
- My Wave batch count (default: 3) - Number of API calls for initial load
- Track details batch size (default: 50) - Batch size for track detail requests
- Discovery initial tracks (default: 5) - Initial display limit for Discover
- Browse initial tracks (default: 15) - Initial display limit for Browse
- Enable Discover (default: true) - Toggle recommendations on/off

Implemented duplicate protection for My Wave tracks using set-based tracking.
Recommendations now refresh every 60 seconds instead of 3 hours for fresher discoveries.

All new settings have sensible defaults that maintain current behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(yandex_music): add configurable base URL

Add Advanced setting for API base URL in Yandex Music provider,
allowing users to change the API endpoint if service updates their URL.

Changes:
- Add CONF_BASE_URL and DEFAULT_BASE_URL constants
- Add Advanced ConfigEntry for base_url in provider settings
- Update YandexMusicClient to accept base_url parameter
- Pass base_url from config to ClientAsync initialization

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(yandex_music): improve Liked Tracks with virtual playlist and sorting

This commit adds three major improvements to the Liked Tracks feature:

1. Reverse chronological sorting:
   - Liked tracks are now sorted by timestamp (most recent first)
   - Matches mobile app behavior for better UX
   - Applied automatically in get_liked_tracks() method

2. Browse folder visibility toggle:
   - Added CONF_ENABLE_LIKED_TRACKS_BROWSE config option
   - Allows hiding Liked Tracks folder from Browse section
   - Default: True (backward compatible)

3. Virtual playlist for Liked Tracks:
   - Added LIKED_TRACKS_PLAYLIST_ID virtual playlist
   - Appears in library playlists (similar to My Wave)
   - Supports full MA playlist features (radio, favorites, etc.)
   - Configurable via CONF_ENABLE_LIKED_TRACKS_PLAYLIST
   - Respects CONF_LIKED_TRACKS_MAX_TRACKS limit (default: 500)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(yandex_music): organize configuration settings with categories and advanced flags

Restructures the 16 Yandex Music provider configuration entries to improve UX:
- Groups My Wave settings (6 entries) in "my_wave" category
- Groups Liked Tracks settings (3 entries) in "liked_tracks" category
- Marks performance tuning settings as advanced (7 entries total)
- Maintains authentication/quality settings at top level

This reduces visible clutter from 16 to ~8 settings by default, with advanced
options hidden behind a toggle. No breaking changes - all config keys, defaults,
and functionality remain unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(yandex_music): Implement FLAC lossless playback with AES-256 decryption

This commit fully implements lossless FLAC playback for Yandex Music, fixing the
issue where only MP3 320kbps was available despite user having a premium subscription.

## Changes

### Quality Levels Restructure
- Replaced HIGH/LOSSLESS quality options with three-tier system matching reference implementation
- EFFICIENT (AAC ~64kbps) - Low quality, efficient bandwidth
- BALANCED (AAC ~192kbps) - Medium quality (new default)
- SUPERB (FLAC Lossless) - Highest quality
- Updated manifest.json and config entries to reflect new quality options

### API Authentication Fix
- Implemented manual HMAC-SHA256 sign calculation matching yandex-music-downloader-realflac
- Critical fix: Remove last character from base64-encoded sign ([:-1])
- Fixed HTTP 403 "not-allowed" errors from /get-file-info endpoint
- Uses DEFAULT_SIGN_KEY from yandex-music library

### FLAC Decryption Implementation
- Added _decrypt_track_url() method using AES-256 CTR mode
- Uses PyCrypto (pycryptodome) which supports 12-byte nonce for CTR mode
- Key is HEX-encoded (bytes.fromhex), not base64 as initially attempted
- Downloads encrypted stream, decrypts on-the-fly, saves to temp file
- Returns StreamDetails with StreamType.LOCAL_FILE pointing to decrypted temp file

### Streaming Logic Updates
- Enhanced get_stream_details() to handle encrypted URLs from encraw transport
- Detects needs_decryption flag in API response
- Falls back gracefully to MP3 if decryption fails
- Supports both encrypted and unencrypted FLAC URLs
- Updated _select_best_quality() to intelligently select based on three quality tiers

### Dependencies
- Added pycryptodome==3.21.0 to support AES CTR mode with 12-byte nonce
- Uses aiohttp for direct HTTP download of encrypted streams

### Testing
- All existing tests pass (7/7 in test_streaming.py)
- Type checking passes (mypy success)
- Code quality checks pass (ruff linter/formatter)

## Technical Details

The Yandex Music API returns encrypted URLs when using transports=encraw. The decryption
process matches the working reference implementation:

1. Calculate HMAC-SHA256 sign with all param values joined
2. Base64 encode and remove last character (critical!)
3. Request /get-file-info with quality=lossless, codecs=flac-mp4,flac,...
4. Download encrypted stream from returned URL
5. Decrypt using AES-256 CTR with 12-byte null nonce and HEX-decoded key
6. Save decrypted FLAC to temporary file
7. Return stream details pointing to temp file

## Tested

- Server starts successfully with Yandex Music provider loaded
- FLAC codec detected from API (codec=flac-mp4)
- Encryption detected and decryption executes (55MB encrypted → decrypted)
- StreamType.LOCAL_FILE allows playback from temp file
- Graceful fallback to MP3 if decryption fails

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(yandex_music): Implement on-the-fly streaming decryption for FLAC

Replace temp file approach with memory-based streaming decryption for better
performance and reduced disk I/O.

## Changes

### StreamType.CUSTOM Implementation
- Use AsyncGenerator[bytes, None] for streaming decryption
- No temporary files on disk - all processing in memory
- Store encrypted URL and key in StreamDetails.data

### Streaming Decryption Pipeline
- Download encrypted stream in 64KB chunks using aiohttp
- Decrypt incrementally with AES-256 CTR mode
- Counter auto-increments for each block (streaming-friendly)
- Yield decrypted chunks directly to audio pipeline

### Performance Improvements
- **First chunk:** 0.39s vs 5+ seconds with temp file approach
- **No disk I/O:** Streaming directly from memory
- **Lower latency:** Start playback while downloading/decrypting
- **Efficient:** 64KB chunks balance memory and throughput

### Implementation Details
- Added get_audio_stream() method to YandexMusicStreamingManager
- Cipher initialization with 12-byte null nonce (PyCrypto)
- ClientTimeout: connect=30s, sock_read=600s for stable streaming
- Proper error handling and logging throughout pipeline

### Technical Notes
AES CTR mode is ideal for streaming because:
- Each block can be encrypted/decrypted independently
- Counter increments automatically - no state management needed
- Supports arbitrary chunk sizes (not just 16-byte blocks)

## Tested
- All 7 unit tests pass
- Type checking passes (mypy)
- Code quality checks pass (ruff)
- Live streaming confirmed: codec=flac, streamtype=custom
- First audio chunk in <0.4s

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(deps): Update pycryptodome to 3.23.0 to resolve dependency conflict

pywidevine==1.9.0 requires pycryptodome>=3.23.0
Updated from 3.21.0 to 3.23.0 to satisfy both dependencies

* feat(yandex_music): add High quality level (MP3 320kbps)

Add new "High" quality level between Balanced and Superb:
- Efficient (AAC ~64kbps) - Low quality
- Balanced (AAC ~192kbps) - Medium quality
- High (MP3 ~320kbps) - High quality lossy (NEW)
- Superb (FLAC Lossless) - Highest quality

Implementation:
- Add QUALITY_HIGH constant in constants.py
- Add "High (MP3 ~320kbps)" option in config UI
- Update _select_best_quality() logic to prefer MP3 >=256kbps
- Fallback chain: high bitrate MP3 → any MP3 → highest non-FLAC

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(yandex_music): add configurable FLAC streaming modes

On low-power devices, encrypted FLAC streaming breaks after ~1 minute
because AES decryption can't keep up with download speed, causing the
server to drop the connection (ClientPayloadError).

Add 3 configurable streaming modes to decouple download from decryption:
- Direct: on-the-fly decrypt (original behavior, fast devices)
- Buffered: async queue with backpressure (recommended, default)
- Preload: full download then decrypt via SpooledTemporaryFile (slow devices)

Closes #29

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(yandex_music): auto-reconnect API client after network outage

_ensure_connected() now attempts reconnect when _client is None instead
of raising immediately. Added _call_with_retry() helper that wraps API
calls with one reconnect attempt on connection errors. Refactored all
API methods to use it, eliminating ad-hoc retry loops.

Fixes permanent provider death after temporary network outage where
_reconnect() failure set _client=None with no recovery path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(yandex_music): extend recommendations with feed, chart, releases, and playlists

Add 4 new recommendation sections beyond My Wave: Made for You (personalized
feed playlists), Chart (top tracks), New Releases (albums), and New Playlists
(editorial). Each section has its own config toggle under a "Discovery" category
and independent cache TTLs (30min for feed, 1h for chart/releases/playlists).

Closes #34

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(yandex_music): enable seek in Preload streaming mode for FLAC

- Preload mode now downloads and decrypts to temp file before playback
- Returns StreamType.LOCAL_FILE with can_seek=True for proper navigation
- Files exceeding size limit (config) fall back to Buffered mode
- Rename config 'Preload memory limit' to 'Preload max file size' with updated description
- Add temp file cleanup on stream completion and provider unload

Fixes: seek not working when using Superb quality + Preload mode
Fixes: progress bar starting before audio is ready
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(yandex_music): add Picks & Mixes browse and discovery sections

Browse:
- picks/ folder with mood, activity, era, genres subfolders
- mixes/ folder with seasonal collections (winter, summer, autumn, newyear)
- Each tag returns curated playlists from Yandex Music tags API

Discovery (home page):
- Top Picks: curated playlists (tag: top)
- Mood Mix: rotating mood playlists (chill, sad, romantic, party, relax)
- Activity Mix: rotating activity playlists (workout, focus, morning, evening, driving)
- Seasonal Mix: playlists based on current season

Configuration (new picks_mixes category):
- Enable Picks in Browse
- Enable Mixes in Browse
- Enable Top Picks on Home
- Enable Mood/Activity/Seasonal Mix on Home

Localization:
- All folder and tag names in Russian and English

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* feat(yandex_music): add lyrics support

- Add ProviderFeature.LYRICS to supported features
- Add get_track_lyrics() method to api_client.py
- Extend parse_track() to accept lyrics and lyrics_synced parameters
- Fetch lyrics in get_track() and attach to track metadata
- Support both synced LRC format and plain text lyrics
- Handle geo-restrictions and unavailable lyrics gracefully

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* fix(yandex_music): fix locale-dependent playlist names caching issue

- Split get_playlist() to separate virtual playlists (not cached) from real ones
- Virtual playlists (My Wave, Liked Tracks) now always use current locale
- Real playlists continue to be cached for 30 days
- Add debug logging for locale detection

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* fix(yandex_music): fix Browse Picks path construction

- Fix base path calculation in _browse_picks() and _browse_mixes()
- Previously: base was incorrectly trimming to parent path
- Now: base correctly appends to current path
- Add debug logging for troubleshooting

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
* fix(yandex_music): add missing get_track_lyrics mock to integration tests

The lyrics feature added in 4fc11fda introduced a get_track_lyrics call
in get_track, but the test fixtures were not updated with the mock,
causing ValueError on tuple unpacking.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address review comments: simplify Yandex Music provider configuration (#41)

* Initial plan

* Fix manifest.json URL and move pycryptodome to provider requirements

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Drastically reduce config entries and fix logging format

- Keep only 8 essential config entries: token, clear auth, quality, streaming mode, preload buffer, My Wave max tracks, Liked Tracks max tracks, and base URL
- Remove 20+ config entries and hardcode sane defaults
- Remove all category attributes from config entries
- Remove conditional recommendation check in setup()
- Replace all f-string logging with %s formatting (17 instances)
- Update constants.py to keep only necessary constants

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Address review feedback: fix parameter naming, temp file leak, and double close (#42)

* Initial plan

* Fix critical review issues: rename key_base64, fix double close, add temp file cleanup

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Fix linter issues: use cleanup_temp_file method and add noqa comment

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* [WIP] Fix file descriptor leak in Yandex Music provider (#44)

* Initial plan

* Fix streaming issues: FD leak, buffered fallback, size limits, task cleanup, stale files

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Fix provider issues: change INFO to DEBUG logs, fix track_map by ID

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Rename misnamed test to reflect QUALITY_BALANCED behavior

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Fix linting issues: move import to top, use Path.stat(), fix line lengths

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Fix Yandex Music AAC codec mapping and timezone awareness (#45)

* Initial plan

* Fix Yandex Music provider: AAC codec mapping, caching issues, and datetime timezone

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Restore @use_cache decorators for mood and activity mix recommendations to reduce API load

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Add test coverage for Yandex Music recommendation methods (#46)

* Initial plan

* Add comprehensive test coverage for Yandex Music recommendations

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Fix linting issues in test_recommendations.py

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Fix mypy type annotations in test_recommendations.py

Add return type annotations to async helper functions to resolve mypy errors:
- return_folder() -> RecommendationFolder (lines 783, 810)
- return_none() -> None (lines 813, 837)

Fixes CI mypy check failure.

* Initial plan

* Restore full test_recommendations.py file and add mypy return type annotations

Co-authored-by: trudenboy0 <261913410+trudenboy0@users.noreply.github.com>
* Increase Discovery initial tracks from 5 to 20

Show more tracks in the Discovery section on Home for better content visibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Yandex Music browse: "Invalid subpath" error and empty tag folders

When pressing Play on a Picks tag folder (e.g. "chill"), the BrowseFolder
URI reconstruction loses the full path (picks/mood/chill → just chill),
causing browse() to fall through to the base class which raises
"Invalid subpath". Add tag recognition fallback before the base class call.

Empty tag folders were caused by hardcoded tag slugs not matching actual
Yandex API slugs. Add dynamic tag discovery via the landing("mixes") API
which returns real MixLink entities with valid tag URLs. Results are cached
for 1 hour with hardcoded tags as fallback.

Fixes #34

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address PR review feedback: dead code, infinite loop, lyrics optimization

- Remove unreachable _stream_preload() from get_audio_stream() (preload
  handled in get_stream_details via LOCAL_FILE)
- Add aac-mp4/he-aac-mp4 codec variants to Efficient and Balanced
  quality selection for consistency with _get_content_type()
- Switch _get_content_length() to shared http_session; add comments
  explaining why streaming methods use dedicated sessions
- Fix My Wave infinite re-fetch when all batch tracks are duplicates
  by breaking on first_track_id_this_batch is None
- Simplify _get_discovered_tags() return type from dict to list
- Add get_track_lyrics_from_track() to eliminate duplicate API call
  when track object is already available
- Update test mocks for new lyrics method

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Picks & Mixes: use dynamic tag discovery, filter empty/useless tags

Replace hardcoded tag lists in browse with dynamically discovered tags
from Landing API. Only tags actually returned by the API are shown,
eliminating empty folders. Blacklist non-musical tags like
"albomy-s-videoshotami". Set is_playable=False on tag/category folders
to prevent loading thousands of tracks on Play. Reduce tag playlist
cache TTL from 1h to 10min for faster recovery.

Fixes #34

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Validate tags via API before showing in browse and recommendations

Replace blacklist-based filtering with runtime tag validation via
client.tags() to ensure only tags with actual playlists are displayed.
Adds new tags (top, newbies, in the mood, background) and filters out
editorial /post/ URLs from landing discovery.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix exception handling, docstring, and log noise in Yandex Music provider (#52)

* Initial plan

* Fix 3 Copilot review issues in Yandex Music provider

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Fix race conditions, dead code, caching bugs, and performance issues in Yandex Music provider

Critical fixes:
- Add asyncio.Lock to protect My Wave shared mutable state from concurrent access
- Fix cache key collision in get_track by normalizing composite IDs before caching
- Fix random.choice + @use_cache interaction: tag selection now happens outside cached methods
- Lower "No liked tracks found" from warning to debug (normal for new accounts)

Dead code cleanup:
- Remove unused _decrypt_track_url from api_client.py (and unused aiohttp/AES imports)
- Remove dead _get_content_type stub from parsers.py, inline ContentType.UNKNOWN

Performance:
- Parallelize tag validation with asyncio.gather + Semaphore(8) instead of sequential
- Reuse shared aiohttp session for streaming instead of creating one per request
- Reduce search cache from 14 days to 3 hours
- Remove excessive per-batch/per-ID debug logging in liked tracks and library playlists

Code quality:
- Extract _parse_my_wave_track helper to eliminate 3x duplicated parsing logic
- Fix LRC detection: use regex r'\[\d{2}:\d{2}' instead of startswith('[')
- Replace hardcoded spring→autumn fallback with dynamic _validate_tag check
- Fix _validate_tag docstring (client.tags → client.get_tag_playlists)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address PR review: retry for lossless API, restore search cache, add quality tests

- Wrap get_track_file_info_lossless in _call_with_retry for automatic
  reconnection on transient API failures (extracted _build_signed_params
  and _do_request helpers)
- Revert search cache from 3h back to 14 days (search results are stable)
- Add 8 unit tests for Efficient and High quality selection branches

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix Yandex Music provider review issues: regex, HMAC signing, temp file cleanup (#54)

* Initial plan

* Fix LRC regex, HMAC sign construction, and temp file cleanup order

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Fix linting issues in tests

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Fix spelling in test comments

Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: trudenboy <139659391+trudenboy@users.noreply.github.com>
* Address PR review comments: fix dict equality check and remove duplicate import

- Use == instead of is for dict comparison (BROWSE_NAMES_RU)
- Remove duplicate AsyncGenerator import from TYPE_CHECKING block

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix MinimalProvider stub missing client/mass attributes in test

The test_temp_file_replacement_order test was failing because
MinimalProvider lacked client and mass attributes expected by
YandexMusicStreamingManager.__init__.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix My Wave over-fetching and locale-aware tag caching

Address Copilot review comments on PR #3147:
- _browse_my_wave: cap fetch loop to BROWSE_INITIAL_TRACKS on initial browse
  instead of post-loop slicing, preventing tracks from being marked as "seen"
  but never shown to the user
- _get_discovered_tags: add locale parameter to cache key so tag titles are
  re-fetched when locale changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix flac-mp4 container handling: separate MP4 container from FLAC codec

Yandex API returns codec "flac-mp4" meaning FLAC audio inside an MP4
container. Previously _get_content_type mapped this to ContentType.FLAC,
causing ffmpeg to misidentify the container format. Now correctly returns
(ContentType.MP4, ContentType.FLAC) as container/codec pair, matching
how Apple Music handles MP4+AAC. Also fixes temp file extension for
preload mode (.mp4 instead of .flac).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Improve flac-mp4 downstream: update logs, temp prefix, and comments

Follow-up to b6b11a22 (flac-mp4 container fix). Replaces hardcoded
"FLAC" in log messages with the actual codec string so logs correctly
reflect flac-mp4 vs flac. Renames TEMP_FILE_PREFIX to "yandex_audio_"
since temp files may now be .mp4. Adds clarifying comment about
flac-mp4 in _select_best_quality.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Set correct sample_rate/bit_depth for Yandex Music AudioFormat

The Yandex API does not return sample rate or bit depth, so AudioFormat
used model defaults (44100/16) even for flac-mp4 streams that are
actually 48kHz/24bit. This caused unnecessary downsampling in
_select_pcm_format. Add codec-based defaults via _get_audio_params and
_build_audio_format helpers to set the correct values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add configurable stream buffer for buffered streaming mode

Increase default buffer from 2MB (32 chunks) to 8MB (128 chunks)
to reduce stuttering on slow/unstable connections (~45s of FLAC audio).
Add CONF_STREAM_BUFFER_MB config entry (1-32 MB, default 8) so users
can tune the buffer size for their network conditions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix unresolved Copilot review comments in PR #3147

- Add implementation to test_temp_file_replacement_order() verifying
  new path is stored before old file deletion to prevent leaks
- Remove misplaced MinimalProvider stub code from test_get_audio_params_none()
- Add "spring" to TAG_MIXES and TAG_SLUG_CATEGORY to align with TAG_SEASONAL_MAP

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix stale comments flagged by Copilot review #3818153899

- Correct base64 padding note: SHA-256 (32 bytes) encodes with "=" not "=="
- Remove hard-coded line number reference from LRC regex test comment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix naming consistency for spring and liked_tracks in BROWSE_NAMES

Add missing "spring" and "liked_tracks" entries to both BROWSE_NAMES_RU
and BROWSE_NAMES_EN dicts, and use LIKED_TRACKS_PLAYLIST_ID constant
instead of hardcoded "tracks" key in get_playlist().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix concurrency issues and harden config entries per Copilot review

- Add asyncio.Lock to _get_streaming_session to prevent session leak on races
- Add threading.Lock to _temp_files to prevent concurrent modification
- Extract _replace_temp_file helper for atomic temp file replacement
- Clarify AES CTR cipher safety in _prepare_cipher docstring
- Clarify HMAC timestamp regeneration in _build_signed_params docstring
- Add range constraints to My Wave and Liked Tracks max tracks config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix temp_fd double-close bug and clarify seasonal fallback comment

- Move temp_fd = -1 before os.fdopen() to prevent double-close when an
  exception occurs inside the with block (Copilot #2823816163)
- Clarify constants.py comment to reflect that fallback is dynamic and
  applies to any unavailable seasonal tag (Copilot #2823816236)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix FLAC seek in buffered/direct mode and improve My Wave reliability

- Enable ffmpeg seek (allow_seek=True) for encrypted CUSTOM streams so
  that seeking fast-forwards through the decrypted pipe instead of
  restarting from the beginning; can_seek stays False since the provider
  can't reposition the AES-CTR cipher mid-stream
- Batch multiple Rotor API calls per playlist-page request to reduce
  round-trips and ensure enough tracks are returned per pagination page
- Guard radioStarted feedback so the flag is only set on confirmed send
- Promote rotor feedback errors from debug to warning for visibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Increase max stream buffer size to 64 MB for buffered FLAC streaming

Raises the upper bound of the stream buffer config from 32 MB to 64 MB
to accommodate longer tracks on slow/weak hardware without dropping the
connection mid-stream.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Address Copilot review comments (round 3)

- Clarify stream buffer description to mention Preload fallback scenario
- Improve HMAC sign comment: state concatenation order and reference
  yandex-music-downloader-realflac as the source of the comma-strip rule
- Add inline comments to LRC regex tests documenting \d{2,3} lower/upper bounds

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Address Copilot review comments: unquote tag slugs, skip known folders, show buffer for preload

- URL-decode tag slugs from get_landing_tags() via urllib.parse.unquote
- Skip _get_discovered_tag_slugs() API call for known top-level browse folders
- Show CONF_STREAM_BUFFER_MB config for both Buffered and Preload modes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix issue #57 (owner name locale) and issue #56 (stream retry + buffered seek)

- Fix #57: normalize all known system owner name variants to locale-aware
  canonical form ("Yandex Music" / "Яндекс Музыка") so playlist filtering
  works regardless of API locale
- Fix #56 retry: resume encrypted streams on ClientPayloadError via HTTP
  Range + AES-CTR counter resume in both direct and buffered modes (3 retries)
- Fix #56 seek: enable can_seek=True for flac-mp4 tracks; new mp4_seek.py
  parses moov/stts/stsc/stco to find byte offset; _stream_buffered_seek
  serves patched moov prefix + Range-resumed mdat from seek position

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add .worktrees/ to .gitignore

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add backward-compat shim for advanced= vs category= in Yandex Music config

Replace 6 hardcoded advanced=True with **_ADVANCED that detects at runtime
whether models >=1.1.87 (advanced= field) or 1.1.86 (category= field) is
installed. This eliminates manual patching when backporting to stable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(yandex_music): remove preload streaming mode

Remove the Preload streaming mode which downloaded and cached entire
encrypted tracks to temp files on disk. This approach is incompatible
with a streaming service model and was flagged in upstream code review.

Direct and Buffered modes are sufficient: Direct decrypts on-the-fly
chunk-by-chunk, Buffered decouples download from consumption via a
bounded async queue.

Also removes the backward-compat _ADVANCED shim (replaced with
advanced=True directly) since upstream models >=1.1.87 supports it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(yandex_music): remove direct streaming mode, buffered only

Simplify FLAC streaming to a single buffered mode. The direct
on-the-fly mode adds complexity without meaningful benefit over
the buffered async-queue approach.

Removes CONF_STREAMING_MODE config entry entirely. The stream
buffer size (MB) remains as an Advanced setting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(yandex_music): fix FLAC seek by delegating to ffmpeg (-ss)

The _stream_buffered_seek approach was broken: it patched chunk offsets
in the moov atom but ffmpeg still tried to decode from sample 0 (time=0),
whose adjusted offsets pointed into the moov itself, producing empty output.

Fix: set can_seek=False, allow_seek=True for encrypted FLAC streams.
The provider always streams from position 0; ffmpeg uses -ss to seek.
Seeking now works correctly at the cost of streaming from the beginning,
which is acceptable and consistent with non-encrypted HTTP streams.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(yandex_music): include liked editorial playlists in library sync

Add get_liked_playlists() to api_client.py calling users_likes_playlists()
endpoint. Update get_library_playlists() to yield liked editorial playlists
alongside user-created ones, with deduplication via seen_ids. Fixes provider
filter showing only virtual playlists (closes #57).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* refactor(yandex_music): remove buffering/seeking infrastructure from streaming

Per maintainer feedback on PR #3147, remove all custom downloading,
buffering and seeking from the provider. Replace the ~430-line buffered
streaming implementation with a minimal on-the-fly AES-256-CTR decrypt
wrapper (~15 lines) that uses mass.http_session.

Changes:
- Remove _stream_buffered, _stream_buffered_seek, _fetch_and_decrypt_partial,
  _patch_stco, _prepare_cipher, _get_streaming_session, close()
- Delete mp4_seek.py (MP4 moov/stco parser, ~250 lines)
- Remove CONF_STREAM_BUFFER_MB config entry
- Use mass.http_session instead of custom aiohttp.ClientSession
- Seeking delegated to ffmpeg via can_seek=False / allow_seek=True

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.0 (#81)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.1 (#82)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.2 (#83)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.3 (#84)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.4 (#85)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.5 (#86)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.6 (#87)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.7 (#88)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.8 (#89)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.9 (#91)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.2.10 (#94)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix(yandex_music): address PR review comments

- provider.py: fix docstring for _get_valid_tags_for_category — tags are
  validated via _validate_tag() → client.get_tag_playlists(), not client.tags()
- .gitignore: remove .worktrees/ (not applicable to upstream repo)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.3.0 (#95)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.3.1 (#96)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.3.2 (#97)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.3.3 (#98)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.4.1 (#99)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.4.2 (#100)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.5.1 (#101)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.5.2 (#102)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.5.3 (#103)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.5.4 (#104)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(yandex_music): sync provider from ma-provider-yandex-music v2.5.5 (#105)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: trudenboy0 <trudenboy0@gmail.com>
Co-authored-by: trudenboy0 <261913410+trudenboy0@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
6 weeks ago⬆️ Update music-assistant-frontend to 2.17.96 (#3229)
music-assistant-machine [Tue, 24 Feb 2026 03:47:58 +0000 (04:47 +0100)]
⬆️ Update music-assistant-frontend to 2.17.96 (#3229)

Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
6 weeks agoFix issue with saving player config not sticking default values
Marcel van der Veldt [Mon, 23 Feb 2026 22:04:41 +0000 (23:04 +0100)]
Fix issue with saving player config not sticking default values

6 weeks agoFix issue with clearing output protocol during track changes
Marcel van der Veldt [Mon, 23 Feb 2026 20:37:31 +0000 (21:37 +0100)]
Fix issue with clearing output protocol during track changes

6 weeks agoFix last small issues with syncgroup
Marcel van der Veldt [Mon, 23 Feb 2026 20:21:41 +0000 (21:21 +0100)]
Fix last small issues with syncgroup

6 weeks agoFix static members of sync group
Marcel van der Veldt [Mon, 23 Feb 2026 19:26:27 +0000 (20:26 +0100)]
Fix static members of sync group

6 weeks ago⬆️ Update music-assistant-frontend to 2.17.95 (#3222)
music-assistant-machine [Mon, 23 Feb 2026 18:29:56 +0000 (19:29 +0100)]
⬆️ Update music-assistant-frontend to 2.17.95 (#3222)

Co-authored-by: stvncode <25082266+stvncode@users.noreply.github.com>
Co-authored-by: Marvin Schenkel <marvinschenkel@gmail.com>
6 weeks agoAdd genre icons and SVG handling to imageproxy (#3223)
Marvin Schenkel [Mon, 23 Feb 2026 18:10:13 +0000 (19:10 +0100)]
Add genre icons and SVG handling to imageproxy (#3223)

* Add genre icons and SVG handling to imageproxy

* Cleanup

6 weeks agoFix player tests
Marcel van der Veldt [Mon, 23 Feb 2026 16:37:45 +0000 (17:37 +0100)]
Fix player tests

6 weeks agoFix flow mode determination
Marcel van der Veldt [Mon, 23 Feb 2026 16:30:09 +0000 (17:30 +0100)]
Fix flow mode determination

6 weeks agoFix Radioparadise image URL (#3220)
OzGav [Mon, 23 Feb 2026 14:36:32 +0000 (00:36 +1000)]
Fix Radioparadise image URL (#3220)

The change to the documentation repo moved the images

6 weeks agoFail job on test failures
Marvin Schenkel [Mon, 23 Feb 2026 12:52:34 +0000 (13:52 +0100)]
Fail job on test failures

6 weeks agoFix select output protocol already in play_index to avoid race on flow mode
Marcel van der Veldt [Mon, 23 Feb 2026 11:49:06 +0000 (12:49 +0100)]
Fix select output protocol already in play_index to avoid race on flow mode

6 weeks agoFix race condition in player register flow wrt config
Marcel van der Veldt [Mon, 23 Feb 2026 11:42:19 +0000 (12:42 +0100)]
Fix race condition in player register flow wrt config

6 weeks agoUpdate Alexa player provider (#3167)
Sameer Alam [Mon, 23 Feb 2026 08:32:30 +0000 (02:32 -0600)]
Update Alexa player provider (#3167)

* Update Alexa player provider

* Remove redundant try catch

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Address PR comments

* Remove ActionUnavailble catches

* Remove extra catch alls and add _on_player_media_updated

* Remove catch all

* Bump AlexaPy

* Fix _upload_metadata when media is not available

---------

Co-authored-by: Sameer Alam <alams154@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
6 weeks agoClear internal HEOS queue before playing (#3219)
Tom Matheussen [Mon, 23 Feb 2026 08:28:09 +0000 (09:28 +0100)]
Clear internal HEOS queue before playing (#3219)

6 weeks agoFix inverted track_number condition in Bandcamp converter (#3211)
David Bishop [Mon, 23 Feb 2026 07:23:25 +0000 (23:23 -0800)]
Fix inverted track_number condition in Bandcamp converter (#3211)

The condition checked output.track_number instead of track.track_number,
meaning track numbers from the API were only applied when the output
already had a non-None default.

Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
6 weeks agoUse ImageType.THUMB for Bandcamp artwork images (#3212)
David Bishop [Mon, 23 Feb 2026 07:20:08 +0000 (23:20 -0800)]
Use ImageType.THUMB for Bandcamp artwork images (#3212)

Bandcamp artwork is square, not landscape. All other music providers
in the codebase use THUMB for standard album and artist art.

Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
6 weeks agoFix bluesound volume jumping back after volume_set.
Marvin Schenkel [Mon, 23 Feb 2026 07:18:53 +0000 (08:18 +0100)]
Fix bluesound volume jumping back after volume_set.

6 weeks agoBandcamp: validate login on init when credentials are configured (#3215)
David Bishop [Mon, 23 Feb 2026 07:12:34 +0000 (23:12 -0800)]
Bandcamp: validate login on init when credentials are configured (#3215)

Co-authored-by: David Bishop <git@gnuconsulting.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
6 weeks ago⬆️ Update music-assistant-frontend to 2.17.94 (#3218)
music-assistant-machine [Mon, 23 Feb 2026 03:52:43 +0000 (04:52 +0100)]
⬆️ Update music-assistant-frontend to 2.17.94 (#3218)

Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
6 weeks agoFix player config not fully persisting
Marcel van der Veldt [Mon, 23 Feb 2026 01:03:33 +0000 (02:03 +0100)]
Fix player config not fully persisting

6 weeks agoFix _cleanup_player_memberships and _handle_set_members
Marcel van der Veldt [Mon, 23 Feb 2026 00:51:19 +0000 (01:51 +0100)]
Fix _cleanup_player_memberships and _handle_set_members

6 weeks agoSpeedup is_hass_supervisor check
Marcel van der Veldt [Mon, 23 Feb 2026 00:36:33 +0000 (01:36 +0100)]
Speedup is_hass_supervisor check

6 weeks agoPre-compile Python bytecode in Dockerimage for faster startup
Marcel van der Veldt [Mon, 23 Feb 2026 00:36:13 +0000 (01:36 +0100)]
Pre-compile Python bytecode in Dockerimage for faster startup

6 weeks agoSpeedup core controller startup
Marcel van der Veldt [Mon, 23 Feb 2026 00:23:04 +0000 (01:23 +0100)]
Speedup core controller startup

6 weeks agoSome minor tweaks to handling prevent-playback of airplay
Marcel van der Veldt [Sun, 22 Feb 2026 23:56:07 +0000 (00:56 +0100)]
Some minor tweaks to handling prevent-playback of airplay

6 weeks agoAuto translate commands directed at protocol player id to visible parent
Marcel van der Veldt [Sun, 22 Feb 2026 23:10:43 +0000 (00:10 +0100)]
Auto translate commands directed at protocol player id to visible parent

6 weeks agoFix fully_played should return boolean
Marcel van der Veldt [Sun, 22 Feb 2026 20:18:34 +0000 (21:18 +0100)]
Fix fully_played should return boolean

6 weeks agoFix player not available in HA at startup
Marcel van der Veldt [Sun, 22 Feb 2026 19:43:27 +0000 (20:43 +0100)]
Fix player not available in HA at startup

6 weeks agoFix set_members with lock
Marcel van der Veldt [Sun, 22 Feb 2026 17:27:20 +0000 (18:27 +0100)]
Fix set_members with lock

6 weeks agoFix some edge cases with AirPlay DACP commands
Marcel van der Veldt [Sun, 22 Feb 2026 17:17:29 +0000 (18:17 +0100)]
Fix some edge cases with AirPlay DACP commands

6 weeks agoFix race condition with enqueue_next_media on SyncGroup
Marcel van der Veldt [Sun, 22 Feb 2026 17:16:44 +0000 (18:16 +0100)]
Fix race condition with enqueue_next_media on SyncGroup

6 weeks agoFix for _cleanup_player_memberships
Marcel van der Veldt [Sun, 22 Feb 2026 16:28:35 +0000 (17:28 +0100)]
Fix for _cleanup_player_memberships

6 weeks agoFix playback speed handling on queue item and not on queue
Marcel van der Veldt [Sun, 22 Feb 2026 15:06:49 +0000 (16:06 +0100)]
Fix playback speed handling on queue item and not on queue

6 weeks agoFix accessing player.state.synced_to
Marcel van der Veldt [Sun, 22 Feb 2026 14:30:51 +0000 (15:30 +0100)]
Fix accessing player.state.synced_to

6 weeks agoAuto ungroup when trying to form syncgroup with already synced player
Marcel van der Veldt [Sun, 22 Feb 2026 14:17:53 +0000 (15:17 +0100)]
Auto ungroup when trying to form syncgroup with already synced player

6 weeks agoAdd note in docstring
Marcel van der Veldt [Sun, 22 Feb 2026 14:09:30 +0000 (15:09 +0100)]
Add note in docstring

6 weeks agoFix ungroup command
Marcel van der Veldt [Sun, 22 Feb 2026 14:07:00 +0000 (15:07 +0100)]
Fix ungroup command

6 weeks agoFix issue with subprocess pips closing
Marcel van der Veldt [Sun, 22 Feb 2026 13:53:11 +0000 (14:53 +0100)]
Fix issue with subprocess pips closing

6 weeks agoLock set_members to avoid concurrent actions
Marcel van der Veldt [Sun, 22 Feb 2026 13:52:33 +0000 (14:52 +0100)]
Lock set_members to avoid concurrent actions

6 weeks agoMore gracefully handle DLNA errors
Marcel van der Veldt [Sun, 22 Feb 2026 13:44:14 +0000 (14:44 +0100)]
More gracefully handle DLNA errors

6 weeks agoSpeed-up core startup a bit
Marcel van der Veldt [Sun, 22 Feb 2026 13:35:10 +0000 (14:35 +0100)]
Speed-up core startup a bit

6 weeks agoFix bluesound volume jumping back after volume_set.
Marvin Schenkel [Sun, 22 Feb 2026 07:29:19 +0000 (08:29 +0100)]
Fix bluesound volume jumping back after volume_set.