L'audio dans Forge (forge-mvc-audio)¶
Ce document explique ce que fait l'opt-in forge-mvc-audio, ce qu'il expose, et comment on s'en sert.
forge-mvc-audio est une chaîne audio complète et sans état : ingérer un fichier, le sonder, le transcoder en MP3, le lire en streaming HTTP Range.
Volontairement sobre : aucune base de données, aucune file de transcodage, des opérations synchrones, des fichiers retrouvés par uuid sur le disque.
1. Rôle du module¶
L'opt-in couvre le cycle d'un fichier audio sans rien imposer en base : on ingère des octets, on les range sur disque sous un uuid, on peut les sonder (ffprobe), les convertir en MP3 (ffmpeg), et les servir.
Il branche ses routes de lecture sur le routeur du projet via register_audio_routes (modèle opt-in de type route).
Sa sobriété est un choix : pas de table SQL, pas de suivi de jobs ; tout est synchrone et le service retrouve les fichiers par uuid.
2. Vue d'ensemble rapide¶
| Élément | Valeur |
|---|---|
| Paquet | forge-mvc-audio |
| Module | forge_mvc_audio |
| Catégorie | Médias et fichiers (ADR-055) |
| Couche | opt-in de type route (couche optins/) |
| Dépend de | forge-mvc, et ffmpeg / ffprobe (binaires système) |
| API publique | ingest_audio, probe_audio, transcode_to_mp3, register_audio_routes, load_audio_config |
| Objets | AudioConfig, AudioMetadata |
| Configuration | load_audio_config (contrat AudioConfig) |
| Commandes | audio:doctor |
| Lecture | streaming HTTP Range, fichiers indexés par uuid |
| État | sans état : pas de base de données, opérations synchrones |
| Exceptions | AudioIngestError, AudioProbeError, FfmpegError |
| Installation | pip install --pre forge-mvc-audio |
3. Schémas UML¶
Les deux schémas suivants montrent deux vues complémentaires de l'opt-in.
Le diagramme de classe montre les modules, les objets et les dépendances externes.
Le diagramme de séquence montre l'ingestion, le transcodage et la lecture.
3.1 Diagramme de classe¶
Le diagramme de classe montre une chaîne sans base de données : les fichiers vivent sur disque sous un uuid, et ffmpeg / ffprobe font le travail média.
classDiagram
direction LR
class ingest {
<<module>>
+ingest_audio(data, filename, title, config, uuid) dict
}
class probe {
<<module>>
+probe_audio(path, config, runner) AudioMetadata
}
class transcode {
<<module>>
+transcode_to_mp3(input_path, output_path, ...)
}
class http {
<<module>>
+register_audio_routes(router, config)
}
class AudioMetadata {
<<dataclass>>
+float duration
+str codec
+int bitrate
+int channels
}
class ffmpeg {
<<binaire externe>>
+ffmpeg
+ffprobe
}
ingest --> Disk : range par uuid
probe --> ffmpeg : ffprobe
transcode --> ffmpeg : ffmpeg
probe --> AudioMetadata : renvoie
http --> Disk : sert par uuid (HTTP Range)
À retenir :
- aucune table : les fichiers sont rangés et retrouvés par
uuid; ffprobesonde,ffmpegtranscode ;probe_audiorenvoie unAudioMetadatatypé ;- la lecture sert le fichier par son
uuid, en streaming.
3.2 Diagramme de séquence¶
Le diagramme de séquence montre une ingestion suivie d'un transcodage, puis la lecture.
sequenceDiagram
actor Op as Code applicatif
participant Ingest as ingest_audio
participant Disk as Disque (uuid)
participant Probe as probe_audio
participant Trans as transcode_to_mp3
participant Routes as register_audio_routes
actor Navigateur
Op->>Ingest: ingest_audio(data, "cours.wav")
Ingest->>Disk: range le fichier sous un uuid
Ingest-->>Op: dict (uuid, chemin, ...)
Op->>Probe: probe_audio(chemin)
Probe-->>Op: AudioMetadata (durée, codec...)
Op->>Trans: transcode_to_mp3(src, dst)
Trans-->>Op: MP3 écrit
Navigateur->>Routes: GET l'audio (avec Range)
Routes-->>Navigateur: flux MP3 (206 Partial Content)
À retenir :
- l'ingestion valide et range les octets sous un
uuid; - le sondage et le transcodage sont des appels synchrones ;
- la lecture honore l'en-tête
Range; - rien n'est suivi en base : l'application gère ses propres références d'
uuid.
4. API publique¶
| Élément | Signature | Rôle |
|---|---|---|
ingest_audio |
ingest_audio(data, filename, title=None, config=None, uuid=None) -> dict |
valide et range un fichier audio |
probe_audio |
probe_audio(path, config=None, runner=None) -> AudioMetadata |
métadonnées via ffprobe |
transcode_to_mp3 |
transcode_to_mp3(input_path, output_path, ffmpeg_bin="ffmpeg", bitrate_kbps=192, ...) |
conversion MP3 via ffmpeg |
register_audio_routes |
register_audio_routes(router, config=None) -> Any |
branche les routes de lecture |
load_audio_config |
load_audio_config(source=None) -> AudioConfig |
charge la configuration |
AudioConfig |
dataclass | contrat de configuration |
AudioMetadata |
dataclass | durée, codec, bitrate, canaux |
AudioIngestError, AudioProbeError, FfmpegError |
exceptions | erreurs d'ingestion, de sondage, de transcodage |
Commandes CLI¶
| Commande | Rôle |
|---|---|
forge audio:doctor |
diagnostic (paquet, config, ffmpeg/ffprobe) |
5. Contextes d'utilisation¶
| Besoin | Élément |
|---|---|
| Vérifier l'installation | forge audio:doctor |
| Ingérer un fichier | ingest_audio(data, filename) |
| Lire les métadonnées | probe_audio(path) |
| Convertir en MP3 | transcode_to_mp3(src, dst) |
| Brancher la lecture | register_audio_routes(router) |
| Configurer le module | load_audio_config(...) |
6. Exemples d'utilisation¶
6.1 Ingérer puis transcoder¶
from forge_mvc_audio import ingest_audio, transcode_to_mp3
stored = ingest_audio(data, "cours.wav", title="Cours 1")
transcode_to_mp3(stored["path"], stored["path"].replace(".wav", ".mp3"))
L'ingestion range le fichier sous un uuid ; le transcodage est synchrone.
6.2 Brancher les routes de lecture¶
# optins/audio/routes.py (couche optins du projet)
from forge_mvc_audio import register_audio_routes
def register(router) -> None:
register_audio_routes(router)
Aide-mémoire
Une chaîne en quatre temps :
ingest_audiopour entrer ;probe_audiopour inspecter ;transcode_to_mp3pour convertir ;register_audio_routespour lire.
7. Sobriété, uuid et dépendances¶
Le module est sans état : pas de table, pas de file de jobs. L'application garde elle-même la trace des uuid qu'elle a ingérés.
ffmpeg et ffprobe sont des binaires système (pas des dépendances pip) ; forge audio:doctor vérifie leur présence.
ffmpeg / ffprobe requis
Sans ces binaires, le sondage et le transcodage échouent (AudioProbeError, FfmpegError).
Lancez forge audio:doctor après installation.
Opérations synchrones
Le transcodage est synchrone : pour de gros fichiers, déclenchez-le hors requête (par exemple via forge-mvc-jobs).
La sobriété est assumée : pas de file intégrée, pas de suivi en base.
Indépendance du cœur
Le cœur de Forge ne dépend pas de forge-mvc-audio : la dépendance va de l'opt-in vers le cœur.
Voir aussi¶
- Configuration (config.py) : contrat
AudioConfig. - Ingestion (ingest.py) :
ingest_audio, stockage par uuid. - Sondage (probe.py) et Transcodage MP3 (transcode.py).
- Lecture HTTP (http.py) : routes et streaming.
- Progression Audio : apprendre l'opt-in pas à pas.