In OBS' Browser-Quelle kam `speechSynthesis` amerikanisch heraus: der eingebaute Browser sah keine deutsche Stimme, und die Seite nahm die erste beliebige. Welche Stimmen es gibt, haengt am Rechner, der streamt. Jetzt spricht der Hub mit Piper (lokal im LXC, 200 Zeichen in 0,7 s). Die WAV liegt kurz im Speicher, `/tts` holt sie unter /tts/audio/<id> mit dem Overlay-Schluessel und spielt sie ueber <audio> ab - das laeuft sicher ueber OBS' Tonspur. Der Browser springt nur noch mit einer deutschen Stimme ein, sonst wird nur angezeigt. Stimme und Sprecher stehen in rewards.tts. Dazu: - `abdulive rewards:anlegen`: Belohnung ueber die API anlegen. Nur die App, die sie angelegt hat, darf Einloesungen abschliessen oder erstatten. - Einloesungen werden nach der Aktion als FULFILLED markiert, statt in Twitchs Warteschlange liegen zu bleiben. - Wortfilter normalisiert vorher: Leetspeak, Punkte dazwischen, gezogene Buchstaben, Akzente. Kurze Eintraege nur am Wortanfang. - Der Testknopf "Vorlesen" geht durch Piper und prueft so die echte Stimme. - scripts/install-piper.sh richtet Piper und Stimme im LXC ein. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
62 lines
2.4 KiB
Bash
62 lines
2.4 KiB
Bash
#!/usr/bin/env bash
|
|
# Piper und die deutsche Stimme in den Hub-LXC bringen.
|
|
#
|
|
# Einmalig noetig, danach nur wieder fuer eine andere Stimme. Das Deploy-
|
|
# Skript fasst beides nicht an: Piper liegt unter /opt/piper, die Stimme im
|
|
# Modellordner, und beides ueberlebt jedes Ausrollen.
|
|
#
|
|
# Piper kommt als fertiges Paket mit eigenem espeak-ng und onnxruntime - im
|
|
# Container muss nichts aus apt dazu. Die Version ist festgenagelt und am
|
|
# 2026-09-23 im LXC geprueft: 200 Zeichen in 0,7 s.
|
|
#
|
|
# Aufruf: scripts/install-piper.sh
|
|
# Umgebung (mit Vorgaben):
|
|
# PVE_HOST=192.168.2.20 Proxmox-Host
|
|
# CT=141 Container-ID
|
|
# STIMME=de_DE-mls-medium Name aus huggingface.co/rhasspy/piper-voices
|
|
set -euo pipefail
|
|
|
|
PVE_HOST="${PVE_HOST:-192.168.2.20}"
|
|
CT="${CT:-141}"
|
|
STIMME="${STIMME:-de_DE-mls-medium}"
|
|
|
|
# de_DE-thorsten-medium -> de/de_DE/thorsten/medium
|
|
IFS=- read -r LOCALE SPRECHER QUALI <<< "$STIMME"
|
|
SPRACHE="${LOCALE%%_*}"
|
|
VOICES="https://huggingface.co/rhasspy/piper-voices/resolve/main/${SPRACHE}/${LOCALE}/${SPRECHER}/${QUALI}"
|
|
PIPER="https://github.com/rhasspy/piper/releases/download/2023.11.14-2/piper_linux_x86_64.tar.gz"
|
|
|
|
ssh "root@${PVE_HOST}" "pct exec ${CT} -- bash -lc '
|
|
set -e
|
|
if [ ! -x /opt/piper/piper ]; then
|
|
echo \"Lade Piper ...\"
|
|
curl -fsSL -o /tmp/piper.tgz ${PIPER}
|
|
tar xzf /tmp/piper.tgz -C /opt --no-same-owner
|
|
rm -f /tmp/piper.tgz
|
|
fi
|
|
|
|
mkdir -p /var/lib/abdulive/models/piper
|
|
cd /var/lib/abdulive/models/piper
|
|
if [ ! -f ${STIMME}.onnx ]; then
|
|
echo \"Lade Stimme ${STIMME} ...\"
|
|
curl -fsSL -o ${STIMME}.onnx.json ${VOICES}/${STIMME}.onnx.json
|
|
curl -fsSL -o ${STIMME}.onnx.part ${VOICES}/${STIMME}.onnx
|
|
mv ${STIMME}.onnx.part ${STIMME}.onnx
|
|
fi
|
|
|
|
# Der Dienst findet Piper ueber PIPER_BIN. Ein Drop-in statt einer
|
|
# Aenderung an der Unit, damit ein neues Ausrollen der Unit das nicht
|
|
# ueberschreibt.
|
|
mkdir -p /etc/systemd/system/abdulive-hub.service.d
|
|
printf \"[Service]\nEnvironment=PIPER_BIN=/opt/piper/piper\n\" \
|
|
> /etc/systemd/system/abdulive-hub.service.d/piper.conf
|
|
systemctl daemon-reload
|
|
|
|
echo \"Probe ...\"
|
|
echo \"Hallo, hier spricht der Hub.\" \
|
|
| /opt/piper/piper --model ${STIMME}.onnx --output_file - --quiet 2>/dev/null \
|
|
| head -c 4 | grep -q RIFF && echo \"Piper spricht.\"
|
|
'"
|
|
|
|
echo "Fertig. Wirksam nach dem naechsten Neustart des Hubs (scripts/deploy-hub.sh)."
|