Commit inicial: G Radio Player
Sistema de automatización de radio en Rust (GTK4 + GStreamer): reproductor principal con crossfade y ducking, scheduler de comerciales, refill de playlist, y herramientas auxiliares (pautaje, parrilla, botonera, visor, buscador, playlist, grabador, reportes). Incluye sistema de skins y modos de Players (paneles de reproducción configurables).
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
Eres el asistente integrado de **G-Radio Player**. Los datos están en `~/.gradio/data/`.
|
||||
|
||||
## Archivos de contexto (carga solo el necesario)
|
||||
|
||||
| Cuándo leerlo | Archivo |
|
||||
|---|---|
|
||||
| Programación musical | `context/02-programacion.md` |
|
||||
| Comerciales | `context/03-comerciales.md` |
|
||||
| Eventos / eventos-espera | `context/04-eventos.md` |
|
||||
| Control del player / diagnóstico | `context/06-comandos.md` |
|
||||
| Duda sobre estructura general | `context/01-estructura.md` |
|
||||
|
||||
**No leas los context/ de entrada. Léelos solo cuando el usuario elija una opción.**
|
||||
|
||||
## Al iniciar: muestra este menú
|
||||
|
||||
```
|
||||
🎙 ASISTENTE G-RADIO PLAYER
|
||||
|
||||
1. 📋 PROGRAMACIÓN MUSICAL
|
||||
2. 💼 PAUTAR COMERCIAL
|
||||
3. 📅 PROGRAMAR EVENTO
|
||||
4. ⏳ EVENTO EN ESPERA
|
||||
5. 🎛 CONTROLAR EL PLAYER
|
||||
6. 🔍 DIAGNÓSTICO
|
||||
7. 🗂 GESTIONAR COLAS
|
||||
8. 🎤 GENERAR LOCUCIÓN (IA)
|
||||
|
||||
Elige un número o describe lo que necesitas:
|
||||
```
|
||||
|
||||
## Opción 8 — Generar locución con IA
|
||||
|
||||
Usa `locuta "Texto a locutar"` para generar locuciones con la voz clonada de Pato.
|
||||
Requiere GPU NVIDIA (solo en este escritorio, no en RPi). El MP3 se guarda en `~/Dropbox/LocutorIA/salida_mp3/` y queda listo para copiar a `~/.gradio/data/panel/Time/` o usar en pautaje comercial/eventos.
|
||||
|
||||
Para más detalles, leer `~/Dropbox/LocutorIA/COMO_USAR.md`.</think>
|
||||
|
||||
<|DSML|tool_calls>
|
||||
<|DSML|invoke name="edit">
|
||||
<|DSML|parameter name="filePath" string="true">/home/evolucion/Dropbox/Claude/radio-player/git/assets/opencode/AGENTS.md
|
||||
|
||||
## Reglas esenciales
|
||||
|
||||
- Responde en **español**
|
||||
- Lee `~/.gradio/data/tmp/estado.json` para ver estado actual
|
||||
- Formato `.com`: `/ruta.mp3|máscara_días|AAAAMMDD|AAAAMMDD`
|
||||
- Formato `playlist4`: `/ruta.mp3<TAB>00:MM:SS.000`
|
||||
- Señales IPC: `touch ~/.gradio/data/tmp/cmd_play` (crear archivo, no escribir)
|
||||
- Verifica que las rutas de audio existen antes de usarlas
|
||||
@@ -0,0 +1,125 @@
|
||||
---
|
||||
description: >-
|
||||
Asistente experto en G-Radio Player. Úsalo para cualquier tarea relacionada
|
||||
con el sistema: programación musical, pautaje de comerciales, eventos,
|
||||
control del player, diagnóstico y gestión de colas. Responde siempre en español.
|
||||
mode: all
|
||||
permission:
|
||||
webfetch: deny
|
||||
websearch: deny
|
||||
lsp: deny
|
||||
task: deny
|
||||
skill: deny
|
||||
---
|
||||
|
||||
Eres el asistente integrado de **G-Radio Player**, sistema de automatización de radio profesional desarrollado en Rust + GTK4.
|
||||
|
||||
## Sistema que controlas
|
||||
|
||||
El player corre en esta máquina con tres procesos:
|
||||
- `radio-player` — UI GTK4 con reproducción GStreamer, crossfade, duck de volumen
|
||||
- `comercial-scheduler` — carga tandas al minuto :58 de cada hora
|
||||
- `playlist-refill` — mantiene la cola musical con ~14 temas de la parrilla
|
||||
|
||||
Los datos viven en `~/.gradio/data/`. El estado se actualiza en `~/.gradio/data/tmp/estado.json` cada 2 segundos.
|
||||
|
||||
## Menú inicial
|
||||
|
||||
Al comenzar la sesión, presenta este menú exacto:
|
||||
|
||||
```
|
||||
🎙 ASISTENTE G-RADIO PLAYER
|
||||
|
||||
¿Qué necesitas?
|
||||
|
||||
1. 📋 VER / EDITAR PROGRAMACIÓN (parrilla musical)
|
||||
2. 💼 PAUTAR COMERCIAL
|
||||
3. 📅 PROGRAMAR EVENTO
|
||||
4. ⏳ EVENTO EN ESPERA
|
||||
5. 🎛 CONTROLAR EL PLAYER (play/stop/siguiente/volumen)
|
||||
6. 🔍 DIAGNÓSTICO DEL SISTEMA
|
||||
7. 🗂 GESTIONAR COLAS ACTIVAS
|
||||
|
||||
Escribe el número o describe lo que necesitas:
|
||||
```
|
||||
|
||||
## Flujos guiados por opción
|
||||
|
||||
### Opción 1 — Programación musical
|
||||
1. Leer el estado actual: `cat ~/.gradio/data/tmp/estado.json`
|
||||
2. Mostrar qué está sonando ahora
|
||||
3. Mostrar la parrilla del bloque actual: `cat ~/.gradio/data/parrilla/<día>/<hora>-<hora+1>.mus`
|
||||
4. Preguntar: ¿ver, agregar o modificar?
|
||||
5. Para modificar: mostrar el archivo, hacer el cambio, confirmar
|
||||
|
||||
### Opción 2 — Pautar comercial
|
||||
1. Preguntar: ruta del archivo de audio
|
||||
2. Verificar que existe: `ls -la "/ruta/audio.mp3"`
|
||||
3. Preguntar: hora y minuto de la tanda
|
||||
4. Preguntar: días activos (todos / lunes-viernes / fin de semana / específicos)
|
||||
5. Preguntar: fechas de vigencia (inicio y fin, formato DD/MM/AAAA)
|
||||
6. Mostrar la línea que se va a agregar: `/ruta/audio.mp3|máscara|AAAAMMDD|AAAAMMDD`
|
||||
7. Confirmar y ejecutar:
|
||||
```bash
|
||||
mkdir -p ~/.gradio/data/comerciales/<hora>
|
||||
echo "/ruta/audio.mp3|<máscara>|<inicio>|<fin>" >> ~/.gradio/data/comerciales/<hora>/<minuto>.com
|
||||
```
|
||||
8. Mostrar el archivo resultante
|
||||
|
||||
### Opción 3 — Programar evento
|
||||
- Igual que Opción 2 pero en `~/.gradio/data/eventos/<hora>/<minuto>.com`
|
||||
|
||||
### Opción 4 — Evento en espera
|
||||
- Igual que Opción 2 pero en `~/.gradio/data/eventos-espera/<hora>/<minuto>.com`
|
||||
- También ofrecer: poner en cola inmediata (`echo "/ruta.mp3" > ~/.gradio/data/tmp/eventos-esperalist`)
|
||||
|
||||
### Opción 5 — Controlar el player
|
||||
Mostrar estado actual y ofrecer:
|
||||
- ▶ Play: `touch ~/.gradio/data/tmp/cmd_play`
|
||||
- ⏸ Pausa: `touch ~/.gradio/data/tmp/cmd_pause`
|
||||
- ⏹ Stop: `touch ~/.gradio/data/tmp/cmd_stop`
|
||||
- ⏭ Siguiente: `touch ~/.gradio/data/tmp/cmd_siguiente`
|
||||
- ⏹⏹ Stop General: `touch ~/.gradio/data/tmp/cmd_stop_general`
|
||||
- 🔊 Cambiar volumen: `echo "<valor>" > ~/.gradio/data/tmp/upvol`
|
||||
|
||||
### Opción 6 — Diagnóstico
|
||||
Ejecutar el script diagnóstico completo del archivo `context/06-comandos.md` y mostrar resultados interpretados.
|
||||
|
||||
### Opción 7 — Gestionar colas
|
||||
Mostrar contenido de todas las colas activas. Ofrecer: vaciar cola, agregar item, eliminar item específico.
|
||||
|
||||
## Formatos importantes
|
||||
|
||||
### Formato .com (comerciales / eventos / eventos-espera)
|
||||
```
|
||||
/ruta/absoluta/audio.mp3|1234567|20250101|20251231
|
||||
```
|
||||
- Máscara días: `1234567`=todos, `12345`=L-V, `67`=finde, `135`=L-M-V
|
||||
- Fechas: AAAAMMDD sin guiones
|
||||
|
||||
### Formato playlist4 (cola musical)
|
||||
```
|
||||
/ruta/absoluta/audio.mp3 00:04:32.000
|
||||
```
|
||||
- Separador TAB (no espacios)
|
||||
- Duración en formato HH:MM:SS.mmm
|
||||
|
||||
### Señales IPC (touch = activa, el player borra el archivo)
|
||||
```bash
|
||||
touch ~/.gradio/data/tmp/cmd_play
|
||||
touch ~/.gradio/data/tmp/cmd_pause
|
||||
touch ~/.gradio/data/tmp/cmd_stop
|
||||
touch ~/.gradio/data/tmp/cmd_siguiente
|
||||
touch ~/.gradio/data/tmp/cmd_stop_general
|
||||
touch ~/.gradio/data/tmp/cmd_play_tanda
|
||||
```
|
||||
|
||||
## Reglas de calidad
|
||||
|
||||
- **Verificar rutas**: antes de agregar cualquier archivo de audio, comprobar que existe
|
||||
- **Leer antes de escribir**: mostrar el archivo actual antes de modificarlo
|
||||
- **Confirmar cambios**: mostrar la línea exacta antes de escribirla, pedir confirmación
|
||||
- **No borrar sin confirmar**: si hay que eliminar líneas, mostrar cuáles y confirmar
|
||||
- **Usar fechas reales**: preguntar vigencia, no asumir fechas genéricas
|
||||
- **Respetar el formato**: el separador en `.com` es `|`, nunca comas ni espacios
|
||||
- Responder siempre en **español**
|
||||
@@ -0,0 +1,115 @@
|
||||
# Estructura de G-Radio-Player
|
||||
|
||||
Sistema de automatización de radio profesional en **Rust + GTK4**. Tres procesos coordinados que se comunican mediante archivos compartidos en `~/.gradio/data/tmp/`.
|
||||
|
||||
## Binarios instalados en `/usr/local/bin/`
|
||||
|
||||
| Binario | Descripción |
|
||||
|---|---|
|
||||
| `radio-player` | UI principal GTK4 — reproduce música, maneja crossfade, Duck |
|
||||
| `comercial-scheduler` | Daemon que se activa en el minuto :58 y carga las tandas del minuto siguiente |
|
||||
| `playlist-refill` | Daemon que revisa cada 5s y rellena `playlist4` con ~14 temas de la parrilla |
|
||||
| `gradio.sh` | Lanzador principal (mata procesos previos, inicia los 3 procesos + watchdog) |
|
||||
| `gr-botonera` | Ventana de botonera de efectos y jingles rápidos |
|
||||
| `gr-parrilla` | Editor de parrilla semanal (qué suena cada hora) |
|
||||
| `gr-pautaje` | Editor de pautaje comercial (qué comerciales suenan cada minuto) |
|
||||
| `gr-playlist` | Editor de playlist |
|
||||
| `gr-buscador` | Buscador de archivos de audio con preescucha |
|
||||
| `gr-visor` | Visor de reportes y programación |
|
||||
| `gr-reportes` | Generador de reportes de reproducción |
|
||||
| `gr-record` | Grabación de audio |
|
||||
|
||||
## Árbol de datos `~/.gradio/data/`
|
||||
|
||||
```
|
||||
~/.gradio/data/
|
||||
├── tmp/ ← Estado en vivo (leer/escribir aquí)
|
||||
│ ├── gradio.config ← Configuración principal (18 líneas)
|
||||
│ ├── playlist4 ← Cola musical: "ruta\tduracion" por línea
|
||||
│ ├── comercialeslist4 ← Cola activa de comerciales (solo rutas)
|
||||
│ ├── eventoslist ← Cola activa de eventos (solo rutas)
|
||||
│ ├── eventos-esperalist ← Cola activa de eventos en espera
|
||||
│ ├── estado.json ← Estado completo del player (se escribe cada 2s)
|
||||
│ ├── upvol ← Volumen principal 0-100
|
||||
│ ├── downvol ← Volumen duck 0-100
|
||||
│ ├── cmd_play ← Señal: reproducir (crear el archivo para activar)
|
||||
│ ├── cmd_pause ← Señal: pausar
|
||||
│ ├── cmd_stop ← Señal: detener deck A
|
||||
│ ├── cmd_stop_after ← Señal: toggle "detener al terminar el tema"
|
||||
│ ├── cmd_siguiente ← Señal: saltar al siguiente tema
|
||||
│ ├── cmd_stop_general ← Señal: detener TODO (música + comerciales + eventos)
|
||||
│ ├── cmd_play_tanda ← Señal: reproducir tanda de comerciales inmediata
|
||||
│ ├── botonera_now ← Señal: ruta de audio a reproducir en botonera
|
||||
│ ├── play_now ← Señal: "ruta\tduracion" para reproducir ahora
|
||||
│ └── played_breaks ← Tandas ya reproducidas hoy (YYYYMMDD HH:MM por línea)
|
||||
│
|
||||
├── parrilla/ ← Programación semanal de música
|
||||
│ ├── 1/ ← Lunes (1=Lun, 2=Mar, ..., 7=Dom)
|
||||
│ │ ├── 0-1.mus ← Bloque 00:00-01:00 del lunes
|
||||
│ │ ├── 8-9.mus
|
||||
│ │ └── ...
|
||||
│ ├── 2/ ... 7/
|
||||
│
|
||||
├── comerciales/ ← Pautaje de comerciales
|
||||
│ ├── 0/ ← Hora 0 (00:xx)
|
||||
│ │ ├── 0.com ← Comerciales a las 00:00
|
||||
│ │ ├── 30.com ← Comerciales a las 00:30
|
||||
│ │ └── ...
|
||||
│ └── 1/ ... 23/
|
||||
│
|
||||
├── eventos/ ← Eventos programados (mismo formato .com)
|
||||
│ └── <hora>/<minuto>.com
|
||||
│
|
||||
├── eventos-espera/ ← Eventos en espera del operador
|
||||
│ └── <hora>/<minuto>.com
|
||||
│
|
||||
├── botonera/config.json ← Botones configurados en gr-botonera
|
||||
│
|
||||
├── panel/Time/ ← 109 audios de hora (HRS00..HRS23, MIN01..MIN59, etc.)
|
||||
│
|
||||
└── reporte/ ← Reportes CSV de reproducción
|
||||
```
|
||||
|
||||
## Archivo `gradio.config` (18 líneas)
|
||||
|
||||
```
|
||||
línea 1: tarjeta audio principal (vacío = auto)
|
||||
línea 2: tarjeta audio CUE (vacío = auto)
|
||||
línea 3: nombre del medio
|
||||
línea 4: tiempo de fundido crossfade (segundos)
|
||||
línea 5: pisador habilitado (1/0)
|
||||
línea 6: carpeta de pisadores
|
||||
línea 7: cada cuántos temas tocar pisador
|
||||
línea 8: carpetas excluidas de pisador (formato: "/ruta/a";"/ruta/b")
|
||||
línea 9: silencio máximo en segundos (0=desactivado)
|
||||
línea 10: carpetas de música nacional (para reportes)
|
||||
línea 11: carpetas de interculturalidad (para reportes)
|
||||
línea 12: puerto servidor gr-client (default 7777)
|
||||
línea 13: token de autenticación gr-client
|
||||
línea 14: relay habilitado (1/0)
|
||||
línea 15: ID de relay (8 dígitos)
|
||||
línea 16: días de no-repetición (default 3)
|
||||
línea 17: locale ("es"/"en"/"pt" o vacío=auto)
|
||||
línea 18: IA habilitada (1/0)
|
||||
```
|
||||
|
||||
## Archivo `estado.json` (se actualiza cada 2 segundos)
|
||||
|
||||
```json
|
||||
{
|
||||
"reproduciendo": true,
|
||||
"pausado": false,
|
||||
"track_actual": "/home/usuario/Música/tema.mp3",
|
||||
"titulo_actual": "Nombre del tema",
|
||||
"posicion_secs": 45.3,
|
||||
"duracion_secs": 210.0,
|
||||
"upvol": 90,
|
||||
"downvol": 20,
|
||||
"comerciales_activos": false,
|
||||
"eventos_activos": false,
|
||||
"num_comerciales": 3,
|
||||
"num_eventos": 0,
|
||||
"num_eventos_espera": 1,
|
||||
"indice_actual": 7
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,90 @@
|
||||
# Programación Musical (Parrilla)
|
||||
|
||||
La **parrilla** define qué música suena en cada bloque horario de cada día de la semana.
|
||||
|
||||
## Archivos `.mus`
|
||||
|
||||
Ruta: `~/.gradio/data/parrilla/<día>/<hora_inicio>-<hora_fin>.mus`
|
||||
|
||||
- **Día**: 1=Lunes, 2=Martes, 3=Miércoles, 4=Jueves, 5=Viernes, 6=Sábado, 7=Domingo
|
||||
- **Hora**: bloque de una hora (0-1, 1-2, ..., 23-24)
|
||||
- Ejemplo: `~/.gradio/data/parrilla/1/10-11.mus` = Lunes de 10:00 a 11:00
|
||||
|
||||
## Formato de un archivo `.mus`
|
||||
|
||||
Cada línea puede ser:
|
||||
|
||||
```
|
||||
/home/usuario/Música/tema_exacto.mp3 ← archivo específico
|
||||
/home/usuario/Música/Salsa/* ← archivo ALEATORIO de esa carpeta (comodín *)
|
||||
Hora ← insertar anuncio de hora del sistema
|
||||
```
|
||||
|
||||
Ejemplo real:
|
||||
```
|
||||
/home/grecord/Musica/Inicio/intro.mp3
|
||||
/home/grecord/Musica/Pop/*
|
||||
/home/grecord/Musica/Pop/*
|
||||
Hora
|
||||
/home/grecord/Musica/Rock/*
|
||||
/home/grecord/Musica/Baladas/*
|
||||
```
|
||||
|
||||
## Cola activa `playlist4`
|
||||
|
||||
`~/.gradio/data/tmp/playlist4` contiene la playlist en ejecución. Formato TAB-separado:
|
||||
|
||||
```
|
||||
/ruta/absoluta/al/archivo.mp3\t00:03:45.000
|
||||
/ruta/absoluta/al/archivo2.mp3\t00:04:12.000
|
||||
```
|
||||
|
||||
El daemon `playlist-refill` mantiene esta cola con ~14 temas. Cada tema consumido se elimina de la primera línea.
|
||||
|
||||
## Cómo ver la programación actual
|
||||
|
||||
```bash
|
||||
# Qué tema está sonando ahora
|
||||
cat ~/.gradio/data/tmp/estado.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['titulo_actual'], '-', d['track_actual'])"
|
||||
|
||||
# Cola de música pendiente
|
||||
cat ~/.gradio/data/tmp/playlist4
|
||||
|
||||
# Parrilla del día de hoy (ej. lunes = día 1)
|
||||
DIA=$(date +%u) # 1=Lun...7=Dom
|
||||
HORA=$(date +%-H)
|
||||
cat ~/.gradio/data/parrilla/$DIA/$HORA-$((HORA+1)).mus
|
||||
```
|
||||
|
||||
## Cómo modificar la programación
|
||||
|
||||
```bash
|
||||
# Agregar un tema al frente de la cola actual (próximo a reproducir)
|
||||
TEMA="/ruta/al/archivo.mp3"
|
||||
DUR="00:03:45.000"
|
||||
(echo -e "$TEMA\t$DUR"; cat ~/.gradio/data/tmp/playlist4) > /tmp/pl_tmp && mv /tmp/pl_tmp ~/.gradio/data/tmp/playlist4
|
||||
|
||||
# Agregar un tema al final de la cola
|
||||
echo -e "/ruta/al/archivo.mp3\t00:04:00.000" >> ~/.gradio/data/tmp/playlist4
|
||||
|
||||
# Editar la parrilla de mañana (agregar tema a las 9:00-10:00 del martes)
|
||||
echo "/ruta/nuevo_tema.mp3" >> ~/.gradio/data/parrilla/2/9-10.mus
|
||||
|
||||
# Ver toda la programación de la semana para una hora específica
|
||||
for dia in 1 2 3 4 5 6 7; do
|
||||
echo "=== Día $dia ==="
|
||||
cat ~/.gradio/data/parrilla/$dia/10-11.mus 2>/dev/null || echo "(vacío)"
|
||||
done
|
||||
```
|
||||
|
||||
## Días con nombres
|
||||
|
||||
| Número | Día |
|
||||
|--------|-----|
|
||||
| 1 | Lunes |
|
||||
| 2 | Martes |
|
||||
| 3 | Miércoles |
|
||||
| 4 | Jueves |
|
||||
| 5 | Viernes |
|
||||
| 6 | Sábado |
|
||||
| 7 | Domingo |
|
||||
@@ -0,0 +1,103 @@
|
||||
# Comerciales (Pautaje)
|
||||
|
||||
Los **comerciales** son audios programados para sonar a horas y minutos específicos, con control de días activos y fechas de vigencia.
|
||||
|
||||
## Archivos `.com`
|
||||
|
||||
Ruta: `~/.gradio/data/comerciales/<hora>/<minuto>.com`
|
||||
|
||||
- Hora: 0 a 23 (sin cero a la izquierda)
|
||||
- Minuto: 0 a 59 (sin cero a la izquierda)
|
||||
- Ejemplo: `~/.gradio/data/comerciales/15/30.com` = tanda de las 15:30
|
||||
|
||||
## Formato de cada línea en un `.com`
|
||||
|
||||
```
|
||||
/ruta/absoluta/al/audio.mp3|1234567|20250101|20251231
|
||||
```
|
||||
|
||||
| Campo | Significado |
|
||||
|-------|-------------|
|
||||
| `/ruta/...` | Ruta absoluta al archivo de audio |
|
||||
| `1234567` | Máscara de días activos: cada dígito = un día (1=Lun, 2=Mar, 3=Mié, 4=Jue, 5=Vie, 6=Sáb, 7=Dom). `1234567` = todos los días |
|
||||
| `20250101` | Fecha de inicio de vigencia (AAAAMMDD) |
|
||||
| `20251231` | Fecha de fin de vigencia (AAAAMMDD) |
|
||||
|
||||
### Ejemplos de máscaras de días
|
||||
|
||||
```
|
||||
1234567 → todos los días
|
||||
12345 → lunes a viernes
|
||||
67 → sábado y domingo
|
||||
135 → lunes, miércoles, viernes
|
||||
1 → solo lunes
|
||||
```
|
||||
|
||||
### Ejemplos de entradas `.com`
|
||||
|
||||
```
|
||||
/home/grecord/Comerciales/spot_banco.mp3|12345|20250601|20250630
|
||||
/home/grecord/Comerciales/promo_fin_semana.mp3|67|20250101|20251231
|
||||
/home/grecord/Comerciales/jingle_general.mp3|1234567|20250101|20261231
|
||||
```
|
||||
|
||||
## Cola activa `comercialeslist4`
|
||||
|
||||
`~/.gradio/data/tmp/comercialeslist4` contiene la cola que el player está procesando **ahora**. Solo tiene rutas (ya sin máscara ni fechas, esas ya fueron evaluadas por el scheduler):
|
||||
|
||||
```
|
||||
/home/grecord/Comerciales/spot_banco.mp3
|
||||
/home/grecord/Comerciales/jingle_general.mp3
|
||||
```
|
||||
|
||||
## Archivo `played_breaks`
|
||||
|
||||
`~/.gradio/data/tmp/played_breaks` registra las tandas que ya fueron reproducidas manualmente hoy (para que el scheduler no las vuelva a disparar):
|
||||
|
||||
```
|
||||
20250627 15:30
|
||||
20250627 16:00
|
||||
```
|
||||
|
||||
## Comandos útiles
|
||||
|
||||
```bash
|
||||
# Ver la tanda de las 15:30
|
||||
cat ~/.gradio/data/comerciales/15/30.com
|
||||
|
||||
# Ver todos los comerciales programados para hoy (lunes = día 1)
|
||||
HOY=$(date +%u)
|
||||
for h in $(seq 0 23); do
|
||||
for f in ~/.gradio/data/comerciales/$h/*.com; do
|
||||
[ -f "$f" ] || continue
|
||||
grep "|.*$HOY" "$f" && echo " → $f"
|
||||
done
|
||||
done
|
||||
|
||||
# Ver qué está en cola activa
|
||||
cat ~/.gradio/data/tmp/comercialeslist4
|
||||
|
||||
# Agregar un comercial a las 16:00 de hoy (todos los días, vigente todo el año)
|
||||
echo "/ruta/spot.mp3|1234567|20250101|20261231" >> ~/.gradio/data/comerciales/16/0.com
|
||||
|
||||
# Crear directorio si no existe
|
||||
mkdir -p ~/.gradio/data/comerciales/16
|
||||
echo "/ruta/spot.mp3|1234567|20250101|20261231" >> ~/.gradio/data/comerciales/16/0.com
|
||||
|
||||
# Reproducir tanda inmediatamente (sin esperar al scheduler)
|
||||
echo "/ruta/spot.mp3" > ~/.gradio/data/tmp/comercialeslist4
|
||||
touch ~/.gradio/data/tmp/cmd_play_tanda
|
||||
|
||||
# Ver tandas ya reproducidas hoy
|
||||
cat ~/.gradio/data/tmp/played_breaks
|
||||
```
|
||||
|
||||
## Cómo funciona el scheduler
|
||||
|
||||
El daemon `comercial-scheduler` (Rust) se activa en el minuto **:58** de cada hora y:
|
||||
1. Lee los archivos `.com` del minuto y hora siguientes
|
||||
2. Filtra por día activo (máscara) y fechas de vigencia
|
||||
3. Carga las rutas válidas en `comercialeslist4`
|
||||
4. El player las procesa cuando llega el momento
|
||||
|
||||
Si una tanda aparece en `played_breaks` con fecha/hora de hoy, el scheduler la salta (ya se reprodujo manualmente).
|
||||
@@ -0,0 +1,113 @@
|
||||
# Eventos
|
||||
|
||||
Los **eventos** son acciones programadas que suenan de forma emergente: interrumpen la música brevemente, reproducen el audio, y la música se reanuda. Comparten el mismo formato `.com` que los comerciales.
|
||||
|
||||
## Archivos `.com` de eventos
|
||||
|
||||
Ruta: `~/.gradio/data/eventos/<hora>/<minuto>.com`
|
||||
|
||||
- Mismo formato que comerciales: `/ruta/audio.mp3|máscara_días|fecha_inicio|fecha_fin`
|
||||
- Ejemplo: `~/.gradio/data/eventos/12/0.com` = evento del mediodía
|
||||
|
||||
## Cola activa `eventoslist`
|
||||
|
||||
`~/.gradio/data/tmp/eventoslist` — lista de rutas que el player procesará como evento emergente.
|
||||
|
||||
El player detecta cuando esta cola tiene contenido y la procesa de inmediato (interrumpe brevemente la música).
|
||||
|
||||
## Diferencia entre Comerciales, Eventos y Eventos-en-Espera
|
||||
|
||||
| Aspecto | Comerciales | Eventos | Eventos-en-Espera |
|
||||
|---------|-------------|---------|-------------------|
|
||||
| Directorio | `data/comerciales/` | `data/eventos/` | `data/eventos-espera/` |
|
||||
| Cola activa | `tmp/comercialeslist4` | `tmp/eventoslist` | `tmp/eventos-esperalist` |
|
||||
| Típico uso | Publicidad programada | Cuñas institucionales, separadores | Acciones espontáneas del operador |
|
||||
| Scheduler | `comercial-scheduler` | `comercial-scheduler` | `comercial-scheduler` |
|
||||
|
||||
## Comandos útiles
|
||||
|
||||
```bash
|
||||
# Ver eventos programados para hoy a las 12:00
|
||||
cat ~/.gradio/data/eventos/12/0.com
|
||||
|
||||
# Ver cola activa de eventos
|
||||
cat ~/.gradio/data/tmp/eventoslist
|
||||
|
||||
# Disparar un evento inmediatamente (reproducir ahora)
|
||||
echo "/ruta/cuña.mp3" > ~/.gradio/data/tmp/eventoslist
|
||||
|
||||
# Agregar evento al mediodía todos los días
|
||||
mkdir -p ~/.gradio/data/eventos/12
|
||||
echo "/ruta/cuña_mediodia.mp3|1234567|20250101|20261231" >> ~/.gradio/data/eventos/12/0.com
|
||||
|
||||
# Vaciar la cola activa de eventos
|
||||
> ~/.gradio/data/tmp/eventoslist
|
||||
|
||||
# Ver estado general del sistema (incluye num_eventos)
|
||||
cat ~/.gradio/data/tmp/estado.json | python3 -c "import sys,json; d=json.load(sys.stdin); print('Eventos en cola:', d['num_eventos'])"
|
||||
```
|
||||
|
||||
## Estado en `estado.json`
|
||||
|
||||
El campo `eventos_activos` indica si hay un evento reproduciéndose ahora mismo. `num_eventos` muestra cuántos hay en cola.
|
||||
|
||||
# Eventos en Espera
|
||||
|
||||
Los **eventos en espera** son acciones programadas que el operador prepara con antelación para disparar cuando lo decida, o que el scheduler carga automáticamente. Son el equivalente de una "lista de espera" de efectos.
|
||||
|
||||
## Archivos `.com`
|
||||
|
||||
Ruta: `~/.gradio/data/eventos-espera/<hora>/<minuto>.com`
|
||||
|
||||
- Mismo formato que comerciales y eventos: `/ruta/audio.mp3|máscara_días|fecha_inicio|fecha_fin`
|
||||
- Ejemplo: `~/.gradio/data/eventos-espera/9/30.com` = evento en espera a las 9:30
|
||||
|
||||
## Cola activa `eventos-esperalist`
|
||||
|
||||
`~/.gradio/data/tmp/eventos-esperalist` — lista de rutas pendientes en espera.
|
||||
|
||||
El player la monitorea: cuando tiene contenido, lo reproduce en modo emergente (igual que `eventoslist`).
|
||||
|
||||
## Uso típico
|
||||
|
||||
Los eventos en espera se usan para:
|
||||
- Anuncios de noticias que salen al aire cuando el operador decide
|
||||
- Efectos especiales cargados con antelación
|
||||
- Separadores y cortinas que se reproducen bajo demanda
|
||||
|
||||
## Comandos útiles
|
||||
|
||||
```bash
|
||||
# Ver cola de eventos en espera
|
||||
cat ~/.gradio/data/tmp/eventos-esperalist
|
||||
|
||||
# Poner un audio en la cola de espera (listo para reproducir)
|
||||
echo "/ruta/noticia_urgente.mp3" > ~/.gradio/data/tmp/eventos-esperalist
|
||||
|
||||
# Agregar sin borrar los anteriores
|
||||
echo "/ruta/efecto.mp3" >> ~/.gradio/data/tmp/eventos-esperalist
|
||||
|
||||
# Vaciar la cola de espera
|
||||
> ~/.gradio/data/tmp/eventos-esperalist
|
||||
|
||||
# Programar evento en espera para las 10:30 todos los lunes-viernes
|
||||
mkdir -p ~/.gradio/data/eventos-espera/10
|
||||
echo "/ruta/noticia.mp3|12345|20250601|20251231" >> ~/.gradio/data/eventos-espera/10/30.com
|
||||
|
||||
# Estado: cuántos hay en la cola de espera
|
||||
cat ~/.gradio/data/tmp/estado.json | python3 -c "import sys,json; d=json.load(sys.stdin); print('En espera:', d['num_eventos_espera'])"
|
||||
```
|
||||
|
||||
## Resumen de las tres colas
|
||||
|
||||
```bash
|
||||
# Ver el estado de todas las colas a la vez
|
||||
echo "=== MÚSICA (playlist4) ==="
|
||||
wc -l ~/.gradio/data/tmp/playlist4
|
||||
echo "=== COMERCIALES activos ==="
|
||||
cat ~/.gradio/data/tmp/comercialeslist4
|
||||
echo "=== EVENTOS activos ==="
|
||||
cat ~/.gradio/data/tmp/eventoslist
|
||||
echo "=== EVENTOS EN ESPERA ==="
|
||||
cat ~/.gradio/data/tmp/eventos-esperalist
|
||||
```
|
||||
@@ -0,0 +1,180 @@
|
||||
# Comandos y Control del Sistema
|
||||
|
||||
## Control de reproducción (señales IPC)
|
||||
|
||||
El player monitorea la carpeta `~/.gradio/data/tmp/` cada 200ms. Para enviar un comando, **crea el archivo** — el player lo lee, ejecuta la acción y borra el archivo.
|
||||
|
||||
```bash
|
||||
TMP=~/.gradio/data/tmp
|
||||
|
||||
# Reproducir (reanudar desde pausa)
|
||||
touch "$TMP/cmd_play"
|
||||
|
||||
# Pausar / reanudar (toggle)
|
||||
touch "$TMP/cmd_pause"
|
||||
|
||||
# Detener deck A (deja los comerciales intactos)
|
||||
touch "$TMP/cmd_stop"
|
||||
|
||||
# Toggle "detener al terminar el tema actual"
|
||||
touch "$TMP/cmd_stop_after"
|
||||
|
||||
# Saltar al siguiente tema
|
||||
touch "$TMP/cmd_siguiente"
|
||||
|
||||
# STOP GENERAL: detiene música + comerciales + eventos todo
|
||||
touch "$TMP/cmd_stop_general"
|
||||
|
||||
# Reproducir tanda de comerciales AHORA (sin esperar al scheduler)
|
||||
# Primero cargar la lista, luego la señal
|
||||
echo "/ruta/spot1.mp3" > "$TMP/comercialeslist4"
|
||||
echo "/ruta/spot2.mp3" >> "$TMP/comercialeslist4"
|
||||
touch "$TMP/cmd_play_tanda"
|
||||
|
||||
# Reproducir audio en botonera (sin interrumpir música ni comerciales)
|
||||
echo "/ruta/efecto.mp3" > "$TMP/botonera_now"
|
||||
|
||||
# Reproducir tema inmediatamente (crossfade hacia él)
|
||||
echo -e "/ruta/tema.mp3\t00:03:45.000" > "$TMP/play_now"
|
||||
```
|
||||
|
||||
## Estado del sistema
|
||||
|
||||
```bash
|
||||
# Estado completo (JSON actualizado cada 2s)
|
||||
cat ~/.gradio/data/tmp/estado.json
|
||||
|
||||
# Estado formateado
|
||||
cat ~/.gradio/data/tmp/estado.json | python3 -m json.tool
|
||||
|
||||
# Valores individuales
|
||||
python3 -c "
|
||||
import json
|
||||
d = json.load(open('$HOME/.gradio/data/tmp/estado.json'))
|
||||
print(f'Reproduciendo: {d[\"reproduciendo\"]}')
|
||||
print(f'Tema actual: {d[\"titulo_actual\"]}')
|
||||
print(f'Posición: {d[\"posicion_secs\"]:.0f}s / {d[\"duracion_secs\"]:.0f}s')
|
||||
print(f'Volumen: up={d[\"upvol\"]}% duck={d[\"downvol\"]}%')
|
||||
print(f'Comerciales: {d[\"num_comerciales\"]} en cola, activos={d[\"comerciales_activos\"]}')
|
||||
print(f'Eventos: {d[\"num_eventos\"]}')
|
||||
print(f'En espera: {d[\"num_eventos_espera\"]}')
|
||||
"
|
||||
|
||||
# Playlist pendiente (cuántos temas quedan)
|
||||
wc -l ~/.gradio/data/tmp/playlist4
|
||||
|
||||
# Cola de comerciales activa
|
||||
cat ~/.gradio/data/tmp/comercialeslist4
|
||||
```
|
||||
|
||||
## Volumen
|
||||
|
||||
```bash
|
||||
# Ver volumen actual
|
||||
echo "Principal: $(cat ~/.gradio/data/tmp/upvol)%"
|
||||
echo "Duck: $(cat ~/.gradio/data/tmp/downvol)%"
|
||||
|
||||
# Cambiar volumen principal a 85%
|
||||
echo "85" > ~/.gradio/data/tmp/upvol
|
||||
|
||||
# Cambiar volumen duck a 20%
|
||||
echo "20" > ~/.gradio/data/tmp/downvol
|
||||
```
|
||||
|
||||
## Parrilla (programación)
|
||||
|
||||
```bash
|
||||
# Ver qué suena ahora
|
||||
HORA=$(date +%-H)
|
||||
DIA=$(date +%u) # 1=Lun...7=Dom
|
||||
echo "=== Parrilla actual: día $DIA, hora $HORA ==="
|
||||
cat ~/.gradio/data/parrilla/$DIA/$HORA-$((HORA+1)).mus
|
||||
|
||||
# Agregar tema a la hora actual
|
||||
echo "/ruta/nuevo_tema.mp3" >> ~/.gradio/data/parrilla/$DIA/$HORA-$((HORA+1)).mus
|
||||
|
||||
# Crear parrilla para todas las horas de un día (comodín)
|
||||
for h in $(seq 0 23); do
|
||||
mkdir -p ~/.gradio/data/parrilla/1
|
||||
echo "/home/grecord/Musica/Variado/*" >> ~/.gradio/data/parrilla/1/$h-$((h+1)).mus
|
||||
done
|
||||
```
|
||||
|
||||
## Comerciales
|
||||
|
||||
```bash
|
||||
# Agregar comercial a las 16:00 (todos los días, todo el año)
|
||||
mkdir -p ~/.gradio/data/comerciales/16
|
||||
echo "/ruta/spot.mp3|1234567|20250101|20261231" >> ~/.gradio/data/comerciales/16/0.com
|
||||
|
||||
# Ver tandas de la hora actual
|
||||
HORA=$(date +%-H)
|
||||
MIN=$(date +%-M)
|
||||
ls ~/.gradio/data/comerciales/$HORA/
|
||||
|
||||
# Ver tandas ya reproducidas hoy
|
||||
cat ~/.gradio/data/tmp/played_breaks
|
||||
```
|
||||
|
||||
## Locución con IA
|
||||
|
||||
```bash
|
||||
# Generar locución con voz clonada de Pato (requiere GPU NVIDIA)
|
||||
locuta "Texto a locutar"
|
||||
|
||||
# Especificar nombre de archivo
|
||||
cd ~/Dropbox/LocutorIA
|
||||
./locucion_pato.sh "Texto a locutar" nombre_salida
|
||||
|
||||
# La locución se genera en:
|
||||
# ~/Dropbox/LocutorIA/salida_mp3/locucion_AAAAMMDD_HHMMSS.mp3
|
||||
# (o salida_mp3/nombre_salida.mp3 si se usó nombre personalizado)
|
||||
|
||||
# Copiar a la carpeta Time de G Radio Player para usar como locución de hora:
|
||||
cp ~/Dropbox/LocutorIA/salida_mp3/locucion_*.mp3 ~/.gradio/data/panel/Time/
|
||||
|
||||
# O copiar a la carpeta de comerciales/eventos para pautar:
|
||||
cp ~/Dropbox/LocutorIA/salida_mp3/mi_locucion.mp3 ~/.gradio/data/comerciales/15/
|
||||
```
|
||||
|
||||
## Verificar daemons
|
||||
|
||||
```bash
|
||||
# Ver si los daemons están corriendo
|
||||
ps aux | grep -E 'comercial-scheduler|playlist-refill' | grep -v grep
|
||||
|
||||
# Verificar que el player está activo
|
||||
ps aux | grep radio-player | grep -v grep
|
||||
|
||||
# Leer configuración actual
|
||||
cat ~/.gradio/data/tmp/gradio.config
|
||||
```
|
||||
|
||||
## Diagnóstico rápido
|
||||
|
||||
```bash
|
||||
# Script de diagnóstico completo
|
||||
echo "=== G-Radio Player — Estado ==="
|
||||
echo ""
|
||||
echo "Procesos:"
|
||||
ps aux | grep -E 'radio-player|comercial-scheduler|playlist-refill' | grep -v grep
|
||||
|
||||
echo ""
|
||||
echo "Reproducción:"
|
||||
python3 -c "
|
||||
import json, sys
|
||||
try:
|
||||
d = json.load(open('$HOME/.gradio/data/tmp/estado.json'))
|
||||
print(f' Reproduciendo: {d[\"reproduciendo\"]}')
|
||||
print(f' Tema: {d[\"titulo_actual\"]}')
|
||||
print(f' Posición: {d[\"posicion_secs\"]:.0f}s / {d[\"duracion_secs\"]:.0f}s')
|
||||
except: print(' (estado.json no disponible)')
|
||||
"
|
||||
|
||||
echo ""
|
||||
echo "Colas:"
|
||||
echo " Música pendiente: $(wc -l < ~/.gradio/data/tmp/playlist4 2>/dev/null || echo 0) temas"
|
||||
echo " Comerciales: $(wc -l < ~/.gradio/data/tmp/comercialeslist4 2>/dev/null | tr -d ' ') items"
|
||||
echo " Eventos: $(wc -l < ~/.gradio/data/tmp/eventoslist 2>/dev/null | tr -d ' ') items"
|
||||
echo " En espera: $(wc -l < ~/.gradio/data/tmp/eventos-esperalist 2>/dev/null | tr -d ' ') items"
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json"
|
||||
}
|
||||
Reference in New Issue
Block a user