No description
| backend | ||
| frontend | ||
| .gitignore | ||
| LICENSE | ||
| README.md | ||
Streambox
Estación de streaming sobre Raspberry Pi para emitir partidos de vóley a Twitch y YouTube simultáneamente, con control y previsualización desde el móvil.
Características
- Multistreaming a Twitch y YouTube con una sola instancia de FFmpeg (muxer
tee). - HLS local en tmpfs para previsualización sin desgaste de SD.
- Control remoto desde cualquier navegador (móvil o PC).
- Dos modos de emisión:
- Preview: FFmpeg arranca solo con HLS local, sin emitir a plataformas.
- OnAir: FFmpeg arranca con HLS + RTMP a Twitch y YouTube.
- Placeholder del
.m3u8para evitar 404 durante el arranque. - Detección automática del formato de cámara (H.264 nativo vs MJPG/YUYV con recodificación).
- Backend optimizado: cachés de CPU y estado, limpieza de FFmpeg huérfanos.
- Frontend optimizado: polling adaptativo, pausa al ocultar pestaña.
Arquitectura
┌──────────────┐ ┌──────────────────────┐ ┌──────────┐
│ Cámara USB │─────▶│ FFmpeg (muxer tee) │─────▶│ Twitch │
│ (H.264/MJPG) │ │ │ └──────────┘
└──────────────┘ │ │ ┌──────────┐
│ │─────▶│ YouTube │
│ │ └──────────┘
│ │ ┌──────────┐
│ │─────▶│ HLS tmpfs│
└──────────────────────┘ └──────────┘
▲ │
│ ▼
┌──────────────────────┐ ┌──────────────┐
│ Flask API (5000) │◀───│ Navegador │
│ + control FFmpeg │ │ (móvil/PC) │
└──────────────────────┘ └──────────────┘
Requisitos
- Raspberry Pi 3/4/5 con Raspberry Pi OS o DietPi (64-bit recomendado).
- FFmpeg, Python 3, Flask.
- Cámara USB (idealmente con H.264 nativo, como la Logitech C925e).
- Conexión a internet para emitir a Twitch/YouTube.
Instalación
1. Dependencias
apt update
apt install -y ffmpeg python3 python3-flask alsa-utils v4l-utils
2. Estructura de directorios
mkdir -p /opt/streambox/backend
mkdir -p /opt/streambox/frontend
mkdir -p /mnt/hls
3. tmpfs para HLS
Añade a /etc/fstab:
tmpfs /mnt/hls tmpfs size=64M,mode=0755,uid=root,gid=root,noatime 0 0
Y monta:
systemctl daemon-reload
mount -a
4. Copiar los ficheros
backend/app.py→/opt/streambox/backend/app.pybackend/config.example.json→/opt/streambox/backend/config.jsonfrontend/index.html→/opt/streambox/frontend/index.html
5. Editar config.json
Copia config.example.json a config.json y rellena:
video.device: normalmente/dev/video0. Idealmente usa el path estable/dev/v4l/by-id/....video.input_format:h264(cámara H.264 nativo) omjpeg(la mayoría de webcams USB).video.size:1280x720recomendado.video.bitrate:2500kpara 720p,4000kpara 1080p.audio.device:plughw:0,0o el que corresponda (verarecord -l).outputs.twitch.urlyoutputs.youtube.url: tus claves reales.
6. Arrancar
cd /opt/streambox/backend
python3 app.py
Y abre en el navegador:
http://<ip-de-la-pi>:5000
Uso
Botones
- 👁 Preview: arranca FFmpeg en modo preview (solo HLS, sin emitir).
- 🔴 Emitir: arranca FFmpeg en modo onair (HLS + RTMP a Twitch/YouTube).
- ⏹ Parar: detiene todo.
Flujo recomendado
- Pulsar 👁 Preview para verificar encuadre, foco, audio.
- Ajustar la cámara mientras se ve la preview.
- Pulsar 🔴 Emitir cuando todo esté listo.
- Al terminar, pulsar ⏹ Parar.
Configuración de cámara
Detectar formatos soportados
v4l2-ctl --list-formats-ext -d /dev/video0
Detectar dispositivos de audio
arecord -l
El formato para FFmpeg es plughw:X,Y donde X es el card y Y el device.
Si la cámara entrega H.264 nativo
Configura "input_format": "h264" en config.json. El backend automáticamente usa -c:v copy sin recodificar (CPU ~5-15%).
Si la cámara entrega MJPG o YUYV
Configura "input_format": "mjpeg" o "yuyv422". El backend recodifica con libx264 -preset ultrafast (CPU ~60-80% en 720p30).
Servicio systemd (opcional)
Crea /etc/systemd/system/streambox.service:
[Unit]
Description=Streambox backend
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/streambox/backend
ExecStart=/usr/bin/python3 app.py
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
Activar:
systemctl daemon-reload
systemctl enable streambox
systemctl start streambox
Notas
- Chrome/Edge de escritorio no soportan HLS nativo. La preview funciona solo en Safari (iOS/macOS) y navegadores móviles (Chrome Android, Firefox Android). Para PC de escritorio habría que añadir hls.js.
?bandwidthtest=trueen la URL de Twitch sirve para probar sin publicar. Quítalo para emitir de verdad.- El tmpfs evita desgaste de la SD. Un reinicio lo vacía, lo cual es deseable.
Licencia
MIT