LeX-logo op titelpagina en in de voet van elk document
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Maakt van sectieoverleg-script.txt een testopname met drie verschillende computerstemmen,
|
||||
zodat de sprekerherkenning (gpt-4o-transcribe-diarize) iets te onderscheiden heeft.
|
||||
|
||||
Gebruik: OPENAI_API_KEY=sk-... python3 maak_opname_drie_stemmen.py
|
||||
Vereist: ffmpeg (aanwezig) en een OpenAI-sleutel in de omgevingsvariabele; de sleutel wordt
|
||||
nergens opgeslagen. Kosten: circa 4.000 tekens bij tts-1, ongeveer 6 cent.
|
||||
|
||||
Uitvoer: sectieoverleg-drie-stemmen.mp3 (128 kbps, om te beluisteren)
|
||||
sectieoverleg-drie-stemmen-klein.mp3 (32 kbps mono, onder de 5 MB-grens van de tool)
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
HERE = Path(__file__).resolve().parent
|
||||
SCRIPT = HERE / "sectieoverleg-script.txt"
|
||||
STEMMEN = {"Karin": "nova", "Bram": "echo", "Fatima": "alloy"} # drie duidelijk verschillende stemmen
|
||||
VERTELLER = "onyx" # voor de openingsregel
|
||||
|
||||
key = os.environ.get("OPENAI_API_KEY")
|
||||
if not key:
|
||||
sys.exit("Zet de sleutel in de omgevingsvariabele OPENAI_API_KEY en start opnieuw.")
|
||||
|
||||
|
||||
def spreek(tekst: str, stem: str, doel: Path) -> None:
|
||||
req = urllib.request.Request(
|
||||
"https://api.openai.com/v1/audio/speech",
|
||||
data=json.dumps({"model": "tts-1", "voice": stem, "input": tekst, "response_format": "mp3"}).encode(),
|
||||
headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
|
||||
)
|
||||
with urllib.request.urlopen(req, timeout=120) as r:
|
||||
doel.write_bytes(r.read())
|
||||
|
||||
|
||||
regels = [r.strip() for r in SCRIPT.read_text(encoding="utf-8").splitlines() if r.strip()]
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
tmp = Path(tmp)
|
||||
delen = []
|
||||
for i, regel in enumerate(regels):
|
||||
m = re.match(r"^(Karin|Bram|Fatima):\s*(.+)$", regel)
|
||||
if m:
|
||||
stem, tekst = STEMMEN[m.group(1)], m.group(2)
|
||||
else:
|
||||
stem, tekst = VERTELLER, regel
|
||||
deel = tmp / f"{i:03d}.mp3"
|
||||
spreek(tekst, stem, deel)
|
||||
delen.append(deel)
|
||||
print(f"{i + 1}/{len(regels)} {stem}: {tekst[:50]}...")
|
||||
lijst = tmp / "lijst.txt"
|
||||
lijst.write_text("".join(f"file '{d}'\n" for d in delen))
|
||||
# Korte stilte tussen sprekers komt vanzelf door de pauze aan het eind van elke zin.
|
||||
subprocess.run(["ffmpeg", "-y", "-loglevel", "error", "-f", "concat", "-safe", "0", "-i", str(lijst),
|
||||
"-c:a", "libmp3lame", "-b:a", "128k", str(HERE / "sectieoverleg-drie-stemmen.mp3")], check=True)
|
||||
subprocess.run(["ffmpeg", "-y", "-loglevel", "error", "-i", str(HERE / "sectieoverleg-drie-stemmen.mp3"),
|
||||
"-ac", "1", "-ar", "16000", "-b:a", "32k", str(HERE / "sectieoverleg-drie-stemmen-klein.mp3")], check=True)
|
||||
for naam in ("sectieoverleg-drie-stemmen.mp3", "sectieoverleg-drie-stemmen-klein.mp3"):
|
||||
p = HERE / naam
|
||||
print(f"{naam}: {p.stat().st_size // 1024} kB")
|
||||
Reference in New Issue
Block a user