# #109 — Support audio & vidéo (lecteurs HTML5 intégrés) > **Version livrée :** 2.18.0 · **Statut :** ✅ · **Impact :** 🟡 > **Zone :** backend (`main`, `indexer`, `media_types`, `bookslm`) + frontend > (`viewer.js`, `utils.js`, `style.css`, `sw.js`). ## Contexte Le socle média de #108 (`backend/media_types.py`) exposait déjà `AUDIO_EXTENSIONS` / `VIDEO_EXTENSIONS`, mais ces fichiers n'étaient ni indexés ni affichables : ils tombaient dans le chemin binaire « Ce fichier est binaire et ne peut pas être affiché » + bouton download. ## Ce qui a été livré ### A. Backend - **Indexation** : `AUDIO_EXTENSIONS` et `VIDEO_EXTENSIONS` sont intégrées à `SUPPORTED_EXTENSIONS` (`indexer.py`). La branche `is_media(ext)` existante indexe **nom / taille / mtime** sans jamais lire les octets (`content: ""`), donc le TF-IDF et les logs restent propres. Le watcher et le filtre `ext:` suivent automatiquement. - **Streaming** : le helper Range de `pdf/stream` a été extrait en `_stream_file_with_range(file_path, request, media_type)` (206 + `Content-Range` + `Accept-Ranges`, `416` sur plage invalide, `FileResponse` simple sinon, lectures offloadées via `asyncio.to_thread`). `pdf/stream` l'utilise désormais aussi (comportement inchangé, tests de régression). - **Nouvel endpoint `GET /api/media/{vault}?path=…`** : sert audio/vidéo avec le MIME `media_types.media_mime_type` (surcharges `.m4a→audio/mp4`, `.opus/.oga→audio/ogg`, `.mov→video/quicktime`, `.m4v→video/mp4`). - **Gardes-fous** : `_resolve_safe_path`, `check_vault_access`, et `OBSIGATE_MEDIA_MAX_INLINE_MB` (défaut **500 Mo**) — au-delà, l'endpoint renvoie `413` et la vue fichier bascule sur l'UI de téléchargement. - **`api_file_view()`** renvoie, avant tout `read_text()`, `is_audio` / `is_video` / `stream_url` / `media_mime` / `size_bytes`. Au-delà de la limite : `unsupported: true` + `media_too_large: true`. ### B/C. Frontend — lecteurs - `viewer.js` dispatche `data.is_audio` → `renderAudioViewer()` et `data.is_video` → `renderVideoViewer()`. - **Audio** : `