From de49e8b34d4c40a9f3953f03882da7cba9eac756 Mon Sep 17 00:00:00 2001 From: R0m1k3 Date: Tue, 11 Aug 2026 11:15:17 +0200 Subject: [PATCH] =?UTF-8?q?fix(player):=20rebasculer=20sur=20HLS=20quand?= =?UTF-8?q?=20la=20piste=20audio=20n'est=20pas=20d=C3=A9muxable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mpegts.js ne démuxe que l'AAC et le MP3. Une chaîne diffusée en E-AC3 (stream_type 0x87) ou en AC-3 (0x81) était donc lue sans aucune piste audio, sans erreur ni avertissement : l'image passait, le son était simplement absent. Les journaux le montrent au PMT — "pid_stream_type":{"256":27,"257":135} avec un "common_pids" réduit au seul h264, là où les flux audibles annoncent "257":15 pour l'AAC. L'évènement MEDIA_INFO porte l'information : quand il arrive sans piste audio, le lecteur détruit la session MPEG-TS et rejoue la même chaîne par /api/live//source/playlist.m3u8. Le préréglage source garde la vidéo en copie de flux et ne réencode que l'audio, en AAC — le coût processeur reste négligeable. La bascule n'est tentée qu'une fois par lecture, et seulement sur une URL live directe. Co-Authored-By: Claude Opus 5 --- web/xf-player-core.js | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/web/xf-player-core.js b/web/xf-player-core.js index fa9842a..f873025 100644 --- a/web/xf-player-core.js +++ b/web/xf-player-core.js @@ -289,6 +289,34 @@ this.mpegts = player; this._mpegtsIsLive = isLive; + // mpegts.js ne démuxe que l'AAC et le MP3. Une chaîne diffusée en E-AC3 + // (stream_type 0x87) ou en AC-3 (0x81) est donc lue sans aucune piste + // audio, sans erreur ni avertissement : l'image passe, le son est + // simplement absent. On bascule alors sur le chemin HLS, où FFmpeg + // réencode systématiquement l'audio en AAC. + player.on(mpegts.Events.MEDIA_INFO, function (mediaInfo) { + if (self._destroyed || self._audioFallbackDone) return; + if (mediaInfo && mediaInfo.hasAudio) return; + + var hlsUrl = self._hlsEquivalent(self.url); + if (!hlsUrl) return; + + self._audioFallbackDone = true; + self.log('Aucune piste audio démuxée (codec non supporté) — bascule HLS'); + self.onLoading('Piste audio incompatible — réencodage'); + + try { + player.unload(); + player.detachMediaElement(); + player.destroy(); + } catch (e) {} + self.mpegts = null; + + self.url = hlsUrl; + if (self._canPlayNativeHls()) self._playDirect(hlsUrl); + else self._startHls(); + }); + player.on(mpegts.Events.ERROR, function (type, detail) { self.log('Erreur MPEG-TS : ' + type + ' / ' + detail); if (self._destroyed) return; @@ -310,6 +338,17 @@ this._attemptPlay(); }; + /// `/api/live/.ts` → `/api/live//source/playlist.m3u8`. + /// + /// Le préréglage `source` garde la vidéo en copie de flux (`-c:v copy`) : + /// seul l'audio est réencodé, le coût processeur reste négligeable. + /// Renvoie `null` si l'URL n'est pas un flux live direct — rien à tenter. + XFPlayer.prototype._hlsEquivalent = function (url) { + var match = /^(.*\/api\/live\/)([^/?#]+)\.ts(\?.*)?$/.exec(url); + if (!match) return null; + return match[1] + match[2] + '/source/playlist.m3u8'; + }; + // ---------------- Lecture directe ---------------- XFPlayer.prototype._playDirect = function (url) {