Transcriptions via la YouTube Data API : pourquoi captions.download échoue

Si vous essayez d'obtenir des transcriptions via la YouTube Data API, vous avez probablement déjà heurté le mur : captions.list renvoie joyeusement les IDs des pistes de sous-titres pour n'importe quelle vidéo, mais dès que vous appelez captions.download sur l'une d'elles, vous obtenez un 403. Vous revérifiez votre clé API, ajoutez le scope youtube.force-ssl, essayez OAuth — toujours 403. Ce n'est ni un bug ni un problème de quota. C'est voulu, et la documentation enterre l'essentiel.
La restriction, précisément
captions.download exige un jeton OAuth d'un compte qui possède la vidéo. Pas n'importe quel compte authentifié — le propriétaire de la chaîne (ou un gestionnaire de contenu qui en a les droits). Les endpoints captions existent pour que les créateurs gèrent les pistes de sous-titres de leurs propres vidéos : téléverser un .srt, corriger une coquille, supprimer une mauvaise traduction automatique. Télécharger les sous-titres de vidéos tierces arbitraires n'a jamais fait partie du contrat.
Le message d'erreur le dit noir sur blanc une fois qu'on le lit attentivement :
The permissions associated with the request are not sufficient
to download the caption track.
Donc le chemin d'escalade habituel — clé API → OAuth en votre nom → scopes plus larges → compte de service — ne mène nulle part. Chaque échelon échoue au même contrôle de propriété. J'y ai brûlé un après-midi avant de l'accepter, et à en juger par le trafic sur Stack Overflow, la moitié d'Internet aussi.
À quoi captions.list sert encore
Pour être juste envers la Data API : captions.list fonctionne avec une simple clé API et coûte environ 50 unités de quota. Il vous indique quelles pistes existent, leurs langues, et si elles sont générées automatiquement (trackKind: "asr") ou mises en ligne par un humain. C'est réellement utile comme vérification préalable — si une vidéo n'a aucune piste, vous savez d'emblée qu'il vous faudra de la reconnaissance vocale plutôt que de l'extraction de sous-titres. La Data API reste aussi le bon outil pour la recherche, l'énumération de playlists et les métadonnées. Elle ne vous donnera simplement pas le texte de la transcription.
Option 1 : récupérer les sous-titres comme le fait le lecteur
Le lecteur vidéo reçoit évidemment les données de sous-titres sans le jeton OAuth du propriétaire, et des bibliothèques comme youtube-transcript-api (Python) les récupèrent de la même manière. Sur votre ordinateur portable, cela fonctionne bien et tient en trois lignes.
Le bémol apparaît en production : YouTube conteste agressivement les requêtes provenant de plages d'IP de datacenter. Déployez les trois mêmes lignes sur AWS, GCP ou Heroku et vous commencerez à voir « Sign in to confirm you're not a bot » et des erreurs IpBlocked. J'ai documenté ce mode de défaillance et les contournements séparément dans pourquoi youtube-transcript-api se fait bloquer dans le cloud — en résumé : c'est réparable avec des proxies résidentiels, mais c'est un projet à part entière.
Option 2 : une API de transcription hébergée
Si vous voulez juste du texte à partir d'une URL, un endpoint hébergé contourne les deux problèmes — aucune exigence de propriété, aucun proxy à surveiller. youtube2text.org exécute la récupération des sous-titres derrière des proxies résidentiels rotatifs côté serveur, donc peu importe d'où vient votre requête :
# grab a free demo key (shared, 5 videos/month per IP)
curl -s https://youtube2text.org/api/demo-key
# fetch a transcript
curl -s "https://youtube2text.org/api/transcribe?url=https://www.youtube.com/watch?v=VIDEO_ID" \
-H "x-api-key: yt_YOUR_KEY"
La réponse est du JSON simple :
{"result": {"videoId": "...", "title": "...", "pubDate": "...",
"content": "full transcript text ...", "contentSize": 12345, "truncated": false}}
Si la vidéo n'a tout simplement pas de sous-titres, vous obtenez TRANSCRIPT_UNAVAILABLE avec un 404 — la même situation que captions.list aurait montrée comme une liste de pistes vide, juste détectée en un appel au lieu de deux.
Un guide plus détaillé avec la gestion des erreurs se trouve dans extraire des transcriptions YouTube avec curl, et une version Python dans le guide de migration youtube-transcript-api si le code basé sur requests est plus dans vos cordes.
Une configuration combinée raisonnable
Ce que je construirais réellement aujourd'hui, après avoir bataillé sur les deux fronts :
- La Data API pour la découverte — recherche, vidéos d'une chaîne, playlists, dates de publication. Elle est fiable et généreusement dotée en quota pour les métadonnées.
- Un endpoint de transcription (hébergé, ou auto-scrapé avec des proxies si ça vous amuse) pour le texte proprement dit.
- La reconnaissance vocale en solution de repli, uniquement pour les vidéos sans aucun sous-titre.
Essayer de forcer captions.download à faire le travail du milieu est le seul chemin qui ne peut catégoriquement pas fonctionner pour des vidéos que vous ne possédez pas — aucun scope, aucune clé, aucun réglage de console n'y change quoi que ce soit.
Si vous voulez votre propre clé plutôt que la clé de démonstration partagée, la connexion se fait uniquement via Google sur youtube2text.org/app/keys — sans numéro de téléphone, sans carte. Le niveau gratuit offre 5 vidéos/mois ; les formules payantes commencent à 5,99 $ pour 50.