Sprachausgabe für ganze Kapitel und kleiner Fix an Kapitel 1
This commit is contained in:
91
speak.sh
91
speak.sh
@@ -1,5 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Resolve input to absolute path before changing directory
|
||||
INPUT_FILE="$1"
|
||||
case "$INPUT_FILE" in
|
||||
/*) ;;
|
||||
*) INPUT_FILE="$PWD/$INPUT_FILE" ;;
|
||||
esac
|
||||
|
||||
if test -z "$INPUT_FILE" || test ! -f "$INPUT_FILE"; then
|
||||
echo "Usage: $0 <input-file>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
if test -f .env; then
|
||||
@@ -8,18 +20,75 @@ if test -f .env; then
|
||||
set +a
|
||||
fi
|
||||
|
||||
OUT="${1:-output.wav}"
|
||||
TMP_DIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
TMP_TEXT=$(mktemp)
|
||||
trap 'rm -f "$TMP_TEXT"' EXIT
|
||||
cat > "$TMP_TEXT"
|
||||
# Split input into paragraph files
|
||||
awk -v tmpdir="$TMP_DIR" '
|
||||
BEGIN { RS = "" }
|
||||
{
|
||||
n++
|
||||
fname = tmpdir "/para" n ".txt"
|
||||
print > fname
|
||||
close(fname)
|
||||
}
|
||||
' "$INPUT_FILE"
|
||||
|
||||
PARA_COUNT=$(awk 'BEGIN { RS = "" } { n++ } END { print n+0 }' "$INPUT_FILE")
|
||||
|
||||
if test "$PARA_COUNT" -eq 0; then
|
||||
echo "Error: no paragraphs found in input file" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CHUNKS=$(( (PARA_COUNT + 2) / 3 ))
|
||||
|
||||
REF_AUDIO_B64=$(base64 -w 0 elena-referenz.wav)
|
||||
ESCAPED_TEXT=$(awk '{gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); gsub(/\t/, "\\t"); if (NR>1) printf "\\n"; printf "%s", $0}' "$TMP_TEXT")
|
||||
|
||||
printf '{"text":"%s","language":"German","ref_text":"Das Café Laube roch nach einer Mischung aus frisch gerösteten Bohnen, süßlichen Lilien und dem metallischen Unterton von Regen","trim_sample":true,"auto_denoise":false,"high_fidelity":false,"ref_audio_b64":"%s"}' "$ESCAPED_TEXT" "$REF_AUDIO_B64" | \
|
||||
curl -X POST "https://vonkaiser-audiodojo.chutes.ai/tts/qwen3clone" \
|
||||
-H "Authorization: Bearer $CHUTES_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @- \
|
||||
--output "$OUT"
|
||||
CHUNK=1
|
||||
while test "$CHUNK" -le "$CHUNKS"; do
|
||||
OUT=$(printf "part%03d.wav" "$CHUNK")
|
||||
|
||||
if test -f "$OUT"; then
|
||||
echo "Skipping existing file: $OUT" >&2
|
||||
CHUNK=$((CHUNK + 1))
|
||||
continue
|
||||
fi
|
||||
|
||||
START=$(( (CHUNK - 1) * 3 + 1 ))
|
||||
END=$(( START + 2 ))
|
||||
|
||||
TMP_TEXT="$TMP_DIR/chunk$CHUNK.txt"
|
||||
: > "$TMP_TEXT"
|
||||
|
||||
P=$START
|
||||
FIRST=1
|
||||
while test "$P" -le "$END"; do
|
||||
PARA_FILE="$TMP_DIR/para$P.txt"
|
||||
if test -f "$PARA_FILE"; then
|
||||
if test "$FIRST" -eq 1; then
|
||||
FIRST=0
|
||||
else
|
||||
printf "\n\n" >> "$TMP_TEXT"
|
||||
fi
|
||||
cat "$PARA_FILE" >> "$TMP_TEXT"
|
||||
fi
|
||||
P=$((P + 1))
|
||||
done
|
||||
|
||||
ESCAPED_TEXT=$(awk '{gsub(/\\/, "\\\\"); gsub(/"/, "\\\""); gsub(/\t/, "\\t"); if (NR>1) printf "\\n"; printf "%s", $0}' "$TMP_TEXT")
|
||||
|
||||
printf '{"text":"%s","language":"German","ref_text":"Das Café Laube roch nach einer Mischung aus frisch gerösteten Bohnen, süßlichen Lilien und dem metallischen Unterton von Regen","trim_sample":true,"auto_denoise":false,"high_fidelity":false,"ref_audio_b64":"%s"}' "$ESCAPED_TEXT" "$REF_AUDIO_B64" | \
|
||||
curl -f -s -S -X POST "https://vonkaiser-audiodojo.chutes.ai/tts/qwen3clone" \
|
||||
-H "Authorization: Bearer $CHUTES_API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @- \
|
||||
--output "$OUT"
|
||||
|
||||
if test $? -ne 0; then
|
||||
rm -f "$OUT"
|
||||
echo "Warning: failed to generate part $CHUNK, skipping" >&2
|
||||
fi
|
||||
|
||||
CHUNK=$((CHUNK + 1))
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user