La bibliothèque du mobile n'offrait aucun moyen de supprimer un fichier : les éléments reçus du serveur, rangés dans Music/Noxely, ne se retiraient pas, et l'écran Hors ligne ne proposait la suppression que pour les enregistrements. Un bouton dossier dans l'en-tête ouvre un écran Fichiers : provenance et taille de chaque élément, filtre par origine, tri par date, taille ou titre, sélection avec poids cumulé, suppression. Elle ne traite pas tout pareil : les fichiers que l'application a créés sont effacés, les liens et podcasts retirés avec leur copie hors ligne, et ceux de l'appareil — qui appartiennent à d'autres applications — passent toujours par la confirmation d'Android, depuis Android 11. Retirer aussi du serveur est une case décochée par défaut, car c'est irréversible. Le morceau en cours de lecture n'est pas sélectionnable, et un fichier déjà disparu est retiré de la liste au lieu d'y rester. Les fichiers de l'appareil affichent leur taille, lue de MediaStore. Sur la carte de lecture, réduire, playlist et stop passent en blanc, posés sur un disque sombre translucide pour rester lisibles dans le thème clair. Compilé et passé au lint de release ; l'écran n'a pas encore été essayé sur un appareil. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N6pmSE168yjyf8vgV8mZx6
429 lines
24 KiB
Markdown
429 lines
24 KiB
Markdown
# Changelog
|
||
|
||
Toutes les évolutions notables de Noxely sont documentées ici.
|
||
|
||
Le format suit [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/)
|
||
et le versionnage [SemVer](https://semver.org/lang/fr/).
|
||
|
||
## [2.6.0] — 2026-09-20
|
||
|
||
### Ajouté
|
||
|
||
- **Gestionnaire de fichiers.** Un bouton dossier dans l'en-tête de la bibliothèque ouvre l'écran
|
||
`Fichiers` : tout ce qui occupe l'appareil, avec sa provenance et sa taille, filtrable par
|
||
origine (serveur, enregistrements, appareil, liens, podcasts) et triable par date, taille ou
|
||
titre. On sélectionne, on voit le poids cumulé, on supprime.
|
||
- **Suppression selon ce qu'est l'élément**, et sans jamais confondre les cas :
|
||
- *reçus du serveur* et *enregistrements*, que l'application a créés : effacés du téléphone ;
|
||
- *liens* et *podcasts* : retirés de la bibliothèque, avec leur copie hors ligne ;
|
||
- *fichiers de l'appareil*, qui appartiennent à d'autres applications : Android demande
|
||
toujours confirmation, et la suppression n'est proposée que depuis Android 11.
|
||
- **« Supprimer aussi du serveur »**, case à cocher décochée par défaut, pour les éléments reçus
|
||
du serveur : la suppression y est irréversible, elle ne se fait donc que sur demande.
|
||
- Les fichiers de l'appareil affichent désormais leur taille, lue de MediaStore.
|
||
|
||
### Modifié
|
||
|
||
- **Boutons de la carte de lecture en blanc** — réduire, ajouter à une playlist, arrêter —, posés
|
||
sur un disque sombre translucide pour rester lisibles sur le fond clair du thème clair.
|
||
|
||
### Notes
|
||
|
||
- Un élément en cours de lecture ne peut pas être sélectionné : le supprimer sous le lecteur le
|
||
ferait échouer.
|
||
- Un fichier déjà disparu du disque est retiré de la liste au lieu d'y rester comme une ligne
|
||
impossible à supprimer.
|
||
|
||
## [2.5.0] — 2026-09-20
|
||
|
||
### Ajouté
|
||
|
||
- **Onglet `📻 Radio`.** Les stations de l'annuaire, filtrables par genre et par nom. Chacune
|
||
s'écoute en direct depuis le navigateur ou s'enregistre, jusqu'à l'arrêt ou pour 15 min, 30 min,
|
||
1 h ou 2 h. Jusqu'à quatre stations en parallèle ; une station déjà en cours est refusée.
|
||
- **Réécoute.** Les enregistrements sont listés avec leur taille et leur durée : on les lit depuis
|
||
le navigateur, on les supprime, et le mobile les reçoit à sa prochaine synchronisation comme
|
||
n'importe quel média. Les captures faites par un guet y figurent aussi.
|
||
- **Reprise sur coupure.** Quand le flux tombe, le serveur le rouvre et continue dans le même
|
||
fichier ; il n'abandonne qu'après cinq tentatives infructueuses d'affilée, en gardant ce qui a
|
||
été capté.
|
||
- Routes `POST /api/radio/record`, `POST /api/radio/record/{id}/stop` et
|
||
`GET /api/radio/recordings`. Réglage `NOXELY_RECORD_MAX_MINUTES` (180) : plafond de durée, pour
|
||
qu'un enregistrement oublié ne remplisse pas le disque.
|
||
|
||
- **Bouton « Synchroniser maintenant » dans l'application.** Il était jusque-là réduit à un
|
||
petit lien dans Réglages ▸ Connexion, visible seulement une fois connecté. Il figure
|
||
désormais en pleine largeur dans l'onglet **Synchronisation**, avec un indicateur pendant le
|
||
transfert, et grisé — avec la raison — tant que le serveur n'est pas renseigné.
|
||
|
||
### Modifié
|
||
|
||
- **Deux synchronisations ne se chevauchent plus.** Le passage planifié et le bouton pouvaient
|
||
télécharger les mêmes fichiers en double ; le second est maintenant refusé avec le message
|
||
« Synchronisation déjà en cours ». Une erreur inattendue pendant la synchronisation manuelle
|
||
s'affiche au lieu de fermer l'application.
|
||
- **Un redémarrage du service ne laisse plus d'enregistrement « en cours » à jamais.** Le serveur
|
||
clôt proprement les captures à l'arrêt ; si le processus meurt brutalement, les fichiers
|
||
qui contiennent de l'audio sont déclarés prêts au démarrage suivant, les vides écartés.
|
||
- La copie d'un flux en retirant les blocs ICY, jusque-là propre au guet, est désormais partagée
|
||
avec l'enregistrement à la demande.
|
||
|
||
## [2.4.0] — 2026-09-20
|
||
|
||
### Ajouté
|
||
|
||
- **Historique des écoutes.** Le serveur note chaque titre que les stations annoncent (ICY),
|
||
même quand aucun morceau n'est guetté : station, heure, artiste et titre. Un nouvel onglet
|
||
`📈 Écoutes` le montre, avec une recherche dans le texte. La route `GET /api/heard` le sert.
|
||
- **Rotation.** `GET /api/rotation` compte, sur les *n* dernières remontées (100 par défaut,
|
||
jusqu'à 500), les passages de chaque titre et de chaque artiste, et le nombre de stations
|
||
distinctes qui les diffusent. Les accents, la casse et la ponctuation ne séparent plus un
|
||
même morceau en deux.
|
||
- Trois réglages : `NOXELY_HISTORY` (0 pour couper), `NOXELY_LISTEN_INTERVAL` (pause entre deux
|
||
tours quand rien n'est guetté, 60 s) et `NOXELY_HISTORY_DAYS` (purge au-delà, 90 jours).
|
||
|
||
### Modifié
|
||
|
||
- **Le balayage ne s'arrête plus quand rien n'est guetté.** Il tourne à cadence lente pour tenir
|
||
l'historique, et reste serré (`NOXELY_WATCH_INTERVAL`) dès qu'un guet est en attente.
|
||
- **Un tour va jusqu'au bout.** Trouver un morceau guetté n'interrompt plus le tour : l'enregistrement
|
||
part aussitôt, mais le reste des stations est lu, pour que l'historique soit complet.
|
||
- **La liste des stations est mise en cache une demi-heure.** Chaque tour interrogeait
|
||
l'annuaire communautaire ; avec un guet, c'était toutes les quelques secondes. En cas de
|
||
panne de l'annuaire, la liste précédente sert au lieu de faire échouer le tour.
|
||
|
||
### Notes
|
||
|
||
- Une station qui n'a pas changé de morceau n'ajoute rien, et un titre déjà relevé sur la même
|
||
station dans les dix minutes est ignoré : certaines stations alternent le vrai titre et un
|
||
titre de repli, ce qui doublait les passages. Les stations qui n'annoncent qu'elles-mêmes sont
|
||
écartées.
|
||
- La séparation « Artiste - Titre » se fait sur le premier tiret entouré d'espaces. Une station
|
||
qui annonce « Titre - Artiste », ou du parlé, est comptée telle quelle.
|
||
|
||
## [2.3.0] — 2026-09-13
|
||
|
||
### Ajouté
|
||
|
||
- **Page « À propos » du serveur.** Un onglet `ℹ️ À propos` avec en-tête d'identité et cinq
|
||
sections : ce que le serveur fait, ce qu'il garantit, avec quoi il est construit, ce qui a
|
||
changé, et qui en répond. Le contenu vit dans un module de constantes séparé du rendu.
|
||
- Le journal est **lu** et non recopié : une route `/api/changelog` sert le `CHANGELOG.md` du
|
||
dépôt, que la page interprète pour ce qu'il emploie réellement — titres, puces et gras.
|
||
|
||
### Modifié
|
||
|
||
- **Le champ « jeton » quitte l'en-tête du serveur**, où il n'avait rien à faire, pour l'onglet
|
||
`⚙️ Réglages`. Une carte y donne aussi le nom du serveur, sa version et le nombre d'appareils
|
||
appairés. Sans jeton connu, la pastille d'état indique où le saisir.
|
||
- **Le serveur annonce la version du dépôt.** Il lisait une constante figée à `1.0.0`, restée en
|
||
arrière de six publications ; il lit maintenant le fichier `VERSION`, comme le client.
|
||
|
||
### Corrigé
|
||
|
||
- `saveToken()` relançait l'amorçage du jeton au lieu de rafraîchir la page : un bloc y avait été
|
||
déplacé par erreur lors d'une édition antérieure.
|
||
- Une garantie annoncée à tort. La page affirmait que toute route hors `/api/health` exigeait un
|
||
jeton ; la page elle-même, ses ressources et le journal répondent sans. Les sept garanties ont
|
||
été confrontées au code une à une, celle-ci reformulée.
|
||
|
||
## [2.2.0] — 2026-09-13
|
||
|
||
### Ajouté
|
||
|
||
- **Un jeton par appareil.** Chaque appairage émet désormais sa propre valeur, au lieu de
|
||
distribuer le jeton maître. Révoquer un téléphone perdu n'atteint plus les autres : vérifié en
|
||
appairant deux appareils, en révoquant le premier, et en constatant que le second continue de
|
||
se synchroniser (401 pour l'un, 200 pour l'autre, jeton maître intact).
|
||
- **Onglet « Appareils »** dans l'interface du serveur : nom du modèle, date d'appairage,
|
||
dernière synchronisation — ou « jamais synchronisé » —, et révocation d'un clic.
|
||
- Le téléphone s'annonce par son modèle lors de l'appairage : un appareil qu'on ne sait pas
|
||
nommer ne se révoque pas.
|
||
|
||
### Sécurité
|
||
|
||
- Les jetons d'appareil ne sont **jamais renvoyés** par la route qui les liste : les afficher
|
||
reviendrait à les distribuer.
|
||
- La date de dernière utilisation est enregistrée à chaque appel authentifié, ce qui permet de
|
||
repérer un appareil oublié.
|
||
|
||
### Compatibilité
|
||
|
||
- La table s'ajoute sans toucher aux données existantes, et le jeton maître reste accepté : un
|
||
appareil appairé avant cette version garde l'accès. Le réappairer lui donnera un jeton propre,
|
||
et donc une révocation individuelle.
|
||
|
||
## [2.1.0] — 2026-09-13
|
||
|
||
### Ajouté
|
||
|
||
- **Appairage du téléphone.** Plus de jeton à recopier : on ouvre une fenêtre depuis l'interface
|
||
du serveur, on appuie sur « Appairer » dans Réglages ▸ Connexion, et l'application reçoit le
|
||
jeton. Le champ de saisie reste disponible pour qui préfère le coller à la main.
|
||
|
||
Le téléphone ne peut pas deviner un jeton — c'est ce qu'il protège — mais il peut le recevoir,
|
||
sous trois conditions cumulées : ouvrir la fenêtre exige déjà le jeton, elle expire au bout de
|
||
deux minutes, et elle se referme dès qu'un appareil s'est servi. La demande doit en outre venir
|
||
d'une adresse privée : un appairage n'est jamais joignable depuis Internet.
|
||
|
||
- En-têtes de licence GPL v3 dans les cinquante fichiers de code (Kotlin, Python, HTML), rédigés
|
||
en français comme le reste du projet, le texte faisant foi restant celui de `LICENSE`.
|
||
|
||
## [2.0.1] — 2026-09-13
|
||
|
||
### Ajouté
|
||
|
||
- **Licence GNU GPL v3.** Le texte intégral est dans `LICENSE` — copié de la référence système,
|
||
empreinte `1ebbd3e34237af26da5dc08a4e440464`, et non retranscrit. Le README expose la formule
|
||
complète, y compris le point le plus souvent passé sous silence : toute version modifiée
|
||
redistribuée doit l'être sous la même licence, code source compris.
|
||
- L'onglet Auteur de la page « À propos » porte la licence et le copyright.
|
||
|
||
### Corrigé
|
||
|
||
- La pastille de licence de la page « À propos » ne s'affiche plus en rouge : elle signalait
|
||
qu'aucune licence n'était déclarée, ce qui n'est plus le cas.
|
||
|
||
## [2.0.0] — 2026-09-13
|
||
|
||
Noxely se sépare en deux : un **serveur** qui collecte, un **mobile** qui écoute. Tout ce qui
|
||
tenait le téléphone éveillé a migré ailleurs — c'est la raison d'être de cette version.
|
||
|
||
### Ajouté
|
||
|
||
- **Serveur** (`server/`, Python + FastAPI + SQLite). Il porte désormais la recherche dans les
|
||
catalogues, le guet des morceaux sur les radios, l'enregistrement des directs et la file de
|
||
téléchargement. Une interface web permet de le piloter depuis un navigateur : recherche, guets,
|
||
file et bibliothèque.
|
||
- **Recherche simultanée sur toutes les sources.** Les quatre catalogues sont interrogés en
|
||
parallèle et les résultats fusionnés, chacun étiqueté de son origine, les plus légers en tête.
|
||
Un catalogue en panne n'empêche pas les autres de répondre.
|
||
- **Balayage radio continu.** Un tour enchaîne sur le suivant au lieu d'attendre trois minutes :
|
||
un morceau guetté a été capté en moins de vingt-cinq secondes à la mesure. Une sonde ne lit que
|
||
le premier bloc de métadonnées puis referme, ce qui rend la permanence tenable là où garder
|
||
quarante flux ouverts coûterait plusieurs mégabits par seconde.
|
||
- **Synchronisation client/serveur.** Le mobile demande ce qui a changé depuis son curseur,
|
||
télécharge les fichiers prêts et se rendort. Toutes les six heures, en Wi-Fi non facturé et
|
||
batterie suffisante.
|
||
- **Réglages en sous-onglets** sur le mobile : Connexion, Synchronisation, Application.
|
||
- Cibles `make server-*` : environnement, lancement, service systemd, jeton, journal.
|
||
|
||
### Changé
|
||
|
||
- **L'application Android devient un client de synchronisation.** Recherche, catalogues, radio,
|
||
guets et enregistrement quittent le téléphone : vingt fichiers supprimés. Restent la
|
||
bibliothèque, la lecture, les playlists, le hors-ligne et les réglages.
|
||
- L'onglet Sources devient Réglages.
|
||
|
||
### Corrigé
|
||
|
||
- Le jeton du serveur était régénéré à chaque démarrage : il aurait fallu reconfigurer le mobile
|
||
après le moindre redémarrage. Il est désormais conservé dans `data/token`, en lecture seule pour
|
||
son propriétaire.
|
||
- Wikimedia Commons répondait 403 : sa politique refuse les agents génériques. L'agent annonce
|
||
maintenant le projet et son dépôt — 28 résultats là où il n'y en avait aucun. L'erreur était
|
||
masquée par la fusion des sources, et n'est apparue qu'en interrogeant la source seule.
|
||
- `NOXELY_DATA` pointait par défaut sur `/var/lib/noxely`, inaccessible au compte qui lance
|
||
`make server-run` : le défaut devient `./data`, et l'unité systemd crée elle-même son dossier
|
||
d'état. Un dossier inutilisable donne désormais une phrase, plus une trace Python.
|
||
- La lecture des métadonnées ICY n'itérait rien côté serveur : `iter_bytes` au lieu de
|
||
`aiter_bytes` sur un client asynchrone. Trente-six stations écoutées, zéro titre lu.
|
||
- Une coupure de l'annuaire Radio Browser faisait échouer tout le balayage : une seconde tentative
|
||
est faite, et l'erreur renvoyée est lisible.
|
||
|
||
### Migration
|
||
|
||
Le mobile seul ne sert plus à rien : il faut installer le serveur (`make server-venv`, puis
|
||
`make server-install`), relever son jeton (`make server-token`) et le saisir dans Réglages ▸
|
||
Connexion. Consultée depuis la machine du serveur, l'interface web se remplit seule.
|
||
|
||
## [1.7.0] — 2026-09-13
|
||
|
||
### Ajouté
|
||
|
||
- **Guet sur l'ensemble des stations.** On nomme un morceau ou un artiste, sans désigner de
|
||
station : Noxely balaie les quarante stations les plus écoutées, quatre à la fois, et déclenche
|
||
l'enregistrement dès qu'une le diffuse. Un écran dédié sépare ce qui est attendu de ce qui a été
|
||
capté, avec le nombre de balayages et l'heure du dernier.
|
||
- **Veille en arrière-plan.** Deux mécanismes, parce qu'un seul ne suffit pas : une tâche
|
||
périodique tourne en permanence au quart d'heure — le minimum qu'autorise Android — et une
|
||
veille active, à enclencher, balaie toutes les trois minutes, écran éteint compris. Un morceau
|
||
durant trois à quatre minutes, la tâche périodique en manque forcément ; l'écran le dit au lieu
|
||
de le taire. La veille s'arrête d'elle-même quand plus rien n'est guetté.
|
||
- **Pochettes automatiques.** Les titres sans image en reçoivent une, cherchée sur leur nom via la
|
||
recherche publique d'iTunes, sans clé. Le nom est nettoyé au préalable : un enregistrement radio
|
||
traîne celui de sa station, qui brouillerait la requête.
|
||
- **Bouton d'actualisation** de l'écran Hors ligne : relance le scan de l'appareil et complète les
|
||
pochettes manquantes, par lots bornés pour ne pas marteler le service.
|
||
- L'écran de lecture affiche la provenance du morceau — nom de la playlist s'il en vient —, sa
|
||
source, sa taille et sa date.
|
||
|
||
### Corrigé
|
||
|
||
- Un morceau guetté n'était pas enregistré : le champ de saisie était vidé avant que la coroutine
|
||
n'en lise la valeur. Elle est désormais capturée avant l'effacement.
|
||
|
||
## [1.6.0] — 2026-09-13
|
||
|
||
### Changé
|
||
|
||
- **L'application s'appelle désormais Noxely.** Le nom affiché, l'identifiant d'application
|
||
(`fr.tuxgyver.noxely`), le paquet Kotlin, le dépôt et le dossier d'enregistrements
|
||
(`Music/Noxely`) suivent tous.
|
||
|
||
⚠️ **Android considère le nouvel identifiant comme une application distincte.** Une
|
||
installation en 1.5.0 ne se met donc pas à jour toute seule : il faut la désinstaller, puis
|
||
installer Noxely. Les enregistrements déjà rangés dans `Music/Cachette` ne sont pas perdus —
|
||
ils sont dans le stockage partagé, restent lisibles par tout lecteur, et le scan continue de
|
||
les écarter pour ne pas les afficher en double.
|
||
|
||
- Nouvelle icône. Le visuel fourni est détouré de son fond, décliné aux cinq densités et posé
|
||
sur une couleur échantillonnée dans l'image : sans cela, le masque du système aurait découpé
|
||
une seconde fois un badge qui l'est déjà, en laissant du blanc sur les bords.
|
||
|
||
### Ajouté
|
||
|
||
- Page « À propos », accessible depuis l'écran Sources : ce que fait l'application, ce qu'elle
|
||
garantit, avec quoi elle est construite, ce qui a changé et qui en répond. La version est lue
|
||
du manifeste et le journal du CHANGELOG du dépôt, recopié à la compilation — l'un et l'autre
|
||
ne peuvent donc pas diverger de la réalité.
|
||
- La pastille de licence signale en rouge qu'aucune licence n'est déclarée dans le dépôt, plutôt
|
||
que d'en afficher une par défaut.
|
||
|
||
## [1.5.0] — 2026-09-13
|
||
|
||
### Ajouté
|
||
|
||
- **Titre en cours par station.** Aucun annuaire ne l'expose : le morceau diffusé est lu dans le
|
||
flux lui-même. Les douze premières stations affichées sont sondées quatre à la fois, et le
|
||
résultat conservé — au-delà, le nombre de connexions ne se justifierait plus. Les stations qui
|
||
n'annoncent rien gardent leur description.
|
||
- **Guet d'un titre.** On indique un morceau ou un artiste, et l'enregistrement se déclenche dès
|
||
que la station l'annonce, puis s'arrête à la fin du morceau. Le flux est lu sans être écrit
|
||
pendant l'attente. Une station sans métadonnées refuse la programmation plutôt que d'attendre
|
||
indéfiniment.
|
||
- **Catalogue Underground.** Restreint aux collections `netlabels` et `freemusicarchive`, où tout
|
||
est publié sous licence libre par les artistes : environ 94 000 morceaux indépendants, que la
|
||
recherche généraliste noyait.
|
||
- **Suppression individuelle d'un enregistrement** depuis l'écran Hors ligne : fichier, entrée
|
||
MediaStore et référence en bibliothèque sont retirés ensemble.
|
||
|
||
### Modifié
|
||
|
||
- Les enregistrements sont désormais écrits dans `Music/Noxely` et déclarés dans MediaStore
|
||
(Android 10 et plus) : ils deviennent visibles des autres lecteurs et survivent à la
|
||
désinstallation. Le scan local ignore ce dossier, faute de quoi chaque enregistrement
|
||
apparaîtrait deux fois.
|
||
- Le nom de fichier porte le titre du morceau. En publiant le fichier, MediaStore le relit et
|
||
réécrit le champ `TITLE` depuis ce nom : l'y inscrire directement ne survivait pas.
|
||
|
||
## [1.4.0] — 2026-09-13
|
||
|
||
### Ajouté
|
||
|
||
- Titrage automatique des enregistrements radio. Le service demande désormais les métadonnées
|
||
ICY, ce qui fait annoncer par la station le morceau diffusé : l'enregistrement prend son nom,
|
||
la station passe en sous-titre, et le titre en cours s'affiche pendant la capture comme dans
|
||
la notification. Ces octets de métadonnées sont retirés avant écriture — laissés dans le
|
||
fichier, ils le rendraient illisible. Les stations qui n'en diffusent pas gardent le nom
|
||
« Station — date ».
|
||
|
||
### Corrigé
|
||
|
||
- Les enregistrements radio n'apparaissaient pas dans l'onglet « Hors ligne », qui ne listait que
|
||
ce qui porte un état de téléchargement. L'écran annonçait donc un nombre d'éléments disponibles
|
||
sans réseau en omettant précisément ceux qui l'étaient déjà. La taille affichée additionne
|
||
maintenant le cache et les enregistrements, et « Tout libérer » précise qu'il ne les touche pas.
|
||
- Les titres comportant une apostrophe étaient tronqués à la première rencontrée : « Ain't That a
|
||
Kick in the Head » devenait « Ain ». La valeur est lue jusqu'à la fin du champ ICY.
|
||
|
||
## [1.3.0] — 2026-09-13
|
||
|
||
### Ajouté
|
||
|
||
- **Radio.** Les stations les plus écoutées via l'annuaire communautaire Radio Browser, avec
|
||
filtres par genre et recherche par nom. Chaque station s'écoute en direct, ou s'enregistre :
|
||
un service de premier plan copie le flux dans un fichier jusqu'à l'arrêt demandé, et le verse
|
||
dans la bibliothèque — déjà hors connexion, sans rien à télécharger ensuite.
|
||
- Relance automatique des téléchargements en échec, après une pause croissante de 5, 15 puis
|
||
45 secondes. Une relance manuelle repart d'un compteur neuf.
|
||
|
||
### Notes
|
||
|
||
- Les flux HLS sont écartés de la liste des stations : ils se lisent, mais ne s'enregistrent pas
|
||
par copie d'octets, et un bouton qui échouerait vaudrait moins que pas de bouton.
|
||
- La relance et la reprise sur coupure réseau sont deux mécanismes distincts, et c'est voulu :
|
||
sans réseau, Media3 met le téléchargement en attente et le reprend de lui-même ; la relance,
|
||
elle, ne traite que les vrais échecs serveur.
|
||
- Le repli automatique vers une autre source n'a pas été retenu : rien ne garantit qu'un même
|
||
titre trouvé sur deux catalogues soit le même enregistrement, et l'application téléchargerait
|
||
silencieusement autre chose que ce qui a été choisi.
|
||
|
||
## [1.2.0] — 2026-09-13
|
||
|
||
### Ajouté
|
||
|
||
- Écran de choix des pistes. Un album ou un livre n'est plus une boîte noire : ses pistes sont
|
||
listées avec leur durée et leur taille, le total est annoncé, et le bouton dit exactement ce
|
||
qu'on s'apprête à télécharger (« Garder 4,2 Mo »). Les variantes d'un même morceau sont
|
||
regroupées — autant de lignes que d'œuvres, pas que de formats.
|
||
- Écoute en ligne avant téléchargement : un appui sur une piste la joue en streaming sans rien
|
||
mettre en cache.
|
||
- Playlists : listes nommées, ajout par appui long sur un média ou depuis l'écran de lecture,
|
||
lecture enchaînée, suppression piste par piste.
|
||
- Contrôles de lecture complétés : arrêt, saut de 15 secondes en avant et en arrière.
|
||
- Filtrage par langue des catalogues (français, anglais, allemand, espagnol, italien, néerlandais).
|
||
- Nouvelle source libre : **Wikimedia Commons**, pour les enregistrements classiques et les
|
||
archives sonores du domaine public.
|
||
|
||
### Corrigé
|
||
|
||
- Le filtre de langue de LibriVox ne pouvait pas fonctionner côté serveur : l'API accepte le
|
||
paramètre `language` puis l'ignore (`language=French` seul renvoie des livres anglais). Le tri
|
||
se fait désormais sur le champ `language` de chaque livre.
|
||
- Délais réseau ajustés d'après la latence mesurée des services : LibriVox répond en 14 à
|
||
16 secondes quelle que soit la taille demandée, ce qui faisait expirer les requêtes parallèles.
|
||
|
||
### Notes
|
||
|
||
- Deux catalogues ont été évalués puis écartés sur mesure plutôt que sur principe : **Openverse**
|
||
refuse désormais l'accès anonyme (401 sur huit requêtes sur huit) et **ccMixter** exige un
|
||
en-tête `Referer` que Media3 ne permet pas de poser par téléchargement.
|
||
|
||
## [1.1.0] — 2026-09-11
|
||
|
||
### Ajouté
|
||
|
||
- Mise à jour intégrée : Noxely surveille les releases du dépôt, télécharge l'APK en Wi-Fi
|
||
et propose l'installation. Vérification quotidienne en tâche de fond, et à la demande depuis
|
||
l'écran Sources, qui affiche aussi la version installée.
|
||
- La taille approximative de chaque résultat Internet Archive est affichée avant sélection : un
|
||
élément de 500 Mo ne se laisse plus confondre avec une chanson.
|
||
|
||
### Corrigé
|
||
|
||
- Recherche LibriVox qui ne renvoyait rien. L'API cherche les titres en correspondance exacte
|
||
sauf si la requête est préfixée par `^`, et les auteurs sur le seul nom de famille : « Jules
|
||
Verne » n'atteignait donc ni l'un ni l'autre. Les trois critères sont désormais interrogés en
|
||
parallèle et dédoublonnés, et un « aucun résultat » (HTTP 404) n'est plus traité comme une panne.
|
||
- Téléchargements Internet Archive qui échouaient ou n'aboutissaient pas. Trois causes distinctes :
|
||
les éléments en accès restreint répondaient 401 et sont maintenant écartés dès la recherche ;
|
||
seuls les fichiers `.mp3` et `.mp4` étaient acceptés, ce qui excluait des éléments ne proposant
|
||
que du `.m4a` ou de l'`.ogg` ; et le fichier retenu était le premier trouvé, souvent l'original
|
||
non compressé — c'est désormais le plus petit dérivé, soit 9 Mo au lieu de 30 sur un cas mesuré.
|
||
|
||
## [1.0.0] — 2026-09-11
|
||
|
||
### Ajouté
|
||
|
||
- Lecture audio et vidéo en arrière-plan (Media3 `MediaSessionService`), avec notification
|
||
système, commandes casque et écran verrouillé.
|
||
- Mise en cache hors connexion explicite : téléchargement à la demande, reprise automatique
|
||
après coupure réseau ou redémarrage via WorkManager.
|
||
- Bibliothèque unifiée mêlant le contenu de l'appareil (MediaStore) et les médias importés.
|
||
- Sources : appareil, lien direct `http(s)`, flux RSS de podcast.
|
||
- Catalogues libres de droits intégrés : Internet Archive et LibriVox, sans compte ni clé d'API.
|
||
- Parcours d'une source avec sélection multiple et téléchargement en lot.
|
||
- Écran « Hors ligne » : taille du cache, progression, libération élément par élément ou en bloc.
|
||
- Interface Jetpack Compose Material 3, thème clair et sombre, palette de marque.
|