Soporte multi-distro en portatil, titulos mas grandes, panel mas ancho y refresco de microfono
install.sh --laptop ahora detecta el gestor de paquetes (apt, dnf, pacman o zypper) e instala las dependencias en Debian/Ubuntu/Mint, Fedora, Arch/Manjaro y openSUSE; en el resto avisa de los 5 paquetes a instalar a mano. En portatil no se compila projectM (opcional). Panel: titulo superior mas grande y cada titulo de tarjeta mas grande y en fuente Xirod; en pantalla ancha el panel ocupa el 94% (hasta 1600px) para aprovechar el portatil. Audio: nuevo boton 'Aplicar microfono' que reconecta la captura desde el panel (evento reacquire_audio); el microfono integrado del portatil se capta como entrada por defecto. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7ebb593288
commit
6df128a377
8 changed files with 172 additions and 62 deletions
|
|
@ -91,9 +91,11 @@ Al reiniciar, la Pi arranca sola en modo kiosko mostrando las visuales.
|
||||||
|
|
||||||
### En un portátil Linux
|
### En un portátil Linux
|
||||||
|
|
||||||
FOSFENO no necesita la Raspberry: corre igual en un portátil con Debian,
|
FOSFENO no necesita la Raspberry: corre igual en un portátil con Linux. El
|
||||||
Ubuntu o Mint. El portátil ya trae micrófono y cámara, y lo conectas al
|
instalador reconoce las familias más comunes —Debian/Ubuntu/Mint, Fedora,
|
||||||
proyector por HDMI como cualquier otra cosa.
|
Arch/Manjaro y openSUSE— e instala las dependencias con el gestor de cada
|
||||||
|
una (`apt`, `dnf`, `pacman` o `zypper`). El portátil ya trae micrófono y
|
||||||
|
cámara, y lo conectas al proyector por HDMI como cualquier otra cosa.
|
||||||
|
|
||||||
```
|
```
|
||||||
[ Música de la sala ]
|
[ Música de la sala ]
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,12 @@ def on_rescan_devices():
|
||||||
socketio.emit("stage_rescan")
|
socketio.emit("stage_rescan")
|
||||||
|
|
||||||
|
|
||||||
|
@socketio.on("reacquire_audio")
|
||||||
|
def on_reacquire_audio():
|
||||||
|
"""Pide al escenario que vuelva a conectar la captura del microfono."""
|
||||||
|
socketio.emit("stage_reacquire")
|
||||||
|
|
||||||
|
|
||||||
@socketio.on("stage_status")
|
@socketio.on("stage_status")
|
||||||
def on_stage_status(data):
|
def on_stage_status(data):
|
||||||
if isinstance(data, dict):
|
if isinstance(data, dict):
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,17 @@ que funciona igual de bien en un portátil con Linux. De hecho un portátil va
|
||||||
más sobrado, ya trae micrófono y cámara, y lo conectas al proyector por HDMI
|
más sobrado, ya trae micrófono y cámara, y lo conectas al proyector por HDMI
|
||||||
como cualquier otra cosa.
|
como cualquier otra cosa.
|
||||||
|
|
||||||
Este modo está pensado para Debian, Ubuntu o Linux Mint, que son las
|
El instalador funciona en las distribuciones más comunes. Reconoce solo el
|
||||||
distribuciones que usan `apt`.
|
gestor de paquetes de cada una e instala lo necesario con él:
|
||||||
|
|
||||||
|
- `apt` — Debian, Ubuntu, Linux Mint, Pop!_OS y derivadas.
|
||||||
|
- `dnf` — Fedora.
|
||||||
|
- `pacman` — Arch, Manjaro, EndeavourOS.
|
||||||
|
- `zypper` — openSUSE.
|
||||||
|
|
||||||
|
En otras distribuciones el instalador avisará y bastará con instalar a mano
|
||||||
|
cinco paquetes: `python3` (con `venv`), `nodejs`, `npm`, `git` y `chromium`.
|
||||||
|
El resto del proceso es idéntico.
|
||||||
|
|
||||||
## Instalar
|
## Instalar
|
||||||
|
|
||||||
|
|
@ -16,10 +25,11 @@ Una sola vez, desde la carpeta del proyecto:
|
||||||
bash install.sh --laptop
|
bash install.sh --laptop
|
||||||
```
|
```
|
||||||
|
|
||||||
Hace lo mismo que en la Raspberry (entorno de Python, librerías de visuales,
|
En el portátil solo hace falta un núcleo pequeño: Python, Node, Git y
|
||||||
y projectM si quieres), pero sin las cosas propias de un aparato dedicado: no
|
Chromium. Los motores de visuales son web y no necesitan nada más. No se
|
||||||
toca el arranque del sistema, no cambia el nombre de red y no necesita
|
compila projectM (es opcional; si tu distro lo trae empaquetado y lo
|
||||||
permisos especiales de puertos.
|
instalas, FOSFENO lo detecta y lo usa). El instalador no toca el arranque del
|
||||||
|
sistema, no cambia el nombre de red y no necesita permisos especiales.
|
||||||
|
|
||||||
## Arrancar
|
## Arrancar
|
||||||
|
|
||||||
|
|
|
||||||
163
install.sh
163
install.sh
|
|
@ -3,7 +3,7 @@
|
||||||
# FOSFENO :: instalador para Raspberry Pi OS Bookworm (Raspberry Pi 4 y 5)
|
# FOSFENO :: instalador para Raspberry Pi OS Bookworm (Raspberry Pi 4 y 5)
|
||||||
#
|
#
|
||||||
# Uso: bash install.sh # Raspberry Pi: instala todo
|
# Uso: bash install.sh # Raspberry Pi: instala todo
|
||||||
# bash install.sh --laptop # portatil Linux (Debian/Ubuntu/Mint)
|
# bash install.sh --laptop # portatil Linux (cualquier distro)
|
||||||
# bash install.sh --no-projectm # omite la compilacion de projectM
|
# bash install.sh --no-projectm # omite la compilacion de projectM
|
||||||
# bash install.sh --check # solo comprueba el sistema, no instala
|
# bash install.sh --check # solo comprueba el sistema, no instala
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
|
|
@ -46,11 +46,6 @@ fi
|
||||||
|
|
||||||
if [ "$LAPTOP" = "yes" ]; then
|
if [ "$LAPTOP" = "yes" ]; then
|
||||||
log_ok "Modo portatil (Linux de escritorio)"
|
log_ok "Modo portatil (Linux de escritorio)"
|
||||||
if ! need_cmd apt-get; then
|
|
||||||
log_fail "El modo --laptop usa apt (Debian, Ubuntu o Mint)."
|
|
||||||
log_fail "Tu sistema no tiene apt; este instalador no sirve aqui."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
MODELO="$(pi_model)"
|
MODELO="$(pi_model)"
|
||||||
log_info "Modelo detectado: $MODELO"
|
log_info "Modelo detectado: $MODELO"
|
||||||
|
|
@ -91,45 +86,117 @@ fi
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# 2. Paquetes del sistema
|
# 2. Paquetes del sistema
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
log_step "[2/9] Instalando dependencias del sistema (apt)"
|
|
||||||
sudo apt-get update
|
|
||||||
if sudo apt-get install -y \
|
|
||||||
python3 python3-venv python3-pip \
|
|
||||||
git cmake build-essential pkg-config \
|
|
||||||
libsdl2-dev libgles2-mesa-dev mesa-common-dev libglm-dev libpoco-dev \
|
|
||||||
pulseaudio-utils \
|
|
||||||
v4l-utils \
|
|
||||||
avahi-daemon \
|
|
||||||
xdotool unclutter; then
|
|
||||||
log_ok "Paquetes apt instalados"
|
|
||||||
else
|
|
||||||
log_fail "Fallo al instalar paquetes apt"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Node.js y npm. Si ya estan (por ejemplo instalados desde NodeSource) no se
|
# Instala las dependencias en un portatil. Soporta apt, dnf, pacman y zypper,
|
||||||
# tocan: el paquete 'npm' de Debian entra en conflicto con el 'nodejs' de
|
# de modo que FOSFENO corre en Debian/Ubuntu/Mint, Fedora, Arch/Manjaro y
|
||||||
# NodeSource, y forzarlo rompe la instalacion entera.
|
# openSUSE. En portatil solo hace falta un nucleo pequeno (Python, Node, git
|
||||||
if need_cmd node && need_cmd npm; then
|
# y Chromium): los motores de visuales son web y no necesitan nada mas.
|
||||||
log_ok "Node.js y npm ya estaban instalados ($(node --version 2>/dev/null))"
|
install_laptop_deps() {
|
||||||
elif need_cmd node; then
|
local mgr=""
|
||||||
warn "Node.js esta, pero falta npm; instalalo con el mismo metodo que node"
|
if need_cmd apt-get; then mgr="apt"
|
||||||
elif sudo apt-get install -y nodejs npm 2>/dev/null; then
|
elif need_cmd dnf; then mgr="dnf"
|
||||||
log_ok "Node.js y npm instalados"
|
elif need_cmd pacman; then mgr="pacman"
|
||||||
else
|
elif need_cmd zypper; then mgr="zypper"
|
||||||
warn "no se pudo instalar Node.js; instalalo a mano (apt o NodeSource) y reintenta"
|
else
|
||||||
fi
|
log_fail "No reconozco el gestor de paquetes de tu distribucion."
|
||||||
|
log_fail "Instala a mano y reintenta: python3 (con venv), nodejs, npm,"
|
||||||
|
log_fail "git y chromium."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
log_info "Gestor de paquetes detectado: $mgr"
|
||||||
|
|
||||||
# El navegador se llama 'chromium' en Debian/Ubuntu/Mint actuales y
|
# --- Python y git ---
|
||||||
# 'chromium-browser' en Raspberry Pi OS. Instalamos el que exista.
|
case "$mgr" in
|
||||||
if need_cmd chromium || need_cmd chromium-browser; then
|
apt) sudo apt-get update
|
||||||
log_ok "Chromium ya estaba instalado"
|
sudo apt-get install -y python3 python3-venv python3-pip git ;;
|
||||||
elif sudo apt-get install -y chromium 2>/dev/null; then
|
dnf) sudo dnf install -y python3 python3-pip git ;;
|
||||||
log_ok "Chromium instalado (paquete 'chromium')"
|
pacman) sudo pacman -Sy --needed --noconfirm python python-pip git ;;
|
||||||
elif sudo apt-get install -y chromium-browser 2>/dev/null; then
|
zypper) sudo zypper --non-interactive install python3 python3-pip git ;;
|
||||||
log_ok "Chromium instalado (paquete 'chromium-browser')"
|
esac || { log_fail "no se pudieron instalar Python y git"; return 1; }
|
||||||
|
log_ok "Python y git instalados"
|
||||||
|
|
||||||
|
# --- Node.js y npm: solo si faltan (respeta NodeSource, nvm, etc.) ---
|
||||||
|
if need_cmd node && need_cmd npm; then
|
||||||
|
log_ok "Node.js y npm ya estaban ($(node --version 2>/dev/null))"
|
||||||
|
else
|
||||||
|
case "$mgr" in
|
||||||
|
apt) sudo apt-get install -y nodejs npm ;;
|
||||||
|
dnf) sudo dnf install -y nodejs npm ;;
|
||||||
|
pacman) sudo pacman -S --needed --noconfirm nodejs npm ;;
|
||||||
|
zypper) sudo zypper --non-interactive install nodejs npm ;;
|
||||||
|
esac
|
||||||
|
need_cmd node && need_cmd npm \
|
||||||
|
&& log_ok "Node.js y npm instalados" \
|
||||||
|
|| warn "no se pudo instalar Node.js; instalalo a mano y reintenta"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Chromium ---
|
||||||
|
if need_cmd chromium || need_cmd chromium-browser || need_cmd google-chrome; then
|
||||||
|
log_ok "Chromium ya estaba instalado"
|
||||||
|
else
|
||||||
|
case "$mgr" in
|
||||||
|
apt) sudo apt-get install -y chromium 2>/dev/null \
|
||||||
|
|| sudo apt-get install -y chromium-browser ;;
|
||||||
|
dnf) sudo dnf install -y chromium ;;
|
||||||
|
pacman) sudo pacman -S --needed --noconfirm chromium ;;
|
||||||
|
zypper) sudo zypper --non-interactive install chromium ;;
|
||||||
|
esac
|
||||||
|
need_cmd chromium || need_cmd chromium-browser \
|
||||||
|
&& log_ok "Chromium instalado" \
|
||||||
|
|| warn "no se pudo instalar Chromium; instalalo a mano (chromium o Chrome)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- avahi: opcional, permite llegar al panel por nombre .local ---
|
||||||
|
case "$mgr" in
|
||||||
|
apt) sudo apt-get install -y avahi-daemon 2>/dev/null || true ;;
|
||||||
|
dnf) sudo dnf install -y avahi 2>/dev/null || true ;;
|
||||||
|
pacman) sudo pacman -S --needed --noconfirm avahi 2>/dev/null || true ;;
|
||||||
|
zypper) sudo zypper --non-interactive install avahi 2>/dev/null || true ;;
|
||||||
|
esac
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
log_step "[2/9] Instalando dependencias del sistema"
|
||||||
|
if [ "$LAPTOP" = "yes" ]; then
|
||||||
|
install_laptop_deps || { log_fail "Faltan dependencias; aborto."; exit 1; }
|
||||||
else
|
else
|
||||||
warn "no se pudo instalar Chromium automaticamente; instalalo a mano"
|
sudo apt-get update
|
||||||
|
if sudo apt-get install -y \
|
||||||
|
python3 python3-venv python3-pip \
|
||||||
|
git cmake build-essential pkg-config \
|
||||||
|
libsdl2-dev libgles2-mesa-dev mesa-common-dev libglm-dev libpoco-dev \
|
||||||
|
pulseaudio-utils \
|
||||||
|
v4l-utils \
|
||||||
|
avahi-daemon \
|
||||||
|
xdotool unclutter; then
|
||||||
|
log_ok "Paquetes apt instalados"
|
||||||
|
else
|
||||||
|
log_fail "Fallo al instalar paquetes apt"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Node.js y npm: si ya estan (p.ej. NodeSource) no se tocan, porque el
|
||||||
|
# paquete 'npm' de Debian choca con el 'nodejs' de NodeSource.
|
||||||
|
if need_cmd node && need_cmd npm; then
|
||||||
|
log_ok "Node.js y npm ya estaban instalados ($(node --version 2>/dev/null))"
|
||||||
|
elif need_cmd node; then
|
||||||
|
warn "Node.js esta, pero falta npm; instalalo con el mismo metodo que node"
|
||||||
|
elif sudo apt-get install -y nodejs npm 2>/dev/null; then
|
||||||
|
log_ok "Node.js y npm instalados"
|
||||||
|
else
|
||||||
|
warn "no se pudo instalar Node.js; instalalo a mano y reintenta"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Chromium: 'chromium' o 'chromium-browser' segun la version del sistema.
|
||||||
|
if need_cmd chromium || need_cmd chromium-browser; then
|
||||||
|
log_ok "Chromium ya estaba instalado"
|
||||||
|
elif sudo apt-get install -y chromium 2>/dev/null; then
|
||||||
|
log_ok "Chromium instalado (paquete 'chromium')"
|
||||||
|
elif sudo apt-get install -y chromium-browser 2>/dev/null; then
|
||||||
|
log_ok "Chromium instalado (paquete 'chromium-browser')"
|
||||||
|
else
|
||||||
|
warn "no se pudo instalar Chromium automaticamente; instalalo a mano"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
@ -141,7 +208,7 @@ require_version "Python" "python3 --version" "$MIN_PYTHON" \
|
||||||
require_version "Node.js" "node --version" "$MIN_NODE" \
|
require_version "Node.js" "node --version" "$MIN_NODE" \
|
||||||
|| warn "Node.js antiguo: 'npm install' podria fallar"
|
|| warn "Node.js antiguo: 'npm install' podria fallar"
|
||||||
require_version "npm" "npm --version" "$MIN_NPM" || true
|
require_version "npm" "npm --version" "$MIN_NPM" || true
|
||||||
if [ "$SKIP_PM" = "no" ]; then
|
if [ "$SKIP_PM" = "no" ] && [ "$LAPTOP" = "no" ]; then
|
||||||
require_version "CMake" "cmake --version" "$MIN_CMAKE" \
|
require_version "CMake" "cmake --version" "$MIN_CMAKE" \
|
||||||
|| { warn "CMake antiguo: projectM no se compilara"; SKIP_PM="yes"; }
|
|| { warn "CMake antiguo: projectM no se compilara"; SKIP_PM="yes"; }
|
||||||
fi
|
fi
|
||||||
|
|
@ -222,10 +289,14 @@ cd "$DIR"
|
||||||
# 6. projectM nativo (compilado desde fuente)
|
# 6. projectM nativo (compilado desde fuente)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
log_step "[6/9] projectM (visualizador nativo)"
|
log_step "[6/9] projectM (visualizador nativo)"
|
||||||
if [ "$SKIP_PM" = "yes" ]; then
|
if command -v projectMSDL >/dev/null 2>&1; then
|
||||||
log_info "projectM omitido"
|
|
||||||
elif command -v projectMSDL >/dev/null 2>&1; then
|
|
||||||
log_ok "projectM ya estaba instalado ($(command -v projectMSDL))"
|
log_ok "projectM ya estaba instalado ($(command -v projectMSDL))"
|
||||||
|
elif [ "$LAPTOP" = "yes" ]; then
|
||||||
|
log_info "projectM nativo no instalado (es opcional)."
|
||||||
|
log_info "Los motores Butterchurn, Hydra, Shaders y Mezclador funcionan sin el."
|
||||||
|
log_info "Si lo quieres, instala el paquete 'projectm' de tu distribucion."
|
||||||
|
elif [ "$SKIP_PM" = "yes" ]; then
|
||||||
|
log_info "projectM omitido"
|
||||||
else
|
else
|
||||||
log_info "Compilando projectM desde fuente (puede tardar 10-20 min en una Pi)..."
|
log_info "Compilando projectM desde fuente (puede tardar 10-20 min en una Pi)..."
|
||||||
if bash "$DIR/scripts/build-projectm.sh"; then
|
if bash "$DIR/scripts/build-projectm.sh"; then
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@
|
||||||
<button class="info" data-help="audio">i</button>
|
<button class="info" data-help="audio">i</button>
|
||||||
</div>
|
</div>
|
||||||
<select id="audio-device"><option>Detectando entradas...</option></select>
|
<select id="audio-device"><option>Detectando entradas...</option></select>
|
||||||
|
<button id="audio-apply" class="cmd accent">Aplicar microfono</button>
|
||||||
<button id="dev-rescan" class="cmd">Buscar dispositivos de nuevo</button>
|
<button id="dev-rescan" class="cmd">Buscar dispositivos de nuevo</button>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="label">BPM detectado</span>
|
<span class="label">BPM detectado</span>
|
||||||
|
|
@ -53,7 +54,7 @@
|
||||||
<!-- Sensibilidad -->
|
<!-- Sensibilidad -->
|
||||||
<section class="card" id="card-sens">
|
<section class="card" id="card-sens">
|
||||||
<div class="cardhead">
|
<div class="cardhead">
|
||||||
<span class="label">Sensibilidad al audio:
|
<span class="label">Sensibilidad:
|
||||||
<span id="sens-val" class="value">1.0</span></span>
|
<span id="sens-val" class="value">1.0</span></span>
|
||||||
<button class="info" data-help="sensibilidad">i</button>
|
<button class="info" data-help="sensibilidad">i</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ header {
|
||||||
}
|
}
|
||||||
header h1 {
|
header h1 {
|
||||||
font-family: "Xirod", "Arial Black", sans-serif;
|
font-family: "Xirod", "Arial Black", sans-serif;
|
||||||
font-size: 21px; font-weight: 400; letter-spacing: 0.16em;
|
font-size: 32px; font-weight: 400; letter-spacing: 0.09em;
|
||||||
color: var(--green); text-shadow: 0 0 16px rgba(180, 255, 0, 0.6);
|
color: var(--green); text-shadow: 0 0 18px rgba(180, 255, 0, 0.65);
|
||||||
}
|
}
|
||||||
#conn {
|
#conn {
|
||||||
position: absolute; right: 20px; top: 50%; transform: translateY(-50%);
|
position: absolute; right: 20px; top: 50%; transform: translateY(-50%);
|
||||||
|
|
@ -74,7 +74,7 @@ main {
|
||||||
/* --- Disposicion: pantalla ancha (portatil) en dos columnas --- */
|
/* --- Disposicion: pantalla ancha (portatil) en dos columnas --- */
|
||||||
@media (min-width: 880px) {
|
@media (min-width: 880px) {
|
||||||
main {
|
main {
|
||||||
max-width: 1080px; flex-direction: row;
|
width: 94%; max-width: 1600px; flex-direction: row;
|
||||||
align-items: flex-start; gap: 18px;
|
align-items: flex-start; gap: 18px;
|
||||||
}
|
}
|
||||||
.column {
|
.column {
|
||||||
|
|
@ -94,6 +94,12 @@ main {
|
||||||
.cardhead {
|
.cardhead {
|
||||||
position: relative; width: 100%;
|
position: relative; width: 100%;
|
||||||
display: flex; align-items: center; justify-content: center;
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
min-height: 30px;
|
||||||
|
}
|
||||||
|
/* Titulo de cada tarjeta: mas grande y en la fuente Xirod */
|
||||||
|
.cardhead .label {
|
||||||
|
font-family: "Xirod", "Arial Black", sans-serif;
|
||||||
|
font-size: 16px; font-weight: 400; letter-spacing: 0.04em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label { color: var(--green); font-size: 13px; text-transform: uppercase;
|
.label { color: var(--green); font-size: 13px; text-transform: uppercase;
|
||||||
|
|
@ -220,7 +226,7 @@ input[type=range] { width: 100%; accent-color: var(--green); height: 30px; }
|
||||||
.notif {
|
.notif {
|
||||||
display: flex; align-items: center; gap: 10px;
|
display: flex; align-items: center; gap: 10px;
|
||||||
padding: 12px 16px; font-size: 14px; font-weight: 600;
|
padding: 12px 16px; font-size: 14px; font-weight: 600;
|
||||||
position: sticky; top: 56px; z-index: 9;
|
position: sticky; top: 66px; z-index: 9;
|
||||||
}
|
}
|
||||||
.notif.info { background: var(--green); color: var(--ink); }
|
.notif.info { background: var(--green); color: var(--ink); }
|
||||||
.notif.warn { background: var(--orange); color: var(--ink); }
|
.notif.warn { background: var(--orange); color: var(--ink); }
|
||||||
|
|
|
||||||
|
|
@ -239,8 +239,7 @@ function renderEditor() {
|
||||||
if (state.engine !== editorEngine) {
|
if (state.engine !== editorEngine) {
|
||||||
editorEngine = state.engine;
|
editorEngine = state.engine;
|
||||||
const isHydra = state.engine === "hydra";
|
const isHydra = state.engine === "hydra";
|
||||||
$("#editor-title").textContent = isHydra
|
$("#editor-title").textContent = isHydra ? "Editor Hydra" : "Editor Shaders";
|
||||||
? "Editor Hydra (JavaScript)" : "Editor de shaders (GLSL)";
|
|
||||||
$("#editor-hint").textContent = isHydra
|
$("#editor-hint").textContent = isHydra
|
||||||
? "Variables: time, a.fft[0..4], bpm. Escribe o pega codigo Hydra."
|
? "Variables: time, a.fft[0..4], bpm. Escribe o pega codigo Hydra."
|
||||||
: "Uniforms: u_time, u_bass, u_mid, u_treble, u_bpm, u_beat, u_fft.";
|
: "Uniforms: u_time, u_bass, u_mid, u_treble, u_bpm, u_beat, u_fft.";
|
||||||
|
|
@ -299,6 +298,13 @@ $("#notif-close").addEventListener("click", () => { $("#notif").hidden = true; }
|
||||||
$("#audio-device").addEventListener("change", (e) =>
|
$("#audio-device").addEventListener("change", (e) =>
|
||||||
socket.emit("update_settings",
|
socket.emit("update_settings",
|
||||||
{ engine: "audio", patch: { device: e.target.value } }));
|
{ engine: "audio", patch: { device: e.target.value } }));
|
||||||
|
// Boton "Aplicar microfono": fija la entrada elegida y obliga al escenario
|
||||||
|
// a re-conectar la captura de audio (util tras enchufar o cambiar el micro).
|
||||||
|
$("#audio-apply").addEventListener("click", () => {
|
||||||
|
socket.emit("update_settings",
|
||||||
|
{ engine: "audio", patch: { device: $("#audio-device").value } });
|
||||||
|
socket.emit("reacquire_audio");
|
||||||
|
});
|
||||||
|
|
||||||
$("#sens").addEventListener("input", (e) =>
|
$("#sens").addEventListener("input", (e) =>
|
||||||
$("#sens-val").textContent = Number(e.target.value).toFixed(1));
|
$("#sens-val").textContent = Number(e.target.value).toFixed(1));
|
||||||
|
|
|
||||||
|
|
@ -575,6 +575,14 @@ socket.on("stage_rescan", () => {
|
||||||
report("warn", "No se pudieron volver a leer los dispositivos."));
|
report("warn", "No se pudieron volver a leer los dispositivos."));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// El panel pide reconectar la captura del microfono (boton "Aplicar").
|
||||||
|
socket.on("stage_reacquire", () => {
|
||||||
|
const dev = (state && state.audio && state.audio.device) || null;
|
||||||
|
acquireMic(dev)
|
||||||
|
.then(() => report("info", "Microfono conectado."))
|
||||||
|
.catch(() => report("error", "No se pudo conectar con el microfono elegido."));
|
||||||
|
});
|
||||||
|
|
||||||
window.addEventListener("resize", () => {
|
window.addEventListener("resize", () => {
|
||||||
if (hydra) hydra.setResolution(window.innerWidth, window.innerHeight);
|
if (hydra) hydra.setResolution(window.innerWidth, window.innerHeight);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue