Résume automatiquement les vidéos YouTube avec Python, Whisper et GPT

Tu passes des heures Ă  regarder des vidĂ©os YouTube pour en extraire l’essentiel : une confĂ©rence de 45 minutes, un tutoriel de 20 minutes, une interview technique
 Et si tu pouvais obtenir un rĂ©sumĂ© structurĂ© en moins de 30 secondes ? C’est exactement ce que tu vas construire dans ce tutoriel : un script Python qui rĂ©cupĂšre la transcription d’une vidĂ©o, la rĂ©sume avec un modĂšle de langage, et te sort un compte-rendu clair avec les points clĂ©s et les actions Ă  retenir.

C’est un projet parfait pour progresser : tu manipules des API, tu dĂ©couvres la transcription audio, tu utilises un vrai LLM et tu obtiens un outil que tu rĂ©utiliseras tous les jours. Et bonne nouvelle, tout est faisable avec les fondamentaux de Python que tu connais dĂ©jĂ  : fonctions, listes, dictionnaires, gestion d’erreurs.

Comment ça marche ?

Le pipeline tient en trois étapes :

  • RĂ©cupĂ©rer la transcription : la plupart des vidĂ©os YouTube ont des sous-titres gĂ©nĂ©rĂ©s automatiquement. On les rĂ©cupĂšre avec la bibliothĂšque youtube-transcript-api.
  • Replier sur Whisper : si la vidĂ©o n’a pas de sous-titres, on tĂ©lĂ©charge l’audio et on le transcrit avec Whisper, le modĂšle de reconnaissance vocale d’OpenAI.
  • RĂ©sumer avec un LLM : on envoie la transcription Ă  un modĂšle de langage (GPT, Claude, ou un modĂšle local) avec un prompt bien construit pour obtenir un rĂ©sumĂ© structurĂ©.

L’idĂ©e clĂ© du rĂ©sumĂ© : ne jamais envoyer la transcription entiĂšre d’un coup. On la dĂ©coupe en morceaux (chunks), on rĂ©sume chaque morceau, puis on rĂ©sume les rĂ©sumĂ©s. C’est la technique du map-reduce appliquĂ©e aux LLM — exactement ce que font les frameworks comme LangChain en interne.

Étape 1 — RĂ©cupĂ©rer la transcription

Commençons par installer les dépendances :

pip install youtube-transcript-api openai-whisper pytube

La récupération des sous-titres est étonnamment simple :

from youtube_transcript_api import YouTubeTranscriptApi

def get_transcript(video_id: str) -> str:
    """RécupÚre la transcription d'une vidéo YouTube."""
    api = YouTubeTranscriptApi()
    transcript = api.fetch(video_id)
    return " ".join(segment.text for segment in transcript)

# Exemple : la vidéo "Python for Beginners" (ID factice)
video_id = "VIDEO_ID_ICI"
print(get_transcript(video_id)[:200])

Chaque segment de la transcription contient aussi un timestamp. Tu peux l’utiliser pour crĂ©er un sommaire cliquable qui pointe vers les moments importants de la vidĂ©o — un vrai plus pour un article de blog ou des notes de cours.

Étape 2 — Le plan B : Whisper pour les vidĂ©os sans sous-titres

Certaines vidĂ©os n’ont pas de sous-titres (musique, vidĂ©os trĂšs anciennes, contenu non sous-titrĂ©). Dans ce cas, on tĂ©lĂ©charge la piste audio et on la transcrit avec Whisper, qui fonctionne 100% en local et gratuitement :

import whisper
from pytube import YouTube

def transcribe_with_whisper(video_url: str) -> str:
    """Télécharge l'audio et le transcrit avec Whisper."""
    yt = YouTube(video_url)
    audio = yt.streams.filter(only_audio=True).first()
    audio.download(filename="audio.mp3")

    model = whisper.load_model("base")  # "small" ou "medium" pour plus de précision
    result = model.transcribe("audio.mp3")
    return result["text"]

Le modĂšle base est un bon compromis : rapide et correct en français. Si la vidĂ©o est en anglais, base est trĂšs bon. Pour un usage ponctuel, c’est largement suffisant — et tu gardes le contrĂŽle de tes donnĂ©es puisque tout tourne sur ta machine.

Étape 3 — RĂ©sumer avec un LLM (map-reduce)

Maintenant, la partie intéressante. On découpe la transcription en chunks de ~4000 caractÚres, on résume chaque chunk, puis on combine :

from openai import OpenAI

client = OpenAI()  # lit la clé API dans la variable d'env OPENAI_API_KEY

def chunk_text(text: str, size: int = 4000) -> list[str]:
    """Découpe un texte long en morceaux de taille fixe."""
    return [text[i:i + size] for i in range(0, len(text), size)]

def summarize_chunk(chunk: str) -> str:
    """Résume un morceau de transcription."""
    prompt = f"""Résume le texte suivant en français, en 3 à 5 phrases.
    Garde les idées techniques importantes et les chiffres clés.

    TEXTE :
    {chunk}"""
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.3,
    )
    return response.choices[0].message.content

def summarize_video(transcript: str) -> str:
    """Pipeline map-reduce : résume chaque chunk puis le tout."""
    chunks = chunk_text(transcript)
    partials = [summarize_chunk(c) for c in chunks]

    final_prompt = f"""À partir des rĂ©sumĂ©s partiels suivants, rĂ©dige un compte-rendu
    structuré en français avec :
    - Un titre
    - Les points clés (liste à puces)
    - Les actions concrĂštes Ă  retenir

    RÉSUMÉS PARTIELS :
    {" ".join(partials)}"""
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": final_prompt}],
        temperature=0.3,
    )
    return response.choices[0].message.content

Pourquoi cette approche ? Parce que les LLM ont une fenĂȘtre de contexte limitĂ©e. Une confĂ©rence d’une heure reprĂ©sente facilement 30 000 caractĂšres de transcription — bien trop pour un seul appel. Le dĂ©coupage permet de traiter n’importe quelle durĂ©e de vidĂ©o, et la phase finale de synthĂšse garantit un rĂ©sumĂ© cohĂ©rent.

Étape 4 — Tout assembler

Il ne reste plus qu’Ă  brancher les piĂšces entre elles, avec une gestion d’erreur propre :

import sys
from youtube_transcript_api import TranscriptsDisabled

def summarize_youtube_video(video_url: str) -> str:
    """Point d'entrĂ©e : URL → rĂ©sumĂ© structurĂ©."""
    video_id = video_url.split("v=")[-1].split("&")[0]

    try:
        transcript = get_transcript(video_id)
        source = "sous-titres YouTube"
    except TranscriptsDisabled:
        print("Pas de sous-titres → transcription Whisper...")
        transcript = transcribe_with_whisper(video_url)
        source = "Whisper"

    print(f"Transcription récupérée ({source}) : {len(transcript)} caractÚres")
    summary = summarize_video(transcript)
    return summary

if __name__ == "__main__":
    url = sys.argv[1] if len(sys.argv) > 1 else input("URL de la vidéo : ")
    print(summarize_youtube_video(url))

Et voilĂ . Lance python resume_youtube.py "https://www.youtube.com/watch?v=..." et en moins d’une minute tu obtiens un compte-rendu structurĂ© de n’importe quelle vidĂ©o.

Aller plus loin

Ce projet est une excellente base pour des idées plus ambitieuses :

  • GĂ©nĂ©rer des flashcards Anki Ă  partir du rĂ©sumĂ© pour mĂ©moriser le contenu.
  • Extraire les questions/rĂ©ponses d’une confĂ©rence pour prĂ©parer un examen.
  • CrĂ©er une playlist intelligente : rĂ©sume plusieurs vidĂ©os et regroupe-les par thĂšme.
  • Automatiser le tout avec un cron qui traite tes vidĂ©os « À regarder plus tard » chaque semaine.

Tu peux aussi remplacer l’API OpenAI par un modĂšle local (via Ollama ou llama.cpp) pour un coĂ»t nul — le code change Ă  peine, c’est toute la puissance des API compatibles OpenAI.

Conclusion

Tu viens de construire un outil concret qui combine transcription automatique et rĂ©sumĂ© par IA : deux compĂ©tences trĂšs demandĂ©es en 2026. Le plus important, ce n’est pas le script en lui-mĂȘme, c’est la mĂ©thode — dĂ©couper un problĂšme, appeler des API proprement, gĂ©rer les erreurs, assembler un pipeline. Exactement ce que font les dĂ©veloppeurs IA au quotidien.

Si certaines parties du code te semblent encore floues (les fonctions, les dictionnaires, la gestion des chaĂźnes de caractĂšres), c’est le moment de consolider tes bases : le cours Python — Les fondamentaux t’apprend tout ce qu’il faut pour Ă©crire ce genre de script en toute confiance, pas Ă  pas et avec des exercices pratiques.