#!/bin/bash # instalar-locutor-amd64.sh — Instalador del paquete gr-locutor (Locutor Automático IA), amd64 # # 1. Instala el motor XTTS-v2 en un venv aislado (~/.gradio/locutor-venv/), # con GPU NVIDIA si está disponible, o CPU si no. # 2. Copia los scripts, contexto (para opencode) y voz de referencia genérica # de GRP a ~/.gradio/data/locutor-ia/ (no sobreescribe si el usuario ya # reemplazó la voz de referencia por la de su estación). # # Descarga varios cientos de MB a varios GB según haya o no GPU — puede # tardar minutos. Cada paso numerado (N/TOTAL) muestra su propio progreso # (pip/tqdm) y cuánto tardó al terminar, para que no parezca colgado. # # Uso: ./instalar-locutor-amd64.sh set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" # Ubicación de los assets: primero la de sistema (instalada por el .deb), # si no existe cae a la del repo (ejecutando el script a mano desde el fuente). if [ -d "/usr/local/share/gr-locutor/locutor-ia" ]; then ASSETS_DIR="/usr/local/share/gr-locutor/locutor-ia" else ASSETS_DIR="$SCRIPT_DIR/assets/locutor-ia" fi VENV_DIR="$HOME/.gradio/locutor-venv" DATA_DIR="$HOME/.gradio/data/locutor-ia" REF_VOICE="$DATA_DIR/referencia/voz_referencia.wav" TOTAL_PASOS=10 paso_n=0 paso() { paso_n=$((paso_n + 1)) paso_t0=$SECONDS echo "" echo "── [$paso_n/$TOTAL_PASOS] $1" } paso_fin() { echo " listo en $((SECONDS - paso_t0))s" } echo "======================================================" echo " Instalador gr-locutor — Locutor Automático IA (GRP)" echo " Plataforma: amd64" echo "======================================================" # ── 1. Requisitos básicos ───────────────────────────────────────────────────── paso "Verificando requisitos..." if ! command -v python3 &>/dev/null; then echo "ERROR: python3 no está instalado." exit 1 fi if ! command -v ffmpeg &>/dev/null; then echo "ERROR: ffmpeg no está instalado (ya debería estarlo si tenés GRP instalado)." exit 1 fi ARCH="$(uname -m)" if [ "$ARCH" != "x86_64" ]; then echo "AVISO: este instalador es para amd64 (x86_64); se detectó '$ARCH'." fi paso_fin # ── 2. Copiar scripts, contexto y voz de referencia ─────────────────────────── paso "Instalando contexto/scripts en $DATA_DIR..." mkdir -p "$DATA_DIR/scripts" "$DATA_DIR/context" "$DATA_DIR/agents" "$DATA_DIR/referencia" "$DATA_DIR/salida" cp "$ASSETS_DIR/AGENTS.md" "$DATA_DIR/" cp "$ASSETS_DIR/generar.py" "$DATA_DIR/" cp "$ASSETS_DIR/scripts/"* "$DATA_DIR/scripts/" cp "$ASSETS_DIR/context/"* "$DATA_DIR/context/" cp "$ASSETS_DIR/agents/"* "$DATA_DIR/agents/" cp "$ASSETS_DIR/curiosidades.txt" "$ASSETS_DIR/frases-motivacionales.txt" "$ASSETS_DIR/identificaciones.txt" "$DATA_DIR/" chmod +x "$DATA_DIR/scripts/"*.sh "$DATA_DIR/scripts/"*.py "$DATA_DIR/generar.py" if [ ! -f "$REF_VOICE" ]; then cp "$ASSETS_DIR/referencia/voz_referencia.wav" "$REF_VOICE" echo " Voz genérica de GRP instalada en: $REF_VOICE" else echo " Ya existe una voz de referencia en $REF_VOICE — no se sobreescribe" echo " (la estación ya puso la suya propia)." fi LOCUTOR_CFG="$DATA_DIR/locutor.config" if [ ! -f "$LOCUTOR_CFG" ]; then cat > "$LOCUTOR_CFG" << 'DEFAULTCFG' # Configuración del Locutor Automático IA — valores por defecto voz_modo=generica voz_propia_path= cada_cuantos_temas=3 ventana_previas=3 porcentaje_identificacion=50 DEFAULTCFG echo " Configuración por defecto creada en: $LOCUTOR_CFG" else echo " Ya existe locutor.config — no se sobreescribe (configuración previa respetada)." fi paso_fin # ── 3. Detección de GPU NVIDIA ──────────────────────────────────────────────── paso "Detectando GPU NVIDIA..." HAS_GPU=0 if command -v nvidia-smi &>/dev/null && nvidia-smi &>/dev/null; then HAS_GPU=1 echo " GPU detectada:" nvidia-smi --query-gpu=name,memory.total --format=csv,noheader | sed 's/^/ /' else echo " No se detectó GPU NVIDIA — se instalará el stack CPU." echo " (Probado: ~29-104s por locución de ~10s según el CPU. Entra en el" echo " margen de una canción de 3-4 min, pero es más lento que con GPU.)" fi paso_fin # ── 4. Crear entorno virtual aislado ─────────────────────────────────────────── paso "Creando entorno virtual en $VENV_DIR..." python3 -m venv "$VENV_DIR" # shellcheck source=/dev/null source "$VENV_DIR/bin/activate" pip install --upgrade pip paso_fin # ── 5. PyTorch + torchaudio (versión pineada, probada en GPU y en RPi5) ──────── if [ "$HAS_GPU" = "1" ]; then paso "Instalando PyTorch 2.11.0 + CUDA 12.8 (descarga ~1-2GB, puede tardar varios minutos)..." pip install torch==2.11.0 torchaudio==2.11.0 --index-url https://download.pytorch.org/whl/cu128 else paso "Instalando PyTorch 2.8.0 CPU (descarga ~100-200MB)..." pip install torch==2.8.0 torchaudio==2.8.0 --index-url https://download.pytorch.org/whl/cpu fi paso_fin # ── 6. coqui-tts + transformers pineado + torchcodec ────────────────────────── paso "Instalando coqui-tts y dependencias (varios paquetes, ~1-2 min)..." pip install coqui-tts echo " Fijando transformers==4.56.2 (versiones más nuevas rompen la capa" echo " 'tortoise' que usa XTTS-v2 internamente — verificado en dos máquinas)." echo " El aviso de pip sobre conflicto de versiones es esperado, se ignora." pip install transformers==4.56.2 echo " Instalando torchcodec (pineado a la build que coincide con torch," echo " la versión genérica de PyPI carga una libtorchcodec incompatible)." if [ "$HAS_GPU" = "1" ]; then pip install torchcodec==0.11.1 --index-url https://download.pytorch.org/whl/cu128 else pip install torchcodec==0.11.1 --index-url https://download.pytorch.org/whl/cpu fi paso_fin # ── 7. Wrapper ejecutable ────────────────────────────────────────────────────── paso "Creando wrapper ejecutable..." cat > "$VENV_DIR/gr-locutor.sh" << WRAPPER #!/bin/bash # Wrapper: gr-locutor.sh "texto" [nombre_salida] source "$VENV_DIR/bin/activate" exec python3 "$DATA_DIR/generar.py" "\$@" WRAPPER chmod +x "$VENV_DIR/gr-locutor.sh" paso_fin # ── 8. Descargar el modelo XTTS-v2 ahora (no esperar a la primera locución) ─── paso "Descargando modelo XTTS-v2 (~1.8GB — se salta si ya está en caché)..." COQUI_TOS_AGREED=1 python3 -c " from TTS.api import TTS TTS('tts_models/multilingual/multi-dataset/xtts_v2') print('Modelo listo.') " paso_fin deactivate # ── 9. Interfaz gráfica (Locutor IA - GRP) ──────────────────────────────────── paso "Instalando la interfaz gráfica (Locutor IA - GRP)..." BIN_PREBUILT="$SCRIPT_DIR/target/release/gr-locutor-config" mkdir -p "$HOME/.local/bin" if [ -f "$BIN_PREBUILT" ]; then cp "$BIN_PREBUILT" "$HOME/.local/bin/gr-locutor-config" echo " Binario preconstruido copiado a ~/.local/bin/gr-locutor-config" elif command -v cargo &>/dev/null; then echo " No hay binario preconstruido, compilando con cargo (puede tardar 1-2 min)..." (cd "$SCRIPT_DIR" && cargo build --release) cp "$BIN_PREBUILT" "$HOME/.local/bin/gr-locutor-config" echo " Compilado e instalado en ~/.local/bin/gr-locutor-config" else echo " AVISO: no hay binario preconstruido ni cargo/rust instalado — se omite" echo " la interfaz gráfica. Los scripts y el motor de voz igual funcionan" echo " (por ejemplo desde el monitor). Instalar Rust o conseguir el binario" echo " preconstruido para tener la interfaz." fi chmod +x "$HOME/.local/bin/gr-locutor-config" 2>/dev/null || true paso_fin # ── 10. Icono / lanzador de escritorio ──────────────────────────────────────── paso "Creando lanzador de escritorio..." DESKTOP_DIR="$HOME/.local/share/applications" mkdir -p "$DESKTOP_DIR" cat > "$DESKTOP_DIR/gr-locutor-config.desktop" << DESKTOPFILE [Desktop Entry] Type=Application Name=Locutor IA - GRP Comment=Configuración del Locutor Automático IA de G Radio Player Exec=$HOME/.local/bin/gr-locutor-config Terminal=false Categories=AudioVideo; DESKTOPFILE echo " Lanzador creado — buscar 'Locutor IA - GRP' en el menú de aplicaciones." paso_fin echo "" echo "======================================================" echo " Instalación completa (total: ${SECONDS}s)" echo "======================================================" echo " Datos y scripts: $DATA_DIR" echo " Voz de referencia: $REF_VOICE" echo " Interfaz gráfica: gr-locutor-config (buscala en el menú, o ~/.local/bin/gr-locutor-config)" echo " Generar una locución de prueba:" echo " $VENV_DIR/gr-locutor.sh \"Estás escuchando la mejor música.\"" echo " Iniciar el monitor (mantiene 3 locuciones listas en la cola):" echo " $DATA_DIR/scripts/start-monitor.sh start" echo ""