Skip to content

Apple Music radio stations and improved URL import support#3392

Open
dmoo500 wants to merge 4 commits intomusic-assistant:devfrom
dmoo500:feature/apple-music-radio-and-url-import
Open

Apple Music radio stations and improved URL import support#3392
dmoo500 wants to merge 4 commits intomusic-assistant:devfrom
dmoo500:feature/apple-music-radio-and-url-import

Conversation

@dmoo500
Copy link

@dmoo500 dmoo500 commented Mar 14, 2026

Summary

This PR adds Apple Music Artist Radio station playback support and improves how Apple Music share URLs are handled throughout Music Assistant.

Note: This feature was developed by @dmoo500 with the assistance of GitHub Copilot (AI). The author is not deeply familiar with all parts of the codebase — please review thoroughly before merging.


What's new

Apple Music Artist Radio stations via "Add URL"

Apple Music share URLs for (Artist Radio) stations can now be added using the "Add URL" dialog:

  • Example: https://music.apple.com/de/station/dead-sara-essentials/ra.331701075

Track-based Artist Radio stations (e.g. "Dead Sara und ähnliche Künstler:innen", ra.xxxxxxxxx)

  • Individual tracks fetched via me/stations/next-tracks/{id} API
  • Auto-plays next track when current track ends (~5s gap)
  • Skip button fetches a fresh track from the station
  • Currently playing artist and track title shown on the player

Improved Apple Music share URL routing

All Apple Music share URL types now resolve to the correct provider and media type:

URL type Example
Station …/station/…/ra.xxx
Playlist …/playlist/…/pl.xxx
Album …/album/…/12345
Artist …/artist/…/12345
Song …/song/…/12345

Previously only station URLs were handled; playlist/album/artist/song URLs fell through to the builtin provider and failed with ffprobe errors.

When a URL resolves to a different media type than the calling controller, it is now automatically delegated to the correct controller.


Known limitations

Live broadcast stations do not work

Apple Music live broadcast stations (Apple Music 1, Apple Music Country, third-party stations like Radio Bob, etc.) cannot be streamed. All attempts via the webPlayback endpoint return error 3077 (MZCommerce.ItemNotFoundForFuse). The me/stations/next-tracks endpoint also returns an empty list for those stations.

The Apple Music app likely uses internal mechanisms to stream live stations that are not accessible through the public API. There is currently no known workaround. For those stations, using an alternative source (e.g. Radio Browser provider, or the station's own direct stream URL) is recommended.

No automatic library sync for radio stations

LIBRARY_RADIOS / get_library_radios() is not implemented. Radio stations must be added manually via "Add URL". An earlier attempt at auto-syncing Apple Music stations was unreliable and has been dropped from this PR.


Files changed

  • music_assistant/providers/apple_music/__init__.py — Main provider: radio stream logic, URL handling, metadata helpers
  • music_assistant/helpers/uri.py — Apple Music URL parsing for all share URL types
  • music_assistant/controllers/media/base.py — URL routing to correct controller; human-readable name from URL slug
  • music_assistant/controllers/player_queues.py — Continuous playback, skip button, and artist/title display for track-based radio

Copilot AI review requested due to automatic review settings March 14, 2026 11:29
@dmoo500
Copy link
Author

dmoo500 commented Mar 14, 2026

Could a maintainer please add the labels new-feature and enhancement? Thanks!

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Apple Music Artist Radio station playback plus broader Apple Music share-URL parsing/routing so “Add URL” resolves to the correct provider/media type, and updates queue behavior to better support continuous (track-based) radio playback.

Changes:

  • Apple Music provider: add get_radio, implement live-radio vs track-based station streaming fallback, and improve behavior when Widevine CDM files are missing.
  • URI parsing + routing: recognize Apple Music share URLs in parse_uri, and let media controllers resolve/delegate URL-based IDs to the correct controller.
  • Player queue handling: treat MediaType.RADIO as a continuous source for next/skip/end-of-queue behavior and surface per-track metadata via StreamMetadata.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
music_assistant/providers/apple_music/__init__.py Adds radio station retrieval and streaming logic (live HLS + track-based fallback) and handles missing Widevine CDM files.
music_assistant/helpers/uri.py Extends parse_uri to map Apple Music share URLs to MA media types/provider.
music_assistant/controllers/media/base.py Resolves URL-based item_id inputs via parse_uri, delegates to the correct controller when media type differs, and derives a fallback name from URL slug.
music_assistant/controllers/player_queues.py Enables “skip” behavior and continuous playback for radio items and applies StreamMetadata to the player’s displayed artist/title.

You can also share your feedback on Copilot code review. Take the survey.

@OzGav OzGav added this to the 2.9.0 milestone Mar 14, 2026
@MarvinSchenkel
Copy link
Contributor

MarvinSchenkel commented Mar 16, 2026

I'm sorry but we cannot accept this PR. This PR contains a lot of changes to code outside of the Apple Music provider. This should not be required when adding functionality to a music provider, unless there is a very good reason to do so. Changes should be isolated to files inside the apple music provider.

Please re-evaluate your code and get rid of changes to files outside of the Apple music provider unless you think it is absolutely necessary. Marking this PR as draft, please click 'ready for review' again when you want us to have another look.

@MarvinSchenkel MarvinSchenkel marked this pull request as draft March 16, 2026 09:33
@dmoo500
Copy link
Author

dmoo500 commented Mar 16, 2026

Thank you for the feedback. I've reviewed all external changes and reduced them to the absolute minimum needed.

Current diff outside the Apple Music provider:

helpers/uri.py (+23 lines)

Adding Apple Music URL parsing here follows the established pattern — Spotify, Tidal and Qobuz share URLs are all handled in this same file. It is not possible to place this inside the provider itself, as parse_uri has no access to a provider instance.

controllers/media/base.py (+4 lines)

This is the minimal controller-layer change required. The music/radios/get_radio API endpoint calls base.get(item_id, provider) directly, and the frontend passes the full share URL as item_id. Without this 4-line hook, the URL cannot be resolved to apple_music and falls through to the builtin provider, which tries to ffprobe the Apple Music URL and fails with InvalidDataError.

controllers/player_queues.py (+48 lines)

These changes are intentionally provider-agnostic — they improve radio playback for any provider that uses track-based stations (continuous playback when a track ends, skip button support, stream_metadata display for artist/title). Moving this logic into the Apple Music provider is not possible because providers have no access to the queue controller.

tests/core/test_helpers.py (+51 lines)

Unit tests for the uri.py changes. They belong here alongside the existing test_uri_parsing tests.

I'm happy to discuss further if you'd like a different approach for any of these.

@dmoo500 dmoo500 marked this pull request as ready for review March 16, 2026 12:09
Copilot AI review requested due to automatic review settings March 16, 2026 12:09
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the Apple Music provider to support playback of Apple Music “Artist Radio” / station share URLs via “Add URL”, and improves URL parsing/routing so Apple Music share links resolve to the correct provider/media type instead of falling back to builtin.

Changes:

  • Added Apple Music share-URL parsing (station/playlist/album/artist/song) and unit tests for these variants.
  • Implemented Apple Music radio station streaming with a track-based fallback (next-tracks) and surfaced now-playing artist/title via stream metadata.
  • Updated queue behavior to allow continuous playback/skip behavior for MediaType.RADIO items and added URL-resolution support in the media base controller.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/core/test_helpers.py Adds unit coverage for Apple Music share URL parsing.
music_assistant/helpers/uri.py Parses Apple Music share URLs into (media_type, provider, item_id) tuples.
music_assistant/providers/apple_music/init.py Adds radio station item lookup and streaming logic, including track-based “next track” fallback.
music_assistant/controllers/media/base.py Attempts to resolve share URLs passed as item_id before fetching provider/library items.
music_assistant/controllers/player_queues.py Adjusts skip/end-of-queue handling and UI metadata for track-based radio playback.

You can also share your feedback on Copilot code review. Take the survey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants