"Después del juego es antes del juego"
Sepp Herberger

martes, 12 de marzo de 2019

TVHeadend: configuración y uso (I)


Aquí conté mi interés por ver y grabar determinados programas de TV desde el PC. Esta era una forma artesanal de hacerlo, pero investigando al respecto he hallado una joyita llamada TVHeadend. Aviso de que este post es un tocho con el resumen de lo que he ido montando en las últimas semanas.

1. ¿Qué es TVHeadend?

TVHeadend es una aplicación servidor gestionada por un interface web que puede recibir streams de vídeo de diferentes fuentes:

  • Streams de IPTV por Internet.
  • Señal de TDT recibida por una tarjeta de TDT PCI/USB.
  • Señal de TV analógica recibida por una tarjeta de TV PCI/USB.
  • Señal de TV por satélite recibida mediante una tarjeta SAT PCI/USB.
  • Señal de televisión por cable.
  • Otras emisiones de TV más exóticas

Una vez configurados los streams de vídeo (que se corresponderían con los canales de TV), TVHeadend nos permite:

  • Grabarlos en un dispositivo de almacenamiento, funcionando como un PVR.
  • Retransmitirlos a otros puntos de nuestra red o a Internet.
  • Transcodificarlos a otro formato de vídeo.

La versión de TVHeadend que he usado es la 4.3, que aunque es una versión beta funciona razonablemente bien.

2. Instalación.

Yo lo instalé en un PC que tengo encendido 24/7, pero la mayoría de la gente opta por hacerlo en una Raspberry Pi u otro minipc con un disco externo conectado si desea grabar contenidos. Es el tipo de PC ideal para estos casos, aunque hay incluso una solución todavía mas austera usando OpenWrt.

En mi caso, con Manjaro la instalación es tan sencilla como hacer:
# yaourt -S tvheadend-git
Para Debian/Ubuntu los pasos son igualmente sencillos.

Una vez instalada y arrancada como servicio con
# systemctl restart tvheadend.service
Queda escuchando en el puerto 9981 de la máquina donde está instalado. Accederemos a él desde el navegador web con http://ip:9981.


La primera vez que entramos salta un asistente que nos permite configurar el idioma del interface, la lengua preferida para los canales, nos hace crear un usuario administrador y un usuario raso y, si tenemos un sintonizador de TV instalado, detectar los canales. Como en mi caso no tenía sintonizador pues me salté esta última parte.

Una vez configurado el asistente en mi caso tuve un pequeño problema: no me permitía entrar con los usuarios creados anteriormente. Mirando en Internet comentaban verificar si el programa estaba lanzándose con el parámetro "-C", para ello tuve que mirar el fichero .service:

# cat /usr/lib/systemd/system/tvheadend.service 
[Unit]
Description=Tvheadend - a TV streaming server and DVR
After=syslog.target network.target auditd.service

[Service]
EnvironmentFile=/etc/conf.d/tvheadend
ExecStart=/usr/bin/tvheadend -f -p /var/run/tvheadend.pid $OPTIONS
PIDFile=/var/run/tvheadend.pid
Type=forking
Restart=on-failure
RestartSec=54s

# To enable watchdog functionality, uncomment these, remove Type=forking
# and compile with --enable-libsystemd_daemon
#Type=notify
#WatchdogSec=1m
#TimeoutStartSec=5m
#TimeoutStopSec=20

[Install]
WantedBy=multi-user.target
Examinando este fichero determino que la configuración se toma de /etc/conf.d/tvheadend. Allí se define la variable OPTIONS con todos los parámetros usados para levantar el proceso. Entre ellos no estaba "-C", así que lo añado:
# cat /etc/conf.d/tvheadend 
# Configuration file for the tvheadend service.

MALLOC_ARENA_MAX=4
OPTIONS="-u hts -g video -6 --http_port 9981 --htsp_port 9982 -C"
Y luego reinicio el servicio. Despues de esto ya si podía conectarme al interface web con los usuarios creados.

3. Configuración de un stream de vídeo IPTV de entrada.

Como no tengo tarjetas de TV de ningún tipo (vamos, que no me han llegado de Aliexpress) vamos a configurar como fuente una emisión de IPTV. Ya comenté que el mejor sitio para los canales de TV española es éste, ya que se actualiza a menudo (por algún extraño motivo que se me escapa, las cadenas de TV privadas cambian con cierta frecuencia la URL para acceder a sus streamings de vídeo) y está muy ordenadio.

Cogemos la URL de Canal Extremadura:
http://hlstv.canalextremadura.es/livetv/multistream.smil/playlist.m3u8.
Para ver si funciona, nada mas sencillo que hacer:
# vlc http://hlstv.canalextremadura.es/livetv/multistream.smil/playlist.m3u8
Entramos en el interface web, en Configuration->DVB Inputs->Networks y creamos una red de tipo IPTV:


A continuación vamos a Configuration->DVB Inputs->Muxes y añadimos un mux. Nos preguntará en que red y diremos que en la creada en el paso anterior. Luego nos sale el formulario:


Debemos rellenar el campo URL con:
pipe:///usr/bin/ffmpeg -i http://hlstv.canalextremadura.es/livetv/multistream.smil/playlist.m3u8
-vcodec copy -acodec copy -f mpegts pipe:1
En negrita pongo la URL original de acceso a Canal Extremadura online. Con eso construimos una URL de TVHeadend en la que se define el comando que leerá ese streaming.

En Mux name y Service name ponemos "canal-extremadura". Guardamos el mux y esperamos un rato:


Cuando en la columna "Scan result" aparece un OK quiere decir que ha conectado con el streaming. Ahora nos vamos a Configuration->DVB Inputs->Services y vemos que se ha creado un "Servicio" para el streaming:


Ya casi estamos. Nos vamos a Configuration/Channel-EPG/Channel y añadimos el canal:


Completando los campos Name con "canal-extremadura" y Services con el servicio creado anteriormente. Con esto aparece el canal en la lista:


Dando al icono de "Play" de la parte izquierda de la lista se descarga un fichero que al abrirlo lanza el vlc y comienza a visualizarse el canal:


Con esto ya tenemos dado de alta un canal como entrada para TVHeadend. Para dar de alta el resto de canales se procedería igual, incluyendo aquí los canales de TV de pago si disponemos de las URL adecuadas para configurarlos. En Internet hay información de sobra sobre como configurar Movistar+, Canal Satélite, etc con TVHeadend.

4. Clientes TVHeadend.

Una vez tenemos los canales configurados la primera utilidad es poder redirigirlos a otros dispositivos dentro de nuestra red o incluso hacia fuera (por ejemplo, podríamos ver Canal Extremadura en Bulgaria o Movistar+ en la casa del pueblo). Para poder verlos simplemente vale con poner en un navegador "https://ip:9981", validarse (es conveniente usar un usuario no administrador de TVHeadend para poder ver canales) y podremos visualizar los canales configurados.

Pero hay alternativas bastante más elegantes, comentamos algunas:

  • Android: para dispositivos Android hay varias aplicaciones, como TVHClient, TVH Client y muchas más. En general es tan sencillo como dar la IP, el puerto y el usuario/contraseña y la aplicación nos permitirá ver los canales en el móvil
  • Kodi: si tenemos Kodi 18 o superior existe un addon muy potente (más que las aplicaciones Android) llamado "TVHeadend HTSP Client". Se configura rápidamente y tenemos acceso sencillo a muchas funcionalidades. Al ser Kodi multiplataforma podemos instalarlo en casi todos los sistemas operativos.
  • Aparte existen clientes para otros sistemas que funcionan con mayor o menor fortuna.

Mi recomendación es instalar Kodi y el complemento en los PC, tablets y Android Box, y una aplicación Android en los móviles. El addon se integra totalmente en Kodi, como podemos ver:


Si queremos emitir los canales hacia Internet sencillamente bastará con abrir los puertos 9981 y 9982 desde el router y darnos de alta en un servicio de DNS, como se haría para cualquier servicio que queramos ofrecer desde nuestro PC hacia el exterior (por ejemplo, para cámaras de vigilancia, clientes de descarga, servidores web, etc).

5. Cosas que se pueden hacer con el stream de entrada.

Parece que lo único que se puede hacer con el stream de entrada es verlo, pero no es así. Las posibilidades que nos ofrece TVHeadend son muchas más. Podemos:

  • Recodificar: los streams suelen venir en formato H.264 o similar, que son bastante pesados. Puede resultar interesante transcodificar al vuelo a otro formato de de vídeo antes de retransmitirlo. No he estudiado esta vía, así que poco puedo decir al respecto, solo que en Configuration/Stream/Stream Profiles hay diversos perfiles de codificación.
  • Grabar: esta parte es muy interesante para mi. Podemos realizar grabaciones de varios tipos desde la opción Digital Video Recording. Las distintas pestañas son:

    Upcoming/Current Recordings: permite ver las grabaciones pendientes y programar una grabación puntual de un canal en una fecha y hora concreta.


    Timers: permite programar una grabación periódica a unas horas fijas en determinados días de la semana.


    Autorecs: permite programar grabaciones "inteligentes" por distintos criterios (título de programa, intervalo de fecha, etc).


    Finished Recordings
    : permite visualizar, eliminar, descargar, etc las grabaciones que han finalizado. Adicionalmente si usamos el cliente Kodi podemos ver, avanzar y retroceder libremente por las grabaciones que se están efectuando en ese mismo momento.

    Failed Recordings: vemos las grabaciones que han fallado por el motivo que sea.

    Removed Recordings: grabaciones que han sido borradas.

    Todas las grabaciones van por defecto al directorio /home/hts de la máquina donde está TVHeadend (siendo hts el usuario creado en la instalación del programa). Podemos modificar el directorio destino cuando añadimos la grabación.

    En "Configuration/Recordings/Digital Video Recorder Profiles" podemos configurar muchos parámetros sobre como se realizarán las grabaciones, tanto de tiempo como de espacio ocupado. A mi me resulta útil "Recorded file(s) retention period" que dice cuantos días se mantendrá por defecto una grabación en el disco duro antes de ser automáticamente eliminada.

  • Timeshift: esta funcionalidad es la que nos permite "parar la TV" cuando estamos viendo un stream y tenemos una interrupción pero queremos seguir luego por donde ibamos. Lo que realmente se hace al parar el stream es iniciar una grabación que luego podemos poner en marcha y por la que queremos desplazarnos. Se activa y configura en Configuration->Recording->Timeshift.


    Una vez activada, con solo pulsar el botón de "Pause" en el cliente durante la reproducción de un stream empieza a funcionar el timeshift.

6. EPG.

Para finalizar veremos como conectar TVHeadend con una EPG para tener accesible la programación de los canales desde el interface web y los clientes. Esto no es en absoluto necesario, simplemente es una pijadita para dejarlo todo bonito.


Desde aquí podemos ver la programación y pulsando sobre el icono izquierdo de cada programa, crear un timer con su grabación:


TVHeadend no tiene un sistema propio para obtener la programación de EPG, pero usa un API bastante sencillo que facilita todo el proceso.

Los datos de EPG están en numerosos portales de Internet, por ejemplo FormulaTV, y en distintos formatos. Para extraer estos datos se usan unos programas llamados EPG Grabber, que conectan con el portal, lo parsean y generan un XML con los datos de programación de los canales durante los próximos días.

Hay muchos EPG Grabber, después de echar un vistazo me he decantado por WebGrab+Plus por su completitud. Todos los EPG que puede acceder están ordenados por paises aquí. De ellos yo he elegido FormulaTV para España, ya que es un portal bastante serio que lleva muchos años funcionando.

En Manjaro se instala y configura fácilmente, como vemos aquí. Una vez instalado hay que configurarlo para que se ejecute mediante crontab y que lea los datos de una de las posibles fuentes. La instalación en Manjaro/Arch se realiza sobre /opt/wg++, teniendo dentro un directorio /opt/wg++/siteini.pack/Spain con todos los grabbers para España.
# cd /opt/wg++/siteini.pack/Spain
# find | grep -i formula
formulatv.com.channels.xml
formulatv.com.ini
Vemos aquí que hay dos ficheros: el .ini contiene las instrucciones y configuración para realizar el parseo, esa parte no nos interesa. El fichero .channels.xml tiene la lista de canales que son leidos por el grabber:
# cat formulatv.com.channels.xml
<?xml version="1.0" encoding="UTF-8"?>
<site generator-info-name="WebGrab+Plus/w MDB &amp; REX Postprocess -- version V1.56.14 -- Jan van Straaten" site="formulatv.com">
 <channels>
  <channel update="i" site="formulatv.com" site_id="la1" xmltv_id="La 1">La 1</channel>
  <channel update="i" site="formulatv.com" site_id="la2" xmltv_id="La 2">La 2</channel>
  <channel update="i" site="formulatv.com" site_id="antena3" xmltv_id="Antena 3 Televisión">Antena 3 Televisión</channel>
  <channel update="i" site="formulatv.com" site_id="cuatro" xmltv_id="Cuatro">Cuatro</channel>
  <channel update="i" site="formulatv.com" site_id="telecinco" xmltv_id="Telecinco">Telecinco</channel>
  <channel update="i" site="formulatv.com" site_id="lasexta" xmltv_id="laSexta">laSexta</channel>
  <channel update="i" site="formulatv.com" site_id="movistar0" xmltv_id="#0">#0</channel>
  ....
  <channel update="i" site="formulatv.com" site_id="canal-extremadura" xmltv_id="Canal Extremadura">Canal Extremadura</channel>
  ....
 </channels>
</site>
Ahora debemos configurar un usuario para ejecutar WebGrab+Plus, en mi caso será con el usuario "hts" (ya creado para TVHeadend). En su home debemos copiar la carpeta "/usr/share/wg++" y programar la ejecución periódica del grabber.
# su hts
$ cp -R /usr/share/wg++ /home/hts/wg++
$ crontab -e
Metemos en el crontab del usuario "hts" la ejecución del grabber todos los días a las 2:15:
15 2 * * * /usr/bin/wg++
Ahora vamos a configurar el Grabber en /home/hts/wg++/WebGrab++.config.xml (como el usuario que ejecuta wg++ es "hts" se buscará en esa ruta).
$ cat /home/hts/wg++/WebGrab++.config.xml
<?xml version="1.0"?>
<settings>

<!-- for detailed info about the settings see http://webgrabplus.com/documentation/configuration/webgrabconfigxml -->

<filename>guide.xml</filename>
<mode></mode>
<postprocess grab="y" run="n">mdb</postprocess>
<user-agent>Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0</user-agent>
<logging>on</logging>
<retry time-out="5">4</retry>
<timespan>2</timespan>
<update>f</update>

<channel update="i" site="formulatv.com" site_id="canal-extremadura" xmltv_id="canal-extremadura">Canal Extremadura</channel>
<channel update="i" site="formulatv.com" site_id="laSexta" xmltv_id="laSexta">laSexta</channel>
<channel update="i" site="formulatv.com" site_id="la1" xmltv_id="La 1">La 1</channel>

</settings>
Sobre la configuración anterior resalto en negrita las partes sensibles:
  • La salida de la ejecución de wg++ se guardará en /home/hts/wg++/guide.xml.
  • En "site" se pone el nombre de la fuente tal y como aparece en el site de formulatv.com.channels.xml.
  • Cada canal se define con un site_id exactamente igual a como aparece en formulatv.com.channels.xml.
  • En "timespan" ponemos el número de días en el futuro a descargar. Lo mejor es empezar probando con 2 y luego ir aumentando. Creo que FormulaTV proporciona hasta 7 días.
Con todo esto ya tenemos un programa que se ejecutará a diario y que parseará el EPG de la fuente y canales definidos en /home/hts/wg++/WebGrab++.config.xml y lo dejará en formato XML en /home/hts/wg++/guide.xml. No hace falta esperar a las 2:15 para saberlo, podemos ejecutar wg++ a mano desde el usuario hts para que se genere el guide.xml y verificar que todo funciona.

Ahora falta la última parte: conectar el guide.xml para que lo lea TVHeadend y lo integre en su interface. En la página de WebGrabPlus se documenta cómo hacerlo interactuar con diferentes softwares, entre ellos TVHeadend.

Básicamente, hay que bajar un script y ponerlo en la ruta "/usr/bin/tb_grab....". Esto hará que TVHeadend lo reconozca automáticamente como un "grabber interno" y lo ejecute de forma periódica y automática para realizar la sincronización. Los pasos para instalarlo son:
$ sudo wget -O /usr/bin/tv_grab_wg++ http://www.webgrabplus.com/sites/default/files/tv_grab_wg.txt
$ sudo chmod +x /usr/bin/tv_grab_wg++
Después hay que modificar el script para decirle donde está el guide.xml:
$ cat /usr/bin/tv_grab_wg++ 
#!/bin/bash
#xmltv_file_location=~/.wg++/guide.xml
xmltv_file_location=/home/hts/wg++/guide.xml
dflag=
vflag=
...
...
Al ejecutarse desde el servicio TVHeadend el script /usr/bin/tv_grab_wg++ procesará guide.xml y generará unos datos EPG que se insertarán en el formato interno de TVHeadend, del cual desconocemos los detalles. Una cosa muy importante ya comentada en el enlace indicado anteriormente es que el nombre del canal en wg++ debe coincidir con el nombre del canal en TVHeadend. En este caso "canal-extremadura" debe ser igual en ambos sitios, ya que si no es así no podrá establecerse una relación directa entre canal de TVHeadend y canal obtenido de la EPG, y por tanto TVHeadend no podrá mostrar la programación aún cuando esté ahí.

El siguiente paso es activar el grabber en TVHeadend. Para ello iremos a Configuration->Channel/EPG y a las pestaña EPG Grabber Modules(1) activando en la lista que se muestra allí el grabber tv_grab_wg++ y ejecutando luego "Rerun Internal EPG Grabbers" para que se aplique de forma inmediata.


En las pestañas EPG Grabber Channels y Channels revisaremos que está la conexión entre los canales EPG y los canales de TVHeadend.



En la pestaña EPG Grabber podemos configurar ciertos aspectos de ejecución del grabber, como las horas de ejecución y la actualización de diversos datos.


(1) Aquí me he encontrado con un problema que me hizo perder un par de días: en el interface web no se veían las pestañas EPG Grabber Modules y EPG Grabber Channels en Configuration->Channel/EPG. Por tanto no podía activar el grabber interno. Tras mucho probar encontré en este enlace la causa: es un bug del interface web de TVHeadend, que oculta esas pestañas por defecto si no estás en modo de interface "Expert". La solución consiste en cambiar el modo de visualización general de Basic a Expert en General->Base->Default View Level. De esta manera ya aparecen ambas pestañas y podemos configurar el grabber.


Bueno, una vez hecho esto ya tenemos la EPG con los títulos y horas de los programas disponible en todos los interfaces y clientes de TVHeadend y doy por concluido el artículo. De momento no me interesa tocar más hasta que no reciba el adaptador USB de DVB.

7. Enlaces y ampliación.

Unos cuantos enlaces que me han servido de guía y en los que hay más información para seguir profundizando:


Dos fotos llenas de significado:



Son dos imágenes tomadas por el orbitador LRO de la Nasa de la sonda Chang'e 4 de China en la cara oculta de la Luna. Los americanos demostrando que los chinos han llegado a la Luna. En el año del 50 aniversario de alunizaje del Apolo XI estos gestos son muy importantes.

Siempre algún conspiranoico podrá decir que todo esto es CGI, pero junto con la Queqiao se lanzó un microsatelite Longjiang-2 que está realizando fotos y pueden ser descargadas desde la Tierra por cualquier radioaficionado con el equipo adecuado que apunte a Lagrange-2 en las frecuencias 435.400 y 436.400 MHz. Ahora vas y lo cascas.

4 comentarios:

  1. ¡Maravilloso! Muchas gracias por la información, voy a probarlo en mi Raspberry. Un saludo.

    ResponderEliminar
  2. Quisiera saber si TvH 4.3-1854 soporta UDP, Pues necesito meter el stream de video de 130 canales a un Modulador IP QAM

    ResponderEliminar
  3. Hola, tengo una duda. Si tengo una lista de IPTV y la meto en tvheadend, de un unico canal por ejemplo. Si tengo dos reproductores fuera de casa, la conexion la hacen hacia mi ip de casa no? El origen no sabe que estoy reproduciendo en varios sitios no? o no es asi. Gracias!

    ResponderEliminar
  4. hola al crear Muxes no me aparece en lista

    ResponderEliminar