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.
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.
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.
- Bump crate and file versions from `v0.3.29` to v\[correction: actually 0\.3\.33] (see Cargo.toml & version.txt)
- Extend cover URL transformation logic to queue items in `pmoserver_ext.rs`—now transforms album art for both current track *and* queue items
- Add debug logging to cover URL transformation steps (local route, instance match & proxy)
- Minor cleanup: remove redundant `clone()` in base_url usage
- Replace sync proxy_cover_url_sync calls with async versions using dedicated tokio runtime in transformCoverUrlSync
- Update comments to reflect usage of asynchronous logic for cover URL transformation
Refactor queue item cover image handling to directly access `album_art_uri` from the top-level struct instead of nested metadata, and update return type to use fully qualified path `crate::openapi::QueueSnapshot` for clarity.
- Introduce optional `pmocover` dependency in pmocontrol
- Add cover URL transformation logic for both REST and SSE endpoints using `pmocovers::proxy_cover_url`/sync
- Refactor `/covers/proxy?...=` handler to accept any external URL and return local cached route
- Implement helper functions `transform_cover_url` (async) & sync variant for consistent cover URL normalization
- Update Cargo.lock to include `pmocovers`
- Implement new /covers/proxy endpoint to cache and rewrite external LAN cover URLs
- Add url/urlencoding dependencies for URL parsing/escaping in pmocontrol and pmocovers Cargo.toml
- Transform album_art_uri fields to use proxy endpoint for LAN URLs in REST and SSE handlers (browse_container, MetadataChanged)
- Add URL validation logic to detect LAN vs public URLs and avoid self-caching
- Update Cargo.lock with new dependencies
Implémente une fonctionnalité de recherche pour les serveurs media (Qobuz et autres) avec:
- Nouvelle API endpoint /servers/{serverId}/search côté backend
- Fonction searchServer dans useMediaServers.ts pour gérer la requête
- Composants MediaBrowser.vue et ServerDrawer.vue avec barre de recherche interactive
- Support des résultats mixtes (albums, artistes, pistes, playlists)
- Gestion des états de chargement, erreur et résultat vide
- Affichage conditionnel selon le mode navigation/recherche
- Add qobuz_debug to .gitignore
- Bump PMOMusic version to 0.3.26
- Add .cargo/ copy in Dockerfile for registry config
- Implement infinite scroll in ServerDrawer.vue with IntersectionObserver and sentinel element
- Add source/source_version fields to playlists for cache invalidation
- Update pmocache and pmoplaylist DB schemas with versioning (SCHEMA_VERSION)
- Add Qobuz API metadata fetching and pagination for playlist tracks
- Implement album/playlist cache invalidation based on released_at/updated_at timestamps
- Refactor adapt_playlist_items_to_qobuz → adapt_items_to_qobuz with cleaner logic
- Add debug mode to save Qobuz API responses when QOBUZ_DEBUG_DIR is set
Add infinite scroll functionality to MediaBrowser component using IntersectionObserver, introduce BrowseState and pagination support (offset/limit) in API and backend, update version to 0.3.24
Cette mise à jour ajoute la prise en charge de l'adresse IP du serveur hébergeant les renderers UPnP. Cela permet d'afficher l'adresse IP des renderers dans l'interface utilisateur lorsqu'ils ont des noms identiques. Les modifications incluent :
- Mise à jour des types pour inclure le champ server_host
- Extraction de l'adresse IP depuis la location UPnP
- Affichage de l'adresse IP dans l'interface utilisateur pour les renderers avec des noms en double
- Modification des appels à register_device pour désactiver le SSDP lors de l'enregistrement des renderers
Cela améliore la clarté de l'interface utilisateur en permettant de distinguer les renderers avec des noms identiques mais hébergés sur des serveurs différents.
Cette mise à jour implémente la détection des flux continus (radio, streaming) et améliore la gestion de la barre de progression pour ces flux. Les changements incluent :
- Ajout d'une méthode predicat `is_playing_a_stream()` au niveau de `MusicRenderer`
- Développement d'une fonction utilitaire `is_continuous_stream_url()` pour analyser les headers HTTP
- Mise à jour des backends (UPnP, OpenHome, LinkPlay, ArylicTcp, Chromecast) pour détecter les flux continus
- Ajout d'un flag `continuous_stream` dans chaque backend
- Export du module de détection de flux
- Mise à jour de l'API REST et des événements SSE pour transmettre l'état du flux
- Correction de la gestion de la position de lecture pour les flux continus
Les flux continus sont maintenant correctement détectés via une analyse HTTP des headers, permettant une gestion appropriée de la barre de progression dans l'interface web.
Corrige le bug empêchant la lecture d'un track Qobuz individuel depuis le ServerDrawer.
- Implémente `get_item()` dans `QobuzSource` pour retourner des URLs HTTP valides au lieu de URLs symboliques
- Rend `format_duration()` publique dans `pmoqobuz/src/didl.rs`
- Ajoute le logging dans `pmocontrol/src/pmoserver_ext.rs` pour suivre le flux de lecture
- Améliore la gestion des objets dans `pmocontrol/src/pmoserver_ext.rs` pour distinguer les conteneurs des éléments
Ajout de la fonctionnalité de shuffle pour mélanger l'ordre des morceaux dans la queue de lecture.
- Implémentation de la méthode shuffle_queue() dans MusicRenderer
- Ajout de l'endpoint REST /api/control/renderers/{renderer_id}/queue/shuffle
- Intégration du bouton shuffle dans l'interface Vue.js
- Centralisation des émissions d'événements SSE dans le MusicRenderer
- Mise à jour de la documentation OpenAPI
Cette fonctionnalité permet de randomiser l'ordre des morceaux dans la queue et de redémarrer la lecture depuis le premier morceau, tout en améliorant l'architecture en centralisant les émissions d'événements.
Replace blocking tasks with async background tasks for play, add to queue, and add after current commands. This improves responsiveness by launching commands in the background and returning immediately, with UI updates handled via SSE events. Remove timeout handling and error wrapping as the async task management now handles these cases properly.
Refactor the seek queue command to run asynchronously in the background, returning immediately to the client. The UI will now be updated via SSE events when the state changes, improving responsiveness. The previous timeout and error handling logic has been replaced with a more robust async approach that logs different error scenarios appropriately.
Ajout de la fonctionnalité de sleep timer pour les renderers audio.
- Création du composant TimerControl.vue avec interface utilisateur interactive
- Implémentation des API endpoints pour gérer le sleep timer (start, update, cancel, get)
- Intégration du système de timer dans le control point avec surveillance par thread dédié
- Ajout de la logique de timer dans les renderers (sleep_timer.rs)
- Mise à jour des types et événements SSE pour le sleep timer
- Intégration du timer dans la barre de bas de l'application
Cette fonctionnalité permet aux utilisateurs de configurer un timer qui arrêtera automatiquement la lecture après une durée définie, avec une interface intuitive et des notifications en temps réel.
Ajout de la fonctionnalité de seek audio dans les renderers avec support des Range requests HTTP pour permettre le seek pendant le téléchargement.
- Ajout de la route /control/renderers/{renderer_id}/seek pour le seek par secondes
- Implémentation du support des Range requests dans le serveur de fichiers (pmocache)
- Mise à jour des dépendances avec http-range-header, tower, tower-http
- Amélioration de l'interface utilisateur avec une barre de progression interactive dans CurrentTrack.vue
- Support du seek pendant le téléchargement avec streaming progressif
- Gestion des erreurs et timeouts pour les commandes de seek
Implémentation complète de la fonctionnalité de transfert de queue entre renderers :
- Ajout d'une nouvelle API POST /renderers/{id}/queue/transfer
- Intégration dans le backend avec la méthode transfer_queue dans ControlPoint
- Mise à jour des structures de données pour inclure l'ID de playlist dans les snapshots
- Ajout d'une interface utilisateur dans RendererDrawer avec menu déroulant pour le transfert
- Gestion des écouteurs d'événements pour fermer le menu en dehors
- Support du transfert de la queue avec préservation de la playlist binding
- Ajout de tests et documentation OpenAPI
Refactor UPnP discovery to use a thread pool for fetching device descriptions, improving performance and responsiveness. Also, use spawn_blocking in server endpoints to prevent blocking the async runtime when performing sync operations. Additionally, add read timeout to SSDP socket and handle WouldBlock errors gracefully.
Refactorisation du contrôle des renderers et amélioration de l'interface utilisateur
Refactorisation complète du composant VolumeControl avec gestion d'erreur améliorée et debounce.
Migration de l'interface de contrôle des renderers :
- Suppression de l'ancienne barre d'onglets en bas
- Intégration d'une nouvelle barre d'infos en bas avec les détails du renderer actif
- Création d'un nouveau drawer pour la sélection des renderers
- Déplacement des informations du renderer de l'onglet vers la barre d'infos
Améliorations UI/UX :
- Nouvelle interface de contrôle des renderers dans le drawer avec boutons de lecture/pause
- Mise à jour des styles et animations pour une meilleure expérience utilisateur
- Adaptation responsive pour les appareils mobiles
Ajout d'un menu déroulant avec les actions 'Ajouter à la queue' et 'Ajouter après' pour les éléments dans le ServerDrawer.
- Remplacement des fonctions handlePlayItem et handleQueueItem par des fonctions plus spécifiques (handlePlayItem, handleAddToQueue, handleAddAfterCurrent)
- Ajout d'une gestion du menu déroulant avec ouverture/fermeture
- Intégration du composant useRenderers pour les actions de lecture
- Mise à jour des styles pour le menu déroulant avec animations
- Correction de l'alignement du backdrop sur mobile
- Amélioration des transitions et animations du drawer
- Ajout de la fonction addAfterCurrent dans l'API et le control point
- Support de l'ajout d'éléments après le morceau actuel dans les queues