New Features
- whats-new: Give Nearby devices its own page
- collections: Reorder saved songs in place
- onboarding: Ask for Nearby devices on Android 17
- linux: Add optional unsecured extension storage
- onboarding: Add a What's New tour for 5.3
- download: Add FLAC quality caps and Opus 160 kbps
- link: Add desktop device picker and file activity
- link: Tell the desktop which audio files embed a picture
- android: Serve cover files to media browsers read-only
- covers: Show stored network covers in cover widgets
- covers: Look up, adopt and refresh stored covers
- covers: Cap cover fetches and back off longer from missing covers
- covers: Add a durable store for network covers
- link: Show computer playback on the iOS 27 Lock Screen
- lyrics: Let synced lyrics run later or earlier than playback
- library: Suggest songs under albums, singles and playlists
- link: Manage desktop music files from mobile
- home: Keep Resume after dismissing the player
- lyrics: Romanize non-Latin lyrics with the AI translation
- link: One player at a time; the computer follows a phone
- player: Footer buttons as filled expressive pills
- settings: Regroup the settings list by purpose
- player: Compact player beside idle lyrics
- home: More kinds of mixes, and genre mixes that keep their genre
- home: Mixes built from the user's own songs
- player: Gapless playback
- search: Recognize songs playing nearby
- lyrics: Translate lyrics with an AI provider
- player: Show the cover full screen by default in Material
- lyrics: Let Mornye's lyrics blur strength be set
- link: Send or save the playing song from the player menu
- link: Send and save songs from desktop menus
- link: Run song transfers on the desktop
- link: Receive whole phone songs for transfers
- link: Transfers rows in Link settings and the player bar
- link: Transfers list with expandable transfers
- link: Keep the session up while songs transfer
- link: Send and save songs from phone screens
- link: Run phone song transfers in the background
- link: Share the song transfer protocol and store
- autoplay: Leave song analysis off until turned on
- lyrics: Raise sung words in Material word-timed lyrics
- settings: Show how well autoplay ranking learned
- autoplay: Learn how much each part of a score counts
- settings: Song analysis controls
- autoplay: Analyze how songs sound
- rust: Describe how songs sound from decoded windows
- autoplay: Learn which songs are played together
- autoplay: Explore artists with Thompson sampling
- autoplay: Learn from loves, playlists and replays; add ranking signals
- autoplay: Rank by the listening session and keep artists apart
- link: Follow the computer's playback and add phone options
- link: Show a paired phone's songs in the desktop's Library
- network: Serve network hosts that are not saved connections
- link: Send a phone's songs and their files to the desktop
- link: Build the list of a phone's songs for the desktop
- link: Describe a phone's songs for the desktop's Library
- android: Add Android TV remote navigation
- l10n: Merge Crowdin updates and enable Chinese and Vietnamese (#731) (#731)
- player: Immersive Material lyrics while idle
- playback: Exclusive output on Windows, macOS and Linux
- search: Show songs as covers in the wide grid view
- library: Browse the Library by folder
- network: Show lyrics for songs on a Subsonic server
- link: Serve song lyrics over the songLyrics extension
- link: Show the playing device on the Devices button
- playlists: Reorder tracks, create from folders, import files
- link: Start a phone-only song on the desktop while it uploads
- link: Drive the desktop queue, notification and uploads from the phone
- link: One player on the phone for both devices
- link: Play the phone's own songs on the desktop
- player: Browse and play the Library from Android Auto
- link: Mark Mornye Link as beta
- link: Add the phone settings page and player bar devices control
- link: Run the Mornye Link host on desktop
- link: Add the Devices sheet and desktop actions on phones
- link: Add phone features for a paired desktop
- link: Download original Subsonic files and decode song paths
- link: Keep the phone link and its sync alive with the app
- link: Add the phone client for desktop discovery and pairing
- link: Sync collections and history between phone and desktop
- link: Track collection and listening changes for sync
- link: Serve the desktop library over OpenSubsonic
- link: Add the HTTPS server core and desktop link methods
- link: Share the active client, router and catalog index providers
- link: Add the Mornye Link crate skeleton and shared protocol types
- player: Shuffle downloads and scanned songs from the Library
- search: Group sort and view tools as on Library pages
- desktop: Animate Material rail items like the playlist rows
- desktop: Expand the Material rail and list playlists in it
- player: Group Material shuffle and repeat and start-align the title
- player: Let the Now Playing menu hide the volume slider
- search: Keep the result rows by default and offer the grid as a view
- search: Show cover grids and shelves for search results on wide screens
- desktop: Let the song table keep the preview and cover saving
- desktop: Adjust volume by scrolling over its controls
- settings: Request local network access with the LAN toggle
- extensions: Allow a network permission for any domain
Bug Fixes
- setup: Accept existing all-files access on Android
- downloads: Preserve cross-provider recording identity
- downloads: Preserve artwork in playlist downloads
- network: Recognize WebDAV NAS addresses behind tunnels
- whats-new: Bring back the 5.2 rebrand tour's look
- whats-new: Match the tutorial on phones, use a dialog on desktop
- network: Handle WebDAV HTTP listing variants
- link: Exchange missing listening statistics covers
- link: Sync AI lyrics translations across devices
- link: Keep Android phones available in the background
- about: Restore Git commit in direct mobile builds
- link: Refresh paired device addresses after network changes
- downloads: Recover moved files after changing folders
- link: Preserve playback position during device handoff
- player: Keep Android PCM defaults apart from the Bluetooth format
- player: Read saved sessions longer than 512 KB in pieces
- ffmpeg: Register the plugin callbacks before Kotlin wraps them
- covers: Keep the index when it cannot be read in a worker
- covers: Never hand out a cover the byte budget deleted
- startup: Report a failed orientation setup once
- covers: Never take a 304 as the cover of a removed image
- network: Keep the desktop's newest Link songs first in latest
- player: Keep the listening flush timer until every write settles
- link: Tell a phone that missed the last catalog push
- network: Log on afresh for connection checks and refused reconnects
- desktop: Rebuild the macOS menu items on hot reload
- link: Export web cover copies as webCoverPath
- link: Rank web cover copies after every other cover
- link: Use a web cover copy only for songs without a picture
- link: Serve desktop web-only covers from a lasting Link folder
- replaygain: Recognize Opus gain tags consistently
- covers: Show a collection song's network cover only where it loads
- link: Keep a song's network cover when a peer's edit comes back
- covers: Keep the network cover reference of Loved and playlist songs
- link: Sync collection songs without network cover references
- downloads: Keep network cover references out of the download queue
- android: Close a cover descriptor on any failed check
- android: Show local covers in Android Auto's queue view
- android: Check cover names per folder and serve the opened file
- player: Look for the cover provider again after a failure
- player: Show local covers in Android Auto browse lists
- covers: Keep a Subsonic cover path while its image is unchanged
- covers: Show the window's cover on the Rewind first song and replay
- covers: Keep a song's recorded cover when its latest day has none
- link: Sync no loopback artwork from older statistics
- home: Show a network cover not stored yet in Continue listening
- player: Keep stored loopback covers out of the Android Auto browser
- covers: Keep temporary player covers out of Loved and recents
- covers: Read stored statistics covers as durable references
- covers: Keep a stored tag cover when a read has none
- covers: Keep desktop covers fresh and drop removed tag covers
- covers: Show a known tag cover and fetch changed covers on use
- player: Fetch network covers when an AutoMix starts a song
- network: Play folder covers by reference
- link: Show stored covers on mirrored playback
- player: Show stored network covers on every play
- library: Match cleared library covers by folder name
- covers: Name untimed embedded previews by their content
- library: Rescan local songs after clearing library covers
- covers: Keep embedded previews of untimed sources on disk
- library: Keep cover files that other stores still name
- library: Keep thumbnail paths across forced rescans
- covers: Key library thumbnails by 128-bit SHA-256
- link: Refresh playback and details after desktop file changes
- network: Keep SMB HEAD 416 framing and test rejected covers
- covers: Fetch awaited covers before background rechecks
- network: Release cover connections and keep the proxy's 416 framing
- link: Keep phone covers until the Library stops showing them
- link: Key extracted cover pictures by their audio file
- link: Fall back when a listed cover file is gone
- covers: Keep a missing local cover out of the error handler
- player: Share the iPhone home indicator inset with Playing on
- home: Keep sections in place while one comes or goes
- player: Shrink Material's empty Playing on row
- player: Keep the motion cover playing after rotating
- search: Keep Sort beside the filters on wide results
- library: Read Opus tags with large artwork
- downloads: Handle unsupported exclusive renames
- ffmpeg: Load large metadata from temporary files
- android: Resolve audio service lint warnings
- android: Guard media artwork against recycled bitmaps
- player: Hide internal playback UI in external mode
- player: Read deferred ReplayGain tags in audio info
- link: Run computer file actions like local ones
- link: Hold seek position until the playing device confirms
- player: Slim the Material volume slider
- metadata: Save animated artwork during re-enrichment
- deezer: Prefer playable releases for ISRC matches
- downloads: Hide temporary SAF audio from media scanners
- library: Stop scans when NAS connections are removed
- link: Recover discovery after network changes
- metadata: Export cover and lyrics for local library files
- downloads: Restart paused items after cancellation settles
- artist: List an artist's releases newest first
- library: Hide CUE sources after a complete split
- player: Stabilize timestamps and restored-session seeking
- metadata: Keep WAV INFO and ID3 tags in sync
- mornye: Show menu glass throughout its opening motion
- motion: Only a list's first reveal staggers in
- link: Resolve phone artwork on desktop and refresh late covers
- player: Controls stay put with or without Playing on
- link: Recover remote covers and retire cancelled playback errors
- desktop: Handle LRC sidecars and percent paths safely
- playback: Drain desktop audio before advancing tracks
- metadata: Review rows span their track card
- link: Send fewer songs ahead of the computer
- macos: Keep one instance for debug builds too
- player: Open a phone song from its resolved source
- link: Show covers for songs a phone sent to the computer
- link: Show paired devices as Mornye Link, not a plain server
- lyrics: Translate in song context, skip lyrics already in the target
- link: Send handed-off songs only a window ahead of the computer
- home: Run the Material desktop search field across the pane
- autoplay: Draw on network Library songs, a paired phone's included
- home: Run Material desktop Home across the whole pane
- link: Show a downloaded song's cover when a phone plays it
- link: Shrink the Mornye Playing on label to footnote size
- link: Give transfer groups the page-wide settings inset
- playback: Start a phone song on macOS while it still arrives
- settings: Run desktop settings across the pane like page cards
- link: Route Android volume keys to desktop player
- player: Give Material landscape lyrics more room
- autoplay: Save played-together sessions on pause and follow learning
- link: Sync playback modes and restore queue covers
- windows: Exclude x64 exception runtime from ARM64 bundles
- extensions: Preserve verification after challenge failures (#610) (#610)
- extensions: Return verification-required when challenge minting fails by @HDShinobi
- desktop: Hide the FFmpeg console on Windows (#727) (#727)
- desktop: Hide the console window when running FFmpeg on Windows by @barakunshetan-design
- windows: Bundle the Visual C++ runtime (#728) (#728)
- windows: Bundle the Visual C++ runtime next to mornye.exe by @barakunshetan-design
- player: Keep Material backdrop blurred in landscape
- ios: Respect verification browser preference
- link: Hide Continue on phone once the phone plays
- desktop: Hide window controls in fullscreen
- link: Send a phone's large embedded covers shrunk
- link: Keep full-size phone covers from the web, shrunk
- player: Show the restored song's cover from its file
- link: Fetch covers of downloaded phone songs on the desktop
- link: Keep a phone's song list until its Library changes
- l10n: Preserve duplicate warning count placeholders
- l10n: Validate Crowdin imports and enable Chinese and Vietnamese
- ui: Keep one scrollbar in desktop menu popups
- Improve playback responsiveness and resource lifecycles
- link: Keep the notification on the desktop's song in the background
- player: Play the song again when Android's media server dies
- library: Keep scanned songs unplayable while Local Library is off
- link: Advertise the desktop over IPv4 only
- link: Keep playback usable while the desktop is out of reach
- link: Keep the sent song in the player until the desktop reports
- link: Start the desktop on Play on from a paused phone
- link: Show desktop addresses as sent and group the phone's code
- link: Report the app version in Subsonic auth errors
- link: Close the desktop pairing dialog only once
- build: Name the macOS SDK for Rust C code built inside Xcode
- link: Let the server derive starred artist ids from names
- link: List OpenSubsonic extensions without credentials
- settings: Keep loading when retired credential cleanup fails
- player: Reshuffle each repeat-all pass in shuffle mode
- desktop: Open sidebar links without passing the Library root
- ui: Keep page titles clear of the back button
- library: Keep playlist songs visible in Songs and Singles
- downloads: Trust the audio bytes over a provider's FLAC label
- search: Leave room under result covers for the text line box
- stats: Credit collaborators individually in listening history
- android: Preserve audio routing during player initialization
- settings: Read the restore heading style inside the dialog
- desktop: Show a short profile label in the sidebar
- repo: Keep the store button beside the text when the title fits
- library: Keep current row text readable on cover fills
- player: Give the phone navigation bar the cover scheme
- android: Coalesce background work progress notifications
- android: Keep background playback resumable
- mornye: Tint album surfaces from the player's source colour
- lyrics: Recover download lyrics after provider failures
Performance
- player: Encode session songs here when no isolate starts
- player: Encode each queued song once for session writes
- ffmpeg: Load FFmpegKit on first use, off the main thread
- player: Send Windows SMTC status and timeline only when needed
- player: Reuse Now Playing artwork and skip unchanged republishes
- player: Bound the Android notification art cache
- player: Mask only the faded band of the full-screen cover
- covers: One batched cover cache from its first use
- covers: Add a cover index that saves in batches
- theme: Build the first frame with the system palette
- startup: Overlap the platform calls before runApp
- theme: Validate and hash custom fonts off the UI isolate
- network: End a search3 sync only on an empty song page
- network: Revalidate stale Subsonic covers with their ETag
- network: Sync a Mornye desktop through search3 song pages
- material: Settle the collection header blur
- ui: Add SettledBlur, a blur drawn from a cached image once settled
- library: Match collection history keys once per page data
- library: Skip history refreshes on resume that change nothing
- library: Skip snapshot builds for pages and failed builds
- library: Reuse the lookup index while the Library is unchanged
- library: Read the download shadow check from a TEMP snapshot
- player: Hold back Now Playing states on macOS too
- player: Load media session art from the app cover cache
- player: Send the phone media session only states it cannot advance
- player: Run the listening flush timer only while there is time to write
- player: Ask the engine only for positions the player uses
- player: Run the libmpv position timer only while playing
- link: Match unmapped history songs in batches
- link: Push the desktop catalog only when its songs changed
- network: Share SMB read sessions across listings and reads
- library: Keep the folder song table rows across rebuilds
- library: Keep the desktop Songs table rows across rebuilds
- library: Build the quality label patterns once
- app: Reuse the orientation fade curve
- app: Keep window metrics out of the app builder
- desktop: Send the macOS menu bar only when it changes
- player: Send the session queue only to Android, newest first
- conversion: Speed up FLAC encoding and reuse SAF sources
- preview: Resolve extension previews when they play
- shell: Read the keyboard inset without a dependency on back press
- shell: Stop rebuilding the shell on every keyboard frame
- library: Rebuild only the toolbar title when local collections flip it
- mornye: Resolve the cover colour when the mini player changes track
- material: Move the mini player wave on the 30 Hz decorative clock
- mornye: Stop the mini player marquee after two passes on liquid glass
- player: Hold decorative motion while the app draws no frames
- material: Cache the full-screen cover blur at quarter resolution
- player: Cap decorative playback motion at 30 Hz
- mornye: Skip the backdrop pass for the extension overview glass
- mornye: Fade full-bleed artwork without a shader mask
- mornye: Skip the backdrop read on plain-page glass
- pages: Rebuild only the toolbar title when it flips
- mornye: Stop glass settings groups sampling the flat page
- mornye: Draw settled lyric blurs from a cached image
- mornye: Decode the details sheet cover at thumbnail size
- library: Reuse the prepared page data across rebuilds
- mornye: Keep position ticks and lyric control fades local
- mornye: Share the bar read with resting side capsules
- mornye: Compose standalone glass lenses into one backdrop read
- mornye: Compute glass tint only for translucent surfaces
- desktop: Summarize downloads in one pass for the toolbar ring
- library: Skip the no-op rebuild after a scanned cover checks out
- desktop: Sort the song table once per input and scope row hover
- mornye: Shade the player from the cover source colour only
- palette: Read cover samples once and add a source colour path
- mornye: Remember Cupertino icon lookups
- navigation: Keep keyboard insets from hidden tabs
- material: Stop flat wavy progress indicators from ticking
- mornye: Reuse artist surface themes across page rebuilds
- mornye: Rebuild layout slivers only when their layout value changes
- startup: Overlap the SAF grant check with the install marker read
- history: Extend lookup indexes when a download is prepended
- mornye: Keep equal Mornye themes identical
- theme: Rebuild the app theme only for theme settings
Refactoring
- library: Keep the shadow check SQL in a leaf file
- app: Name the app content builder
- covers: Normalize statistics covers only where rows are read
- link: Keep the sync protocol free of the cover store
- link: Share the desktop cover reference
- network: Read network covers directly over the connection
- covers: Show screen covers through the shared helper
- covers: Read every stored cover form through one helper
- Import moved files directly and remove the re-export shims
- repo: Build the store category chips from a list
- Drop the unused LogBuffer.filter tag option
- Drop the always-true AnimatedSelectionCheckbox visible flag
- Fix MotionHeaderBanner to cover and top center
- Drop the unused AppChoiceChip visualDensity
- Drop AppTextField options every caller left at default
- Drop showAppBottomSheet flags no caller sets
- Make ClickableArtistName single-line with ellipsis
- Push plain material pages through pushPage
- pages: Drop the title flip rebuild opt-out from the header mixin
- library: Share the selection bar toggle in the library folder
- library: Build the album selection bars with LibraryTrackSelectionBar
- settings: Resolve the library dialogs' error fill in the dialog
- settings: Build the cache rows from one helper
- settings: Use the shared section slivers and confirm dialog
- settings: Move library and lyrics pages to shared sheets and dialogs
- dialogs: Resolve the error confirm color inside the dialog
- playback: Share the library queue playback path
- library: Derive unified item quality in one call
- metadata: Share one lyrics fetch body
- library: Move confirm dialogs to showAppConfirmDialog
- player: Make the metadata title always ellipsize
- Drop parameters every caller leaves at the default
- settings: Build the plain-page glass group from MornyeGlassPanel
- convert: Share the batch convert choice section
- search: Loop the collection result sections
- extensions: Share the feature row and priority link widgets
- mornye: Drop the MornyeGlass default constructor
- library: Share the collection selection bar toggle
- library: Share the album and playlist header action row
- settings: Move download, metadata and files pages to shared helpers
- settings: Share confirm dialog, choice sheet and section helpers
- download: Pass AppSettings to the output folder builders
- ffmpeg: Call the FFmpeg modules directly
- library: Build songs, singles and collection cells once
- library: Remove the unreachable Mornye page chip row
- library: Share the staged ingestion steps
- library: Share queue store sort terms, paging and counts
- player: Share the current queue index rule
- mornye: Drop unused filter chip glass options
- Use switch expressions in format and model mappers
- bridge: Share channel invoke helpers in PlatformBridge
- material: Share expressive press squish and disabled fill
- history: Share schema column, backfill and single-row helpers
- settings: Route setters through one commit helper
- settings: Reuse the shared library quality label normalizer
Documentation
- player: Point each position mirror at the code it copies
- library: Fold the collections JSON export comment
Styling
- settings: Keep the song.link regions as a const list
- test: Format two tests after the repository rename
Testing
- player: Make the position tick tests prove the change under load
- covers: Cross-check the document slot and steady the marker test
- playback: Expect the exclusive output wrapper on macOS
- link: Accept a reset when an idle WebSocket client is dropped
- search: Cover the wide result layouts and pin the phone rows
- settings: Keep a page test for the choice sheets
- settings: Pump the cache page and check its rows
- settings: Compare the migrated dialogs and sheets with the old ones
- player: Check the shared motion clock in now playing rows
- download: Pin relative output folders for a settings matrix
- mornye: Find lyric blur snapshots by render object type
- library: Cover incremental upsert and source replacement
- library: Pin the generated queue Library SQL
Dependencies
- deps: Update Flutter, native and Rust dependencies
Chores
- desktop: Remove beta release label
- link: Drop imports the Link actions now export
- Update AltStore source to v5.2.6 by @github-actions[bot]
- link: Drop an unused import from the sync protocol
- windows: Prepare verified SignPath release signing
- desktop: Build macOS FFmpeg with Opus 1.6.1 and NASM 3.02
- android: Update Gradle to 9.8.2 and android-junit5 to 2.0.2
- flutter: Update packages and refresh the iOS pod lock
- rust: Update toolchain, Tokio, scraper and lockfile dependencies
- Bump version to 5.3.0 (166)
- Remove unused searchProviders and a write-only track index
- library: Drop the unread playlist id from the folder track tile
- screens: Drop write-only private widget data fields
- services: Drop write-only result and config fields
- services: Remove unused service members and write-only fields
- providers: Remove unused provider members
- Remove unused widget and utility members
- Remove unread extension manifest model fields
- download: Remove test-only DownloadQueueNotifier.updateProgress
- ffmpeg: Remove unused FFmpegProbe.isLosslessAudioCodec
- lyrics: Move the active lyric reference into its test
- library: Remove the test-only collections map export
- backup: Remove test-only legacy envelope helpers
- motion: Remove the test-only withMotionArtworkProxy wrapper
- library: Remove test-only single-item collection mutators
- history: Remove the unused streaming history restore
- library: Remove unused collection JSON factories
- library: Remove unused loadPlaylistTracks
- Remove unused library database write wrappers
- palette: Skip the unused sample copy and document the builder
- mornye: Remove the glass warmup re-export
- Remove unused history lookups and restore wrapper
Merge
- Integrate reviewed Windows and extension fixes
- Integrate validated Crowdin translations with local changes
New Contributors
- @barakunshetan-design made their first contribution
- @HDShinobi made their first contribution
Full Changelog: v5.2.6...v5.3.0
Downloads
Android
- arm64:
Mornye-v5.3.0-arm64.apk(recommended for modern devices) - arm32:
Mornye-v5.3.0-arm32.apk(older devices) *.apk.idsig: V4 signatures foradb install --incrementalonly; normal installs do not need them
iOS
- iOS:
Mornye-v5.3.0-ios-unsigned.ipa(sideload required)
SHA256SUMS.txt lists the SHA-256 of every file above.
Installation
Android: Enable "Install from unknown sources" and install the APK
iOS: Use AltStore, Sideloadly, or similar tools to sideload the IPA