Arquitectura de Radio 3 Desktop - Zarrapo/radio3-electron GitHub Wiki

🏗️ Arquitectura de Radio 3 Desktop

📌 Introducción

Esta página describe la arquitectura interna de Radio 3 Desktop, su estructura de archivos y cómo se comunican los distintos componentes dentro de la aplicación Electron.js.


📂 Estructura del Proyecto

La aplicación sigue una arquitectura basada en dos procesos principales en Electron.js:

  1. Proceso Principal (main.js) → Controla la ventana principal y la lógica de fondo.
  2. Proceso Renderer (renderer.js) → Maneja la interfaz de usuario y las interacciones.

📁 Estructura del proyecto:

electron-radio3/
│── assets/               # Iconos e imágenes
│── build/                # Configuración del instalador NSIS
│── dist/                 # Carpeta de salida tras compilar
│── docs/                 # Documentación del proyecto
│── images/               # Capturas de pantalla y gráficos
│── node_modules/         # Dependencias del proyecto
│── .gitignore            # Archivos ignorados en Git
│── about.html            # Página "Acerca de" de la aplicación
│── config.json           # Configuración de emisoras y etiquetas
│── index.html            # Interfaz principal
│── LICENSE               # Licencia del proyecto
│── main.js               # Código del proceso principal (backend)
│── package.json          # Configuración de dependencias y scripts
│── package-lock.json     # Versión exacta de las dependencias
│── README.md             # Documentación principal
│── renderer.js           # Código del proceso renderer (frontend)
│── styles.css            # Estilos de la aplicación

🔹 Proceso Principal (main.js)

El Proceso Principal en Electron es el encargado de controlar la ventana principal, manejar la barra de tareas (Tray) y gestionar la comunicación con el proceso renderer.

📜 Código clave en main.js:

import { app, BrowserWindow, ipcMain, Menu, Tray } from 'electron';
import path from 'path';
import Store from 'electron-store';

const store = new Store();
let mainWindow;

// Crear la ventana principal
function createWindow() {
    mainWindow = new BrowserWindow({
        width: 300,
        height: 400,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false
        }
    });

    mainWindow.loadFile('index.html');
}

// Guardar última emisora seleccionada
ipcMain.on('change-station', (event, url) => {
    store.set('lastStation', url);
});

app.whenReady().then(() => {
    createWindow();
});

Se crea la ventana principal usando BrowserWindow.
ipcMain.on() escucha eventos desde renderer.js para guardar configuraciones.


🔹 Proceso Renderer (renderer.js)

El Proceso Renderer maneja la interfaz gráfica, actualiza los elementos en pantalla y envía eventos al proceso principal.

📜 Código clave en renderer.js:

const { ipcRenderer } = require('electron');

const audio = document.getElementById('audio');
const stationButtons = document.querySelectorAll('.station-button');

// Cargar y reproducir la última emisora usada
ipcRenderer.on('play-last-station', (event, lastStation) => {
    audio.src = lastStation;
    audio.play();
});

// Enviar cambio de emisora al proceso principal
function changeStation(url) {
    audio.src = url;
    audio.play();
    ipcRenderer.send('change-station', url);
}

ipcRenderer.send() envía la URL de la emisora al proceso principal (main.js).
ipcRenderer.on() recibe eventos del proceso principal y los ejecuta en la UI.


🔄 Comunicación entre Procesos

Electron usa ipcMain (en main.js) e ipcRenderer (en renderer.js) para la comunicación entre procesos.

📜 Ejemplo de Comunicación

1️⃣ El usuario selecciona una emisora en la UI.
2️⃣ renderer.js envía la URL al proceso principal:

ipcRenderer.send('change-station', url);

3️⃣ main.js recibe el evento y guarda la URL:

ipcMain.on('change-station', (event, url) => {
    store.set('lastStation', url);
});

🎨 Interfaz de Usuario (index.html y styles.css)

📌 La interfaz está en index.html, y los estilos se definen en styles.css.
📌 Se usa config.json para definir las emisoras y sus nombres.

📜 Código clave en index.html:

<body>
    <img src="assets/icons/rne.png" alt="RNE Logo" class="rne-logo">
    <div class="button-container">
        <button id="station1" class="station-button">Radio 3</button>
        <button id="station2" class="station-button">Radio Clásica</button>
        <button id="station3" class="station-button">Radio 5</button>
        <button id="station4" class="station-button">Radio Nacional</button>
    </div>
    <audio id="audio"></audio>
</body>

📜 Código clave en styles.css:

button {
    font-size: 18px;
    font-weight: bold;
    color: white;
    background-color: #d00000;
    border: none;
    padding: 10px 30px;
    width: 220px;
    height: 50px;
    cursor: pointer;
}

Los botones se generan dinámicamente y controlan la reproducción de emisoras.
La interfaz tiene un diseño minimalista y responsive.


⚙️ Configuración Personalizada (config.json)

El archivo config.json permite modificar las URLs de las emisoras y sus etiquetas sin tocar el código.

📌 Ejemplo de config.json:

{
    "stations": {
      "station1": {
        "url": "https://dispatcher.rndfnk.com/crtve/rner3/main/mp3/high",
        "label": "Radio 3"
      },
      "station2": {
        "url": "https://dispatcher.rndfnk.com/crtve/rnerc/main/mp3/high",
        "label": "Radio Clásica"
      }
    }
}

Los usuarios pueden personalizar fácilmente las emisoras.
El archivo se carga al inicio y se usa para generar los botones en la UI.


🛠️ Próximas Mejoras

📌 Integrar un menú de configuración dentro de la aplicación.
📌 Permitir cambiar colores y estilos desde config.json.
📌 Soporte para más emisoras personalizadas.

⚠️ **GitHub.com Fallback** ⚠️