← back to AgentAbrams
video/tts_engine.py
77 lines
#!/usr/bin/env python3
"""
tts_engine.py — Text-to-speech using ElevenLabs API.
Generates a 55-year-old male voiceover from script text.
Usage:
python3 video/tts_engine.py "Text to speak" output.mp3
Environment variables:
ELEVEN_API_KEY
ELEVEN_VOICE_ID (optional, defaults to a preset)
"""
import os
import sys
import requests
DEFAULT_VOICE_ID = "pNInz6obpgDQGcFmaJgB" # Adam — deep male voice
def generate_audio(text: str, output_file: str, voice_id: str | None = None):
api_key = os.environ.get("ELEVEN_API_KEY")
if not api_key:
print("ERROR: ELEVEN_API_KEY not set", file=sys.stderr)
sys.exit(1)
vid = voice_id or os.environ.get("ELEVEN_VOICE_ID", DEFAULT_VOICE_ID)
url = f"https://api.elevenlabs.io/v1/text-to-speech/{vid}"
headers = {
"xi-api-key": api_key,
"Content-Type": "application/json",
}
payload = {
"text": text,
"model_id": "eleven_monolingual_v1",
"voice_settings": {
"stability": 0.65,
"similarity_boost": 0.70,
"style": 0.3,
},
}
resp = requests.post(url, json=payload, headers=headers, timeout=120)
resp.raise_for_status()
with open(output_file, "wb") as f:
f.write(resp.content)
size_kb = len(resp.content) / 1024
print(f"Audio generated: {output_file} ({size_kb:.0f} KB)")
def main():
if len(sys.argv) < 3:
print("Usage: tts_engine.py <text_or_file> <output.mp3>", file=sys.stderr)
sys.exit(2)
source = sys.argv[1]
output = sys.argv[2]
from pathlib import Path
if Path(source).is_file():
text = Path(source).read_text(encoding="utf-8")
else:
text = source
generate_audio(text, output)
if __name__ == "__main__":
main()