fix(transcript): pipeline URLs signees yt-dlp + fetch durci anti-429
CI / build-and-test (push) Successful in 14m1s

Les URLs timedtext InnerTube repondent 200-vide (throttle YouTube) :
sonde rapide max 2 sans retry, puis dump yt-dlp -> URLs signees en
direct (max 4), puis --write-sub. 200-vide traite comme 429
(retryAfterSec), fmt= plus jamais duplique (signature), cookies
YT_COOKIES_FILE reutilises par le fetch direct. Tests 26/26.
This commit is contained in:
2026-09-27 20:47:28 -04:00
parent 148a00e60f
commit a79831f406
7 changed files with 214 additions and 62 deletions
+6 -2
View File
@@ -299,8 +299,12 @@ export function mapCaptionTracks(captionTracks) {
if (!base) continue;
const lang = normCaptionLang(t?.language_code) || 'und';
const name = t?.name?.text ?? (typeof t?.name === 'string' ? t.name : lang);
const sep = base.includes('?') ? '&' : '?';
const track = { url: `${base}${sep}fmt=json3`, ext: 'json3', name: String(name) };
// Ne jamais dupliquer `fmt=` : une URL signée dont on altère la query
// voit sa `signature` invalidée (YouTube répond 429/Sorry).
const trackUrl = /[?&]fmt=/i.test(base)
? base
: `${base}${base.includes('?') ? '&' : '?'}fmt=json3`;
const track = { url: trackUrl, ext: 'json3', name: String(name) };
const dict = t?.kind === 'asr' ? automatic_captions : subtitles;
if (!Array.isArray(dict[lang])) dict[lang] = [];
if (!dict[lang].some((x) => x.url === track.url)) dict[lang].push(track);