#!/usr/bin/env bash # Busfahrt UI-Sounds via ElevenLabs Sound Effects API. # # Aufruf: # set -a; source App/.env.local; set +a # App/sims/busfahrt/scripts/generate-sounds.sh # alle fehlenden # App/sims/busfahrt/scripts/generate-sounds.sh hit-ok # gezielt # # FORCE=1 ./generate-sounds.sh hit-ok # ueberschreiben set -e : "${ELEVENLABS_API_KEY:?ELEVENLABS_API_KEY env var nicht gesetzt}" cd "$(dirname "$0")/.." mkdir -p assets/sounds OUT_DIR="$(pwd)/assets/sounds" mapfile -t LINES < <(python -c " import json data = json.load(open('scripts/sounds-list.json', encoding='utf-8')) for s in data['sounds']: print(s['file'] + '|||' + str(s['duration']) + '|||' + str(s.get('influence', 0.5)) + '|||' + s['prompt']) ") TARGETS=("$@") TOTAL=${#LINES[@]} i=0 ok=0 fail=0 for line in "${LINES[@]}"; do i=$((i+1)) IFS='|||' read -r file dur infl prompt <<< "$line" # Bash split mit ||| → gibt nur ersten Token, wir brauchen split via tr/awk file=$(echo "$line" | awk -F'\\|\\|\\|' '{print $1}') dur=$(echo "$line" | awk -F'\\|\\|\\|' '{print $2}') infl=$(echo "$line" | awk -F'\\|\\|\\|' '{print $3}') prompt=$(echo "$line" | awk -F'\\|\\|\\|' '{print $4}') id="${file%.mp3}" if [ ${#TARGETS[@]} -gt 0 ]; then skip=1 for t in "${TARGETS[@]}"; do [ "$t" = "$id" ] || [ "$t" = "$file" ] && { skip=0; break; } done [ $skip -eq 1 ] && continue fi out="$OUT_DIR/$file" if [ -f "$out" ] && [ -z "$FORCE" ]; then echo "[$i/$TOTAL] $file: skip (existiert)" continue fi echo -n "[$i/$TOTAL] $file (${dur}s): " payload=$(PROMPT="$prompt" DUR="$dur" INFL="$infl" python -c ' import json, os print(json.dumps({ "text": os.environ["PROMPT"], "duration_seconds": float(os.environ["DUR"]), "prompt_influence": float(os.environ["INFL"]), }))') http_code=$(curl -s -o "$out" -w "%{http_code}" --max-time 60 -X POST \ https://api.elevenlabs.io/v1/sound-generation \ -H "xi-api-key: $ELEVENLABS_API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: audio/mpeg" \ -d "$payload") if [ "$http_code" = "200" ]; then sz=$(stat -c%s "$out" 2>/dev/null || stat -f%z "$out" 2>/dev/null) if [ "$sz" -gt 200 ]; then echo "ok ($((sz/1024)) KB)" ok=$((ok+1)) else echo "x file too small ($sz bytes)" cat "$out" rm -f "$out" fail=$((fail+1)) fi else echo "x HTTP $http_code" head -c 300 "$out" echo "" rm -f "$out" fail=$((fail+1)) fi sleep 1 done echo "" echo "Fertig: $ok ok, $fail Fehler"