# Parametres Papermill - JAMAIS modifier ce commentaire
# Configuration notebook
notebook_mode = "interactive" # "interactive" ou "batch"
skip_widgets = False # True pour mode batch MCP
debug_level = "INFO"
# Parametres contenu educatif
tts_model = "tts-1" # "tts-1" ou "tts-1-hd"
narrator_voice = "nova" # Voix principale de narration
secondary_voice = "onyx" # Voix secondaire (exemples, citations)
llm_model = "gpt-4o-mini" # Modele LLM pour generation de scripts
target_languages = ["fr", "en"] # Langues cibles
accessibility_speed = 0.85 # Vitesse reduite pour accessibilite
# Configuration sauvegarde
generate_audio = True
save_audio_files = TrueCreation de Contenu Audio Educatif
Module : 04-Audio-Applications
Niveau : Applications
Technologies : OpenAI TTS, Kokoro TTS, Whisper, GPT (LLM), pydub
VRAM estimee : ~10 GB
Duree estimee : 50 minutes
Objectifs d’Apprentissage
Prerequis
- Notebooks Foundation (01-1 a 01-5) completes
- Cle API OpenAI configuree (
OPENAI_API_KEYdans.env) - pydub installe (manipulation audio)
- Comprehension de base du TTS et du STT
Navigation : Index | << Précédent | Suivant >>
# Parameters
BATCH_MODE = True
skip_widgets = TrueL’environnement de travail est configure avec les paramètres Papermill. La cellule suivante charge les bibliotheques Python necessaires : gestion des fichiers audio, appels API et utilitaires de traitement.
# Setup environnement et imports
import os
import sys
import json
import time
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Any, Optional
from io import BytesIO
import logging
from IPython.display import Audio, display, HTML
# Resolution GENAI_ROOT
GENAI_ROOT = Path.cwd()
while GENAI_ROOT.name != 'GenAI' and len(GENAI_ROOT.parts) > 1:
GENAI_ROOT = GENAI_ROOT.parent
HELPERS_PATH = GENAI_ROOT / 'shared' / 'helpers'
if HELPERS_PATH.exists():
sys.path.insert(0, str(HELPERS_PATH.parent))
try:
from helpers.audio_helpers import (
play_audio_bytes, display_audio_bundle, synthesize_openai, transcribe_openai,
get_audio_info, estimate_audio_duration
)
print("Helpers audio importes")
except ImportError as e:
print(f"Helpers audio non disponibles - mode autonome : {e}")
# Repertoire de sortie
OUTPUT_DIR = GENAI_ROOT / 'outputs' / 'audio' / 'educational'
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
# Configuration logging
logging.basicConfig(level=getattr(logging, debug_level))
logger = logging.getLogger('educational_audio')
print(f"Creation de Contenu Audio Educatif")
print(f"Date : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Mode : {notebook_mode}, TTS : {tts_model}")
print(f"Voix narrateur : {narrator_voice}, Voix secondaire : {secondary_voice}")
print(f"Sortie : {OUTPUT_DIR.relative_to(GENAI_ROOT)}")Helpers audio importes
Creation de Contenu Audio Educatif
Date : 2026-08-16 01:49:49
Mode : interactive, TTS : tts-1
Voix narrateur : nova, Voix secondaire : onyx
Sortie : outputs\audio\educational
Les modules Python sont importes. Cette cellule charge les cles API depuis le fichier .env en remontant l’arborescence de repertoires pour s’adapter aux différents contextes d’exécution (local, Papermill, CI).
# Chargement robuste de la configuration .env (Pattern A - Papermill-safe)
from dotenv import load_dotenv
import os
from pathlib import Path
current_path = Path.cwd()
genai_path = None
# Remonter jusqu'au dossier GenAI
while len(current_path.parts) > 1:
if current_path.name == "GenAI":
genai_path = current_path
break
current_path = current_path.parent
if genai_path:
env_path = genai_path / ".env"
if env_path.exists():
load_dotenv(env_path)
print(f".env charge depuis: {env_path.name}")
# Configuration API OpenAI
openai_key = os.environ.get('OPENAI_API_KEY', '')
openai_available = bool(openai_key and not openai_key.startswith('sk-or-'))
if openai_available:
print("OPENAI_API_KEY valide - API disponible")
from openai import OpenAI
client = OpenAI(api_key=openai_key)
else:
print("OPENAI_API_KEY non disponible ou invalide (cle OpenRouter)")
openai_key = "dummy_key_for_validation"
client = None.env charge depuis: .env
OPENAI_API_KEY valide - API disponible
Pipeline complet de creation de contenu audio educatif
Ce notebook explore la creation de contenus audio pedagogiques en utilisant les technologies de l’IA : LLM pour la generation de scripts, TTS (Text-to-Speech) pour la narration, et STT (Speech-to-Text) pour la validation qualite.
Cas d’usage pedagogiques :
| Scénario | Description | Technologies |
|---|---|---|
| Cours audio pour MOOC | Modules narres accessibles offline | LLM + TTS multi-voix |
| Contenu multilingue | Cours traduits en plusieurs langues | Traduction LLM + TTS multilingue |
| Accessibilite MALV | Adaptation pour publics a besoins spécifiques | TTS vitesse reduite + enonciation claire |
| Podcasts educatifs | Contenu audio structuré et engageant | Multi-voix + assemblage pydub |
| Validation qualite | Verification fidelite narration | Round-trip TTS->STT |
Architecture du pipeline :
Texte de cours (ecrit)
↓
[LLM] GPT-4o-mini
(Adaptation ecrit→oral)
↓
Script narre avec marqueurs
[NARRATEUR], [EXPERT], [PAUSE]
↓
[Parsing] Python
(Extraction segments par voix)
↓
[TTS] OpenAI tts-1
(Synthese audio multi-voix)
↓
[Assemblage] pydub
(Concatenation + normalisation)
↓
[Validation] Whisper
(Round-trip STT)
↓
Cours audio final (.mp3)
Nous allons implementer ce pipeline étape par étape, en testant différentes configurations (multi-voix, multilingue, accessibilite) pour evaluer leur impact pedagogique.
Section 1 : Generation de scripts de narration via LLM
La première étape d’un contenu audio educatif consiste a transformer un texte brut de cours en un script de narration naturel. Un LLM adapte le contenu technique en discours oral fluide :
| Étape | Description | Outil |
|---|---|---|
| Texte source | Contenu pedagogique brut | – |
| Reformulation | Adaptation pour la narration orale | GPT-4o-mini |
| Structuration | Decoupage en sections narrees | GPT-4o-mini |
| Attribution voix | Assignation des voix par section | Configuration |
Le LLM recoit le texte de cours et genere un script avec des indications de voix, pauses et intonation.
# Generation de scripts de narration a partir de texte de cours
print("GENERATION DE SCRIPTS DE NARRATION")
print("=" * 50)
# Texte de cours source (exemple : introduction a l'IA)
course_text = """
L'intelligence artificielle (IA) est un domaine de l'informatique qui vise
a creer des systemes capables de realiser des taches necessitant normalement
l'intelligence humaine. Ces taches incluent la reconnaissance vocale,
la prise de decision, la traduction et la generation de contenu.
Le machine learning (apprentissage automatique) est une sous-branche de l'IA
qui permet aux machines d'apprendre a partir de donnees sans etre explicitement
programmees. Les reseaux de neurones profonds (deep learning) sont une technique
de machine learning inspiree du cerveau humain.
""".strip()
# Prompt pour le LLM : transformer en script de narration
narration_prompt = f"""
Transforme ce texte de cours en un script de narration audio educatif.
Le script doit :
- Etre naturel a l'oral (phrases courtes, transitions fluides)
- Inclure des marqueurs [PAUSE] pour les pauses naturelles
- Indiquer les changements de voix avec [NARRATEUR] et [EXPERT]
- Ajouter une introduction accueillante et une conclusion
Texte source :
{course_text}
Genere uniquement le script, sans commentaires.
"""
narration_script = ""
if generate_audio:
start_time = time.time()
response = client.chat.completions.create(
model=llm_model,
messages=[{"role": "user", "content": narration_prompt}],
temperature=0.7,
max_tokens=1000
)
narration_script = response.choices[0].message.content
gen_time = time.time() - start_time
print(f"Script genere en {gen_time:.1f}s")
print(f"Tokens utilises : {response.usage.total_tokens}")
print(f"\n--- Script de narration ---")
print(narration_script)
print(f"--- Fin du script ---")
print(f"\nLongueur : {len(narration_script)} caracteres")
print(f"Duree estimee : {estimate_audio_duration(narration_script):.0f}s")
else:
print("Generation desactivee (generate_audio=False)")GENERATION DE SCRIPTS DE NARRATION
==================================================
Script genere en 5.4s
Tokens utilises : 609
--- Script de narration ---
[NARRATEUR] Bonjour et bienvenue dans cet épisode consacré à l'intelligence artificielle, ou IA. [PAUSE] Aujourd'hui, nous allons explorer ce domaine fascinant de l'informatique. [PAUSE] Prêt ? C'est parti !
[NARRATEUR] L'intelligence artificielle vise à créer des systèmes capables d'accomplir des tâches qui nécessitent normalement l'intelligence humaine. [PAUSE] Ces tâches incluent, par exemple, la reconnaissance vocale, [PAUSE] la prise de décision, [PAUSE] la traduction et même la génération de contenu. [PAUSE] Intéressant, n'est-ce pas ?
[EXPERT] En effet, l'IA est omniprésente dans notre quotidien. [PAUSE] Mais pour mieux comprendre, il est essentiel de se pencher sur une de ses sous-branches : le machine learning, ou apprentissage automatique. [PAUSE] Cette technique permet aux machines d'apprendre à partir de données, sans être explicitement programmées. [PAUSE] C'est ce qui les rend si puissantes.
[NARRATEUR] Exactement ! [PAUSE] Et pour aller encore plus loin, nous avons le deep learning, ou apprentissage profond. [PAUSE] C'est une technique inspirée du fonctionnement du cerveau humain. [PAUSE] Les réseaux de neurones profonds imitent la façon dont nous apprenons, [PAUSE] ce qui permet aux machines de résoudre des problèmes complexes.
[NARRATEUR] Voilà un aperçu de l'intelligence artificielle et de ses sous-disciplines. [PAUSE] C'est un domaine en constante évolution, [PAUSE] qui transforme notre monde de manière incroyable. [PAUSE] Merci de nous avoir écoutés aujourd'hui ! [PAUSE] À très bientôt pour de nouvelles découvertes !
--- Fin du script ---
Longueur : 1566 caracteres
Duree estimee : 89s
Interpretation : Generation de scripts par LLM
| Aspect | Valeur observee | Analyse pedagogique |
|---|---|---|
| Temps de generation | runtime machine-dep : ~8 secondes | Rapide, permet itérations et affinements |
| Tokens utilises | 599 (input + output) | Economique pour GPT-4o-mini |
| Longueur script | 1516 caractères | ~2x le texte source (adaptation ecrit->oral) |
| Duree estimee | ~80 secondes | Format micro-module ideal |
| Structure | Alternance NARRATEUR/EXPERT | Decoupage pedagogique coherent |
Points cles : 1. Le LLM adapte naturellement le registre ecrit vers l’oral (phrases plus courtes, transitions) 2. Les marqueurs [PAUSE] indiquent les rythmes naturels de la parole 3. La structure multi-voix emerge spontanement du prompt pedagogique 4. Temperature 0.7 = equilibre entre fidelite au contenu et creativité orale
Note technique : Pour des contenus plus longs, decouper en sections de 200-300 mots et generer des scripts separes avec des contextes différents (introduction, développement, conclusion).
Section 1 : Generation de scripts de narration via LLM
La première étape d’un contenu audio educatif consiste a transformer un texte brut de cours en un script de narration naturel. Un LLM (Large Language Model) comme GPT-4o-mini adapte le contenu technique en discours oral fluide.
Pipeline de transformation :
Texte source (cours) -> LLM (GPT-4o-mini) -> Script narre avec marqueurs -> Parsing -> Segments par voix
Marqueurs generes par le LLM :
| Marqueur | Signification | Utilisation |
|---|---|---|
[NARRATEUR] |
Voix principale | Introduction, transitions, conclusion |
[EXPERT] |
Voix d’autorite | Definitions, concepts techniques |
[PAUSE] |
Silence naturel | Respiration, emphasis, transitions |
Le LLM recoit le texte de cours et un prompt pedagogique specifiant le format de sortie, puis genere un script avec des indications de voix, pauses et intonation.
Exercice : Prompt engineering pour scripts de narration
Duree estimee : 15-20 minutes
Objectif
Créer un prompt système optimise pour generer des scripts de narration educative adaptes a différents publics (debutants, experts, enfants).
Contexte
Le script de narration est la base du pipeline audio. La qualite du prompt LLM determine directement la qualite du script genere. Un bon prompt precise le format de sortie, les marqueurs de voix et le registre de langue attendu.
Instructions
- Analyser le prompt
narration_promptutilise dans la cellule précédente - Créer une fonction qui genere des scripts adaptes a un niveau de public
- Tester avec un même texte source pour 2 niveaux différents
- Comparer les scripts obtenus (longueur, structure, vocabulaire)
Indices : -
# Étape 1: Définir les paramètres de niveau (vocabulaire simple vs technique) -# Étape 2: Construire un prompt dynamique en fonction du niveau -# Étape 3: Appeler le LLM avec le prompt personnalise -# Indice: Utiliser les paramètrestemperatureetmax_tokenspour ajuster la creativite -# Indice: Un prompt “debutant” doit demander des phrases courtes et des analogies
# TODO: Creer un generateur de scripts adapte au niveau du public
def generate_adaptive_script(source_text: str, target_audience: str = "debutant",
llm_client=None, model: str = "gpt-4o-mini") -> str:
"""
Genere un script de narration adapte au niveau du public cible.
Args:
source_text: Texte de cours source
target_audience: "debutant", "intermediaire" ou "expert"
llm_client: Client OpenAI initialise
model: Modele LLM a utiliser
Returns:
Script avec marqueurs [NARRATEUR], [EXPERT], [PAUSE]
"""
# Etape 1 : Definir les instructions par niveau
# Indice: Un debutant a besoin d'analogies, un expert de termes techniques
audience_instructions = None # TODO etudiant : construire le prompt
# Etape 2 : Construire le prompt complet
# Indice: Inclure le texte source et les consignes de format
full_prompt = None # TODO etudiant
# Etape 3 : Appeler le LLM
# Indice: adapter temperature selon le niveau (plus creatif pour debutant)
generated_script = None # TODO etudiant : appeler llm_client.chat.completions.create()
return generated_script if generated_script else ""
# Test avec le texte de cours du notebook
test_levels = ["debutant", "expert"]
for level in test_levels:
print(f"\n--- Niveau : {level} ---")
# script = generate_adaptive_script(course_text, level, client, llm_model)
# print(f"Script genere ({len(script)} chars) :")
# print(script[:200] + "...")
print(f"Exercice a completer pour le niveau {level}")
--- Niveau : debutant ---
Exercice a completer pour le niveau debutant
--- Niveau : expert ---
Exercice a completer pour le niveau expert
Section 2 : Narration multi-voix
Un contenu educatif beneficie de plusieurs voix pour distinguer les rôles :
| Rôle | Voix suggeree | Utilisation |
|---|---|---|
| Narrateur principal | nova |
Explications, transitions |
| Expert / Citations | onyx |
Definitions, concepts cles |
| Exemples | echo |
Illustrations pratiques |
Nous allons parser le script genere, identifier les segments par voix, et generer chaque segment avec la voix appropriee.
# Narration multi-voix : parser et generer par segments
print("NARRATION MULTI-VOIX")
print("=" * 50)
import re
# Mapping des roles vers les voix OpenAI
voice_mapping = {
"NARRATEUR": narrator_voice,
"EXPERT": secondary_voice,
"DEFAULT": narrator_voice
}
def parse_narration_script(script: str) -> List[Dict[str, str]]:
"""Parse un script avec marqueurs [ROLE] en segments."""
segments = []
current_role = "DEFAULT"
current_text = []
for line in script.split('\n'):
line = line.strip()
if not line:
continue
# Detection marqueur de role
role_match = re.match(r'\[(NARRATEUR|EXPERT)\]', line)
if role_match:
# Sauvegarder le segment precedent
if current_text:
text = ' '.join(current_text).strip()
text = re.sub(r'\[PAUSE\]', '...', text)
if text:
segments.append({"role": current_role, "text": text})
current_role = role_match.group(1)
# Texte apres le marqueur
remaining = line[role_match.end():].strip()
current_text = [remaining] if remaining else []
else:
current_text.append(line)
# Dernier segment
if current_text:
text = ' '.join(current_text).strip()
text = re.sub(r'\[PAUSE\]', '...', text)
if text:
segments.append({"role": current_role, "text": text})
return segments
# Parser le script
if narration_script:
segments = parse_narration_script(narration_script)
else:
# Script de demonstration si la generation a ete sautee
segments = [
{"role": "NARRATEUR", "text": "Bienvenue dans ce cours sur l'intelligence artificielle."},
{"role": "EXPERT", "text": "L'intelligence artificielle est un domaine qui vise a creer des systemes intelligents."},
{"role": "NARRATEUR", "text": "Voyons maintenant le machine learning, une sous-branche fondamentale."},
{"role": "EXPERT", "text": "Le machine learning permet aux machines d'apprendre a partir de donnees."}
]
print(f"Segments identifies : {len(segments)}")
print(f"\nDetail des segments :")
for i, seg in enumerate(segments):
voice = voice_mapping.get(seg['role'], narrator_voice)
print(f" [{i+1}] {seg['role']:12s} -> voix '{voice}' | {seg['text'][:60]}...")
# Generer chaque segment avec la voix appropriee
audio_segments = []
if generate_audio:
print(f"\nGeneration audio par segment :")
total_start = time.time()
for i, seg in enumerate(segments):
voice = voice_mapping.get(seg['role'], narrator_voice)
start_time = time.time()
response = client.audio.speech.create(
model=tts_model,
voice=voice,
input=seg['text'],
response_format="mp3",
speed=1.0
)
audio_data = response.content
gen_time = time.time() - start_time
audio_segments.append({
"role": seg['role'],
"voice": voice,
"audio": audio_data,
"size_kb": len(audio_data) / 1024,
"time": gen_time
})
print(f" Segment {i+1}/{len(segments)} : {voice} | {gen_time:.1f}s | {len(audio_data)/1024:.1f} KB")
total_time = time.time() - total_start
print(f"\nTotal : {len(audio_segments)} segments en {total_time:.1f}s")
print(f"Taille totale : {sum(s['size_kb'] for s in audio_segments):.1f} KB")
# Ecouter le premier segment
if audio_segments:
print(f"\nEcoute du premier segment ({audio_segments[0]['role']}, voix {audio_segments[0]['voice']}) :")
display_audio_bundle(audio_segments[0]['audio'])
else:
print("Generation desactivee")NARRATION MULTI-VOIX
==================================================
Segments identifies : 5
Detail des segments :
[1] NARRATEUR -> voix 'nova' | Bonjour et bienvenue dans cet épisode consacré à l'intellige...
[2] NARRATEUR -> voix 'nova' | L'intelligence artificielle vise à créer des systèmes capabl...
[3] EXPERT -> voix 'onyx' | En effet, l'IA est omniprésente dans notre quotidien. ... Ma...
[4] NARRATEUR -> voix 'nova' | Exactement ! ... Et pour aller encore plus loin, nous avons ...
[5] NARRATEUR -> voix 'nova' | Voilà un aperçu de l'intelligence artificielle et de ses sou...
Generation audio par segment :
Segment 1/5 : nova | 3.3s | 178.1 KB
Segment 2/5 : nova | 2.5s | 283.9 KB
Segment 3/5 : onyx | 4.2s | 337.9 KB
Segment 4/5 : nova | 2.0s | 306.8 KB
Segment 5/5 : nova | 2.0s | 257.6 KB
Total : 5 segments en 13.9s
Taille totale : 1364.2 KB
Ecoute du premier segment (NARRATEUR, voix nova) :
Interpretation : Narration multi-voix
| Aspect | Valeur observee | Analyse pedagogique |
|---|---|---|
| Segments generes | 5 segments (4 narrateur, 1 expert) | Equilibre narrateur/expert = 4:1, demonstration courte |
| Voix utilisees | nova (narrateur), onyx (expert) | Differentiation claire, ton adapte au rôle |
| Temps generation | runtime machine-dep : ~20 secondes pour 5 segments (observe 19.7s) | Performance adequate pour production batch |
| Taille totale | 1.6 MB (observe 1623.8 KB) | Compact pour ~20 secondes d’audio |
Points cles : 1. La multi-voix ameliore l’engagement en variant le timbre et le rythme 2. Les marqueurs [NARRATEUR] et [EXPERT] structurent le contenu de facon automatique 3. Les pauses [PAUSE] converties en ellipses (…) créent un rythme naturel 4. La distinction voix feminine (nova) vs voix masculine (onyx) aide a suivre les changements de rôle
Bon a savoir : Pour les contenus plus complexes, vous pouvez ajouter d’autres rôles (EXEMPLE, DEFINITION, CONCLUSION) avec des voix distinctes (echo, shimmer, fable).
En complement — benefice pedagogique : la multi-voix rend le contenu plus dynamique qu’un narrateur unique, en maintenant l’attention de l’auditeur sur les changements de role.
Section 2 : Narration multi-voix
Un contenu educatif beneficie de plusieurs voix pour distinguer les rôles et maintenir l’engagement de l’auditeur. Cette technique, commune dans les documentaires et podcasts educatifs, s’applique également aux cours audio generes par IA.
Rôles typiques dans un cours audio :
| Rôle | Voix suggeree | Fonction pedagogique |
|---|---|---|
| Narrateur principal | nova (F) ou alloy (N) |
Explications, transitions, fil conducteur |
| Expert / Citations | onyx (M) ou fable (N) |
Definitions techniques, concepts cles, autorite |
| Exemples / Illustrations | echo (F) ou shimmer (F) |
Cas pratiques, analogies, ton plus leger |
Nous allons parser le script genere par le LLM pour identifier les segments par rôle (marqueurs [NARRATEUR], [EXPERT]), puis generer chaque segment avec la voix OpenAI appropriee.
Section 3 : Contenu multilingue
L’API OpenAI TTS gere nativement de nombreuses langues. Pour créer du contenu multilingue, deux approches :
| Approche | Description | Avantage |
|---|---|---|
| Traduction LLM + TTS | Traduire via GPT, puis synthetiser | Contrôle total du texte |
| TTS direct multilingue | Fournir le texte dans la langue cible | Plus simple, qualite variable |
Nous utilisons la première approche pour garantir la qualite pedagogique du contenu traduit.
# Contenu multilingue : traduction + narration
print("CONTENU MULTILINGUE")
print("=" * 50)
# Texte source en francais
source_text_fr = (
"L'apprentissage automatique permet aux ordinateurs d'apprendre "
"a partir d'exemples. Au lieu de programmer chaque regle manuellement, "
"on fournit des donnees et l'algorithme decouvre les patterns par lui-meme."
)
lang_configs = {
"fr": {"name": "Francais", "voice": "nova", "text": source_text_fr},
"en": {"name": "English", "voice": "alloy", "text": None} # A traduire
}
multilingual_results = {}
if generate_audio:
# Etape 1 : Traduction vers l'anglais via LLM
print("Etape 1 : Traduction via LLM")
translation_response = client.chat.completions.create(
model=llm_model,
messages=[{
"role": "user",
"content": f"Traduis ce texte educatif en anglais, en gardant le ton pedagogique :\n\n{source_text_fr}"
}],
temperature=0.3
)
lang_configs["en"]["text"] = translation_response.choices[0].message.content
for lang_code, config in lang_configs.items():
print(f"\n--- {config['name']} ({lang_code}) ---")
print(f"Texte : {config['text'][:80]}...")
start_time = time.time()
response = client.audio.speech.create(
model=tts_model,
voice=config['voice'],
input=config['text'],
response_format="mp3"
)
audio_data = response.content
gen_time = time.time() - start_time
multilingual_results[lang_code] = {
"audio": audio_data,
"text": config['text'],
"voice": config['voice'],
"size_kb": len(audio_data) / 1024,
"time": gen_time
}
print(f"Voix : {config['voice']} | {gen_time:.1f}s | {len(audio_data)/1024:.1f} KB")
display_audio_bundle(audio_data)
if save_audio_files:
filepath = OUTPUT_DIR / f"multilingual_{lang_code}.mp3"
with open(filepath, 'wb') as f:
f.write(audio_data)
print(f"Sauvegarde : {filepath.name}")
# Comparaison
print(f"\nComparaison multilingue :")
print(f"{'Langue':<12} {'Voix':<10} {'Taille (KB)':<12} {'Temps (s)':<10}")
print("-" * 44)
for lang, data in multilingual_results.items():
print(f"{lang:<12} {data['voice']:<10} {data['size_kb']:<12.1f} {data['time']:<10.1f}")
else:
print("Generation desactivee")CONTENU MULTILINGUE
==================================================
Etape 1 : Traduction via LLM
--- Francais (fr) ---
Texte : L'apprentissage automatique permet aux ordinateurs d'apprendre a partir d'exempl...
Voix : nova | 2.2s | 195.8 KB
Sauvegarde : multilingual_fr.mp3
--- English (en) ---
Texte : Machine learning enables computers to learn from examples. Instead of manually p...
Voix : alloy | 1.6s | 160.9 KB
Sauvegarde : multilingual_en.mp3
Comparaison multilingue :
Langue Voix Taille (KB) Temps (s)
--------------------------------------------
fr nova 195.8 2.2
en alloy 160.9 1.6
Interpretation : Contenu multilingue
| Langue | Voix | Taille fichier | Qualite perçue |
|---|---|---|---|
| Francais (nova) | F = voix feminine | 253 KB | Excellente, ton pedagogique naturel |
| Anglais (alloy) | N = voix neutre | 201 KB | Excellente, native pour le modèle |
Points cles : 1. L’API OpenAI TTS gere nativement de nombreuses langues avec une qualite constante 2. La traduction LLM (GPT-4o-mini) preserve le ton pedagogique et la structure 3. La différence de taille fichier (~20%) s’explique par la densite linguistique (anglais plus concis) 4. Pour des productions multilingues, créer d’abord le script dans la langue source, puis traduire avec des prompts de contexte pedagogique
Note technique : Pour les langues moins supportees (arabe, hindi, etc.), tester avec un locuteur natif avant production large echelle.
Section 3 : Contenu multilingue
L’API OpenAI TTS supporte plus de 50 langues, ce qui permet de créer du contenu educatif multilingue sans changer d’outil. Deux approches sont possibles :
| Approche | Méthode | Avantages | Inconvenients |
|---|---|---|---|
| Traduction LLM + TTS | Traduire via GPT, puis synthetiser | Contrôle total, preservation du ton pedagogique, adaptation culturelle | Deux étapes (plus lent) |
| TTS direct multilingue | Fournir texte traduit, synthetiser direct | Plus simple, une seule étape | Qualite depend de la traduction source |
Nous utilisons la première approche (traduction LLM) pour garantir que le contenu reste pedagogique et naturel dans chaque langue cible. Le prompt de traduction inclut le contexte “educatif” pour preserver le ton.
Section 4 : Accessibilite audio
Un contenu educatif accessible doit prendre en compte différents profils d’apprenants :
| Paramètre | Valeur standard | Valeur accessible | Impact |
|---|---|---|---|
| Vitesse | 1.0x | 0.85x | Meilleure comprehension |
| Pauses | Courtes | Allongees | Temps de reflexion |
| Voix | Au choix | Claire, posee | Intelligibilite |
| Repetitions | Aucune | Concepts cles repetes | Memorisation |
# Accessibilite : vitesse reduite et enonciation claire
print("ACCESSIBILITE AUDIO")
print("=" * 50)
accessibility_text = (
"Un reseau de neurones est compose de couches de neurones artificiels. "
"Chaque neurone recoit des entrees, les multiplie par des poids, "
"et applique une fonction d'activation. "
"Retenez bien : entrees, poids, activation. "
"C'est le fonctionnement fondamental de tout reseau de neurones."
)
speed_configs = [
{"label": "Standard (1.0x)", "speed": 1.0},
{"label": f"Accessible ({accessibility_speed}x)", "speed": accessibility_speed},
{"label": "Lent (0.7x)", "speed": 0.7}
]
accessibility_results = []
if generate_audio:
for config in speed_configs:
print(f"\n--- {config['label']} ---")
start_time = time.time()
response = client.audio.speech.create(
model=tts_model,
voice=narrator_voice,
input=accessibility_text,
response_format="mp3",
speed=config['speed']
)
audio_data = response.content
gen_time = time.time() - start_time
accessibility_results.append({
"label": config['label'],
"speed": config['speed'],
"audio": audio_data,
"size_kb": len(audio_data) / 1024,
"time": gen_time
})
print(f"Taille : {len(audio_data)/1024:.1f} KB | Temps : {gen_time:.1f}s")
display_audio_bundle(audio_data)
# Comparaison
print(f"\nComparaison des vitesses :")
print(f"{'Mode':<25} {'Vitesse':<10} {'Taille (KB)':<12}")
print("-" * 47)
for r in accessibility_results:
print(f"{r['label']:<25} {r['speed']:<10} {r['size_kb']:<12.1f}")
print(f"\nLa version accessible est ~{accessibility_results[1]['size_kb']/accessibility_results[0]['size_kb']*100:.0f}% de la taille standard")
else:
print("Generation desactivee")ACCESSIBILITE AUDIO
==================================================
--- Standard (1.0x) ---
Taille : 268.5 KB | Temps : 1.6s
--- Accessible (0.85x) ---
Taille : 312.0 KB | Temps : 2.4s
--- Lent (0.7x) ---
Taille : 384.8 KB | Temps : 2.9s
Comparaison des vitesses :
Mode Vitesse Taille (KB)
-----------------------------------------------
Standard (1.0x) 1.0 268.5
Accessible (0.85x) 0.85 312.0
Lent (0.7x) 0.7 384.8
La version accessible est ~116% de la taille standard
Interpretation : Paramètres d’accessibilite
| Vitesse | Taille fichier | Impact pedagogique |
|---|---|---|
| 1.0x (standard) | 338 KB | Rythme normal, adapté aux apprenants familiers |
| 0.85x (accessible) | 396 KB (+17%) | Meilleure comprehension, temps de reflexion |
| 0.7x (lent) | 478 KB (+41%) | Pour contenus complexes ou public non expert |
Points cles : 1. La vitesse reduite (0.85x) est recommandee pour l’accessibilite cognitive 2. L’augmentation de taille (~17%) est acceptable pour le gain pedagogique 3. Les pauses implicites (vitesse reduite) aident a la memorisation 4. Pour les publics MALV (Malentendants, Aveugles, Low Vision, troubles cognitifs), privilegier 0.85x
Bon a savoir : L’API OpenAI TTS supporte des vitesses de 0.25 a 4.0, mais 0.7-1.0 est la plage optimale pour la voix naturelle.
Section 4 : Accessibilite audio
Un contenu educatif accessible doit prendre en compte différents profils d’apprenants. Les paramètres d’accessibilite audio visent a rendre le contenu comprehensible par le plus grand nombre :
| Profil | Besoin | Adaptation audio |
|---|---|---|
| Apprenants non experts | Temps d’assimilation | Vitesse reduite (0.85x) |
| Public MALV cognitif | Traitement séquentiel | Pauses allongees, reformulations |
| Malentendants | Clarte d’enonciation | Voix posee, vitesse stable |
| Non-natifs | Exposition progressive | Vitesse 0.85x, articulation claire |
Nous allons tester l’impact de la vitesse sur la qualite perçue et la taille du fichier audio.
Section 5 : Assemblage d’un cours narrate complet
L’assemblage final combine tous les segments audio en un fichier unique avec pydub. Le processus :
- Charger chaque segment audio genere
- Ajouter des silences entre les sections (transition naturelle)
- Concatener dans l’ordre du script
- Normaliser le volume global
- Exporter en format final
# Assemblage du cours narrate complet
print("ASSEMBLAGE DU COURS NARRATE")
print("=" * 50)
# Verifier la disponibilite de pydub/ffmpeg
skip_assembly = False
try:
from pydub import AudioSegment
from pydub.silence import detect_nonsilent
# Tester l'acces a ffmpeg
test_segment = AudioSegment.silent(duration=100)
del test_segment
except (ImportError, FileNotFoundError, OSError) as e:
print(f"ATTENTION: pydub/ffmpeg non disponible - assemblage saute")
print(f" Raison: {type(e).__name__}: {str(e)[:100]}")
print(f" Solution: installez ffmpeg ou utilisez un environnement avec ffmpeg dans PATH")
skip_assembly = True
audio_segments_assembled = None
if not skip_assembly and generate_audio and audio_segments:
try:
# Silence entre les segments (ms)
inter_segment_silence = 800 # Entre segments du meme role
inter_section_silence = 1500 # Entre sections (changement de role)
# Construire le fichier final
final_audio = AudioSegment.silent(duration=500) # Silence initial
prev_role = None
for i, seg in enumerate(audio_segments):
# Charger le segment
segment_audio = AudioSegment.from_mp3(BytesIO(seg['audio']))
# Ajouter silence adapte
if prev_role is not None:
silence_ms = inter_section_silence if seg['role'] != prev_role else inter_segment_silence
final_audio += AudioSegment.silent(duration=silence_ms)
final_audio += segment_audio
prev_role = seg['role']
print(f" Segment {i+1} : {seg['role']:12s} ({len(segment_audio)/1000:.1f}s)")
# Silence final
final_audio += AudioSegment.silent(duration=500)
# Normalisation du volume
target_dBFS = -20.0
change_in_dBFS = target_dBFS - final_audio.dBFS
final_audio = final_audio.apply_gain(change_in_dBFS)
print(f"\nCours assemble :")
print(f" Duree totale : {len(final_audio)/1000:.1f}s")
print(f" Volume normalise : {final_audio.dBFS:.1f} dBFS")
print(f" Segments : {len(audio_segments)}")
# Sauvegarde
if save_audio_files:
output_path = OUTPUT_DIR / "cours_complet_assemble.mp3"
final_audio.export(str(output_path), format="mp3", bitrate="192k")
print(f" Sauvegarde : {output_path.name} ({output_path.stat().st_size/1024:.1f} KB)")
# Ecouter le resultat
final_bytes = BytesIO()
final_audio.export(final_bytes, format="mp3")
print(f"\nEcoute du cours complet :")
display_audio_bundle(final_bytes.getvalue())
audio_segments_assembled = final_audio
except Exception as e:
print(f"Erreur lors de l'assemblage: {type(e).__name__}: {str(e)[:200]}")
print("L'assemblage a ete saute, mais les segments individuels restent disponibles.")
audio_segments_assembled = None
else:
if skip_assembly:
print("Assemblage non disponible (ffmpeg requis)")
else:
print("Assemblage ignore (pas de segments audio disponibles)")ASSEMBLAGE DU COURS NARRATE
==================================================
Segment 1 : NARRATEUR (11.4s)
Segment 2 : NARRATEUR (18.2s)
Segment 3 : EXPERT (21.6s)
Segment 4 : NARRATEUR (19.6s)
Segment 5 : NARRATEUR (16.5s)
Cours assemble :
Duree totale : 92.9s
Volume normalise : -20.0 dBFS
Segments : 5
Sauvegarde : cours_complet_assemble.mp3 (1816.4 KB)
Ecoute du cours complet :
Interpretation : Assemblage du cours complet
| Aspect | Valeur observee | Signification pedagogique |
|---|---|---|
| Duree totale | ~90 secondes | Format ideal pour un micro-module |
| Silences entre segments | 800-1500ms | Pauses naturelles pour la comprehension |
| Normalisation volume | -20 dBFS | Volume confortable, ecoute prolongee possible |
| Segments | 5 segments | Decoupage pedagogique efficace |
Points cles : 1. L’assemblage avec pydub permet de créer un flux continu et naturel 2. Les silences variables (800ms vs 1500ms) marquent les changements de rôle 3. La normalisation du volume evite les sauts de loudness entre segments 4. Le format MP3 192kbps offre un bon compromis qualite/taille
Note technique : Pour des cours plus longs, decouper en chapitres de 3-5 minutes chacun avec des titres intermediaires.
En complement — dependance outil : pydub utilise ffmpeg en arriere-plan ; assurez-vous que ffmpeg est installe dans votre environnement avant l’assemblage.
Section 5 : Assemblage d’un cours narre complet
L’assemblage final combine tous les segments audio en un fichier unique avec pydub. Le processus suit 5 étapes :
- Charger chaque segment audio genere (format MP3 depuis BytesIO)
- Ajouter des silences entre les segments (800ms intra-rôle, 1500ms inter-rôle)
- Concatener dans l’ordre du script narre
- Normaliser le volume global a -20 dBFS
- Exporter en format final (MP3 192kbps)
Cette approche créé une expérience d’ecoute fluide et professionnelle.
Section 6 : Verification qualite par round-trip STT
Pour valider que la narration est fidele au texte source, nous effectuons un round-trip :
Texte source -> TTS -> Audio -> STT -> Texte transcrit -> Comparaison
La similarite entre le texte source et le texte retranscrit mesure la fidelite du pipeline.
# Verification qualite par round-trip STT
print("VERIFICATION QUALITE - ROUND-TRIP STT")
print("=" * 50)
from difflib import SequenceMatcher
roundtrip_text = (
"Le deep learning utilise des reseaux de neurones profonds "
"pour apprendre des representations hierarchiques des donnees."
)
if generate_audio:
# Etape 1 : TTS
print("Etape 1 : Generation TTS")
tts_response = client.audio.speech.create(
model=tts_model,
voice=narrator_voice,
input=roundtrip_text,
response_format="mp3"
)
tts_audio = tts_response.content
print(f" Audio genere : {len(tts_audio)/1024:.1f} KB")
# Sauvegarder temporairement pour Whisper
temp_path = OUTPUT_DIR / "roundtrip_temp.mp3"
with open(temp_path, 'wb') as f:
f.write(tts_audio)
# Etape 2 : STT
print("Etape 2 : Transcription STT")
with open(temp_path, 'rb') as audio_file:
transcript = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
language="fr"
)
transcribed_text = transcript.text
print(f" Texte transcrit : {transcribed_text}")
# Etape 3 : Comparaison
print("\nEtape 3 : Comparaison")
similarity = SequenceMatcher(None,
roundtrip_text.lower(),
transcribed_text.lower()).ratio()
print(f" Texte original : {roundtrip_text}")
print(f" Texte transcrit : {transcribed_text}")
print(f" Similarite : {similarity*100:.1f}%")
if similarity >= 0.9:
print(f" Verdict : EXCELLENT - Narration fidele")
elif similarity >= 0.75:
print(f" Verdict : BON - Quelques differences mineures")
else:
print(f" Verdict : A VERIFIER - Differences significatives")
# Nettoyage
if temp_path.exists():
temp_path.unlink()
else:
print("Verification desactivee")VERIFICATION QUALITE - ROUND-TRIP STT
==================================================
Etape 1 : Generation TTS
Audio genere : 112.9 KB
Etape 2 : Transcription STT
Texte transcrit : Les Deep Learning utilisent des réseaux de neurones profonds pour apprendre des représentations hiérarchiques des données.
Etape 3 : Comparaison
Texte original : Le deep learning utilise des reseaux de neurones profonds pour apprendre des representations hierarchiques des donnees.
Texte transcrit : Les Deep Learning utilisent des réseaux de neurones profonds pour apprendre des représentations hiérarchiques des données.
Similarite : 95.4%
Verdict : EXCELLENT - Narration fidele
Exercice : Validation de contenus multilingues par round-trip
Duree estimee : 20-25 minutes
Objectif
Créer une fonction de validation qui genere un contenu audio dans une langue, le retranscrit via STT, puis compare le texte original avec la transcription pour mesurer la fidelite du pipeline multilingue.
Contexte
Dans un contexte de production de contenus educatifs multilingues, il est essentiel de verifier que le pipeline TTS + traduction ne deforme pas le contenu. Le round-trip (texte -> TTS -> STT -> texte) est une méthode automatisee de validation.
Instructions
- Choisir un texte pedagogique court (2-3 phrases)
- Le traduire en anglais via LLM
- Generer l’audio TTS pour les deux versions
- Retranscrire chaque audio via Whisper
- Comparer original vs retranscrit avec
SequenceMatcher
Indices : -
# Étape 1: Définir le texte source et le traduire viaclient.chat.completions.create()-# Étape 2: Utiliserclient.audio.speech.create()pour generer l’audio dans chaque langue -# Étape 3: Sauvegarder les fichiers temporairement puis appelerclient.audio.transcriptions.create()-# Indice: Utiliserfrom difflib import SequenceMatcherpour calculer la similarite -# Indice: Un score > 90% indique une bonne fidelite du pipeline
# TODO: Implementer la fonction de validation multilingue par round-trip
def validate_multilingual_content(source_text: str, source_lang: str = "fr",
target_lang: str = "en") -> dict:
"""
Valide la fidelite du pipeline multilingue par round-trip TTS->STT.
Args:
source_text: Texte pedagogique source
source_lang: Langue source (ex: "fr")
target_lang: Langue cible (ex: "en")
Returns:
Dict avec similarite_source, similarite_target, verdict
"""
# Etape 1 : Traduire le texte source vers la langue cible
# Indice: Utiliser client.chat.completions.create() avec un prompt de traduction
translated_text = None # TODO etudiant : traduire source_text
# Etape 2 : Generer l'audio TTS pour les deux langues
# Indice: client.audio.speech.create(model="tts-1", voice="nova", input=text)
audio_source = None # TODO etudiant : generer audio source
audio_target = None # TODO etudiant : generer audio target
# Etape 3 : Retranscrire via Whisper
# Indice: Sauvegarder temporairement, puis client.audio.transcriptions.create()
transcribed_source = None # TODO etudiant
transcribed_target = None # TODO etudiant
# Etape 4 : Calculer la similarite
# Indice: SequenceMatcher(None, original.lower(), transcribed.lower()).ratio()
similarity_source = 0.0 # TODO etudiant
similarity_target = 0.0 # TODO etudiant
return {
"similarity_source": similarity_source,
"similarity_target": similarity_target,
"verdict": "Exercice a completer"
}
# Test avec un texte pedagogique
test_text = "Le deep learning est une technique d'apprentissage automatique inspiree du cerveau humain."
# result = validate_multilingual_content(test_text, "fr", "en")
# print(f"Similarite FR: {result['similarity_source']*100:.1f}%")
# print(f"Similarite EN: {result['similarity_target']*100:.1f}%")
print("Exercice a completer")Exercice a completer
Interpretation : Verification qualite par round-trip
| Aspect | Valeur | Signification |
|---|---|---|
| Similarite texte | > 95% | Fidelite excellente du pipeline |
| Erreurs typiques | Accentuation, majuscules | Whisper standardise l’orthographe |
| Verdict | EXCELLENT | La narration est fidele au contenu |
Points cles : 1. Le round-trip TTS->STT permet de valider la qualite de la narration 2. Une similarite > 90% indique une narration fidele 3. Les différences mineures (majuscules, accents) n’impactent pas la comprehension
Note technique : Cette technique est utile pour valider des contenus dans des langues que vous ne parlez pas couramment.
Section 6 : Verification qualite par round-trip STT
Pour valider que la narration est fidele au texte source, nous effectuons un round-trip :
Texte source -> TTS -> Audio -> STT -> Texte transcrit -> Comparaison
La similarite entre le texte source et le texte retranscrit mesure la fidelite du pipeline.
Le mode interactif permet de tester la pipeline avec un sujet personnalise. Si notebook_mode n’est pas "interactive", cette cellule est ignoree automatiquement.
# Mode interactif - Creer votre propre contenu educatif
if notebook_mode == "interactive" and not skip_widgets:
print("MODE INTERACTIF - CONTENU EDUCATIF PERSONNALISE")
print("=" * 50)
print("\nEntrez un paragraphe de cours a transformer en narration audio :")
print("(Laissez vide pour passer)")
try:
user_course = input("\nVotre texte de cours : ")
if user_course.strip():
# Generer script de narration
script_resp = client.chat.completions.create(
model=llm_model,
messages=[{"role": "user", "content": f"Transforme en narration orale educative :\n\n{user_course}"}],
temperature=0.7
)
user_script = script_resp.choices[0].message.content
print(f"\nScript genere :\n{user_script}")
# Narrer
tts_resp = client.audio.speech.create(
model=tts_model,
voice=narrator_voice,
input=user_script,
response_format="mp3"
)
print(f"\nNarration generee ({len(tts_resp.content)/1024:.1f} KB) :")
display_audio_bundle(tts_resp.content)
if save_audio_files:
ts = datetime.now().strftime('%Y%m%d_%H%M%S')
filepath = OUTPUT_DIR / f"custom_course_{ts}.mp3"
with open(filepath, 'wb') as f:
f.write(tts_resp.content)
print(f"Sauvegarde : {filepath.name}")
else:
print("Mode interactif ignore")
except (KeyboardInterrupt, EOFError):
print("Mode interactif interrompu")
except Exception as e:
error_type = type(e).__name__
if "StdinNotImplemented" in error_type or "input" in str(e).lower():
print("Mode interactif non disponible (execution automatisee)")
else:
print(f"Erreur : {error_type} - {str(e)[:100]}")
else:
print("Mode batch - Interface interactive desactivee")Mode batch - Interface interactive desactivee
Le module de statistiques consolide les metriques collectees durant la session : nombre de fichiers generes, modèles utilises, durees de traitement et couts API estimés.
# Statistiques de session et recapitulatif
print("STATISTIQUES DE SESSION")
print("=" * 50)
print(f"Date : {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"Mode : {notebook_mode}")
print(f"Modele TTS : {tts_model} | Modele LLM : {llm_model}")
print(f"Voix narrateur : {narrator_voice} | Voix secondaire : {secondary_voice}")
if audio_segments:
total_segments = len(audio_segments)
total_size_kb = sum(s['size_kb'] for s in audio_segments)
print(f"Segments multi-voix generes : {total_segments}")
print(f"Taille totale segments : {total_size_kb:.1f} KB")
if multilingual_results:
print(f"Langues generees : {', '.join(multilingual_results.keys())}")
if save_audio_files:
saved_files = list(OUTPUT_DIR.glob('*'))
print(f"Fichiers sauvegardes : {len(saved_files)} dans {OUTPUT_DIR.relative_to(GENAI_ROOT)}")
print(f"\nPROCHAINES ETAPES")
print(f"1. Creer un pipeline de transcription (04-2-Transcription-Pipeline)")
print(f"2. Explorer la composition musicale (04-3-Music-Composition-Workflow)")
print(f"3. Synchroniser audio et video (04-4-Audio-Video-Sync)")
print(f"\nNotebook termine - {datetime.now().strftime('%H:%M:%S')}")STATISTIQUES DE SESSION
==================================================
Date : 2026-08-16 01:50:28
Mode : interactive
Modele TTS : tts-1 | Modele LLM : gpt-4o-mini
Voix narrateur : nova | Voix secondaire : onyx
Segments multi-voix generes : 5
Taille totale segments : 1364.2 KB
Langues generees : fr, en
Fichiers sauvegardes : 3 dans outputs\audio\educational
PROCHAINES ETAPES
1. Creer un pipeline de transcription (04-2-Transcription-Pipeline)
2. Explorer la composition musicale (04-3-Music-Composition-Workflow)
3. Synchroniser audio et video (04-4-Audio-Video-Sync)
Notebook termine - 01:50:28
Synthese des apprentissages
Ce notebook a presente un pipeline complet de creation de contenu audio educatif utilisant les technologies de l’IA. Voici les points cles a retenir :
Technologies exploitees
| Technologie | Rôle | Avantages pedagogiques |
|---|---|---|
| GPT-4o-mini | Generation de scripts narres | Adaptation ecrit→oral, structure multi-voix, creativity controlee |
| OpenAI TTS (tts-1) | Synthese vocale | Voix naturelles, 50+ langues, vitesse ajustable |
| pydub + ffmpeg | Assemblage audio | Silences, normalisation, concatenation fluide |
| Whisper (STT) | Validation qualite | Round-trip pour verification fidelite |
Bonnes pratiques identifiees
- Multi-voix pour l’engagement : Alterner narrateur et expert (ratio 2:1) maintient l’attention
- Vitesse reduite pour accessibilite : 0.85x recommande pour publics non-experts
- Marqueurs structurels : [NARRATEUR], [EXPERT], [PAUSE] permettent un parsing automatique
- Silences variables : 800ms intra-rôle, 1500ms inter-rôle pour transitions naturelles
- Validation round-trip : TTS→STT pour verifier la fidelite (>90% = excellent)
Metriques de production
| Indicateur | Valeur typique | Commentaire |
|---|---|---|
| Duree generation script | runtime machine-dep : ~8s | Rapide, permet itérations |
| Duree synthese TTS | runtime machine-dep : ~30s pour 9 segments | Adequat pour production batch |
| Taille fichier final | ~1.8 MB pour 90s | Compromis qualite/taille acceptable |
| Similarite round-trip | >95% | Fidelite excellente du pipeline |
Limitations et extensions
Limitations actuelles : - Nombre de voix limite (6 voix OpenAI) - Pas de synchronisation video (traité dans notebook 04-4) - Pas de musique de fond (traité dans notebook 04-3)
Extensions possibles : - Ajouter voix dynamiques (rythme, emotion) avec modèles avancés - Generer sous-titres synchronises automatiquement - Créer versions adaptees par niveau (debutant, intermediaire, expert) - Integrer feedback apprenant (re-generation adaptee)
Applications reelles
Ce pipeline s’applique directement a : - MOOCs et formations en ligne : Modules audio accessibles offline - Accessibility : Contenu pour publics MALV (malvoyants, troubles cognitifs) - Podcasts educatifs : Generation automatique a partir de textes - Corporate training : Formation multilingue pour entreprises internationales - Audiobooks pedagogiques : Synthese de manuels et supports de cours
Exercice : Cours Audio Multilingue
Duree estimee : 30-35 minutes
Objectif
Créer un module de cours audio complet en 2 langues (FR et EN) avec narration multi-voix et accessibilite.
Instructions
- Choisir un sujet educatif court (100-150 mots)
- Generer un script de narration adapte a l’oral pour chaque langue
- Créer une narration multi-voix (narrateur + expert) dans les 2 langues
- Appliquer les paramètres d’accessibilite (vitesse reduite)
- Assembler les modules en cours audio complet
Indices : - Utilisez la fonction
parse_narration_script()pour structurer les voix - Pour la traduction, utilisez GPT avec un prompt de traduction pedagogique - Pour l’accessibilite, reduisez la vitesse a 0.85x - Utilisez pydub pour assembler les segments avec des silences
# TODO: Definir votre sujet de cours
course_topic = """
[L'IA pour les debutants - 100-150 mots]
TODO: Ecrire votre texte ici en francais
"""
# TODO: Generer le script de narration FR
def generate_narration_script(source_text: str, language: str = "fr") -> str:
"""
Genere un script de narration pedagogique.
Args:
source_text: Texte source du cours
language: Langue cible ("fr" ou "en")
Returns:
Script avec marqueurs [NARRATEUR], [EXPERT], [PAUSE]
"""
# Indice: Appeler GPT pour transformer le texte en script de narration
# Prompt: "Transforme ce texte en script pedagogique oral avec [NARRATEUR] et [EXPERT]"
pass
# TODO: Creer une fonction de narration multi-voix multilingue
def create_multilingual_multivoice_narration(script_fr: str, script_en: str) -> dict:
"""
Genere la narration multi-voix en 2 langues.
Args:
script_fr: Script de narration FR
script_en: Script de narration EN
Returns:
Dict avec: audio_fr, audio_en, segments, duree
"""
# Indice: Parser les scripts (utiliser parse_narration_script du notebook)
# Indice: Generer l'audio pour chaque segment avec la voix appropriee
# Indice: Assembler les segments par langue
# Indice: Appliquer la vitesse 0.85x pour accessibilite
pass
# TODO: Creer le cours complet
# course_fr = generate_narration_script(course_topic, "fr")
# course_en = generate_narration_script(course_topic, "en")
# narration = create_multilingual_multivoice_narration(course_fr, course_en)