REPRODUCTOR DE EMISORAS DE RADIO
Introducción
El propósito de este proyecto es crear una aplicación web en la que los usuarios
puedan seleccionar y reproducir diferentes emisoras de radio a través de un navegador
web. La aplicación está desarrollada utilizando Python, con el framework web Flask
para gestionar el servidor, y VLC a través de la librería python-vlc para reproducir los
streams de las emisoras de radio.
La aplicación permite seleccionar entre emisoras nacionales e internacionales, que
están organizadas y separadas visualmente. Los usuarios pueden iniciar la reproducción
de una emisora y detenerla mediante un botón. Este informe describe en detalle el
código y su funcionamiento.
Tecnologías Utilizadas
Python 3: Para la lógica principal de la aplicación.
Flask: Un micro-framework para crear aplicaciones web con Python.
VLC (python-vlc): Librería que permite manejar la reproducción de streams
multimedia desde Python usando VLC.
HTML + CSS: Para la interfaz de usuario que permite seleccionar y reproducir las
emisoras.
JavaScript (Fetch API): Para la comunicación entre el frontend (HTML) y el
backend (servidor Flask).
Estructura del Proyecto
El proyecto se compone de dos archivos principales:
app.py: El archivo Python que contiene la lógica del servidor Flask, maneja las
rutas, y controla la reproducción del contenido multimedia mediante VLC.
index.html: La plantilla HTML que se renderiza en el navegador para mostrar la
interfaz del usuario. Incluye botones para iniciar y detener la reproducción de
las emisoras de radio.
Código Fuente
1. Código app.py (servidor Flask)
Este es el archivo Python que ejecuta el servidor Flask y se comunica con VLC para
manejar la reproducción de las emisoras de radio.
from flask import Flask, render_template, jsonify, request
import vlc
app = Flask(__name__)
# Instancia de VLC para manejar la reproducción
vlc_instance = vlc.Instance()
player = vlc_instance.media_player_new()
# Lista de emisoras nacionales e internacionales
stations = {
'nacionales': [
{'Radio Moda': {'nombre': 'Radio Nacional 1', 'url':
'https://24973.live.streamtheworld.com/CRP_MOD_SC?
csegid=20001&dist=20001&ttag=20001'}},
{'Radio Nueva Q': {'nombre': 'Radio Nacional 2', 'url':
'https://18253.live.streamtheworld.com/CRP_NQ_SC?
csegid=20001&dist=20001&ttag=20001'}},
{'Radio Ritmo Romantica': {'nombre': 'Radio Nacional 3', 'url':
'https://13743.live.streamtheworld.com/CRP_RIT_SC?
csegid=20001&dist=20001&ttag=20001'}},
{'Radiomar': {'nombre': 'Radio Nacional 4', 'url':
'https://19473.live.streamtheworld.com/CRP_MAR_SC?
csegid=20001&dist=20001&ttag=2000'}},
{'Radio Magica': {'nombre': 'Radio Nacional 5', 'url':
'http://stream5.example.com/nacional5'}}
],
'internacionales': [
{'Istanbul FM': {'nombre': 'Radio Internacional 1', 'url':
'https://yayin.istanbulfm.com.tr/istanbulfm'}},
{'Los 40 Principales': {'nombre': 'Radio Internacional 2', 'url':
'https://14843.live.streamtheworld.com/LOS40_MEXICO_SC'}},
{'Radio 10': {'nombre': 'Radio Internacional 3', 'url':
'https://edge06.radiohdvivo.com/stream/radio10'}},
{'Classical FM Radio': {'nombre': 'Radio Internacional 4', 'url':
'https://cheetah.streemlion.com:2465/stream'}},
{'Rádio MFM Angola': {'nombre': 'Radio Internacional 5', 'url':
'https://centova87.instainternet.com/proxy/mfm?mp=/stream'}}
]
}
@app.route('/')
def index():
"""Renderiza la página principal con la lista de emisoras"""
return render_template('index.html', stations=stations)
@app.route('/play')
def play_station():
"""Inicia la reproducción del stream de radio usando VLC"""
# Obtener la URL de la emisora desde los parámetros de consulta
station_url = request.args.get('station_url')
if station_url:
# Mensaje de depuración para verificar si llega la URL
print(f"Reproduciendo: {station_url}")
# Crear un medio nuevo con la URL
media = vlc_instance.media_new(station_url)
player.set_media(media)
player.play()
return jsonify({'status': 'Reproduciendo', 'url': station_url})
else:
return jsonify({'status': 'Error', 'message': 'No se proporcionó la URL de la
estación'})
@app.route('/stop')
def stop_station():
"""Detiene la reproducción actual"""
player.stop()
return jsonify({'status': 'Detenido'})
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
Explicación del código app.py:
I. Instanciación de Flask y VLC:
o Se crea una instancia de Flask (app = Flask(__name__)) para manejar el
servidor web.
o Se utiliza vlc.Instance() para crear una instancia de VLC y controlar la
reproducción mediante el objeto player.
II. Lista de emisoras:
o stations: Diccionario que contiene emisoras nacionales e
internacionales. Cada emisora tiene un nombre y una URL
correspondiente para el streaming.
III. Ruta @app.route('/'):
o Esta ruta maneja la página principal (/) y utiliza
render_template('index.html', stations=stations) para renderizar la
plantilla HTML (index.html) y pasarle la lista de emisoras.
IV. Ruta @app.route('/play'):
o Esta ruta recibe la URL de la emisora seleccionada como un parámetro
de consulta (station_url) y utiliza VLC para reproducir el stream. Si la URL
se recibe correctamente, VLC inicia la reproducción.
V. Ruta @app.route('/stop'):
o Esta ruta detiene la reproducción del stream actual cuando el usuario
hace clic en el botón "Detener".
2. Código index.html (interfaz de usuario)
Este es el archivo HTML que se muestra en el navegador y contiene la interfaz
visual para seleccionar y reproducir las emisoras de radio.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Emisoras de Radio</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
background-color: #f4f4f4;
}
h1 {
color: #333;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
}
.section {
margin-bottom: 40px;
}
.card-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.station-card {
background-color: #fff;
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
margin: 10px;
width: 250px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
text-align: center;
}
.station-title {
font-size: 18px;
margin-bottom: 10px;
}
.station-button {
padding: 10px 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s;
}
.station-button:hover {
background-color: #0056b3;
}
/* Responsive styling */
@media (max-width: 600px) {
.station-card {
width: 90%;
}
}
audio {
margin-top: 20px;
width: 80%;
}
</style>
</head>
<body>
<h1>Reproductor de Emisoras de Radio</h1>
<div class="container">
<!-- Sección de Emisoras Nacionales -->
<div class="section">
<h2>Emisoras Nacionales</h2>
<div class="card-container">
{% for station in stations['nacionales'] %}
{% for key, value in station.items() %}
<div class="station-card">
<div class="station-title">{{ key }}</div>
<button class="station-button"
onclick="playStation('{{ value['url'] }}')">Escuchar</button>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
<!-- Sección de Emisoras Internacionales -->
<div class="section">
<h2>Emisoras Internacionales</h2>
<div class="card-container">
{% for station in stations['internacionales'] %}
{% for key, value in station.items() %}
<div class="station-card">
<div class="station-title">{{ key }}</div>
<button class="station-button"
onclick="playStation('{{ value['url'] }}')">Escuchar</button>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
<!-- Elemento de audio para reproducir el stream -->
<audio id="audioPlayer" controls>
<source id="audioSource" src="" type="audio/mpeg">
Tu navegador no soporta el elemento de audio.
</audio>
<script>
// Función para reproducir la emisora seleccionada
function playStation(url) {
var audioPlayer = document.getElementById('audioPlayer');
var audioSource = document.getElementById('audioSource');
// Cambiar la fuente de audio al URL de la emisora seleccionada
audioSource.src = url;
audioPlayer.load(); // Cargar la nueva fuente
audioPlayer.play(); // Iniciar la reproducción
}
</script>
</body>
</html>
Explicación del código index.html:
1. Estructura HTML:
o El archivo HTML organiza las emisoras en dos secciones: Emisoras
Nacionales e Internacionales.
o Cada emisora está dentro de un recuadro (tarjeta) que muestra el
nombre de la emisora y un botón para reproducirla.
2. CSS:
o Se utiliza CSS para dar estilo a las tarjetas y botones. Las tarjetas tienen
bordes redondeados, sombras y un efecto "hover" que las agranda al
pasar el mouse sobre ellas.
o El diseño es responsivo, ajustándose automáticamente a pantallas
pequeñas (por ejemplo, teléfonos móviles).
3. JavaScript (Fetch API):
o La función playStation(url) utiliza Fetch API para enviar una solicitud al
servidor Flask con la URL de la emisora cuando se hace clic en el botón
"Escuchar".
o La función stopStation() envía una solicitud para detener la
reproducción actual.
Conclusión
Este proyecto demuestra cómo integrar Flask y VLC para reproducir emisoras de radio
desde una aplicación web simple pero efectiva. La aplicación permite reproducir y
detener streams de radio de manera interactiva a través de botones en la interfaz de
usuario. Utiliza tecnologías modernas como Fetch API para la comunicación asíncrona
entre el cliente (frontend) y el servidor (backend).
Si la aplicación está correctamente configurada en un entorno de red (o incluso
desplegada en la nube), puede ser accedida desde cualquier dispositivo con un
navegador web.