Integración de PeerCast en MythTV
Abstract
[ANGLÈS] Creating a software to integrate the streaming P2P technology in a PVR.
Full text
Integración de PeerCast en MythTV Josu Lazkano Lete Director: Jose Luis Muñoz Tapia - Mayo 2012 -
- 2 -
Índice 1. Introducción.............................................................................................................................5 1.1. El streaming vino para quedarse......................................................................................5 1.2. Motivación del proyecto...................................................................................................9 1.3. Objetivos........................................................................................................................10 1.4. Estructura de la memoria...............................................................................................12 2. Estudio de la tecnología.........................................................................................................13 2.1. El streaming...................................................................................................................13 2.2. P2P.................................................................................................................................15 2.3. Vídeo bajo demanda.......................................................................................................18 2.4. Grabador de vídeo digital ..............................................................................................20 3. La base del Proyecto..............................................................................................................23 3.1. PeerCast.........................................................................................................................23 3.2. Yellow Pages...................................................................................................................28 3.3. MythTV...........................................................................................................................30 3.4. MythStream....................................................................................................................34 4. Desarrollo del proyecto..........................................................................................................36 4.1. MythCast........................................................................................................................37 4.1.1. Funcionamiento......................................................................................................38 4.1.2. Integración con Mythfrontend.................................................................................41 4.1.2.1. settings.pro.....................................................................................................41 4.1.2.2. mythcast.pro...................................................................................................42 4.1.3. Parsers....................................................................................................................44 4.1.4. Desarrollo del plugin...............................................................................................47 4.1.4.1. Modificaciones respecto a MythStream...........................................................50 4.1.4.2. harvester.cpp...................................................................................................52 4.1.4.3. streambrowser.cpp..........................................................................................55 4.1.4.4. streamstatus.cpp.............................................................................................56 4.1.4.5. playerencap.cpp..............................................................................................59 4.1.4.6. fft.cpp..............................................................................................................60 4.1.4.7. storagehandler.cpp..........................................................................................61 4.1.4.8. accessfiles.cpp................................................................................................63 4.1.5. Compilación............................................................................................................66 4.1.6. Manejo del plugin....................................................................................................69 4.2. Yellow Pages...................................................................................................................75 4.2.1. Configuración del Yellow Pages...............................................................................76 - 3 -
4.2.2. Cómo utilizar el Yellow Pages..................................................................................78 4.3. Repositorio de software..................................................................................................80 4.3.1. Software utilizado para crear el repositorio.............................................................81 4.3.2. Software disponible en el repositorio......................................................................83 4.3.3. Uso del repositorio..................................................................................................83 4.4. Hardware utilizado.........................................................................................................86 4.4.1. Plugin MythCast......................................................................................................86 4.4.2. Yellow Pages............................................................................................................87 4.4.3. Repositorio de software...........................................................................................87 5. Conclusiones y líneas futuras.................................................................................................88 6. Anexos...................................................................................................................................90 6.1. Código MythCast............................................................................................................90 6.2. Código de YellowPages...................................................................................................90 6.2.1. Interfaz web............................................................................................................90 6.2.2. Core........................................................................................................................94 6.2.3. Configuración de Apache........................................................................................99 6.3. Código Parsers................................................................................................................99 6.4. Versiones del software en el repositorio.......................................................................100 6.5. Configuración de PeerCast...........................................................................................102 6.5.1. Yellow Pages..........................................................................................................102 6.5.2. MythCast...............................................................................................................104 6.6. Controles de Mplayer....................................................................................................106 7. Bibliografía...........................................................................................................................107 7.1. Documentos de UPC.....................................................................................................107 7.2. Documentación oficial..................................................................................................107 7.3. Internet........................................................................................................................107 - 4 -
1. Introducción 1. Introducción 1.1. El streaming vino para quedarse Hoy en día nadie duda de los cambios de hábito encabezados por Internet en los últimos años. No somos capaces de entender nuestra vida social o profesional sin una conexión a la Red. Una experiencia de conexión que ha ido evolucionando de forma espectacular gracias a la fuente inagotable de aplicaciones y servicios que han sido desarrollados. Uno de los muchos usos que se hace de internet es el consumo de contenido multimedia, como pueden ser vídeos, música, radios, videoconferencias, etc. En esta introducción se va a analizar los cambio y mejoras que ha sufrido el streming en internet. El streming nace de una necesidad de comunicación entre personas, la importancia de disponer de la información en el menor tiempo posible. Es la evolución natural del telégrafo o de las radios y televisiones analógicas llevadas al mundo de internet. Vamos a revisar la evolución del streaming en los últimos 20 años para entender las mejoras que se han ido realizando: –1992: se lanza MBone (multicasting backbone) y RealTime Player versión 1 –1994: concierto en directo de Rolling Stone mediante Mbone –1995: Xing Technology Corp. desarrolla StreamWorks, la primera emisión en directo mediante web. Nace el streaming. –1996: Progressive Networks (RealNetworks) anuncia su arquitectura RealMedia. –1997: RealNetworks anuncia Real Video, la primera solución multiplataforma para vídeo brodcast para la web. Más de 10 millones de usuarios se actualizan desde RealAudio a RealVideo. –1998: RealNetworks anuncia RealSystem. G2 Xing Technologies presenta el primer servidor de vídeo multicast de alta calidad. Virage Inc. presenta el primer buscador de vídeo streaming. –1999: RealNetworks lanza RealJukebx, un sistema completo para obtener, reproducir - 5 -
1.1. El streaming vino para quedarse y gestionar colecciones de música. RealNetworks introduce RealServer 7.0, mejorando la calidad de vídeo MPEG-1 en la mitad de datos, ofreciendo calidad VHS a 800Kbps. –2000: 100 millones de usuarios utilizan RealPlayer. WindowsMedia 7.0 y RealSystem 8.0 son lanzados. –2003: se lanza la versión beta de Microsoft Windows Media 9 con HD. –2005: YouTube se lanza en febrero. Apple lanza un vídeo podcast para iTunes. –2006: Microsoft Windows Media lanza vídeo streaming en HD. –2007: se crea la web de televisión y vídeos Hulu. –2008: NetFlix empieza a hacer streaming de vídeo. Apple lanza un smartphone 3G con capacidad para reproducir streaming. –2009: se lanza Amazon Video On Demand. –2010: Apple Inc. vende mas de 1 millón de Apple Tvs. –2012: se lanza el servicio BitTorrent Live en versión beta, un servicio de streaming P2P. La utilización de las nuevas técnicas y las mejoras en las transmisiones por fibra óptica y la expansión del acceso a Internet mediante xDSL han permitido, entre otras muchas cosas, aumentar considerablemente la capacidad de los enlaces y la normalización de la conexión global a la red. De esta manera, hemos pasado de una red estática basada en los textos y las imágenes, a una nueva red dinámica basada en la interacción y los contenidos multimedia como música o vídeos. Las costumbres de uso también han evolucionado, de hecho, actualmente el uso de Internet se ha desplazado al entretenimiento, cuando años atrás el principal uso que se le daba era profesional y orientado a la investigación. Aparte de la importancia que toman fenómenos sociales como Facebook o Twitter, en estos últimos tiempos hemos podido observar como el tráfico generado en la red para las aplicaciones Peer-to-Peer ha ido tomando cada vez más importancia y ha llegado a cuotas que superan en algunos casos el 80% del total. No ha sido hasta los estudios más recientes donde se ha empezado a detectar el primer descenso en muchos años de este tipo de tráfico. Las razones principales son dos: –La aparición de páginas web que ofrecen contenido multimedia en modo de descarga directa. Se trata de servicios web que permiten a cualquier usuario alojar cualquier tipo de archivo en servidores y distribuirlos posteriormente. Como ejemplo tendríamos los servicios de RapidShare o MegaUpload. - 6 -
1.1. El streaming vino para quedarse –La explosión del streaming, tanto los de audio como los de vídeo han sufrido un incremento muy importante en los últimos años gracias a servicios como YouTube, Spotify o Netflix. En la siguiente gráfica se muestra la evolución de tipo de tráfico en los últimos años en Europa: Como se puede apreciar en la gráfica, la evolución es clara hacia el tráfico P2P y el de entretenimiento, superando el 60% del tráfico total. - 7 - Imagen 1: Gráfica de la evolución de tráfico en Europa según la consultora Sandvine
1.1. El streaming vino para quedarse En esta otra tabla se muestra las aplicaciones más utilizadas en Europa: En esta tabla también es visible el dominio de aplicaciones de P2P como el BitTorrent y las aplicaciones o servicios de multimedia como YouTube. Hace años era impensable ver la televisión o escuchar la radio desde Internet. Hoy en día, en cambio, es muy habitual acudir a Internet para ver los últimos acontecimientos en vídeos o escuchar emisoras de radio de cualquier parte del planeta desde nuestro navegador. Aunque a las grandes discográficas o industrias audiovisuales les cueste reconocer, Internet está facilitando el consumo de contenidos audiovisuales. Hemos pasado de comprar CDs o DVDs en tiendas físicas a descargar directamente desde nuestro PC o teléfonos móviles. Los libros electrónicos están desbancando a los libros en soporte de papel. Ya compramos menos el periódico y consultamos los medios digitales. - 8 - Imagen 2: Top 10 de las aplicaciones en las conexiones fijas para Europa según Sandvine
1.2. Motivación del proyecto 1.2. Motivación del proyecto Como hemos visto anteriormente, los hábitos de visionado de contenidos multimedia han cambiado rápidamente en los últimos años gracias a la evolución de las conexiones de alta velocidad. La motivación principal de este proyecto es analizar las diferentes opciones que existen para tener acceso a recursos multimedia desde Internet en plataformas PVR (Personal Video Recorder) utilizando protocolos P2P. En el departamento de Telemática disponen de varios proyectos de fin de carrera y tesis sobre el protocolo de streaming P2P PeerCast, incluso disponen de una versión mejorada llamada NeuroCast. Pero necesitaban aplicar estos protocolos en un software actual, que la gente pueda utilizarlo en sus casas sin tener conocimientos en redes. Este proyecto comienza con una charla con el profesor Jose Luis Muñoz del departamento Telemática de la UPC. Gracias al interés común que teníamos los dos en los sistema multimedia sobre GNU/Linux, me propuso hacer una integración del protocolo PeerCast en un PVR. Yo había probado varios PVR hasta la fecha, en concreto XBMC y MythTV. La elección de MythTV fue gracias a su estructura modular, se basa en plugins para añadir diferentes funcionalidades, y es justo lo que necesitábamos. Personalmente, ha sido un reto sumamente intenso a la vez que gratificante. El hecho de participar en un proyecto cuya base me apasiona, ha servido de presión a la hora de indagar y querer llegar a una solución que veo necesaria a nivel de usuario personal. Lo que se pretende en este proyecto de fin de carrera es poder manejar el software PeerCast desde un centro multimedia sin ninguna iteración con el navegador, simplemente desde un mando a distancia. A lo largo de esta memoria intentaré explicar este proceso de la forma más simple y cercana para que sea entendido por todo tipo de lector interesado en la temática. - 9 -
2.2. P2P Uno de los cambios más importantes que ha experimentado la tecnología P2P ha sido el paso de la estructura en árbol a la estructura de malla. La principal diferencia está en la capacidad que tienen los usuarios con la estructura mallada de recibir el stream de diferentes usuarios a la vez, mientras que la estructura en árbol sólo nos permitía recibirlo de un único usuario. Así, el paso a la estructura mallada nos ha permitido superar la limitación que presenta Internet desde sus inicios, y es esta asimetría que encontramos en las redes de acceso en cuanto a los enlaces de subida y de bajada, ya que desde principio se había pensado que el usuario final recibiría muchos más datos de los que enviaría. La eficacia de los nodos en el enlace y transmisión de datos puede variar según su configuración local (cortafuegos, NAT, routers, etc.), velocidad de proceso, disponibilidad de ancho de banda de su conexión a la red y capacidad de almacenamiento en disco. Con la arquitectura P2P conseguimos superar el problema de la escalabilidad, el servidor sólo envía el stream a un número limitado de usuarios. Estos usuarios serán los que enviarán el stream a otros usuarios, hasta que todo el mundo lo haya recibido. La gran ventaja en este caso es que la cantidad de datos que el servidor debe enviar (y por tanto la capacidad del servidor y del enlace) no varía en función del número de usuarios a los que servimos el stream. - 16 - Imagen 4: Las tres topologías de red según los famosos grafos de Paul Baran que aplican también al diseño P2P.
2.2. P2P Las redes P2P son útiles para diversos propósitos: •Normalmente se utilizan para compartir ficheros de cualquier tipo (por ejemplo, audio, vídeo o software). Programas como Napster, eDonkey, Gnutella, eMule, Kazaa o BitTorrent han ido apareciendo y evolucionando durante los últimos 10 años. Su utilización en los programas de intercambio de archivos está ampliamente extendida, representa hoy en día la mayor parte del tráfico total de la red. •Este tipo de red también suele usarse en telefonía VoIP para hacer más eficiente la transmisión de datos en tiempo real. Skype lo lleva utilizando años en sus redes para minimizar la latencia de las comunicaciones. •En el mundo del P2P, la implementación del streaming multimedia se encuentra en sus inicios, son pocos los servicios que existen para hacer streaming en tiempo real sobre P2P. Pero se prevé que esta tecnología despunte en los próximos años. El P2P es una tecnología que crece imparable, ya sea por el beneficio que trae sobre los costes de las infraestructuras, como el anonimato y la velocidad en las descargas de ficheros. - 17 -
2.3. Vídeo bajo demanda 2.3. Vídeo bajo demanda La televisión a la carta o vídeo bajo demanda, es un sistema de televisión que permite al usuario el acceso a contenidos multimedia de forma personalizada ofreciéndole, de este modo, la posibilidad de solicitar y visualizar una película o programa concreto en el momento exacto que el telespectador lo desee. Existe, por tanto, la posibilidad de visualización en tiempo real o bien descargándolo en un dispositivo como puede ser un ordenador, una grabadora de vídeo digital o un reproductor portátil para verlo en cualquier momento. Permite al usuario disponer del programa deseado sin depender de horarios fijos de programación. El espectador dispone de una amplia oferta de programas para visualizar o realizar un pago por ciertos programas como en el caso del PPV (pago por visión). Normalmente la distribución del contenido se hace a través de LAN, donde podemos realizar una distribución mucho más rápida a los usuarios. En cambio, si lo hacemos a través de WAN, la respuesta es más lenta pero el alcance será mucho más amplio. Los servicios de descarga son posibles en lugares con conexión de banda ancha como pueden ser el cable o el xDSL. Para poder ofrecer el vídeo bajo demanda con garantías, se utilizan protocolos en tiempo real, como por ejemplo RTP (Real Time Protocol) sobre UDP con el protocolo de control RTCP (Real Time Control Protocol). Un buen complemento a estos, sería un protocolo de reserva de recursos como el RSVP (ReSerVation Protocol). En los últimos años, grandes compañías de telecomunicaciones están ofreciendo diferentes servicios de vídeo bajo demanda para integrarlos a los canales tradicionales de televisión, aquí se listan algunos de ellos: –Digital+ a la carta: es uno de los primeros en ofrecer este tipo de servicio en España. Es un servicio que nos permitirá disfrutar de toda la programación que no hemos podido ver en la plataforma de Digital+ en el momento en que se emitía. Se puede utilizar con cualquier tipo de conexión de Internet de banda ancha. –Jazztelia TV: es un servicio del operador de telecomunicaciones de Jazztel, utiliza el sistema multicast dentro de su red de xDSL. Los contenidos son de Digital+. - 18 -
2.3. Vídeo bajo demanda –Imagenio: es la plataforma de Movistar para la distribución multimedia, utiliza su red privada para emitir en modo multicast. Los contenidos son muy variados. –ONO: utiliza el servicio TiVo y solo es accesible desde su red privada de fibra. Desde hace poco tiempo han ido apareciendo diferentes servicios de este tipo asociados a canales de televisión, todos disponen de contenidos propios y no están sujetos a ningún operador de banda ancha: –RTVE a la carta –TV3 a ala carta –EITB a la carta –la Sexta on La principal diferencia de estos servicios sobre los primeros, es que estos no disponen de una integración en la televisión, ya que necesitan que los propios televisores dispongan de conexión a internet. Para poder acceder a los contenidos necesitamos un navegador web en un PC. A parte de estos servicios, podemos encontrar servicios en internet que nos ofrecen contenido multimedia, tanto gratuitos como de pago: –NetFlix: es una empresa estadounidense que se espera que próximamente entre en España. No esta ligado a ningún operador de telecomunicaciones y dispone una amplia carta de series y películas. Necesita una suscripción de pago para poder disfrutar de los contenidos multimedia. –YouTube: es el servicio por excelencia de descarga de vídeos, es propiedad de Google. Dispone de millones de vídeos online. Su modelo de negocio se basa en la publicidad. Para el usuario, los contenidos son gratuitos, a cambio tendremos que visionar publicidad en algunos de los vídeos. - 19 -
2.4. Grabador de vídeo digital 2.4. Grabador de vídeo digital Un grabador de vídeo digital (PVR por las siglas en inglés de Personal Video Recorder) es un dispositivo interactivo de grabación de televisión y vídeo en formato digital. Se podría considerar como un set-top box más sofisticado y con capacidad de grabación. Un PVR se compone, por una parte, del hardware, que consiste principalmente en un disco duro de gran capacidad, un microprocesador y los buses de comunicación; y por otra, del software, que proporciona diversas funcionalidades para el tratamiento de las secuencias de vídeo recibidas, acceso a guías de programación y búsqueda avanzada de contenidos. El PVR nace gracias al nuevo formato digital de la televisión, este hecho permite almacenar la información y manipularla posteriormente con un ordenador. De modo que se podría calificar al PVR como un ordenador especializado en el tratamiento de imágenes digitales. Así el PVR se ha diferenciado de su predecesor analógico, la videograbadora, en la cual tan solo se podían almacenar imágenes de forma pasiva, con la posibilidad de rebobinarlas hacia delante o hacia atrás, como pausarlas. A diferencia de un ordenador convencional, los PVR se integran con el televisor y disponen de un mando a distancia para controlar todo el contenido. Justamente, la integración con la televisión es lo que hace estos productos realmente interesantes. Algunos de los PVR más utilizados actualmente: –MythTV: es un conjunto de aplicaciones que convierte a un PC con el hardware adecuado en una grabadora de vídeo digital con el cual se permite grabar programas de televisión en un disco duro para su visualización. Actualmente esta aplicación llega más lejos, convirtiendo el PC en un verdadero MediaCenter con el que se puede jugar, navegar, reproducir vídeos, escuchar música y mucho más, todo ello utilizando un sencillo mando a distancia, sin necesidad de teclado ni ratón. –XBMC: es un software multiplataforma y de código abierto. Este programa convierte un ordenador en un potente centro multimedia, soportando una gran variedad de formatos de audio y vídeo. Incluye características tales como listas de reproducción, presentación de diapositivas, subtítulos, programas de TV OnLine, juegos, información del clima y muchas más funciones ampliables mediante una gran - 20 -
2.4. Grabador de vídeo digital cantidad de plug-ins. Además, su interfaz es muy completa e intuitiva pudiendo ser manejada tanto desde el teclado o ratón como desde un mando a distancia. –TiVo: es una tecnología que permite grabar el contenido de la televisión, pero a diferencia de los clásicos vídeos, lo hace en un disco duro que permite almacenar entre 80 y 300 horas de programación recibida a través del cable, transmisión satélite o TDT. TiVo se contrata vía suscripción y permite elegir series, actores o eventos desde el menú, sin preocupación por cambios o retrasos en la programación. Pero más que un dispositivo, la compañía TiVo creó toda una categoría de productos cuando en 1997 presentó su primer grabador de vídeo digital para el hogar. La creación de la firma estadounidense inauguró la capacidad de poner pausa a la televisión en directo. Gracias a TiVo, el espectador puede disfrutar de su programa favorito, detener la imagen y retomar la transmisión en el punto exacto en el cual quedó ya que, mientras tanto, el DVR almacena automáticamente el programa o película en su disco duro. –Freevo: es una aplicación de código abierto, cuenta con las características necesarias para convertir nuestro PC en un verdadero centro multimedia para reproducir música, vídeos en alta definición y la TV en vivo. Cuenta con una interfaz gráfica que lo hace sumamente fácil de usar para todos los niveles de usuarios. Este programa es un excelente administrador de todo el contenido multimedia que tenemos en nuestro disco duro, ya que Freevo facilita catalogar cada archivo incluso añadiéndoles etiquetas para identificarlos mejor y más rápido. Freevo también aprovecha al máximo todo el potencial del hardware que tenemos instalado. Está escrito en Python, es muy fácil de instalar y soporta la mayor parte del hardware existente. –VDR: es una aplicación de código abierto para GNU/Linux diseñado para permitir a cualquier ordenador funcionar como un grabador de vídeo digital, con el fin de grabar y reproducir programas de televisión mediante el disco duro del PC. El ordenador debe estar equipado con una tarjeta de sintonizador de TV digital. VDR también puede funcionar como un reproductor de mp3 y reproductor de DVD mediante plugins disponibles. VDR utiliza controladores del proyecto LinuxTV. –Moovida: es el nuevo nombre del antiguo Elisa Media Center. Es una aplicación para las necesidades multimedia, organizar y reproducir todos tus archivos multimedia - 21 -
2.4. Grabador de vídeo digital desde una aplicación intuitiva. Es un proyecto para crear un centro multimedia multiplataforma de código abierto. La principal plataforma de desarrollo y distribución es Linux y sistemas operativos tipo Unix, aunque actualmente también soporta Microsoft Windows y Mac OS X. Elisa se ejecuta sobre el framework multimedia Gstreamer y aprovecha al máximo las ventajas de la aceleración de hardware que proveen las tarjetas gráficas modernas usando APIs de OpenGL. Además de contar con un grabador personal de vídeo (PVR) y soporte de reproductores musicales, Elisa también interopera con dispositivos siguiendo el estándar DLNA como los sistemas de Intel Viiv. –Boxee: es una aplicación de software multi-plataforma gratuita para HTPC con funciones de redes sociales diseñado para la TV del salón. Boxee era originalmente un “fork” de XBMC que ahora es omercializado como el primer "Social Media Center", Boxee permite a sus usuarios ver, calificar y recomendar contenido a sus amigos a través de muchos servicios de redes sociales. –Windows Media Center: es una aplicación diseñado para servir como equipo personal de cine en casa. Está incluido en Windows XP Media Center Edition como parte de dicha versión del sistema operativo. También es parte de Windows Vista y Windows 7. Está diseñado para equipos que dispongan de un mando a distancia, aunque también puede funcionar con ratón y teclado. Media Center reproduce o visualiza en el equipo del usuario fotografías, vídeos y música provenientes de discos duros locales, unidades ópticas y ubicaciones de red. También clasificará el contenido multimedia por nombre, fecha, etiquetas y otros atributos de archivo. El contenido multimedia gestionado a través de Media Center puede ser reenviado a través de redes locales a televisores o a la consola Xbox 360. –Dreambox: es un set-top box basado en Linux para poder ver canales tanto de satélite, terrestre o cable. Es un producto de la empresa Dream Multimedia. La mayoría de estos PVR son solo software, después se complementan con el hardware que cada uno necesite, tanto el disco, los sintonizadores y el mando a distancia son personalizables. - 22 -
3. La base del Proyecto 3. La base del Proyecto Una vez analizados los diferentes conceptos que se utilizan en el proyecto, ahora se explicará las diferentes partes de las que se compone el proyecto. Por un lado, tenemos el software PeerCast, que es quien se encarga de obtener los streams mediante P2P. Yellow Pages, que es el directorio donde podremos buscar diferentes streams para poder reproducirlos. Y por último MythTV, que es con lo que reproduciremos los stream. 3.1. PeerCast PeerCast es una herramienta de streaming P2P de código abierto para distribuir streams multimedia. Utiliza la tecnología P2P para minimizar el ancho de banda de subida del broadcaster original. Creado en abril del año 2002 por “giles” (apodo del autor), desde el año 2007 el proyecto está abandonado y no existe ninguna versión mas reciente, aunque todavía es utilizado en pequeñas comunidades de usuarios y es el protocolo de streaming P2P de referencia. Utiliza una técnica de ancho de banda distribuido para agilizar la carga de ancho de banda de subida de los broadcaster, donde cada cliente retransmite los streams que ha bajado a otros clientes. Los usuarios pueden escoger el número de retransmisiones, si un cliente fija sus retransmisiones a 0, no contribuirá en la emisión del stream. El principal beneficio de utilizar PeerCast es que permite a cualquier broadcaster, sobre todo - 23 - Imagen 5: Diagrama de flujo del plugin MythCast
3.1. PeerCast pequeños y particulares, distribuir sus streams sin tener que utilizar o contratar anchos de banda elevados, ahorrando así en costes. Teóricamente permite tener infinitos clientes, ya que existen suficientes retransmisiones. Al utilizarse en entornos domésticos, el ancho de banda de subida no suele ser fiable, es por eso que la transmisión a veces puede ser inestable. Cuando se pierde una retransmisión, todos los peers que “están por debajo de éste” perderán la conexión al stream y tendrán que conectarse a otra retransmisión (peer), además, al volver a conectarse a otro peer, el oyente (cliente) tendrá que aceptar el punto o instante donde está la retransmisión, casi siempre causando un corte o una repetición en el stream. Esto es debido a que no dispone del entrelazado de tramas por ser un protocolo en tiempo real. Al ser un sistema descentralizado, los clientes se convierten en servidores, esto hace que sea imposible controlar el contenido que se transmite sobre esta red. Por eso, en algunos casos puede que se infrinja la ley en la distribución de contenidos con derechos de autor, dependiendo de la legislación del territorio vigente de cada usuario. Siguiendo la evolución experimentada por los programas de intercambio de ficheros P2P, con el PeerCast hemos pasado de utilizar una arquitectura de red estructurada en árbol a una arquitectura mallada. Esta evolución ha permitido a PeerCast utilizar de manera conjunta los anchos de banda de N usuarios que por sí solos no podrían difundir el stream, pero que en conjunto sí son capaces. El software ya no está disponible en la página oficial http://peercast.org, pero gracias a los repositorios públicos de Debian disponemos de la última versión (0.1218), tanto el código fuente como paquetes para diferentes ramas de Debian. Lo podemos encontrar en esta dirección: http://packages.debian.org/peercast Para instalar PeerCast en un PC, es suficiente con descargar el paquete desde cualquier repositorio Debian e instalarlo: $ wget http://ftp.us.debian.org/debian/pool/main/p/peercast/peercast_0.1218+svn20080104-1.1_i386.deb # dpkg -i peercast_0.1218+svn20080104-1.1_i386.deb La configuración del servicio se puede hacer mediante el fichero de configuración ubicado en /etc/peecast/peercat.ini o desde la sección “Settings” de la interfaz web. Este archivo se carga - 24 -
3.1. PeerCast cada vez que se inicia PeerCast, y se actualiza si ha cambiado algún parámetro al finalizar la sesión. Una vez instalado, arrancamos el servicio con el script init: # /etc/init.d/peercast start El usuario interactúa con el PeerCast a través de una interfaz web desde el puerto 7144. Una vez iniciado el programa, el servidor genera páginas web a través de las cuales podemos obtener, por ejemplo, información de los canales (streams) que hemos creado, las retransmisiones que realizamos o los peers desde donde descargamos el stream. - 25 - Imagen 6: Captura de la interfaz web de PeerCast
3.3. MythTV Después, disponer simples frontends con capacidades de reproducción por hardware. Este es un esquema típico para un sistema de un servidor backend y varios clientes frontends: Los frontends se manejan con mandos infrarrojos y se visualiza el contenido multimedia mediante televisores, pantallas o proyectores. La comunicación entre el backend y los frontend se hace mediante una red IP, normalmente una LAN. El backend dispone de discos para almacenar el contenido multimedia y una base de datos donde se almacena la información. Además dispone de varias tarjetas capturadoras, como pueden ser de TDT, satélite, cable o - 32 - Imagen 10: Esquema da una configuración típica de MythTV
3.3. MythTV IPTV. Otra de las grandes ventajas de MythTV es la incorporación de plugins dentro del frontend. Existen diferentes plugin, como MythMusic para escuchar música o MythVideo para ver películas en DVD u otros formatos. Estos son los plugins que son soportados de manera oficial por la comunidad de desarrolladores: •MythArchive •MythControls •MythGallery •MythGame •MythMusic •MythNettv •MythNetvision •MythNews •MythNotify •MythRoast •MythVideo •MythWeather •MythWeb •MythZoneMinder - 33 -
3.4. MythStream 3.4. MythStream MythStream es un plugin no oficial para MythTV, sirve para poder reproducir contenidos de audio y vídeo de internet mediante streaming en modo cliente-servidor. El plugin fue creado por Eric Giesselbach en el año 2003 y podemos descargar la última versión desde la página del autor: http://home.kabelfoon.nl/~moongies/streamtuned.html MythStream puede leer, reproducir e interactuar con fuentes de streams para conectarte con noticias, música, vídeo clips, webcams o documentales accesibles en todo el mundo mediante streaming. El mundo de los streams es muy dinámico, y se necesita algo de control y organización para mantenerlo al día. MythStream está diseñado para tener todos los stream ordenados. Interactúa con índices de streams, RSS, páginas de descarga de vídeos y otros sitios que ofrecen enlaces actualizados de contenidos multimedia. Para una mayor flexibilidad, la interacción con las fuentes de enlaces de streams se delega a parsers externos que pueden ser creados y modificados fácilmente. La instalación por defecto de MythStream contiene parsers que proporcionan las siguientes funcionalidades: •Reproducción directa de streams (añade la URL y comienza la reproducción). •Enlaces RSS (por ejemplo podcasts). •Navegación en contenidos interactivos (por ejemplo Shoutcast, BBC, wwiTV, Uitzendinggemist.nl). •Búsquedas personalizadas utilizando el teclado virtual de MythTV. •Reproducción o descarga de vídeos (por ejemplo YouTube y Dailymotion). •Playlists (puedes crear tu canal personal de música). •Analiza y busca stream en enlaces URL en páginas HTML. - 34 -
3.4. MythStream MythStream se puede compilar para la versión de MythTV v0.20 y anteriores. Actualmente, el proyecto está abandonado por el autor, y ya se considera “deprecated” por la comunidad de usuarios de MythTV y desde la versión 0.22 no se añade dentro de los plugins no oficiales de MythTV. La única opción para poder utilizar el plugin es en versiones muy antiguas de MythTV. La alternativa de MythStream, actualmente, es el plugin MythNetvision, que puede reproducir streams de portales de vídeo como YouTube, Vimeo, Hulu o DailyMotion. Además, en las últimas versiones del plugin MythMusic es posible añadir directamente enlaces de streaming. - 35 -
4. Desarrollo del proyecto 4. Desarrollo del proyecto Una vez analizadas las diferentes tecnologías y diferentes partes del proyecto, en este apartado explicaré el desarrollo, la creación de software y el montaje del sistema. El desarrollo del proyecto se basa en la creación de un plugin para MythTV para poder ver contenidos multimedia mediante el software PeerCast. El mayor beneficio que trae el plugin es que así no tendremos que interactuar con ningún cliente reproductor ni añadir nuestros canales desde la interfaz web de PeerCast. Esto nos ofrece la comodidad de ver todos los canales disponibles desde el sofá y con un mando a distancia. Además de crear el plugin, para que el proyecto tenga una continuidad y se siga utilizando por la comunidad de usuarios, se ha creado un Yellow Pages donde se van a listar todos los streams que yo pueda ofrecer y para que otros usuarios de PeerCast den a conocer sus propias emisiones. Por último, se ha creado un repositorio de software público para Debian donde los que quieran utilizar el plugin, puedan instalarlo de una forma sencilla sin tener que compilar el código fuente, con un simple comando pueden tener en marcha el plugin MythCast. Además, se crea un site dedicado a este proyecto, donde pondré esta memoria y toda la información relevante del proyecto: http://mythtv.jlazkano.net - 36 -
4.1. MythCast 4.1. MythCast El plugin que se ha creado se llama MythCast (de MythTV y PeerCast). Para ello se ha utilizado parte del código del plugin MythStream, que me ha servido para poder enlazar el programa PeerCast con el reproductor de medios Mplayer. MythStream lleva sin actualizarse desde años y no funciona con la versión actual de MythTV, es por ello que se ha tenido que modificar la gran mayoría de código para que sea compatible con las últimas versiones de MythTV, sobre todo por la compatibilidad con las bibliotecas multiplataforma Qt4. He intentado ponerme varias veces en contacto con el autor del plugin MythStream mediante correo electrónico, para hacerle saber que utilizaría su software en mi proyecto para adaptarlo al software PeerCast. No he tenido ninguna respuesta del autor, y viendo que su página web no se actualiza desde hace años, he decidido seguir sin su consentimiento, ya que la licencia GNU/GPL me lo permite. La Licencia Pública General de GNU, es una licencia creada por la Free Software Foundation, y está orientada principalmente a proteger la libre distribución, modificación y uso de software. Su propósito es declarar que el software cubierto por esta licencia es software libre y protegerlo de intentos de apropiación que restrinjan esas libertades a los usuarios. Por esta razón la licencia de uso de MythCast es al igual que el de MythStream, GNU/GPL. La gran mayoría del código está escrito en lenguaje de programación C++, aunque algunos scripts están escritos en Perl y en Bash. Para desarrollar no se ha utilizado ningún entorno de desarrollo de software (como puede ser Eclipse). Toda la programación se ha realizado mediante editores de texto “nano” y “gedit”. - 37 -
4.1. MythCast 4.1.1. Funcionamiento Para que el plugin funcione, necesitamos que se cumplan algunos requisitos previos (son configuraciones externas al plugin que se deben de hacer antes de iniciar MythCast): –PeerCast: es imprescindible tener el servicio de PeerCast ejecutándose en la misma máquina donde se ejecute el plugin. Si disponemos de más de un frontend en nuestra red, es posible configurar el plugin para que el servicio de PeerCast no esté en la misma máquina, sino en la máquina donde esté el servicio mythbackend, así aprovecharemos mejor el ancho de banda dentro de nuestra red. PeerCast es quien se encargará de hacer todas las conexiones P2P con otros servicios PeerCast para obtener el stream deseado. Por defecto, el plugin viene configurado para que se conecte a PeerCast en la dirección localhost y el puerto 7144. El servicio PeerCast no requiere ninguna configuración especial, si queremos podemos añadir una contraseña para el acceso a la interfaz web, aunque no es necesario, ya que los usuarios no tendrán que acceder por web. Para poder optimizar el ancho de banda podremos configurar las conexiones y limitar el número de peers. La configuración de PeerCast se encuentra en el fichero “/etc/peercast/peercast.ini”. –Fuentes de streams: además, necesitaremos al menos una fuente de streams, pueden ser direcciones URL de Yellow Pages o de ficheros XML que contengan un listado de streams para poder descargar mediante el software PeerCast. Para poder reproducir los streams, necesitamos saber donde tiene que buscar el plugin los canales a reproducir, al menos tendremos que añadir una fuente, sino el plugin no nos mostrará ningún canal. Las fuentes son simples scripts que parsean los datos, obtenidos, normalmente, de Yellow Pages o ficheros XML de PeerCast y nos dan la información necesaria para poder conectar los streams a nuestro PeerCast local. Estos scripts los guardaremos en el directorio de configuración de MythCast: /home/$USER/.mythtv/mythcast/yp/ - 38 -
4.1. MythCast Estos son los pasos que el plugin realizará para reproducir un stream mediante P2P: 1. Al ejecutar al plugin desde el frontend, automáticamente buscará todos los parsers disponibles para cada fuente y los ejecutará. 2. Los parsers descargarán un listado de streams que los almacenarán en un fichero llamado “stream.res”. 3. El usuario visualizará en la pantalla todos los streams que tenemos disponibles, agrupados por diferentes fuentes. 4. Al seleccionar el stream, el plugin enviará toda la información necesaria mediante una URL al PeerCast local para que empieza la transferencia P2P con otros servicios - 39 - Imagen 11: Funcionamiento detallado del plugin MythCast
4.1. MythCast PeerCast disponibles. 5. Una vez que el servicio local de PeercCast tenga accesible todos los peers que comparten ese stream, le enviará el stream que esté recibiendo de la red P2P a Mplayer para que reproduzca el stream. 6. Mplayer tratará el stream como un stream cliente-servidor desde nuestro servidor de PeerCast. 7. En la pantalla del plugin MythCast ya tendremos la reproducción en curso que nos da Mplayer con todo el control, podremos pausar la reproducción, ponerlo a pantalla completa, subir y bajar el volumen, etc. 8. Mientras descargamos el stream para reproducirlo, estamos contribuyendo a la distribución del stream mediante el protocolo P2P PeerCast a otros peers que quieran disponer de este mismo stream. Cuando salgamos del plugin, los streams seguirán “enganchados” en el servicio PeerCast, esto es muy interesante, ya que la próxima vez que queramos reproducir este mismo stream, lo tendremos añadido en el servidor y el tiempo de respuesta será menor. Además estaremos ayudando en la distribución de esos streams a través de internet para los usuarios de PeerCast. - 40 -
4.1. MythCast 4.1.2. Integración con Mythfrontend En esta parte es donde se configura la integración y la visualización que tendrá en pantalla el plugin dentro del frontend de MythTV, desde aquí se llamarán a las librerías necesarias para poder ejecutar el código. En esta sección es importante indicar donde se encuentran las librerías propias del MythTV para que la integración sea óptima, tanto con las versiones de software como el “theme” que se utilizará. Además se tienen que declarar los flags de compilación para el “make” y las rutas de todos los ejecutables implicados en la compilación: librerías Qt, gcc... Para esta parte ha sido fundamental la documentación obtenida en la wiki del proyecto MythTV (http://www.mythtv.org/wiki/), así como el código fuente de otros plugins. Esta parte es muy similar para casi todos los plugins, ya que es donde se indica cómo deben ejecutarse e integrarse con el core del frontend. Para la compilación del plugin son imprescindibles los fciheros “settings.pro” y mythcast.pro”. 4.1.2.1. settings.pro CONFIG += debug VERSION=0.24 # Where binaries, includes and runtime assets are installed by 'make install' isEmpty( PREFIX ) { PREFIX = /usr } # Where the binaries actually locate the assets/filters/plugins at runtime isEmpty( RUNPREFIX ) { RUNPREFIX = $$PREFIX } INCLUDEPATH += $${SYSROOT}$${PREFIX}/include INCLUDEPATH += $${SYSROOT}$${PREFIX}/include/mythtv INCLUDEPATH += $${SYSROOT}$${PREFIX}/include/mythtv/libmythdb INCLUDEPATH += $${SYSROOT}$${PREFIX}/include/mythtv/libmythui INCLUDEPATH += $${SYSROOT}$${PREFIX}/include/mythtv/libmyth INCLUDEPATH += $${SYSROOT}$${PREFIX}/include/qt4/Qt DEFINES += _GNU_SOURCE DEFINES += PREFIX=\\\"$${RUNPREFIX}\\\" DEFINES += VERSION=\\\"$${VERSION}\\\" QMAKE_LFLAGS -= -Wl,--no-undefined QMAKE LFLAGS += -DQT_THREAD_SUPPORT release { - 41 -
4.1. MythCast funciones: –mythplugin_init: se llama cuando se inicia el frontend. Este método se encarga de actualizar correctamente el plugin, ya que será el primer método que se llama después de que se haya instalado una nueva versión del plugin. Sin una correcta inicialización, el plugin no se mostrará en el menú. Para poder acceder al plugin, la función (mythplugin_init) deberá de devolver 0 (OK). –mythplugin_run: el objetivo de esta función es crear el menú del plugin cuando se ejecute desde el menú de MythTV mediante la directiva PLUGIN. Es lo que se ejecuta cuando el usuario accede al plugin. Normalmente, la estructura de esta función es parecida para todos los plugins, solo varía el objeto de la ventana que se muestra en pantalla. –mythplugin_config: esta función es llamada al ejecutarse la directiva CONFIGPLUGIN desde el menú de MythTV. Es la función que se ejecuta cuando el usuario quiera configurar algún aspecto del plugin desde el menú “Settings” del frontend. –mythcast.cpp: aquí es donde se programa el comportamiento que tendrá el plugin en la pantalla. Es necesario indicar cuáles son los eventos externos que tendrán que manejar. Desde este fichero se llama a diferentes funciones que están en los ficheros dentro del directorio “lib”. En este fichero se estructura la pantalla principal del plugin y se indican las etiquetas asociadas a cada panel, como por ejemplo: –status_panel: statuslabel, timelabel, cachelabel, stabilitylabel, playlabel, harvestlabel, playled, harvestled, cachebar, stabilitybar –dyn_panel: volumebar –browse_panel: browse_title, harvest_title, item - 48 -
4.1. MythCast - 49 - Imagen 15: Configuración del panel del plugin MythCast
4.1. MythCast 4.1.4.1. Modificaciones respecto a MythStream Como he comentado con anterioridad, este plugin utiliza gran parte de código obtenido del plugin MythStream, en este apartado explicaré las diferencias más notables de MythStream respecto al MythCast. El plugin MythStream tiene un tamaño en disco de 1.9MB, en cambio, el plugin MythCast tiene un tamaño de 688KB. Estas son las funciones que han sufrido los cambios más importantes: –SpeechProc: MythStream tiene implementado la función de síntesis de voz para los mensajes dirigidos al usuario, esto lo hace a través del software “Festival”, no se ha podido probar esta función en MythStream, ya que requiere utilizar unas librerías obsoletas de “Festival”. Se ha eliminado todo el código que hace uso del sintetizado de voz, todas las indicaciones se muestran por pantalla de una manera clara para el usuario mediante la función “reportEvent()”. –Harvester: la función que se encarga de recoger los datos del stream desde el servidor broadcaster ha sufrido cambios importantes, en MythStream existen muchas fuentes de streams y diferentes encapsulados como pueden ser RM (Real Media), PLS (Play List), RMVB (Real Media Variable Bitrate) o M3U (MPEG Versión 3.0 URL). En MythCast en cambio, todos los streams que se descargan vienen con el encapsulado PLS y desde una única fuente (desde nuestro servicio PeerCast local). Se ha adaptado el código para que solo funcione con el encapsulado Play List, así se simplifica el código y se gana en rapidez de descarga del stream. –Recorder: se ha eliminado la función de grabación que trae el plugin MythStream. Estas grabaciones se guardan con simples identificadores numéricos (fecha y hora) y es muy difícil relacionar cada grabación con el contenido que tiene. –StreamStorage y StorageHandlers: estas son las funciones que más cambios han sufrido en el plugin. En MythStream la información de los streams se puede guardar en un fichero de texto o en una base de datos MySQL. Para el plugin MythCast se ha eliminado la opción de la base de datos, y toda la información se - 50 -
4.1. MythCast guarda en un único fichero de texto. Es mucho más sencillo interactuar con un fichero de texto, sobre todo para los parsers, que son los que gestionarán toda la información de los streams. En MythCast, el usuario no tiene que gestionar los streams, son los parsers quienes gestionan automáticamente toda la información de los streams. Cada vez que entramos al plugin MythCast, se actualiza la lista de los streams. Esto es muy cómodo para el usuario, ya que en MythStream es el propio usuario quien tiene que añadir la información de los streams (nombre, URL, descripción y categoría). En MythCast, no tenemos las opciones para editar y añadir los streams, esto simplifica mucho el código, no tenemos que preocuparnos si un stream cambia de URL o de nombre, automáticamente, los parsers correspondientes los actualizarán. - 51 -
4.1. MythCast 4.1.4.2. harvester.cpp Aquí están las funciones que se encargan de la transmisión del stream desde el origen (PeerCast) hasta el reproductor (Mplayer). Se implementan las llamadas HTTP al servicio PeerCast e informa del resultado obtenido de la conexión. Si la conexión ha sido exitosa (código de estado “200”) comienza la descarga del stream, en caso contrario notificará del error y volverá al menú inicial. //Comprobar el mensaje de conexion del servidor HTTP void Requester::slotResponseHeaderReceived(const QHttpResponseHeader& response) { QString temp; QList< QPair<QString,QString> > list = response.values(); QPair<QString,QString> pair; for (int i = 0; i < list.count(); i++) { pair = list.at(i); } if ( response.statusCode() >= 300 && response.statusCode() <= 400 ) { status = sethost; this->url = response.value("Location"); Q3Url *qurl = new Q3Url( url ); status = abort; http->abort(); http = new QHttp(); fetchBuffer = 0; connect( http, SIGNAL(requestFinished(int, bool)), this, SLOT(slotRequestFinished(int, bool)) ); connect( http, SIGNAL(dataReadProgress(int, int)), this, SLOT(slotDataReadProgress(int, int)) ); connect( http, SIGNAL(readyRead(const QHttpResponseHeader&)), this, SLOT(slotReadyRead(const QHttpResponseHeader&)) ); connect( http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader&) ), this, SLOT( slotResponseHeaderReceived(const QHttpResponseHeader&) ) ); if (fetchBuffer) { delete fetchBuffer; fetchBuffer = 0; } if (!qurl->isValid() || redirectCount > 20) { delete qurl; if (redirectCount > 20) temp = TARGET": too much redirections, giving up"; else temp = TARGET": redirected to invalid URL"; emit fetchReady(true, temp); return; } - 52 -
4.1. MythCast if (qurl->hasHost()) { hHost = qurl->host(); port = qurl->port(); host = qurl->host(); if (port != -1) hHost += ":" + QString::number(qurl->port()); else port=80; } hUrl = qurl->encodedPathAndQuery(); delete(qurl); status = sethost; redirectCount++; QString errorMsg; int ident = http->setHost(host, port); fetchBuffer = new FetchBuffer( host, url, fileName, ident, errorMsg); if (errorMsg != "") { status = abort; http->abort(); delete fetchBuffer; fetchBuffer = 0; cout << "TARGET error: " << errorMsg.latin1() << endl; return; } } if ( response.statusCode() == 200 && fetchBuffer ) fetchBuffer->setResponseDate( response.value("Date") ); } //Envia la URL al parser para sacar la informacion de la lista PLS void StreamHarvester::externalParserStart(QString srcUrl, QString parser, QString srcName) { if ( eParser ) return; QString ppath = parsersPath; parser = "stream.pl"; sourceUrl = srcUrl; urlCount = 0; eParserUrl = NULL; urlList.clear(); parserOutput = ""; eParser = new Q3Process( this ); eParser->setWorkingDirectory(QDir(ppath)); eParser->setCommunication( Q3Process::Stdin | Q3Process::Stdout ); srcName = srcName.replace('"', "'"); //Ejecuta el script perl eParser->addArgument( "perl" ); eParser->addArgument( ppath + parser ); eParser->addArgument( "list.xml" ); eParser->addArgument( "\"" + sourceUrl + "\"" ); eParser->addArgument( "\"" + srcName + "\"" ); pending = false; - 53 -
4.1. MythCast connect( eParser, SIGNAL(readyReadStdout()), this, SLOT(externalParserRead()) ); connect( eParser, SIGNAL(processExited()), this, SLOT(externalParserExited()) ); if ( !eParser->start() ) fprintf( stderr, "error starting parser " + parser + "\n" ); baseUrl = sourceUrl; int lastSlash = baseUrl.findRev("/", -1); int lastDot = baseUrl.findRev(".", -1); if ( lastSlash > 0 && lastSlash < lastDot && baseUrl.mid(lastSlash - 1, 1) != "/" ) baseUrl = baseUrl.left(lastSlash); } //Obtiene la informacion del stream bool StreamBrowser::getCurrentObjectDetails(QString& title, QString& field1, QString& field2, bool preferFolder) { StreamObject* obj; StreamFolder *folder = 0; obj = itemTree->getStreamFolder(); if (obj) folder = dynamic_cast<StreamFolder*>(obj); if (folder) { title = folder->getName(); field1 = folder->getValue("caption"); field2 = folder->getValue("descr"); } else return false; if (preferFolder) return true; if ( obj && obj->getObject() ) { StreamFolder *folder = dynamic_cast<StreamFolder*>(obj); if ( folder ) { StreamItem *item = folder->getStreamItem(); if (item) { title = item->getName(); field1 = item->getValue("url"); field2 = item->getValue("descr"); } } } return true; } //Da la informacion del reproductor void StreamBrowser::signalPlayerService(QString signal) { if ( streamStatus->getStreamPServ() != "" ) if ( !playerService->sendToService(signal) ) { reportEvent("Player Service not running", ""); } } - 54 -
4.1. MythCast 4.1.4.3. streambrowser.cpp Aquí es donde se analiza el stream que está siendo transferido al Mplayer, si es audio o vídeo, qué códec y qué formato tiene. Además, es el que muestra la información como el título, descripción y que categoría tiene. Se comunica con Mplayer para obtener información. //Muestra la informacion del stream StreamBrowser::StreamBrowser(QWidget *parent, QWidget *focusProxy, StreamStorage *storage) : QObject() { userMessage = ""; video = false; markedStorage = NULL; playListActive = false; setItemDisplayFolded( -1, false); setFolderDisplayFolded( -1, false ); sampler = 0; converter = 0; streamStatus = new StreamStatus(this); streamHarvester = new StreamHarvester(); oldStatus = StreamStatus::idle; connect( streamStatus, SIGNAL(statusChange()), this, SLOT(streamStatusChanged()) ); connect( streamStatus, SIGNAL(pollSignal()), this, SLOT(streamPollEvent()) ); connect( streamHarvester, SIGNAL(fetchStatus(int, unsigned int)), this, SLOT(harvesterReady(int, unsigned int)) ); connect( streamHarvester, SIGNAL(showError(QString, QString)), this, SLOT(harvesterShowError(QString, QString)) ); itemTreeLoaded = streams; lastItemTreeLoaded = streams; itemTree = &databaseTree; if ( parent ) videoContainer = new VideoContainer( parent, "TARGET Video", Qt::Widget); else videoContainer = new VideoContainer( parent, "TARGET Video", Qt::WStyle_Customize | Qt::WStyle_DialogBorder ); connect( videoContainer, SIGNAL(statusChange(int)), this, SLOT(slotVideoStatusChanged(int)) ); if ( parent ) viewerWindow = new ViewerWindow( parent, "TARGET Viewer", Qt::WStyle_Customize | Qt::WStyle_NoBorder ); else viewerWindow = new ViewerWindow( parent, "TARGET Viewer", Qt::WStyle_Customize | Qt::WStyle_DialogBorder ); videoContainer->installEventFilter( this ); streamStatus->setVideoContainer(videoContainer); this->focusProxy = focusProxy; streamStorage = storage; connect ( streamStorage, SIGNAL( storageEvent(int, int, bool ) ), this, SLOT ( slotStorageEvent(int, int, bool ) ) ); int i = -1; while ( streamStatus->checkCustomStreamInfoExists( "StreamCustomEvent" + QString::number(++i) )) - 55 -
4.1. MythCast {} streamCustomParameterCount = (unsigned int)i; recorderManager = new RecorderManager(this, storage); playerService = new PlayerService(); connect( playerService, SIGNAL(playerServiceParameter(QString, QString, QString)), this, SLOT(slotPlayerServiceParameter(QString, QString, QString)) ); connect( streamHarvester, SIGNAL(playerServiceParameter(QString, QString, QString)), this, SLOT(slotPlayerServiceParameter(QString, QString, QString)) ); connect( playerService, SIGNAL(playerServiceDataError(QString)), this, SLOT(slotPlayerServiceDataError(QString)) ); } 4.1.4.4. streamstatus.cpp Aquí se gestiona el estado del stream, tanto el estado de la descarga (cache y estabilidad) como el estado de la reproducción, si está pausado, reproduciendo, en pantalla completa, etc. //Calcula el aspect ratio del video QRect VideoContainer::calcVideoRectFromAspect(double vaspect, QRect targetRect, bool zoom) { int vheight = 0; int vwidth = 0; int vdelta = 0; double saspect; QRect vRect; if (vaspect == 0) vRect = targetRect; else { saspect = (double)targetRect.width()/targetRect.height(); if ( (vaspect > saspect) != zoom ) { vRect.setWidth( targetRect.width() ); vRect.setLeft(0); vheight = int( (double)targetRect.width() / vaspect ); vdelta = int( (targetRect.height() - vheight)/2 ); vRect.setTop(vdelta); vRect.setHeight(vheight); } else { vRect.setHeight( targetRect.height() ); vRect.setTop(0); vwidth = int( (double)targetRect.height() * vaspect ); vdelta = int( (targetRect.width() - vwidth)/2 ); vRect.setLeft(vdelta); vRect.setWidth(vwidth); } } return vRect; } - 56 -
4.1. MythCast //Obtiene el estado del stream void StreamStatus::setStatus(Status stat) { setIdleOnZero = 0; Status oldstatus = status; status = stat; switch (stat) { case idle: { reset(); statusString = "idle"; if ( lastPlayedConsole.length() > 20000 ) lastPlayedConsole = lastPlayedConsole.right(20000); if ( status != oldstatus) emit statusChange(); break; } case starting: { reset(); statusString = "starting"; lastPlayedConsole += "\n***" + QString(TARGET": starting " + pendingName + ", " + pendingUrl + "***\n\n"); if ( status != oldstatus) emit statusChange(); break; } case videoinit: { if ( videoSet() ) { statusString = "videoinit"; if ( status != oldstatus) emit statusChange(); videoAspect = getVideoAspect(); m_videoContainer->goPreview(videoAspect, true); } else if ( status != oldstatus) emit statusChange(); break; } case buffering: { statusString = "buffering"; if ( status != oldstatus) emit statusChange(); break; } case playing: { if (oldstatus != paused) { lastPlayedUrl = streamUrl; lastPlayedName = streamName; lastPlayedDescr = streamDescr; lastPlayedHandler = streamHandler; lastPlayedConsole += "\n***" + QString(TARGET": stream playing***\n\n"); if (m_videoContainer->getVideoStatus() != VideoContainer::novideo && videoSet() ) myX11MapWindow(m_videoContainer->getVideoWindowId()); } statusString = "playing"; if ( status != oldstatus) emit statusChange(); break; } case paused: { statusString = "paused"; if ( status != oldstatus) emit statusChange(); break; - 57 -
4.1. MythCast source.setFilter( QDir::Files | QDir::NoSymLinks | QDir::Dirs); const QFileInfoList list = source.entryInfoList(); QFileInfo fi; for (i = 0; i< list.size(); i++) { fi = list.at(i); if ( fi.isDir() ) { if ( fi.fileName() != "." && fi.fileName() != ".." ) { newDir = destDir + "/" + fi.fileName(); if ( !newDir.exists() ) newDir.mkdir( destDir + "/" + fi.fileName(), true); copyFiles(fi.filePath(), destDir + "/" + fi.fileName() ); } } else if ( fi.fileName() != "list.xml" ) copyFile(sourceDir + "/" + fi.fileName(), destDir + "/" + fi.fileName() ); } return true; } //Añadir contenido a un fichero bool ReposStorage::createStorageRepos(const QString& dest, const QString& path) { QFile dst(dest); if ( !dst.open(QIODevice::ReadWrite) ) return false; Q3TextStream dstStream( &dst ); dstStream << endl; dstStream << "[item]" << endl; dstStream << "*" << endl; dstStream << "file" << endl; dstStream << "streams in homedir" << endl; dstStream << path << "/."SUBPATH"/streams.res" << endl; dstStream << endl; dst.close(); return true; } //Comprobar el directorio de parsers bool ReposStorage::checkParsers() { QString home = getenv("HOME"); QDir dir( home + "/."SUBPATH"/parsers" ); if ( !dir.exists() ) { dir.mkdir(dir.homeDirPath() + "/."SUBPATH"/parsers", true); } QString source = QString(PREFIX"/share/"SUBPATH"/parsers"); QString dest = home + "/."SUBPATH"/parsers"; if ( !QFile::exists(home + "/."SUBPATH"/parserupdate"VERSION"_done") ) { - 64 -
4.1. MythCast if (!copyFiles(source, dest) ) { cerr << "error: cannot copy files from" << source.latin1() << " to " << dest.latin1() << endl; QApplication::exit(-1); } QFile checkFile(home + "/."SUBPATH"/parserupdate"VERSION"_done"); if ( !checkFile.open(QIODevice::ReadWrite) ) cerr << "MythCast error: cannot create file " << home.latin1() << "/."SUBPATH"/parserupdate"VERSION"_done" << endl; else { QString txt = "this file stops mythcast version "VERSION" from updating the ./parsers directory\n"; checkFile.writeBlock( txt, txt.length() ); checkFile.close(); } } dir = QDir( home + "/."SUBPATH"/cache" ); if ( !dir.exists() ) dir.mkdir(dir.homeDirPath() + "/."SUBPATH"/cache", true); return true; } - 65 -
4.1. MythCast 4.1.5. Compilación Para poder utilizar el software en un PC, es necesario compilar el código fuente. La distribución del sistema operativo utilizada en este proyecto ha sido Debian, es por ello que la compilación se hace al estilo Debian. Esto nos facilita el trabajo a la hora de instalar, ya que disponemos de todos los ficheros en un único paquete y se puede desinstalar y actualizar mediante simples comandos. En la distribución Debian y sus derivados, el software se distribuye en forma de paquetes con extensión DEB. Estos paquetes además del software, incluyen mucha información, como pueden ser el nombre completo, una descripción de su funcionalidad, el número de versión, el distribuidor del software, la suma de verificación y una lista de otros paquetes requeridos para el correcto funcionamiento del software (dependencias). Esta meta-información se introduce normalmente en una base de datos de paquetes local. El sistema de gestión de paquetes de Debian se llama “dpkg”, se trata de una colección de herramientas que sirven para automatizar el proceso de instalación, actualización, configuración y eliminación de paquetes de software. Una vez creado el plugin, necesitamos crear una serie de ficheros para poder compilar y empaquetar el software; estos ficheros se crean el directorio “debian”. Los paquetes deben ser generados a partir de un código fuente basado en las políticas de Debian. $ tree debian/ debian/ ├── changelog ├── compat ├── control ├── copyright ├── README.source ├── rules ├── source │ └── format └── watch 1 directory, 8 files –source/format: especifica el formato del código fuente, el más recomendado es 3.0 (quilt). –changelog: lista cronológica de versiones del paquete, que además contiene una descripción significativa de los cambios hechos en cada una de ellas. - 66 -
4.1. MythCast –compat: versión de “debhelper” utilizada. –control: es el archivo más importante en un paquete. Especifica las dependencias, el nombre del paquete, el responsable (mantenedor) y la descripción entre otros campos: Source: mythcast Section: graphics Priority: extra Maintainer: Josu Lazkano <[email protected]> Bugs: mailto:[email protected] Homepage: http://jlazkano.net Standards-Version: 3.9.2 Build-Depends: debhelper (>= 7.0.50~), libmyth-dev (>= 0.24), fftw3-dev, libqt4-dev, libx11-dev, libexpat1-dev, quilt, ccache Package: mythcast Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, libxml-xql-perl, libwww-perl, libxml-dom-perl, libxml-simple-perl, mythtv-frontend, peercast, mplayer Description: MythTv plugin that plays PeerCast streams. –copyright: declaración de derechos de autor (si los hubiere) y licencia de distribución del paquete. –rules: el archivo rules especifica las reglas para el empaquetado de la aplicación: #!/usr/bin/make -f %: dh $@ --parallel --with quilt override_dh_auto_configure: qmake-qt4 mythcast.pro override_dh_builddeb: dh_builddeb -- -Zbzip2 –watch: este archivo nos sirve para verificar si hay actualizaciones del paquete. Para esta tarea se usa el programa llamado “uscan”. –README: descripción detallada del software. Una vez creado los ficheros correspondientes y configurado de acuerdo a nuestras necesidades, para obtener el paquete DEB se ejecuta el siguiente comando: dpkg-buildpackage -us -uc Los parámetros que hemos utilizado con dpkg-buildpackage: –us: código fuente sin firmar. –uc: cambios sin firmar. - 67 -
4.1. MythCast Podremos observar en la pantalla todo el proceso de compilación, sino ha habido ningún error, se habrán creado estos ficheros: –mythcast_0.02.dsc: este es un sumario de los contenidos del código fuente. Este fichero se genera a partir del fichero de control y se usa cuando se descomprimen las fuentes con dpkg-source. –mythcast_0.02.tar.gz: este es el código fuente original comprimido, simplemente se ha renombrado para seguir los estándares de Debian. –mythcast_0.02_i386.changes: este fichero describe todos los cambios hechos en la revisión actual del paquete, y lo utilizan los programas de mantenimiento de Debian para instalar los paquetes binarios y fuentes. Se genera parcialmente a partir del fichero changelog y el fichero “mythcast_0.02.dsc”. –mythcast_0.02_i386.deb: este es el paquete con los ficheros binarios completo. Se puede usar dpkg para instalar o eliminar el paquete. Una vez que creado el fichero DEB, para poder instalar con todas las dependencias, se ejecuta el siguiente comando: dpkg -i mythcast_0.02_i386.deb Esto nos instalará el plugin además de todas las dependencias que precise, como pueden ser el frontend de MythTV, Mplayer y diferentes librerías de audio y vídeo. - 68 -
4.1. MythCast 4.1.6. Manejo del plugin El plugin está integrado dentro del frontend de MythTV, para poder acceder al plugin pondremos en marcha nuestro frontend de la siguiente forma: $ mythfrontend -v most -l mythfrontend.log Los parámetros: –v most: para que nos muestre (verbose) “mucha” información a la salida. –l mythfrontend.log: para guardar el log de la salida estándar (stdout) en el fichero mythfrontend.log Una vez que arrancamos el software MythTV, podremos navegar tanto con los cursores del teclado como con el mando a distancia gracias a LIRC. LIRC (Linux Infrared Remote Control) es un software que permite recibir y enviar las señales de infrarrojos usadas en la mayoría de mandos a distancia. Además de mandos infrarrojos, se puede activar la interfaz por red de LIRC y así poder manejar MythTV mediante un smartphone o cualquier otro dispositivo conectado a la red. Para poder utilizar LIRC, es necesario tener configurado los botones de nuestro mando a distancia, para ello crearemos un fichero llamado “.lircrc” en nuestra $HOME. Aquí añadiremos unos cuantos “atajos” para poder prescindir del teclado. Ejemplo de configuración de botones para MythCast: begin prog = mythtv button = Green config = f end begin prog = mythtv button = Yellow config = c end begin prog = mythtv button = Red config = s end - 69 -
4.1. MythCast Con este fichero de configuración, podremos poner un vídeo a pantalla competa o bajar y subir el volumen de los streams que se estén reproduciendo. MythTV dispone de una nueva interfaz de usuario de la biblioteca llamada “libmythui”. Esta biblioteca permite que se utilicen tanto OpenGL como Qt para el renderizado de las imágenes en los menús. Si se opta por utilizar OpenGL, se obtiene una interfaz de usuario más moderna y avanzada. Al mismo tiempo, el proceso de renderizado de la interfaz de usuario MythTV permitirá que sea más consistente. MythUI tiene como objetivo hacer más fácil la creación de “themes”, introduciendo el concepto de herencia. El estilo de los menús se pueden definir una vez, después se copian unos de otros o desde las definiciones globales. Esto reduce la cantidad de código duplicado, lo que significa que los cambios del “theme” se pueden hacer mediante la edición de pocas líneas de código. El “theme” que se ha escogido para este proyecto es el de “Blue Abstract”, el cual se integra muy bien con el frontend. Se ha añadido el logo de UPC para personalizar y se han cambiado algunos aspectos del “theme”. Una vez en el programa, para entrar a MythCast, tendremos que dirigirnos al menú “Media Library” y veremos que existe una entrada con el nombre “MythCast”. - 70 -
4.1. MythCast - 71 - Imagen 16: Menú principal de Mythfrontend Imagen 17: Submenú "Media Library" con el plugin MythCast
4.1. MythCast Cuando pulsemos en “MythCast”, automáticamente se cargarán todos los stream en la parte inferior organizados en diferentes fuentes. - 72 - Imagen 18: Captura del plugin MythCast
4.1. MythCast Podemos observar en la parte superior varios indicadores: –status: indica el estado del stream, estos son los diferentes estados posible para un stream: –idle –buffering –playing –stopped –harvesting –time: indica el tiempo de reproducción del stream. –cache: es la caché que dispone Mplayer para el stream. –stability: es la estabilidad que nos indica Mplayer sobre el stream. –player: indica cuándo se ejecuta el reproductor Mplayer. –harvester: indica cuándo el plugin está obteniendo información del servicio PeerCast. - 73 - Imagen 19: Captura del plugin MythCast reproduciendo un stream
4.3. Repositorio de software 4.3. Repositorio de software Para poder ofrecer el plugin MythCast a la comunidad de usuarios, se ha creado un repositorio público en la URL http://repo.jlazkano.net El objetivo de este repositorio, es que cualquier usuario, añadiendo dicho repositorio pueda instalar el plugin MythCast con todas sus dependencias, incluido el software PeerCast y una versión reciente de MythTV. Un repositorio de software es un archivo donde se almacenan los paquetes actualizados y con una estructura bien definida. De momento, solamente están disponibles los paquetes para la versión estable de Debian (actualmente llamado Squeeze) y para la arquitectura i386. En un futuro se pretende dar soporte para la distribución Ubuntu y ampliar el número de arquitecturas, como pueden ser amd64 y ARM. Para cumplir con las dependencias del plugin y completar el repositorio, se ha optado por utilizar los paquetes disponibles en el repositorio debian-multimedia.org. “debian-multimedia.org” es un repositorio no oficial de software para la distribución Debian mantenido por Christian Marillat que nos proporciona software para tareas multimedia como por ejemplo: avidemux, cinelerra o MythTV. Además de software libre, alberga software no libre (non-free), entre otros: flash-player, w32codecs, w64codecs o acroread. El software PeerCast se ha obtenido de los repositorios oficiales de la versión Lenny de Debian. Se ha probado su funcionamiento tanto en la versión estable (Squeeze) como en la versión testing (Wheezy) y no existe ningún problema de incompatibilidad de dependencias. - 80 -
4.3. Repositorio de software 4.3.1. Software utilizado para crear el repositorio Los paquetes contenidos en un repositorio son indexados en estos archivos: –Packages.gz: contienen los binarios del software. –Sources.gz: contienen el código fuente del software. Para crear el repositorio, se han utilizado diferentes herramientas de gestión de repositorios que dispone Debian: –debmirror: este programa descarga y mantiene parcial o completamente un repositorio local de Debian. Puede crear réplicas o espejos de cualquier combinación de arquitecturas, distribuciones y secciones. Los ficheros se transfieren mediante ftp o http. –dpkg-scanpackages: busca paquetes binarios de Debian en un árbol de directorios, creando un fichero Packages.gz para mostrar al usuario los paquetes disponibles para su instalación. Este fichero Packages.gz es idéntico a los que existen en los archivos de Debian en Internet. –dpkg-scansources: busca ficheros dsc en el directorio-binario dado, creando un fichero Sources.gz. Esto sirve para crear un índice de fuentes de Debian, que se muestra por la salida estándar. Además de estas herramientas, se han necesitado estas otras: –GPG (GNU Privacy Guard): es una herramienta de cifrado y firmas digitales que cifra los mensajes usando pares de claves individuales asimétricas generadas por los usuarios. Las claves públicas pueden ser compartidas con otros usuarios de muchas maneras, un ejemplo de ello es depositándolas en los servidores de claves. –Apache2: el mismo servidor web utilizado para el Yellow Pages, es el software que permite listar y descargar los paquetes desde el repositorio. Para descargar todos los paquetes disponibles del repositorio de debian-multimedia.org, utilizaremos el software “debmirror”. En este caso descargaremos solamente la rama estable de la distribución y software para la arquitectura i386. Todos los paquetes los guardaremos en - 81 -
4.3. Repositorio de software el directorio “/var/repo/”: debmirror /var/repo/ --host=www.debian-multimedia.org --ignore-small-errors --diff=none --dist=stable --arch=i386 --root=/ --method=http --section=main Para crear el índice del repositorio, utilizaremos el comando “dpkg-scanpackages”, lo que hacemos es leer todos los archivos DEB que tenemos en el directorio y con el programa “gzip” creamos el archivo Packages.gz que indica a “apt” cuáles son los paquetes que luego podremos instalar: dpkg-scanpackages /var/repo/pool/ /dev/null | gzip -9c > /var/repo/dists/squeeze/main/binary- i386/Packages.gz Haremos lo mismo para los paquetes de fuentes mediante “dpkg-scansources”: dpkg-scansources /var/repo/pool/ /dev/null | gzip -9c > /var/repo/dists/squeeze/main/source/Sources.gz Para crear el site del repositorio, se ha utilizado Apache, esta es la configuración: # nano /etc/apache2/sites-available/repo <VirtualHost *:80> ServerAdmin [email protected] ServerName repo.jlazkano.net DocumentRoot /var/repo <Directory /> Options FollowSymLinks AllowOverride All </Directory> <Directory /var/repo/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory> </VirtualHost> - 82 -
4.3. Repositorio de software 4.3.2. Software disponible en el repositorio Estos son los paquetes que se han añadido en el repositorio: –MythTV: tanto el frontend como el backend. –MythCast: el plugin creado en este proyecto. –Plugins de MythTV: todos los plugins oficiales: mytharchive, mythbrowser, mythgallery, mythgame, mythmusic, mythnetvision, mythnews, mythvideo, mythweather y mythzoneminder. –MythWeb: interfaz web para gestionar el backend MythTV. –MythThemes: varios temas para MythFrontend. –FFmpeg: es un software que puede grabar, convertir y hacer streaming de audio y vídeo, necesario para el funcionamiento de MythTV. –PeerCast: el software de streaming P2P. –Librerías: librerías necesarias para cumplir las dependencias. Con el software disponible en este repositorio además de los oficiales de Debian, tendremos una versión completa y actualizada de MythTV y PeerCast. 4.3.3. Uso del repositorio En los sistema Debian, los repositorios de software vienen indicados en el archivo /etc/apt/sources.list. En este fichero cada línea representa a un repositorio y la forma en la que se obtendrán los paquetes, así como la rama de la distribución que se desea utilizar (stable, testing, unstable). Es importante ingresar los repositorios en un orden justo, es decir, los primeros en la lista, serán los más importantes. Para añadir el repositorio en nuestro sistema es suficiente con añadir estas líneas en el fichero /etc/apt/sources.list: deb http://repo.jlazkano.net squeeze main non-free deb-src http://repo.jlazkano.net squeeze main non-free - 83 -
4.3. Repositorio de software Cada línea que describe un repositorio tiene una determinada sintaxis: deb url distribution [component...] Analizamos los componentes por separado: –deb ó deb-src: sirve para indicar si el repositorio indicado contiene paquetes binarios o paquetes fuente (si posee ambos, es necesario especificarlo en dos líneas diferentes). –url: indica la dirección donde es posible encontrar el repositorio. –distribution: indica la distribución utilizada. Es posible usar el nombre en código (squeeze, wheezy, sid) o el nombre genérico (stable, testing, unstable). –component: indica las secciones del repositorio, non-free, main, contrib. Navegando en el directorio component, observamos que están divididos en diferentes secciones: –main: es la sección principal donde solamente encontraremos paquetes libres, que contiene el 90% de los paquetes presentes en Debian. –contrib: encontramos los paquetes que cumplen con 5 ó 6 puntos de las DFSG (Debian Free Software Guidelines), pero que dependen de paquetes que no la respetan. –non-free: contiene los paquetes que poseen limitaciones en su distribución (como aquellos que no pueden ser usados en ámbito comercial o porque dependen de paquetes que no respetan las DFSG). Una vez añadido el repositorio, es necesario actualizar el repositorio local con el siguiente comando: # apt-get update Con esto lo que hacemos es bajarnos el listado de los paquetes con las versiones disponibles desde el repositorio remoto al sistema local. - 84 -
4.3. Repositorio de software Para instalar el plugin MythCast basta con teclear en la consola: # apt-get install mythcast Con esto, instalaremos el plugin y nos aseguraremos que nos instala todo el software necesario y las dependencias automáticamente. Por defecto, no nos instala el backend de MythTV, ya que el plugin solo depende del frontend. Si queremos tener en la máquina el servicio backend, tendremos que ejecutar el siguiente comando: # apt-get install mythtv-backend O también podremos tener el sistema completo (frontend+backend) instalando el metapaquete MythTV: # apt-get install mythtv Una vez que termine la instalación, tendremos todo lo necesario para poder ver o escuchar los streams desde nuestro PC. - 85 -
4.4. Hardware utilizado 4.4. Hardware utilizado Para el desarrollo del proyecto se han utilizado 3 PCs con diferentes características para tres tareas diferentes. 4.4.1. Plugin MythCast La gran mayoría del montaje y el desarrollo del plugin se ha llevado a cabo en un portátil con las siguientes características: –CPU: Intel Celeron a 2 GHz. –Memoria: 2 GB. –Sistema operativo: Debian Squeeze (kernel 2.6.32). –Gráfica: ATI Radeon Mobility X600 (128 MB). Se han hecho pruebas en diferentes PCs para comprobar la compatibilidad del plugin en otros sistemas, como procesadores de bajo consumo (Intel Atom), y en versión de kernel actuales como el 3.2.9. No se ha detectado ningún problema en ninguna de las pruebas. Para garantizar un correcto funcionamiento se recomienda como mínimo una CPU de 1GHz y 512MB de memoria. Las arquitecturas probadas han sido x386 y amd64. Para un correcto funcionamiento de todo el sistema se recomienda utilizar un sistema especialmente diseñados para HTPC como son las placas Nvidia ION, que a pesar de tener procesadores de bajo consumo tienen unas gráficas potentes para poder acelerar vídeos y streams con altos bitrates mediante hardware. Además, consumen muy poco y por eso se calientan menos, esto también implica que hagan menos ruido por no tener disipadores activos (ventiladores). Esto es muy importante ya que normalmente los dispositivos PVR suelen instalarse en el salón de casa, donde es preferible que sean silenciosos. La versión de MythTV que se ha utilizado para integrar el plugin es la 0.24.2, que se liberó el 22 de enero del 2012. - 86 -
4.4. Hardware utilizado 4.4.2. Yellow Pages Para el montaje del Yellow Pages, se ha utilizado un PC antiguo con las siguientes características: –CPU: Intel Pentium 4 a 1,8 GHz. –Memoria: 512 MB. –Sistema operativo: Debian Squeeze (kernel 2.6.32). –Conexión a Internet: 10Mbps / 800Kbps (ADSL2+). Al ser un servidor, no dispone de entorno gráfico, esto hace que no requiera de mucha memoria ni CPU. No se ha detectado ningún problema con el rendimiento del servidor web, aunque el número de streams albergados en el Yellow Pages todavía es muy pequeño, se prevee que no habrá ningún problema en un futuro. Para minimizar la carga de trabajo del servidor, se puede optar por el servidor web lighttpd, que es un servidor web diseñado para ser rápido, seguro y flexible. 4.4.3. Repositorio de software Para el montaje del repositorio, se ha utilizado un PC con las siguientes características: –CPU: Intel Atom N330 a 1,6 GHz. –Memoria: 2 GB. –Sistema operativo: Debian Squeeze (kernel 2.6.32). –Conexión a Internet: 30Mbps / 3Mbps (VDSL2). En este caso, el PC no está dedicado solo al uso del repositorio, comparte otros servicios como diferentes páginas webs, servidor de descargas, y dispone de un sistema MythTV. El servicio de repositorio no requiere de mucha potencia, ya que únicamente sirve ficheros estáticos. - 87 -
5. Conclusiones y líneas futuras 5. Conclusiones y líneas futuras El objetivo principal que nos habíamos marcado al inicio de este proyecto era integrar el protocolo Peercast en el PVR MythTV, mejorando la usabilidad al usuario a la hora de ver o escuchar contenidos multimedia mediante protocolos P2P. Este objetivo se ha logrado e incluso se han realizado mejoras como la creación de un Yellow Pages y un repositorio público de software. Los resultados han sido satisfactorios, se ha podido reproducir todo tipo de streams multimedia mediante el plugin MythCast, desde emisoras de radio de pocos “bitrates” a canales de televisión en alta definición. El mayor problema que he tenido en el desarrollo del proyecto ha sido la poca información existente sobre el software PeerCast. No existe ninguna ayuda ni fuente oficial en Internet al estar el proyecto abandonado, es por ello que he tenido que aprender su funcionamiento. Además, al ser un proyecto de integración por software, explicar el código en un documento escrito es un ejercicio complejo. Se tiene que abstraer el código para poder explicar con frases cada una de las funciones más significativas del software utilizado. Las mejoras que se pueden aplicar al plugin son varias: –Selección de diferentes Yellow Pages desde la interfaz del plugin. Esto sería de gran interés si tuviéramos muchos Yellow Pages, pero como hemos comentado en este documento solo se tienen dos fuentes de stream de PeerCast, es por eso que se ha optado por no integrar esta función en el plugin. –Expandir la utilización de otros protocolos a parte de PeerCast, como pueden ser NeuroCast o GridCast. En el departamento de Telemática de UPC se pretende dar continuidad a este proyecto reemplazando el PeerCast por el protocolo evolucionado llamado NeuroCast, este paso será muy importante para la continuidad de un protocolo de streming de P2P de código abierto. –Portarlo a un hardware “empotrado”, así poder integrar tanto MythTV como el plugin en una pequeña caja. Esto estaría muy bien visto por la industria de consumo y podría - 88 -
5. Conclusiones y líneas futuras integrarse esta tecnología en televisores y grabadores. Últimamente, se están popularizando productos como el Raspberry Pi, una placa con un SoC de menos de 35 dólares capaz de reproducir contenidos multimedia con un gasto energético mínimo. A parte de aprender a programar un plugin, se han aprendido las formas de trabajar con el software libre, ya que he tenido que utilizar herramientas de versiones como SVN y Trac. He tenido que pedir ayuda en foros y listas de correo y aprender a empaquetar paquetes para las distribuciones del tipo Debian. Las dificultades encontradas a la hora de trabajar en un proyecto paralizado, han prolongado los tiempos de investigación y pruebas. Me he encontrado con un escenario inesperado pero a su vez retador. En el proyecto de final de carrera, valoro dos pilares que he trabajado. Gestión del conocimiento y desarrollo de investigación. Dentro de mi carrera profesional, en todo desarrollo realizado he encontrado varias fuentes de información. Muchas veces tratamos de gestionar la información técnica. En este proyecto en cambio, he aprendido a gestionar la poca información temática existente y utilizar estrategias de benchmarking. He tenido que reutilizar mucha información de otros desarrollos y aplicarlo a mi proyecto. El hecho de traer a nuestro terreno desarrollos realizados con otros objetivos ha resultado muy positivo. Todo ello me ha permitido desarrollar un afán de investigación muy útil a nivel personal y a nivel de proyecto. Puedo llegar a entender que el desarrollo técnico realizado se podría realizar de forma más óptima por un equipo profesional de desarrolladores. Aún así, el camino de pruebas y cambios me han permitido realizar un desarrollo de investigación a título individual del que estoy muy orgulloso. Tras el desarrollo realizado, me encantaría seguir avanzando y seguir abriendo puertas a esta tecnología que creo que va a marcar un antes y un después en el uso del P2P y consumo de contenidos multimedia en la Red. - 89 -
6.2. Código de YellowPages //Borrar la base de datos sqlite_query($db, 'DELETE FROM streams;'); foreach($chlist as $info) { $sql = 'INSERT INTO streams VALUES('; $info['name_raw'] = $info['name']; $info['name_url'] = urlencode($info['name_raw']); $info['name'] = htmlspecialchars($info['name_raw'], ENT_QUOTES, 'UTF-8'); $info['genre'] = htmlspecialchars($info['genre'], ENT_QUOTES, 'UTF-8'); $info['desc'] = htmlspecialchars($info['desc'], ENT_QUOTES, 'UTF-8'); $info['url'] = htmlspecialchars($info['url'], ENT_QUOTES, 'UTF-8'); $info['comment'] = htmlspecialchars($info['comment'], ENT_QUOTES, 'UTF-8'); $info['status'] = htmlspecialchars($info['status'], ENT_QUOTES, 'UTF-8'); array_walk($info, 'sqlite_escape_string_walk'); $sql .= sprintf("'%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'", $info['id'], $info['name'], $info['name_raw'], $info['name_url'], $info['bitrate'], $info['type'], $info['age'], $info['genre'], $info['desc'], $info['url'], $info['comment'], $info['status'], $info['limit'], $info['ns']); $sql .= ');'; //Filtrar streams no validos if ($info['id']!="00000000000000000000000000000000") { sqlite_query($db, $sql); } } sqlite_close($db); ?> /var/yp/util.php <?php function sqlite_table_exists($db, $mytable) { $result = sqlite_query($db,"SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='$mytable'"); $count = intval(sqlite_fetch_single($result)); return $count > 0; } function sqlite_set_var($db, $name, $value) { $sql = sprintf("UPDATE var SET value='%s', last_update='%d' WHERE name='%s';", sqlite_escape_string($value), time(), sqlite_escape_string($name)); $ret = sqlite_query($db, $sql); if(sqlite_changes($db) <= 0) - 96 -
6.2. Código de YellowPages { $sql = sprintf("INSERT INTO var (name, value, last_update) VALUES('%s', '%s', '%d');", sqlite_escape_string($name), sqlite_escape_string($value), time()); $ret = sqlite_query($db, $sql); } if($ret === false) return false; else return true; } function sqlite_get_var($db, $name, &$last_update) { $sql = sprintf("SELECT value, last_update FROM var WHERE name='%s';", sqlite_escape_string($name)); $res = sqlite_array_query($db, $sql, SQLITE_ASSOC); $res = array_shift($res); if($res) { $last_update = $res['last_update']; return $res['value']; } else { return false; } } function remove_ctrl($str) { $str = ereg_replace("[\x01-\x1f\x7f]", '', $str); $str = trim($str); return $str; } function upto($str) { return preg_replace('/(.*)\/[^\/]+[\/]?$/', '$1', $str); } function clean_utf8(&$str) { $len = strlen($str); $padding_char = '?'; for($i=0; $i < $len; ) { if((ord($str[$i]) & 0x80) == 0x00) { if(!($str[$i] >= ' ' && $str[$i] <= '~') && ($str[$i] != "\t") && ($str[$i] != "\n") && ($str[$i] != "\r")) { $str[$i] = $padding_char; } $i++; } else if((ord($str[$i]) & 0xe0) == 0xc0) { if($i+1 < $len) { if((ord($str[$i+1]) & 0xc0) != 0x80) { $str[$i] = $padding_char; $i++; - 97 -
6.2. Código de YellowPages } else { $i+=2; } } else { $str[$i] = $padding_char; $i++; } } else if((ord($str[$i]) & 0xf0) == 0xe0) { if($i+2 < $len) { if(((ord($str[$i+1]) & 0xc0) != 0x80) || ((ord($str[$i+2]) & 0xc0) != 0x80)) { $str[$i] = $padding_char; $i++; } else { $i+=3; } } else { $str[$i] = $padding_char; $i++; } } else { $str[$i] = $padding_char; $i++; } } } function _array_combine($key, $value) { $ret = array(); $n = count($key); for($i=0; $i<$n; $i++) $ret[$key[$i]] = $value[$i]; return $ret; } function remove_ctrl_walk(&$item, $key) { $item = remove_ctrl($item); } function add_prefix_walk(&$item, $key, $prefix) { $item = $prefix.$item; } function sqlite_escape_string_walk(&$item, $key) { $item = sqlite_escape_string($item); } ?> - 98 -
6.2. Código de YellowPages 6.2.3. Configuración de Apache /etc/apache2/sites-available/yp <VirtualHost *:80> ServerAdmin [email protected] ServerName yp.jlazkano.net DocumentRoot /var/www/yp/html <Directory /> Options FollowSymLinks AllowOverride All </Directory> <Directory /var/www/yp/html/> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory> ErrorLog /var/www/yp/log/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog /var/www/yp/log/access.log combined </VirtualHost> 6.3. Código Parsers El código del scripts para el parser de yp.jlazkano.net. parser_jlazkano.sh #!/bin/bash # Variables a configurar server_yp="yp.jlazkano.net" port_yp="7144" server_peer="localhost" port_peer="7144" collection="yp.jlazkano.net" url="http://$server_yp/yp.xml" temp_file="jlazkano.temp" # Descargar el fichero XML CONTENT="`wget -qO- $url`" # Seleccionar la parte de los canales CONTENT=${CONTENT#*<channels_found*>} CONTENT=${CONTENT%%</channels_found*} # Seleccionar solo la linea de canales echo "$CONTENT" | grep "channel name" > $temp_file - 99 -
6.3. Código Parsers # Formatear a nuestro gusto sed -i 's/<channel name="//g' $temp_file sed -i 's/" id="/|/g' $temp_file sed -i 's/" bitrate=/|/g' $temp_file # Analizamos cada linea while read A; do # Guardamos el campo ID id=`echo $A | cut -f2 -d "|"` # Guardamos el campo NOMBRE izena=`echo $A | cut -f1 -d "|"` # Guardamos el campo DIRECCION helbidea="http://$server_peer:$port_peer/pls/$id?tip=$server_yp:$port_yp" # Si el campo DIRECCION esta vacio, ponemos algo if [ "$izena" == "" ]; then izena="[No name]" fi # Sacamos por la salida la info if [ "$id" != "00000000000000000000000000000000" ]; then echo "[item]" echo "$collection" echo "$izena" echo "$helbidea" echo "[emptystring]" echo "[emptystring]" echo "" fi done < $temp_file # Borrar el fichero temporal rm $temp_file 6.4. Versiones del software en el repositorio Versiones actualizadas de software en el repositorio: # tree /var/repo/pool/main/ /var/repo/pool/main/ ├── ffmpeg-dmo │ ├── ffmpeg_0.7.11-0.0_i386.deb │ ├── ffmpeg-dbg_0.7.11-0.0_i386.deb │ ├── ffmpeg-dmo_0.7.11-0.0.diff.gz │ ├── ffmpeg-dmo_0.7.11-0.0.dsc │ ├── ffmpeg-dmo_0.7.11.orig.tar.gz │ ├── ffmpeg-doc_0.7.11-0.0_all.deb │ ├── libavcodec52_0.7.11-0.0_i386.deb │ ├── libavcodec-dev_0.7.11-0.0_i386.deb │ ├── libavcore0_0.6.1+svn20101128-0.2squeeze2_i386.deb │ ├── libavcore-dev_0.6.1+svn20101128-0.2squeeze2_i386.deb │ ├── libavdevice52_0.7.11-0.0_i386.deb │ ├── libavdevice-dev_0.7.11-0.0_i386.deb │ ├── libavfilter1_0.7.11-0.0_i386.deb │ ├── libavfilter-dev_0.7.11-0.0_i386.deb │ ├── libavformat52_0.7.11-0.0_i386.deb │ ├── libavformat-dev_0.7.11-0.0_i386.deb - 100 -
6.4. Versiones del software en el repositorio │ ├── libavutil50_0.7.11-0.0_i386.deb │ ├── libavutil-dev_0.7.11-0.0_i386.deb │ ├── libpostproc51_0.7.11-0.0_i386.deb │ ├── libpostproc-dev_0.7.11-0.0_i386.deb │ ├── libswscale0_0.7.11-0.0_i386.deb │ └── libswscale-dev_0.7.11-0.0_i386.deb ├── mythplugins │ ├── mytharchive_0.24.1+fixes20111029-0.1squeeze1_i386.deb │ ├── mytharchive-data_0.24.1+fixes20111029-0.1squeeze1_all.deb │ ├── mythbrowser_0.24.1+fixes20111029-0.1squeeze1_i386.deb │ ├── mythcast_0.02_i386.deb │ ├── mythgallery_0.24.1+fixes20111029-0.1squeeze1_i386.deb │ ├── mythgame_0.24.1+fixes20111029-0.1squeeze1_i386.deb │ ├── mythmusic_0.24.1+fixes20111029-0.1squeeze1_i386.deb │ ├── mythnetvision_0.24.1+fixes20111029-0.1squeeze1_i386.deb │ ├── mythnetvision-data_0.24.1+fixes20111029-0.1squeeze1_all.deb │ ├── mythnews_0.24.1+fixes20111029-0.1squeeze1_i386.deb │ ├── mythplugins_0.24.1+fixes20111029-0.1squeeze1_all.deb │ ├── mythplugins_0.24.1+fixes20111029-0.1squeeze1.diff.gz │ ├── mythplugins_0.24.1+fixes20111029-0.1squeeze1.dsc │ ├── mythplugins_0.24.1+fixes20111029.orig.tar.gz │ ├── mythvideo_0.24.1+fixes20111029-0.1squeeze1_i386.deb │ ├── mythweather_0.24.1+fixes20111029-0.1squeeze1_i386.deb │ └── mythzoneminder_0.24.1+fixes20111029-0.1squeeze1_i386.deb ├── myththemes │ ├── myththemes_0.24+fixes20110828-0.0.diff.gz │ ├── myththemes_0.24+fixes20110828-0.0.dsc │ ├── myththemes_0.24+fixes20110828.orig.tar.gz │ └── mythtv-themes_0.24+fixes20110828-0.0_all.deb ├── mythtv │ ├── libmyth-0.24-0_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── libmythavcodec52_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── libmythavcore0_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── libmythavdevice52_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── libmythavfilter1_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── libmythavformat52_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── libmythavutil50_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── libmyth-dev_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── libmythpostproc51_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── libmythswscale0_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── libmythtv-perl_0.24.1+fixes20111029-0.0squeeze1_all.deb │ ├── mythffmpeg_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── mythtv_0.24.1+fixes20111029-0.0squeeze1_all.deb │ ├── mythtv_0.24.1+fixes20111029-0.0squeeze1.diff.gz │ ├── mythtv_0.24.1+fixes20111029-0.0squeeze1.dsc │ ├── mythtv_0.24.1+fixes20111029.orig.tar.gz │ ├── mythtv-backend_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── mythtv-common_0.24.1+fixes20111029-0.0squeeze1_all.deb │ ├── mythtv-database_0.24.1+fixes20111029-0.0squeeze1_all.deb │ ├── mythtv-doc_0.24.1+fixes20111029-0.0squeeze1_all.deb │ ├── mythtv-frontend_0.24.1+fixes20111029-0.0squeeze1_i386.deb │ ├── mythtv-perl_0.24.1+fixes20111029-0.0squeeze1_all.deb │ └── python-mythtv_0.24.1+fixes20111029-0.0squeeze1_all.deb ├── mythweb │ ├── mythweb_0.24+fixes20111029-0.0squeeze1_all.deb │ ├── mythweb_0.24+fixes20111029-0.0squeeze1.diff.gz │ ├── mythweb_0.24+fixes20111029-0.0squeeze1.dsc │ └── mythweb_0.24+fixes20111029.orig.tar.gz └── peercast ├── peercast_0.1218+svn20080104-1.1.diff.gz ├── peercast_0.1218+svn20080104-1.1.dsc ├── peercast_0.1218+svn20080104-1.1_i386.deb ├── peercast_0.1218+svn20080104.orig.tar.gz ├── peercast-handlers_0.1218+svn20080104-1.1_all.deb └── peercast-servent_0.1218+svn20080104-1.1_all.deb - 101 -
6.5. Configuración de PeerCast 6.5. Configuración de PeerCast Los ficheros de configuración de PeerCast se guardan en la ruta “/etc/peercast/peercast.ini”. Aquí se se muestran tanto el fichero de configuración de la parte del YellowPage como el de los clientes (MythCast). 6.5.1. Yellow Pages [Server] serverPort = 7144 autoServe = Yes forceIP = isRoot = Yes maxBitrateOut = 0 maxRelays = 2 maxDirect = 0 maxRelaysPerChannel = 0 firewallTimeout = 30 forceNormal = No rootMsg = authType = cookie cookiesExpire = session htmlPath = html/en minPGNUIncoming = 10 maxPGNUIncoming = 20 maxServIn = 200 chanLog = networkID = 00000000000000000000000000000000 [Broadcast] broadcastMsgInterval = 10 broadcastMsg = icyMetaInterval = 8192 broadcastID = 008145B5C0427118B595AF7D9E110000 hostUpdateInterval = 180 maxControlConnections = 12 rootHost = yp.jlazkano.net [Client] refreshHTML = 5 relayBroadcast = 30 minBroadcastTTL = 1 maxBroadcastTTL = 7 pushTries = 5 pushTimeout = 60 maxPushHops = 8 autoQuery = 0 queryTTL = 7 [Privacy] password = password maxUptime = 0 [Filter] ip = 255.255.255.255 private = No ban = No network = Yes direct = Yes - 102 -
6.5. Configuración de PeerCast [End] [Notify] PeerCast = Yes Broadcasters = Yes TrackInfo = Yes [End] [Server1] allowHTML = Yes allowBroadcast = Yes allowNetwork = Yes allowDirect = Yes [End] [Server2] allowHTML = Yes allowBroadcast = Yes allowNetwork = No allowDirect = No [End] [Debug] logDebug = Yes logErrors = Yes logNetwork = Yes logChannel = Yes pauseLog = No idleSleepTime = 10 [RelayChannel] name = genre = sourceURL = http://provisioning.streamtheworld.com/pls/NATIONAL.pls sourceProtocol = HTTP contentType = MP3 bitrate = 24 contactURL = id = 18995DADD85A6900AD8DB76586091818 stayConnected = Yes [End] [RelayChannel] name = RAC105 Entre la musica i tu genre = Various sourceURL = http://www.congreso.es/wc/htdocs/cparlamento.asx sourceProtocol = HTTP contentType = MP3 bitrate = 48 contactURL = http://www.rac105.cat id = 008145B5C0427118B595AF7D9E110000 stayConnected = Yes [End] [RelayChannel] name = RAC105 Entre la musica i tu genre = Various sourceURL = http://streaming105.radiocat.net sourceProtocol = HTTP contentType = MP3 bitrate = 48 contactURL = http://www.rac105.cat id = 008145B5C0427118B595AF7D9E110000 stayConnected = Yes [End] [RelayChannel] name = genre = - 103 -
6.5. Configuración de PeerCast sourceURL = http://pointers.audiovideoweb.com/asxfiles-live/ny60winlive7001.asx sourceProtocol = HTTP contentType = ASX bitrate = 0 contactURL = id = 00000000000000000000000000000000 stayConnected = Yes [End] [RelayChannel] name = Arraio Irratia 99.3 FM Zarautz genre = Arraio Irrati librea sourceURL = http://www.arraio.net:9001/irratia.ogg sourceProtocol = HTTP contentType = OGG bitrate = 36 contactURL = http://www.arraio.net id = 008145B5C0427118B595AF7D9E504C50 stayConnected = Yes [End] [RelayChannel] name = Arrate Irratia genre = Folk sourceURL = http://radio1.tecnicofm.com/tunein.php/arrateirratia/playlist.pls sourceProtocol = HTTP contentType = MP3 bitrate = 120 contactURL = http://www.arrateirratia.com id = 7FE423C7CC194645D49FF01EE363787F stayConnected = Yes [End] 6.5.2. MythCast [Server] serverPort = 7144 autoServe = Yes forceIP = isRoot = No maxBitrateOut = 0 maxRelays = 2 maxDirect = 2 maxRelaysPerChannel = 0 firewallTimeout = 30 forceNormal = No rootMsg = authType = cookie cookiesExpire = session htmlPath = html/en minPGNUIncoming = 10 maxPGNUIncoming = 20 maxServIn = 50 chanLog = networkID = 00000000000000000000000000000000 [Broadcast] broadcastMsgInterval = 10 broadcastMsg = icyMetaInterval = 8192 broadcastID = 008145B5C0427118B595AF7D9E110000 hostUpdateInterval = 180 maxControlConnections = 3 rootHost = yp.jlazkano.net - 104 -
6.5. Configuración de PeerCast [Client] refreshHTML = 5 relayBroadcast = 30 minBroadcastTTL = 1 maxBroadcastTTL = 7 pushTries = 5 pushTimeout = 60 maxPushHops = 8 autoQuery = 0 queryTTL = 7 [Privacy] password = password maxUptime = 0 [Filter] ip = 255.255.255.255 private = No ban = No network = Yes direct = Yes [End] [Notify] PeerCast = Yes Broadcasters = Yes TrackInfo = Yes [End] [Server1] allowHTML = Yes allowBroadcast = Yes allowNetwork = Yes allowDirect = Yes [End] [Server2] allowHTML = No allowBroadcast = Yes allowNetwork = No allowDirect = No [End] [Debug] logDebug = Yes logErrors = Yes logNetwork = Yes logChannel = Yes pauseLog = No idleSleepTime = 10 - 105 -