Documentación
Todo lo que tu web, tu app o tu programador necesitan para usar una radio de StreamBol. Reemplaza PUERTO por el puerto de tu radio (lo ves en el panel).
1. URLs de la radio
| Para | URL |
|---|---|
| Web, apps, iPhone, miles de oyentes (HLS) | https://streambol.online/securehls/PUERTO/TOKEN/playlist.m3u8 |
| Winamp, VLC, directorios, apps viejas (directo ICY) | https://streambol.online/stream/PUERTO/TOKEN |
| Página de prueba | https://streambol.online/reproductor/PUERTO |
Si la radio tiene la firma apagada, TOKEN puede ser la palabra public. Con la firma encendida, cada oyente necesita un token que vence (sección 2).
2. Firma de URLs (securelink)
El token se arma con la clave secreta de la radio (pestaña Firma del panel) y va en la ruta, así los segmentos .ts heredan la firma.
inicio = ahora - 300 # segundos (5 min de tolerancia entre relojes) fin = inicio + vigencia # p. ej. 3 h = 10800 sal = 32 caracteres hex al azar ip = IP del oyente, o la cadena "no_check_ip" para no atar el token a una IP hash = sha1( PUERTO + ip + inicio + fin + CLAVE + sal ) token = hash + "-" + sal + "-" + fin + "-" + inicio
Reglas: vence en fin; si el token lleva IP, solo esa IP puede escuchar; si lleva no_check_ip, cualquiera con el enlace puede escuchar hasta que venza (recomendado para celulares, que cambian de IP). Un token sirve para el HLS y para el directo.
3. Generadores de token
PHP
function streambol_token(int $puerto, string $clave, int $vigencia = 10800, string $ip = 'no_check_ip'): string {
$inicio = time() - 300; $fin = $inicio + $vigencia; $sal = bin2hex(random_bytes(16));
return sha1($puerto . $ip . $inicio . $fin . $clave . $sal) . "-$sal-$fin-$inicio";
}
$url = "https://streambol.online/securehls/PUERTO/" . streambol_token(PUERTO, $clave) . "/playlist.m3u8";
Node.js
const crypto = require('crypto');
function token(puerto, clave, vigencia = 10800, ip = 'no_check_ip') {
const inicio = Math.floor(Date.now() / 1000) - 300, fin = inicio + vigencia, sal = crypto.randomBytes(16).toString('hex');
return crypto.createHash('sha1').update(`${puerto}${ip}${inicio}${fin}${clave}${sal}`).digest('hex') + `-${sal}-${fin}-${inicio}`;
}
Python
import hashlib, os, time
def token(puerto, clave, vigencia=10800, ip='no_check_ip'):
inicio = int(time.time()) - 300; fin = inicio + vigencia; sal = os.urandom(16).hex()
return hashlib.sha1(f"{puerto}{ip}{inicio}{fin}{clave}{sal}".encode()).hexdigest() + f"-{sal}-{fin}-{inicio}"
¿No quieres poner la clave en tu servidor? Pide la URL firmada a la API con tu llave (sección 4).
4. API
Respuestas JSON con el sobre {"ok": true, "data": {...}}. Las públicas se guardan unos segundos en caché: puedes llamarlas desde todas tus apps sin miedo.
| Método y ruta | Qué devuelve | Llave |
|---|---|---|
GET /api/v1/radios/PUERTO/ahora | estado (al_aire, sin_fuente, apagada), oyentes (hls, directo, total), pico, título que suena, bitrate, formato, tiempo al aire | no |
GET /api/v1/radios/PUERTO/historial | últimas 20 canciones con hora | no |
GET /api/v1/servidor/estado | radios al aire y oyentes totales del servidor | no |
GET /api/v1/radios/PUERTO/url?ip=&horas=3 | URLs firmadas (hls, directo), token y vencimiento. ip opcional | sí |
GET /api/v1/radios/PUERTO/oyentes?minutos=180 | serie de oyentes por minuto | sí |
GET /api/v1/radios/PUERTO/verificar?token=&ip= | si un token es válido y por qué no | sí |
La llave se genera en el panel (pestaña API) y se manda así: Authorization: Bearer sb_ID_SECRETO. Límite: 600 llamadas por minuto por radio.
curl -H "Authorization: Bearer sb_4_…" "https://streambol.online/api/v1/radios/PUERTO/url?horas=6"
{"ok":true,"data":{"hls":"https://streambol.online/securehls/PUERTO/…/playlist.m3u8","directo":"https://streambol.online/stream/PUERTO/…","token":"…","vence":"2026-10-14T03:00:00-04:00","ip":null}}
Ejemplo de ahora:
{"ok":true,"data":{"puerto":8206,"radio":"Mi Radio","estado":"al_aire","oyentes":{"hls":312,"directo":6,"total":318},
"max_oyentes":10000,"pico":445,"titulo":"Los Kjarkas - Llorando se fue","bitrate":64,"formato":"AAC","tiempo_al_aire":5400,"hora":"…"}}
5. Reproductor en tu web
Primero agrega tu dominio en el panel (Conexión → Webs que pueden reproducir el audio). Luego, con hls.js:
<audio id="radio" controls></audio>
<script src="https://cdn.jsdelivr.net/npm/hls.js@1/dist/hls.min.js"></script>
<script>
var url = "https://streambol.online/securehls/PUERTO/TOKEN/playlist.m3u8"; // el TOKEN lo genera tu servidor
var audio = document.getElementById('radio');
if (Hls.isSupported()) { var hls = new Hls(); hls.loadSource(url); hls.attachMedia(audio); }
else { audio.src = url; } // Safari/iPhone reproduce HLS solo
</script>
Para apps Android (Media3/ExoPlayer) o iOS (AVPlayer) usa la misma URL HLS; para apps viejas que solo saben ICY, la URL /stream/PUERTO/TOKEN. Si usas la firma, que la app pida la URL a tu servidor (o a nuestra API con tu llave) al arrancar y cada vez que falle con 403.
6. Para transmitir
Servidor, puerto, clave de emisión (y montaje si es Icecast) están en la pestaña Conexión. SHOUTcast v1 usa el puerto + 1; SHOUTcast v2 e Icecast el puerto base. Recomendamos AAC 64 kbps o MP3 128 kbps. Con AutoDJ encendido, el locutor en vivo entra por el puerto + 10000, montaje /live, misma clave.