#!/usr/bin/env bash # Generisches Audio-Batch-Script via OpenAI TTS. # Nimmt JSON-Textbuch mit Struktur: # { "lines": [ {"id": "...", "text": "..."} ] } # und generiert MP3s in sounds/radio/.mp3 # # Voraussetzung: OPENAI_API_KEY (aus App/.env.local) # # Aufruf: # set -a; source App/.env.local; set +a # App/sims/heli/scripts/generate-audio-openai.sh tower-geo-lines.json # App/sims/heli/scripts/generate-audio-openai.sh tower-start-lines.json # FORCE=1 … überschreibt bestehende # OPENAI_VOICE=shimmer … andere Stimme set -e : "${OPENAI_API_KEY:?OPENAI_API_KEY muss gesetzt sein}" VOICE="${OPENAI_VOICE:-nova}" MODEL="${OPENAI_MODEL:-gpt-4o-mini-tts}" # Stil-Instruktion nur bei gpt-4o-mini-tts wirksam. Warmherzige Fluglotsin, # ruhig, klare deutsche Aussprache, als ob sie Schuelerinnen begleitet. INSTRUCTIONS="${OPENAI_TTS_INSTRUCTIONS:-Speak warmly and patiently like an encouraging female flight controller guiding a young student co-pilot. Unhurried, clear, friendly German pronunciation. Gentle reassuring tone, never robotic.}" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" OUT_DIR="$SCRIPT_DIR/../sounds/radio" mkdir -p "$OUT_DIR" JSON_INPUT="$1" if [ -z "$JSON_INPUT" ]; then echo "Usage: $0 " exit 2 fi JSON_FILE="$SCRIPT_DIR/$JSON_INPUT" if [ ! -f "$JSON_FILE" ]; then echo "Datei nicht gefunden: $JSON_FILE"; exit 2 fi echo "Modell: $MODEL · Stimme: $VOICE" echo "Quelle: $JSON_INPUT" echo generate() { local id="$1" local text="$2" local out="$OUT_DIR/${id}.mp3" if [ -f "$out" ] && [ -z "$FORCE" ]; then echo "ok ${id}.mp3 schon da" return 0 fi echo "gen ${id}" local payload payload=$(TEXT="$text" MODEL="$MODEL" VOICE="$VOICE" INSTR="$INSTRUCTIONS" python -c ' import json, os body = { "model": os.environ["MODEL"], "voice": os.environ["VOICE"], "input": os.environ["TEXT"], "response_format": "mp3" } # instructions nur bei gpt-4o-mini-tts unterstuetzt if "mini-tts" in os.environ["MODEL"]: body["instructions"] = os.environ["INSTR"] print(json.dumps(body, ensure_ascii=False))') local http http=$(curl -sS -w "%{http_code}" -o "$out" \ -X POST https://api.openai.com/v1/audio/speech \ -H "Authorization: Bearer $OPENAI_API_KEY" \ -H "Content-Type: application/json; charset=utf-8" \ -d "$payload") if [ "$http" != "200" ]; then echo "FEHLER ${id}: HTTP $http" cat "$out"; echo; rm -f "$out" return 1 fi local size; size=$(wc -c <"$out") if [ "$size" -lt 1500 ]; then echo "FEHLER ${id}: Datei zu klein ($size B)" cat "$out"; rm -f "$out" return 1 fi echo "ok ${id}.mp3 (${size} B)" sleep 0.2 } ok=0; fail=0 while IFS=$'\t' read -r id text; do [ -z "$id" ] && continue if generate "$id" "$text"; then ok=$((ok+1)); else fail=$((fail+1)); fi done < <(python -c " import json, sys d = json.load(sys.stdin) for line in d['lines']: print(line['id'] + '\t' + line['text']) " < "$JSON_FILE") echo echo "Zusammenfassung: ok=$ok, fail=$fail" ls -1 "$OUT_DIR"/*.mp3 2>/dev/null | wc -l | xargs printf "Dateien im Ordner: %s\n"