Skip to content

Add native FeiNiu Music provider - #6416

Open
neqq3 wants to merge 9 commits into
music-assistant:devfrom
neqq3:feat/feiniu-music
Open

neqq3 wants to merge 9 commits into
music-assistant:devfrom
neqq3:feat/feiniu-music

Conversation

@neqq3

@neqq3 neqq3 commented Sep 20, 2026 •

Copy link
Copy Markdown

What does this implement/fix?

Adds an experimental, read-only provider for FeiNiu Music, the personal music-library service for fnOS.

This allows users to browse and play their FeiNiu-managed music library directly in Music Assistant, without deploying a separate protocol bridge. The provider connects to the music service over HTTP(S) using a regular music account and password; it does not require NAS administrator access.

Supported features

  • Library synchronization and browsing for tracks, albums, artists and playlists.
  • Search, artwork, and plain-text or line-synchronized lyrics.
  • Track playback and multiple provider instances with separate music accounts.

Provider authentication and caches are isolated per instance. Track metadata is checked against the account-specific access status returned by FeiNiu, while album, artist and playlist lookups rely on the service's native account filtering. Artwork requests are validated against the accessible owner item before the image is fetched, and server-side playback refusals are respected. The integration is read-only, with no playlist or metadata write operations.

No MA core changes or additional runtime dependencies are included.

Related issue (if applicable): None.

Types of changes

  • Bugfix (non-breaking change which fixes an issue) — bugfix
  • New feature (non-breaking change which adds functionality) — new-feature
  • Enhancement to an existing feature — enhancement
  • New music/player/metadata/plugin provider — new-provider
  • Breaking change (fix or feature that would cause existing functionality to not work as expected) — breaking-change
  • Refactor (no behaviour change) — refactor
  • Documentation only — documentation
  • Maintenance / chore — maintenance
  • CI / workflow change — ci
  • Dependencies bump — dependencies

Checklist

  • The code change is tested and works locally.
  • pre-commit run --all-files passes.
  • pytest passes, and tests have been added/updated under tests/ where applicable.
  • For changes to shared models, the companion PR in music-assistant/models is linked.
  • For changes affecting the UI, the companion PR in music-assistant/frontend is linked.
  • I have read and complied with the project's AI Policy for any AI-assisted contributions.
  • I have raised a PR against the documentation repository targeting the main or beta branch as appropriate.

Testing

The provider tests pass on a clean checkout without requiring live FeiNiu credentials or service access. In addition, the upstream GitHub Actions test workflow for this PR completed successfully.

Live integration testing used FeiNiu Music 1.0.1 (0.8.41) with three accounts, including a restricted-library account. Testing covered synchronization, account scoping, artwork, FLAC/MP3/OGG samples, and a 150-entry playlist.

Player-state checks covered pause/resume, seeking, completion of two full tracks, and automatic advance. Playback was assessed through player state and progress, without a listening check for that run.

Limitations

  • This is an unofficial integration marked experimental. Only the music-service version above has been tested; large libraries, cross-process concurrent logins and long-term natural session expiry remain unverified.
  • FN ID, NAS OAuth, CUE split-track playback and arbitrary reverse-proxy path prefixes are not supported.
  • Changing the server URL or username requires removing the source and adding it again. Password updates for the existing account are supported.
  • Metadata and artwork already cached by MA or its clients may remain after permission changes or source removal; immediate removal of previously delivered data is not guaranteed.

@musicassistant-bot

musicassistant-bot Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
Contributor

✅ The title and description are good to go. Thanks!

@OzGav OzGav left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the new provider! Looks pretty good already. A few things below and also we need icons in colour and monochrome SVG

Comment thread music_assistant/providers/feiniu_music/client.py Outdated
Comment thread music_assistant/providers/feiniu_music/provider.py Outdated
Comment thread music_assistant/providers/feiniu_music/provider.py Outdated
Comment thread music_assistant/providers/feiniu_music/provider.py
Comment thread music_assistant/providers/feiniu_music/provider.py Outdated
Comment thread music_assistant/providers/feiniu_music/provider.py Outdated
@neqq3

neqq3 commented Sep 21, 2026

Copy link
Copy Markdown
Author

Thanks for the detailed review — it was very helpful.

I’ve pushed the requested changes:

the FeiNiu client errors now inherit directly from the corresponding Music Assistant error types, and the provider-side conversion layer has been removed;
search pagination is explicitly closed on early exit;
the development-era bare artwork ID compatibility path has been removed;
the duplicate audio preflight request has been removed;
account-visible membership is now separated from per-item metadata, so normal per-item detail expiry no longer causes a full library scan before every track;
colour and monochrome SVG provider icons have been added.

I’ve left native seeking unchanged for now, pending verification of the real service’s Range behaviour.

One detail I’d like your opinion on is the membership refresh policy. The current implementation keeps the account-visible membership set for 15 minutes, and a normal full library sync also refreshes it. Once that membership cache itself expires, the next lookup still performs a full list refresh before continuing.

This avoids scanning the library before every track, but can still cause an occasional blocking refresh after expiry. Would that be acceptable for the initial provider, or would you prefer membership refresh to be driven by sync/background work so playback never waits on a full refresh?

@OzGav

OzGav commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Please comment on each conversation with your resolution and resolve it.

Comment thread music_assistant/providers/feiniu_music/provider.py

@OzGav OzGav left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is looking good. Just one thing to think about after your rework.

This branch has not been deployed

No deployments
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.

2 participants