This patch release bumps the version to 0.3.61 and introduces several key improvements across the stack. The backend `/info` route registration is deferred until after UPnP initialization to ensure the local server ID is correctly exposed. A new `GET /{id}/search` endpoint has been added to the pmosource API for querying music catalogs. On the frontend, Web Share Target support is enabled via Vite configuration and a dedicated composable that handles incoming URL parameters, playback state, and error notifications. Renderer selection state is also now exposed for UI synchronization.
Update PMOMusic/Cargo.toml and version.txt from 0.3.59 to 0.3.60. Add explicit application/manifest+json detection for .webmanifest files in serve_embed.rs to compensate for mime_guess limitations, converting the MIME value to an owned String and updating the CONTENT_TYPE header reference accordingly.
Integrate vite-plugin-pwa to enable service worker generation, offline caching, and standalone display mode. Configure manifest metadata, 192px/512px icons, theme color, and iOS status bar styling. Bump project version to 0.3.59 across Cargo.toml, Cargo.lock, and version.txt, and regenerate package-lock.json.
Updates Cargo.toml, Cargo.lock, and version.txt from 0.3.53 to 0.3.56. Resolves divergent branch changes across configuration files and preserves the macOS .DS_Store binary structure during integration.
Update PMOMusic crate version in Cargo.toml and the project version.txt from 0.3.53 to 0.3.54. Add Serena project configuration by introducing .serena/.gitignore to exclude local cache files, and create .serena/project.yml to set Rust as the language server target with UTF-8 encoding.
Update PMOMusic crate version in Cargo.toml and the project version.txt from 0.3.53 to 0.3.54. Add Serena project configuration by introducing .serena/.gitignore to exclude local cache files, and create .serena/project.yml to set Rust as the language server target with UTF-8 encoding.
Update UrlSource::new() to accept a base_url parameter for relative path resolution. Extend the Qobuz router with Playlist and Artist variants to fetch metadata and construct DIDL containers. Introduce an in-memory PlaylistStore cache, refactor search() and browse() to route and cache dynamic playlist items, and add helper utilities for deterministic ID generation.
Introduce an async `get_container` method across source implementations to fetch lightweight container metadata efficiently. Add the `futures` crate as a dependency to enable concurrent operations. Refactor the `browse` flow to short-circuit ephemeral IDs and delegate metadata resolution to `get_container`. Update the RadioFrance handler to scrape episode pages in parallel, bypassing limited RSS feeds and improving overall browsing performance.
Uses `get_source_from_registry` to browse target sources and extract real metadata (title, artist, cover, track count). Updates fallback logic to set `parent_id` to `source_id` instead of `"url"`, ensuring consistent frontend routing and accurate UI rendering.
Introduces the pmourlsource crate as a standard MusicSource that resolves HTTP/HTTPS URLs via a priority-ordered UrlHandler registry. Includes specialized handlers for Qobuz and Radio France alongside an SSRF-safe generic scraper supporting playlists, feeds, and HTML audio. Integrates with existing browse flows, REST endpoints, and Android Web Share targets while updating source capability flags to correctly route URL queries.
Make `handleClearSearch` async and reset navigation to the root container. Explicitly clear the search input across menu clear, server switch, and disconnect transitions to ensure consistent UI synchronization and prevent stale queries. Also bump the project version from 0.3.52 to 0.3.53 in Cargo.toml and version.txt.
Refactor search handling across the frontend and backend to use a unified reactive state and dynamic container ID generation. The frontend now leverages a centralized `useMediaServers` composable for search queries and results, while the backend computes container IDs dynamically from source entries instead of using hardcoded values. Bumps version to 0.3.52.
Replaces raw string queries with structured `SearchQuery` types across the `MusicSource` trait and UPnP handlers. Adds dedicated paginated endpoints, explicit caching, and type-specific filtering for the Qobuz source. Fixes a frontend navigation bug by aligning state management with UPnP browse semantics and properly routing virtual container IDs. Also updates the Makefile for dynamic `RUST_LOG` configuration, standardizes logging with `tracing`, and adds the dependency lockfile.
Append sections 7–9 to the architecture roadmap detailing implementation steps for API robustness (request signing, audio metadata, stream restriction parsing, quality fallback, and rate-limit handling), multi-category search endpoints, and editorial discovery. Also update the priority tracking table to reflect these new tasks.
Parallelize Qobuz playlist track fetching by increasing the page size to 500 and processing remaining pages concurrently via `futures::try_join_all` with a configurable semaphore (default 3). Results are offset-sorted to preserve original order. Adds a `page_concurrency` configuration option, updates the API client initialization, and introduces the `futures` dependency. This reduces large playlist latency from ~1.6s to ~0.7s.
Replace the hardcoded semaphore capacity of 16 with a configurable `register_concurrency` setting (defaulting to 4). This mitigates SQLite write contention and optimizes concurrent API and network requests during parallel track caching.
Replaces sequential track requests with a chunked batch enrichment workflow using MD5-signed POST requests (50-ID windows). Introduces cache-first fetching, order preservation via HashMap lookups, and graceful fallbacks for playlist and favorite loading.
Refactor Qobuz bundle fetching to improve resilience and performance. Add HTTP timeout and retry configuration, and implement a retry loop that returns version metadata. Introduce bundle version caching and persistence to skip redundant extractions when the bundle remains unchanged. Replace console logging with structured tracing macros and update the architectural tracking document to mark these improvements as complete.
Introduce a `/tracks/:id/flac` endpoint and `open_cmaf_stream` client method to enable incremental decryption and caching of FLAC audio. Refactor segment decryption into a reusable helper and stream decrypted frames via a bounded tokio channel. Add `tokio-util` as an optional dependency, update the `pmoserver` feature, and implement conditional routing for local proxy versus direct API access. Update the architecture roadmap to document these improvements.
Introduces a new CMAF streaming module for Qobuz that handles progressive segment fetching and full-track decryption. The implementation adds HKDF session key derivation, AES-128-CBC key unwrapping, and AES-128-CTR frame decryption, alongside an ISO BMFF parser for extracting FLAC headers and segment metadata. It also integrates automatic session renewal with double-checked locking, a generic async retry mechanism for transient HTTP errors, and centralized error handling. Finally, it exposes `CmafStreamInfo` and async streaming methods in the public API, updating cryptographic dependencies accordingly.
Removes the strict `transport_state` condition and now triggers `api.resume(id)` solely based on a non-empty queue. This improves resilience against transient or unknown device states, such as post-sleep-timer or network errors, where transport state strings may mismatch expected values but playback should still proceed.
Introduce a `consecutiveSnapshotErrors` counter with a threshold of 3 to debounce transient fetch failures. The last known snapshot is preserved and UI notifications are suppressed until the threshold is met, filtering out intermittent device glitches. The counter resets on success.
Update `isNavigable` to explicitly validate `item.is_container` and disable navigation for playlists with only one item. This forces users to enter the playlist container, preserving metadata update benefits.
Replace malformed max-height values with precise calc() expressions and update open/closed transform states. Apply flexbox improvements to ensure reliable mobile drawer layout and proper safe-area padding above the BottomTabBar.
Update mobile portrait media queries in RendererDrawer and ServerDrawer to span full viewport width, reduce background opacity to 6%, and remove side box shadows. This flattens the visual style and improves layout for narrow screens.
Adds a Vue watch in `ServerDrawer.vue` to trigger a manual container directory refresh when SSE cache invalidation clears `browseData`. Includes guards to prevent redundant requests during active loads and properly manages the `isLoading` state. Additionally, introduces `rust-toolchain.toml` to enforce the nightly Rust compiler across all environments, ensuring consistent builds and access to recent language improvements.
- Add viewport-fit=cover to HTML meta for iOS safe-area support
- Extend bottom drawers and tab bar into system navigation area using env(safe_area_inset_bottom)
- Adjust queue drawer transforms to account for safe-area padding
+ Add enrich_position_from_queue() helper and integrate across UPnP, Arylic TCP,
LinkPlay & Chromecast backends to ensure queue-authoritative metadata
+ Add transient error retry logic for UPnP control actions (2 retries, 300ms delay)
+ Separate timeouts: short poll timeout for GetTransportInfo/GetPosition (3s),
longer actiontimeout SetAVTURI/SetNext... for slow devices
+ Remove duplicate continuous-stream detection from play_uri() methods (now handled centrally)
- Bump version to 0.3.49
- Replace `.lock().unwrap()` with explicit error messages for poisoned MutexGuard
- Improve robustness against mutex poisoning in renderer, queue and event subsystems
Remove duplicate `play_from_queue`, ` play_next `,
`play_previous , and
``
pay _from_index implementations across all renderers (ArylicTcp, Chromecast,
LinkPlay , OpenHome UPnP) and instead provide default implementations in the
`QueueTransportControl `trait. Also introduce dispatch macros to simplify backend delegation for Transport/Volume control, and expose parse_didl_duration as public(crate).
Replace all `lock().unwrap()` calls on Mutex guards with explicit error messages using `.expect("... mutex poisoned")`. This improves robustness by providing clear diagnostics when a thread panics while holding the lock, preventing silent failures. Affected modules: events.rs (Renderer/MediaServer), all renderer backends, queue backend/implementation files. Also adds documentation to marker traits (HasQueue、 HasContinuousStream) and clarifies error handling in watcher loop with panic catching.
- Add `Hasqueue` trait and implement it for all renderers (Upnp, OpenHome, LinkPlay, ArylicTcp, Chromecast)
- Replace manual `QueueBackend` implementations with blanket impl for types implementing Hasqueue
(removes ~30+ duplicated methods across renderers)
- Fix BUG: `sync_queue` in UpnpRenderer now correctly propagates cancel_token instead of ignoring it
- Update version to 0.3.48 in Cargo.toml, lockfile and root file
- Add refactoring plan document (`refactoring_pmocontrol.md`) detailing remaining P1-P3 tasks
(refactor) Replace tokio::spawn_blocking with std thread for metadata preloading
- Use `std::thread` instead of Tokio's blocking pool to avoid potential thread starvation in async context
- Ensures long-running metadata loading does not block Tokio workers
- Update Cargo.lock packageversion
- Refactor DB initialization: move PRAGMA settings after table creation for correctness and clarity (WAL, cache size etc.)
- Add foreign key enforcement (`PRAGMAforeign_keys = ON`)
>- Reorder index creation to follow table definition
- Add new indexes: `idx_asset_last_used`, idx`_asset_hits`
>- Introduce indexed lazy_pk support with unique constraint on non-NULL values
> - Improve LRU index to use ASC ordering for efficient oldest-record lookup
- Update package versions in Cargo.toml, lockfile and version.txt to v0.3.47
- Optimize SQLite database initialization with WAL mode, larger cache and critical missing indexes (idx_metadata_key_value, idx_asset_last_used/hits)
- Fix production bug in OpenHome renderer: avoid blocking main thread when loading metadata for large queues; offload preloading of next 10 items to background task with small delays
- Minor formatting cleanup in db.rs