Servidor modular de streaming con protocolo RTSP
Servidor modular de streaming con protocolo RTSP
Servidor modular de streaming con protocolo RTSP
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Universidad<br />
Rey Juan Carlos<br />
INGENIERÍA INFORMÁTICA<br />
Curso Académico 2006/2007<br />
Proyecto <strong>de</strong> Fin <strong>de</strong> Carrera<br />
SERVIDOR MODULAR DE STREAMING<br />
CON PROTOCOLO <strong>RTSP</strong><br />
Autor: Pablo Montero Nóvoa<br />
Tutores: Luis López Fernán<strong>de</strong>z y Micael Gallego Carrillo
Agra<strong>de</strong>cimientos<br />
Al terminar la etapa <strong>de</strong> la universidad es inevitable mirar hacia atrás y hacer<br />
balance <strong>de</strong> todos estos años. Son muchas horas <strong>de</strong>lante <strong>de</strong>l or<strong>de</strong>nador peleando <strong>con</strong> las<br />
prácticas, muchos exámenes y muchas horas <strong>de</strong> clase. Algunos sinsabores cuando los<br />
resultados no eran los esperados, pero en estos casos una vez superado el obstáculo la<br />
satisfacción ha sido mayor.<br />
Ahora al terminar me quedo <strong>con</strong> la sensación <strong>de</strong> que el esfuerzo ha valido la<br />
pena, tanto en lo personal como <strong>de</strong> cara al futuro.<br />
En primer lugar quiero agra<strong>de</strong>cer a mi familia y amigos el apoyo prestado, así<br />
como el interés sobre el avance (más bien fecha <strong>de</strong> finalización) <strong>de</strong> este proyecto.<br />
También quiero dar las gracias a todos mis compañeros durante este año <strong>de</strong> trabajo en el<br />
Laboratorio <strong>de</strong> Algoritmia Distribuida y Re<strong>de</strong>s: Alberto, Juan, José, Rosana, Ana,<br />
Roberto y Despo. Gracias a Micael y Luis por su <strong>con</strong>fianza y la ayuda prestada.<br />
Por último, un recuerdo para todos los compañeros <strong>de</strong> la universidad durante<br />
estos años, tanto en Móstoles como Helsinki.
Índice<br />
SERVIDOR MODULAR DE STREAMING...........................................................1<br />
CON PROTOCOLO <strong>RTSP</strong>...................................................................................1<br />
AGRADECIMIENTOS..........................................................................................2<br />
ÍNDICE.................................................................................................................3<br />
RESUMEN............................................................................................................5<br />
1.INTRODUCCIÓN...............................................................................................6<br />
2.OBJETIVOS....................................................................................................11<br />
3.DESCRIPCIÓN INFORMÁTICA......................................................................13<br />
3.1. Multimedia...........................................................................................................................................13<br />
3.2. Java.......................................................................................................................................................14<br />
3.3. Protocolos y tecnologías <strong>de</strong> <strong>streaming</strong>...............................................................................................16<br />
3.3.1. Protocolos......................................................................................................................................16<br />
3.3.1.1. <strong>RTSP</strong>.................................................................................................................................... ...........16<br />
3.3.1.2. SIP............................................................................................................................. .....................20<br />
3.3.1.3. RTP.................................................................................................................................. ...............20<br />
3.3.1.3.1. Arquitectura RTP.............................................................................................. ......................21<br />
3.3.1.3.2. Alternativas a RTP.............................................................................................. ....................23<br />
3.3.1.3. SDP........................................................................................................................................ .........24<br />
3.3.2. Tecnologías para la creación <strong>de</strong> <strong>streaming</strong> RTP............................................................................25<br />
3.3.2.1. Java Media Framework.................................................................................................... ...............25<br />
3.3.2.2. Freedom for Media in Java.......................................................................................................... ....27<br />
3.3.2.3. VLC Media Player...................................................................................................... ....................28<br />
3.3.2.4. Gstreamer.................................................................................................................................. ......30<br />
3.3.2.5. IBM Toolkit for MPEG-4....................................................................................................... .........31<br />
3.4. Entorno y herramientas ....................................................................................................................33<br />
3.4.1. Sistema operativo Windows XP....................................................................................................33<br />
3.4.2. Entorno <strong>de</strong> <strong>de</strong>sarrollo Eclipse.......................................................................................................33<br />
3.4.3. Wireshark......................................................................................................................................34<br />
3.4.4. JavaCC..........................................................................................................................................35<br />
3.4.5. Reproductores multimedia............................................................................................................36<br />
3.4.5.1. Reproductor VLC..................................................................................................................... .......36<br />
3.4.5.2. Reproductor QuickTime Player.............................................................................................. .........37<br />
3.5. Diseño e Implementación ..................................................................................................................39<br />
3.5.1. Arquitectura <strong>de</strong>l sistema................................................................................................................39<br />
3.5.1.1. Diagrama <strong>de</strong> clases Java............................................................................................................. .....41<br />
3.5.2. Proceso <strong>de</strong> <strong>de</strong>sarrollo....................................................................................................................43<br />
3.5.3. Arranque <strong>de</strong>l servidor....................................................................................................................45<br />
3.5.4. Implementación <strong>de</strong>l <strong>protocolo</strong> <strong>RTSP</strong>............................................................................................47<br />
3.5.4.1. Petición <strong>RTSP</strong>.................................................................................................................. ...............47<br />
3.5.4.2. Respuesta <strong>RTSP</strong>................................................................................................................ ..............48
3.5.4.3. Funcionamiento <strong>de</strong>l <strong>protocolo</strong> <strong>RTSP</strong>........................................................................................ .......49<br />
3.5.4.3.1. Mensajes básicos para la reproducción <strong>de</strong> un archivo............................................ .................50<br />
3.5.4.3.2. Otros mensajes implementados................................................................................... ............55<br />
3.5.4.3.3. Resto <strong>de</strong> mensajes <strong>RTSP</strong>............................................................................................... ..........56<br />
3.5.4.4. Aspectos <strong>de</strong> la implementación <strong>de</strong>l <strong>protocolo</strong>................................................................................. .59<br />
3.5.5. Mantenimiento <strong>de</strong>l estado en el servidor......................................................................................62<br />
3.5.5.1. Estructura <strong>de</strong> datos............................................................................................................ ..............62<br />
3.5.5.2. Relación entre los mensajes <strong>RTSP</strong> y el estado <strong>de</strong>l servidor........................................... ..................64<br />
3.5.6. Módulo JmfRtpSen<strong>de</strong>r..................................................................................................................69<br />
3.5.6.1. Arquitectura <strong>de</strong> Java Media Framework................................................................................ ..........69<br />
3.5.6.2. Processors.................................................................................................................... ...................73<br />
3.5.6.3. API para RTP.............................................................................................................. ....................78<br />
3.5.6.4. Sesión RTP................................................................................................................................. .....79<br />
3.5.6.5. Implementación <strong>de</strong> la clase JmfRtpSen<strong>de</strong>r.......................................................................... ............81<br />
3.5.6.6. Problema <strong>de</strong> JMF: sincronización <strong>de</strong> las pistas........................................................ .......................83<br />
3.5.7. Módulo VlcRtpSen<strong>de</strong>r...................................................................................................................84<br />
3.5.7.1. Módulos VLC para <strong>streaming</strong>...................................................................................... ...................84<br />
3.5.7.2. Comandos para el envío <strong>de</strong> datos RTP......................................................................... ...................86<br />
3.5.7.3. Control <strong>de</strong> VLC a través <strong>de</strong> su interfaz Telnet..................................................................... ............87<br />
3.5.7.4. Clase Runtime....................................................................................................................... ..........88<br />
3.5.7.5. Problemas en el uso <strong>de</strong> VLC <strong>con</strong> la clase Runtime........................................................................ ..89<br />
3.5.7.6. Implementación <strong>de</strong> la clase VlcRtpSen<strong>de</strong>r................................................................... ...................93<br />
3.5.8. Módulo VlcSdpGenerator.............................................................................................................95<br />
3.5.8.1. Ejecución <strong>de</strong> VLC como servidor <strong>RTSP</strong>................................................................... ......................95<br />
3.5.8.2. Implementación <strong>de</strong> la clase VlcSdpGenerator................................................................... ..............97<br />
3.5.9. Módulo FileSdpGenerator...........................................................................................................100<br />
4.CONCLUSIONES Y LÍNEAS FUTURAS......................................................101<br />
4.1. Conclusiones......................................................................................................................................101<br />
4.2. Líneas futuras....................................................................................................................................102<br />
BIBLIOGRAFÍA................................................................................................104
Resumen<br />
La difusión <strong>de</strong> <strong>con</strong>tenidos multimedia está adquiriendo cada vez más relevancia.<br />
El acceso <strong>de</strong> los usuarios domésticos a Internet y la posibilidad <strong>de</strong> adquirir hardware<br />
cada vez más potente son los factores que están impulsando este proceso. Dentro <strong>de</strong>l<br />
mundo <strong>de</strong> la multimedia, <strong>de</strong>staca en los últimos años la posibilidad <strong>de</strong> reproducción a<br />
través <strong>de</strong> <strong>streaming</strong>, entendiendo como tal la reproducción <strong>de</strong> cierta información<br />
multimedia obteniendo un flujo <strong>de</strong> datos a través <strong>de</strong> la red, sin necesidad <strong>de</strong> <strong>de</strong>scargar<br />
todo el <strong>con</strong>tenido previamente al disco duro.<br />
Este tipo <strong>de</strong> tecnología <strong>de</strong>manda un ancho <strong>de</strong> banda importante. Este factor,<br />
unido al hecho <strong>de</strong> que los <strong>con</strong>tenidos multimedia son cada vez más ricos y por lo tanto<br />
ocupan cada vez más espacio, provoca la <strong>con</strong>tinua aparición <strong>de</strong> nuevos <strong>protocolo</strong>s y<br />
métodos <strong>de</strong> compresión y <strong>de</strong>scompresión. Es pues un campo en <strong>con</strong>stante evolución, y<br />
resulta complicado <strong>con</strong>seguir una i<strong>de</strong>a global <strong>de</strong> todas las tecnologías existentes y las<br />
características que diferencian unas <strong>de</strong> otras.<br />
En el presente proyecto se aborda esta cuestión, a través <strong>de</strong> la implementación<br />
<strong>de</strong> un servidor <strong>de</strong> <strong>streaming</strong> mediante el <strong>protocolo</strong> <strong>RTSP</strong>. Dicho servidor será<br />
<strong>con</strong>figurable y <strong>de</strong> estructura <strong>modular</strong>, <strong>de</strong> forma que se puedan utilizar diferentes<br />
herramientas para <strong>con</strong>seguir enviar los datos a los clientes, los cuales serán<br />
reproductores multimedia habituales. Esta arquitectura permitirá a<strong>de</strong>más dotar al<br />
servidor <strong>de</strong> la capacidad <strong>de</strong> evolucionar en el futuro incorporando nuevos módulos,<br />
característica muy interesante teniendo en cuenta el dinamismo presente en el campo <strong>de</strong>l<br />
<strong>streaming</strong>.
El proceso <strong>de</strong> <strong>de</strong>sarrollo implicará un estudio <strong>de</strong> las tecnologías <strong>de</strong> <strong>streaming</strong><br />
existentes, y su posterior adaptación e implementación en el servidor. Se evaluarán las<br />
ventajas e in<strong>con</strong>venientes <strong>de</strong> cada una <strong>de</strong> ellas, y se enumerarán los posibles problemas<br />
y aspectos a mejorar.<br />
1. Introducción<br />
La palabra <strong>streaming</strong> hace referencia al envío <strong>de</strong> <strong>con</strong>tenido multimedia<br />
(habitualmente audio y ví<strong>de</strong>o) <strong>de</strong> forma <strong>con</strong>tinua <strong>de</strong>s<strong>de</strong> un origen hasta un <strong>de</strong>stino,<br />
<strong>de</strong>stino en el cual normalmente el <strong>con</strong>tenido es reproducido a la vez que se recibe. Es un<br />
<strong>con</strong>cepto relacionado <strong>con</strong> la forma en que la información se transmite, no <strong>con</strong> el tipo <strong>de</strong><br />
información en si.<br />
En realidad se pue<strong>de</strong> hablar <strong>de</strong> <strong>streaming</strong> remontándonos incluso a antes <strong>de</strong> la<br />
aparición <strong>de</strong> la informática. Por ejemplo escuchar un programa <strong>de</strong> radio o ver la<br />
televisión se pue<strong>de</strong>n <strong>con</strong>si<strong>de</strong>rar como transmisiones <strong>de</strong> <strong>streaming</strong>, aunque no haya<br />
ningún or<strong>de</strong>nador involucrado, ya que la forma en que se transmite el <strong>con</strong>tenido encaja<br />
<strong>de</strong>ntro <strong>de</strong> la <strong>de</strong>finición dada anteriormente. Como <strong>con</strong>traposición a este ejemplo,<br />
podríamos ver el mismo ví<strong>de</strong>o o escuchar el mismo sonido utilizando medios que no<br />
serían <strong>streaming</strong>, como una película en DVD o un CD <strong>de</strong> música.<br />
En el campo <strong>de</strong> la informática, el interés por distribuir <strong>con</strong>tenidos multimedia<br />
existe <strong>de</strong>s<strong>de</strong> los inicios <strong>de</strong> la computación, a mediados <strong>de</strong>l siglo pasado, si bien al<br />
principio tímidamente <strong>de</strong>bido a las limitaciones tecnológicas <strong>de</strong> la época y al alto coste<br />
que era necesario par alcanzar un rendimiento mínimamente aceptable, coste prohibitivo<br />
para los usuarios domésticos. Estas circunstancias unidas al hecho <strong>de</strong> que Internet no<br />
existía, hacían que esta área no pudiera ser comercialmente rentable. Durante los años<br />
sesenta y setenta los avances fueron mínimos.<br />
En la década <strong>de</strong> los ochenta se produjeron avances significativos en cuanto a la<br />
capacidad <strong>de</strong>l hardware, especialmente aumento <strong>de</strong> velocidad en los procesadores y
uses <strong>con</strong> mayor ancho <strong>de</strong> banda. A<strong>de</strong>más se redujeron costes, <strong>de</strong> forma que empezaron<br />
a aparecer usuarios domésticos <strong>con</strong> equipos capaces <strong>de</strong> reproducir <strong>con</strong>tenido<br />
multimedia. Sin embargo las re<strong>de</strong>s <strong>de</strong> or<strong>de</strong>nadores eran todavía muy limitadas y lentas,<br />
Internet aun estaba dando sus primeros pasos, así que la mayoría <strong>de</strong>l <strong>con</strong>tenido<br />
multimedia todavía se transmitía a través <strong>de</strong> medios no <strong>streaming</strong>, como disquetes o<br />
CD-ROMS.<br />
En los noventa se ha producido el gran salto tecnológico que ha permitido la<br />
expansión <strong>de</strong> los <strong>con</strong>tenidos multimedia a gran escala. En primer lugar las prestaciones<br />
<strong>de</strong> los equipos domésticos han aumentado <strong>de</strong> forma vertiginosa, tanto es así que<br />
<strong>con</strong>tinuamente aparecen nuevos mo<strong>de</strong>los <strong>de</strong> procesadores, memorias, etc. que <strong>de</strong>jan<br />
obsoletos a los mo<strong>de</strong>los anteriores en poco tiempo.<br />
Otro factor fundamental han sido las mejoras en las re<strong>de</strong>s y especialmente en<br />
Internet. No solo en cuanto a fiabilidad y ancho <strong>de</strong> banda, si no en cuanto a<br />
accesibilidad: hasta hace no muchos años su uso estaba generalmente limitado a<br />
<strong>de</strong>terminados ámbitos (universida<strong>de</strong>s, tecnología militar, investigación). A día <strong>de</strong> hoy<br />
Internet se ha expandido al ámbito doméstico, y cada día siguen aumentando tanto el<br />
número <strong>de</strong> usuarios como la velocidad <strong>de</strong> las <strong>con</strong>exiones. También ha <strong>con</strong>tribuido el uso<br />
<strong>de</strong> <strong>protocolo</strong>s y formatos estandarizados y bien <strong>con</strong>ocidos, esto es fundamental para que<br />
millones <strong>de</strong> usuarios puedan compartir y reproducir el mismo <strong>con</strong>tenido.<br />
Por último hay que señalar un factor que si bien no es tecnológico, es el que ha<br />
posibilitado el <strong>de</strong>sarrollo <strong>de</strong> todos los anteriores: la aparición <strong>de</strong>l negocio en Internet.<br />
Gracias a estos factores los usuarios domésticos pudieron empezar a <strong>de</strong>scargar y<br />
reproducir <strong>con</strong>tenidos multimedia. Sin embargo, pronto surgió una nueva necesidad.<br />
Los archivos <strong>de</strong> audio y ví<strong>de</strong>o eran cada vez más ricos y por lo tanto empezaron a<br />
ocupar más espacio. No había tecnologías <strong>de</strong> <strong>streaming</strong>, y era necesario tener todo el<br />
archivo grabado en disco antes <strong>de</strong> po<strong>de</strong>r hacer uso <strong>de</strong> él. Esto, en un entorno don<strong>de</strong> el<br />
ancho <strong>de</strong> banda es limitado, provocó que los tiempos <strong>de</strong> espera <strong>de</strong>scargando un archivo<br />
antes <strong>de</strong> po<strong>de</strong>r reproducirlo empezaran a ser cada vez mayores, acabando muchas veces<br />
<strong>con</strong> la paciencia <strong>de</strong>l usuario.
De ahí surgió el <strong>con</strong>cepto <strong>de</strong> audio y ví<strong>de</strong>o en tiempo real, y en los últimos años<br />
se ha producido una auténtica invasión <strong>de</strong> esta tecnología en la Web. Para el usuario ha<br />
supuesto un cambio radical, ya que un simple doble clic basta para empezar a ver u oír<br />
el archivo <strong>de</strong>seado <strong>de</strong> forma prácticamente inmediata. Por otra parte han aparecido<br />
necesida<strong>de</strong>s tecnológicas asociadas a este tipo <strong>de</strong> <strong>de</strong>manda, don<strong>de</strong> la capacidad y estado<br />
<strong>de</strong> la red tienen un fuerte impacto. Por ejemplo nuevos <strong>protocolo</strong>s <strong>de</strong> transmisión,<br />
nuevas formas más eficaces <strong>de</strong> comprimir la información para facilitar el <strong>streaming</strong> <strong>de</strong><br />
archivos muy gran<strong>de</strong>s, la aparición <strong>de</strong>l multicasting, que permite enviar la misma<br />
información a muchos usuarios simultáneamente sin tener que replicarla para cada uno<br />
<strong>de</strong> ellos y ahorrando por lo tanto ancho <strong>de</strong> banda, etc.<br />
La filosofía <strong>de</strong>l <strong>streaming</strong> es simple: dividir un archivo gran<strong>de</strong> en pequeños<br />
paquetes que se pue<strong>de</strong>n enviar <strong>de</strong> forma <strong>con</strong>tinua, para que el <strong>de</strong>stinatario pueda<br />
empezar a reproducir el archivo en cuanto llena su buffer <strong>de</strong> entrada. Los paquetes son<br />
almacenados únicamente el tiempo necesario para reproducirlos, y por lo tanto no<br />
quedan almacenados en el disco duro. A<strong>de</strong>más, el servidor <strong>de</strong>be ser capaz <strong>de</strong> informar<br />
previamente al cliente <strong>de</strong> los formatos <strong>de</strong> audio y ví<strong>de</strong>o que va a utilizar, para que el<br />
cliente pueda <strong>de</strong>scomprimir y reproducir el <strong>con</strong>tenido correctamente. Por otra parte el<br />
<strong>con</strong>tenido origen no tiene que ser necesariamente un archivo almacenado localmente, si<br />
no que pue<strong>de</strong> ser una fuente <strong>de</strong> captura en tiempo real. En este sentido, es necesario<br />
diferenciar entre dos tipos <strong>de</strong> <strong>streaming</strong>:<br />
• Streaming en vivo: el <strong>con</strong>tenido multimedia es capturado y enviado<br />
inmediatamente. Un ejemplo claro sería una vi<strong>de</strong>o<strong>con</strong>ferencia.<br />
• Streaming bajo <strong>de</strong>manda: el <strong>con</strong>tenido está previamente almacenado en algún<br />
servidor, y el usuario <strong>de</strong>ci<strong>de</strong> cuando visualizarlo.<br />
El <strong>streaming</strong> ha abierto una amplia gama <strong>de</strong> posibilida<strong>de</strong>s en Internet y las<br />
telecomunicaciones en general, y su presencia sigue aumentando. Algunos ejemplos<br />
son:<br />
• Desarrollo nuevas formas <strong>de</strong> televisión que incluyan <strong>streaming</strong> mezclando<br />
imágenes reales <strong>con</strong> ficticias, y la composición <strong>de</strong> historias <strong>con</strong> texto, fotografía,<br />
audio y vi<strong>de</strong>o, ya sea <strong>con</strong> fines educativos o <strong>de</strong> entretenimiento.
• Vi<strong>de</strong>o<strong>con</strong>ferencias en forma <strong>de</strong> vi<strong>de</strong>o presencial o <strong>con</strong>ferencias pregrabadas para<br />
audiencias en Internet o Intranet. Telemedicina.<br />
• Vi<strong>de</strong>opresentaciones en diapositivas acompañadas <strong>de</strong> una narración en audio.<br />
• Karaoke o canciones para mezclas <strong>de</strong> MIDI (Interfaz Digital <strong>de</strong> Instrumentos<br />
Musicales), <strong>con</strong> animación y texto <strong>de</strong> referencia. Sesión en vivo <strong>de</strong> MIDI, a<br />
través <strong>de</strong>l teclado o <strong>de</strong> aparatos <strong>de</strong> percusión vía Internet.<br />
• Programas <strong>de</strong> vi<strong>de</strong>o dinámicos para aumentar la capacitación en diferentes<br />
<strong>de</strong>partamentos <strong>de</strong> una empresa.<br />
• Presentaciones <strong>de</strong> <strong>streaming</strong> en Power Point.<br />
El <strong>streaming</strong>, es un área <strong>de</strong> la informática en <strong>con</strong>stante evolución. Hay varias<br />
tecnologías <strong>de</strong> <strong>streaming</strong>, y <strong>con</strong>tinúan apareciendo otras nuevas, <strong>de</strong> forma que no hay<br />
una única aplicación que permita reproducir cualquier <strong>con</strong>tenido. A<strong>de</strong>más,<br />
<strong>con</strong>tinuamente se <strong>de</strong>sarrollan nuevos formatos <strong>de</strong> compresión y <strong>de</strong>scompresión que<br />
aumentan la eficacia <strong>de</strong> las transmisiones y ahorran ancho <strong>de</strong> banda, obligando al<br />
usuario a actualizarse para po<strong>de</strong>r ver los últimos ví<strong>de</strong>os. Esto, unido a la importancia<br />
creciente <strong>de</strong>l <strong>streaming</strong> en Internet, <strong>con</strong>duce a la <strong>con</strong>clusión <strong>de</strong> que es un área que<br />
merece la pena investigar.<br />
Por último cabe señalar que la popularización <strong>de</strong>l <strong>streaming</strong> ha <strong>con</strong>llevado la<br />
aparición <strong>de</strong> ciertas cuestiones sociales y legales. Por ejemplo, la distribución <strong>de</strong><br />
<strong>con</strong>tenido ina<strong>de</strong>cuado o <strong>con</strong> <strong>de</strong>rechos <strong>de</strong> autor. Algunos sectores comerciales temen que<br />
se puedan producir pérdidas e<strong>con</strong>ómicas al po<strong>de</strong>r los usuarios acce<strong>de</strong>r a casi cualquier<br />
<strong>con</strong>tenido <strong>de</strong> forma gratuita <strong>de</strong>s<strong>de</strong> sus casas, y evitando ver los mensajes publicitarios al<br />
po<strong>de</strong>r manejar la reproducción a su antojo. De hecho los productores <strong>de</strong> <strong>streaming</strong><br />
vienen tratando <strong>de</strong> impedir que los usuarios puedan grabar en disco los ví<strong>de</strong>os que están<br />
visualizando, tanto por medios técnicos como legales. Sin embargo, estas medidas<br />
pue<strong>de</strong>n ser habitualmente burladas. La legislación ha tenido que ponerse al día, en<br />
cuanto a temas <strong>de</strong> <strong>de</strong>rechos <strong>de</strong> autor, patentes y licencias.
2. Objetivos<br />
El objetivo <strong>de</strong> este proyecto es la implementación <strong>de</strong> un servidor <strong>de</strong> <strong>streaming</strong>.<br />
Se <strong>de</strong>sarrollará un servidor que esperará <strong>con</strong>exiones <strong>de</strong> los clientes, y será capaz <strong>de</strong><br />
enviarles un flujo <strong>de</strong> <strong>streaming</strong> para que estos lo reproduzcan, usando algún tipo <strong>de</strong><br />
<strong>protocolo</strong> existente. Los clientes harán peticiones <strong>de</strong> <strong>streaming</strong> indicando el nombre <strong>de</strong><br />
la fuente o fichero <strong>de</strong>seado, y el servidor será capaz <strong>de</strong> informar al cliente <strong>de</strong>l tipo <strong>de</strong><br />
multimedia que se va a enviar, y luego transmitir un flujo <strong>de</strong> datos coherente <strong>con</strong> lo<br />
anunciado. Por lo tanto, las tareas fundamentales que el servidor <strong>de</strong>be ser capaz <strong>de</strong><br />
acometer son:<br />
• Intercambio <strong>de</strong> mensajes <strong>con</strong> los clientes.<br />
• Ser capaz <strong>de</strong> obtener información sobre los formatos <strong>de</strong> los archivos que sirve.<br />
• Transmitir a los clientes la información sobre dichos formatos.<br />
• Transmitir a los clientes el propio flujo <strong>de</strong> <strong>streaming</strong>.<br />
Hay que señalar que los objetivos <strong>con</strong>cretos en cuanto a funcionalidad que <strong>de</strong>be<br />
cumplir el servidor no están claros al inicio <strong>de</strong>l <strong>de</strong>sarrollo (posibilidad <strong>de</strong> pausar la<br />
transmisión, saltar a un punto <strong>de</strong>terminado <strong>de</strong>l archivo, etc.) Esto es <strong>de</strong>bido a que se<br />
parte <strong>de</strong> un <strong>de</strong>s<strong>con</strong>ocimiento <strong>de</strong> las capacida<strong>de</strong>s que ofrecen las actuales tecnologías <strong>de</strong><br />
<strong>streaming</strong> para los <strong>de</strong>sarrolladores. Por lo tanto, se ha realizado una labor <strong>de</strong><br />
investigación <strong>de</strong> algunas <strong>de</strong> estas tecnologías y se ha tratado <strong>de</strong> añadir toda la<br />
funcionalidad que ha sido posible. Sin embargo, po<strong>de</strong>mos señalar algunos requisitos<br />
básicos que se ha <strong>con</strong>si<strong>de</strong>rado que el servidor <strong>de</strong>be cumplir en cualquier caso:<br />
• Modularidad: esta es la principal característica que se preten<strong>de</strong> incorporar en el<br />
servidor. El servidor no usará una única tecnología para la obtención <strong>de</strong> la<br />
información sobre los archivos y la creación <strong>de</strong>l flujo <strong>de</strong> <strong>streaming</strong>, si no que<br />
será <strong>con</strong>figurable, <strong>de</strong> forma que se puedan implementar diversas soluciones y<br />
elegir cuales <strong>de</strong> ellas utilizar al arrancar el servidor.
• Extensibilidad: al hilo <strong>de</strong> la característica anterior, se implementará el servidor<br />
<strong>de</strong> forma que en un futuro sea fácil añadir nuevos módulos. Esta característica y<br />
la anterior son especialmente <strong>de</strong>seables, dado el carácter dinámico <strong>de</strong> las<br />
tecnologías <strong>de</strong> <strong>streaming</strong>.<br />
• Compatibilidad: el servidor <strong>de</strong>be ser capaz <strong>de</strong> interoperar <strong>con</strong> varios clientes<br />
diferentes, que serán reproductores multimedia habituales. Más <strong>con</strong>cretamente<br />
<strong>de</strong>berá ser compatible <strong>con</strong> los reproductores VLC y QuickTime, <strong>de</strong> los que se<br />
hablará más a<strong>de</strong>lante.<br />
• Calidad <strong>de</strong> servicio: en la medida <strong>de</strong> lo posible la calidad <strong>de</strong> la reproducción en<br />
los clientes <strong>de</strong>be ser óptima, siendo la imagen y sonido fieles a los originales y<br />
no produciéndose retardos excesivos ni ralentizaciones.<br />
• Escalabilidad: el servidor <strong>de</strong>be ser capaz <strong>de</strong> aten<strong>de</strong>r a varios clientes<br />
simultáneamente.<br />
• Capacidad <strong>de</strong> servir ficheros almacenados localmente: el objetivo principal<br />
es que el cliente pueda reproducir los ficheros que el servidor tiene almacenados<br />
en su disco duro (ví<strong>de</strong>o bajo <strong>de</strong>manda).
3. Descripción informática<br />
3.1. Multimedia<br />
En el presente documento se habla <strong>de</strong> archivos y <strong>con</strong>tenido multimedia, y si bien<br />
las nociones básicas <strong>de</strong> este <strong>con</strong>cepto son ampliamente <strong>con</strong>ocidas, llegado este punto<br />
<strong>con</strong>viene <strong>de</strong>finir más formalmente algunas <strong>de</strong> sus características.<br />
Un <strong>con</strong>tenido multimedia es aquel que está compuesto <strong>de</strong> diversos “medios”,<br />
como pue<strong>de</strong>n ser audio, vi<strong>de</strong>o, texto, etc. Se dice que un <strong>con</strong>tenido multimedia está<br />
basado en el tiempo en tanto que cada uno <strong>de</strong> sus medios cambia significativamente <strong>con</strong><br />
él. Esta característica hace que un <strong>con</strong>tenido multimedia requiera ser proporcionado y<br />
procesado en unas <strong>con</strong>diciones temporales estrictas. Por ejemplo cuando se reproduce<br />
un vi<strong>de</strong>o, si los datos multimedia no pue<strong>de</strong>n ser proporcionados lo suficientemente<br />
rápido pue<strong>de</strong>n producirse pausas y retardos en la reproducción; por otro lado si los datos<br />
no pue<strong>de</strong>n ser recibidos y procesados lo suficientemente rápido el vi<strong>de</strong>o se reproduce a<br />
saltos ya que se <strong>de</strong>sechan cuadros como mecanismo para mantener la tasa <strong>de</strong><br />
reproducción. A <strong>con</strong>tinuación se enumeran los principales elementos que componen el<br />
<strong>con</strong>tenido multimedia, <strong>con</strong>viene que el lector se familiarice <strong>con</strong> ellos porque serán<br />
usados a lo largo <strong>de</strong> todo el documento.<br />
• Pista (track): Cada uno <strong>de</strong> los medios <strong>de</strong> los que se compone un <strong>con</strong>tenido<br />
multimedia. Por ejemplo un <strong>con</strong>tenido multimedia correspondiente a una<br />
vi<strong>de</strong>o<strong>con</strong>ferencia pue<strong>de</strong> <strong>con</strong>tener una pista <strong>de</strong> audio y otra <strong>de</strong> ví<strong>de</strong>o. Se dice que<br />
las pistas que componen un <strong>con</strong>tenido multimedia están multiplexadas. Al<br />
proceso <strong>de</strong> extracción <strong>de</strong> las distintas pistas que componen un <strong>con</strong>tenido<br />
multimedia se le <strong>de</strong>nomina <strong>de</strong>multiplexación.<br />
• Formato (format): cada pista posee un formato que <strong>de</strong>fine como están<br />
estructurados los datos que forman parte <strong>de</strong> ella. Los distintos formatos se<br />
distinguen en función <strong>de</strong>:
o La calidad que proporcionan<br />
o Su exigencia <strong>de</strong> recursos <strong>de</strong> CPU para ser procesados<br />
o La cantidad <strong>de</strong> ancho <strong>de</strong> banda requerida para su transmisión<br />
Cada formato está <strong>de</strong>stinado a diferentes tipos <strong>de</strong> aplicaciones y<br />
servicios. Formatos como MPEG 1 <strong>de</strong> gran calidad pero altos requerimientos <strong>de</strong><br />
ancho <strong>de</strong> banda están <strong>de</strong>stinados usualmente a aplicaciones que trabajan <strong>con</strong><br />
almacenamiento local o en dispositivos ópticos como CD-ROM o DVD don<strong>de</strong> el<br />
ancho <strong>de</strong> banda y la capacidad <strong>de</strong> almacenamiento no son limitantes. En cambio<br />
otros formatos como H.261 y H.263 se usan para aplicaciones <strong>de</strong><br />
vi<strong>de</strong>o<strong>con</strong>ferencia don<strong>de</strong> el ancho <strong>de</strong> banda es un bien escaso; <strong>de</strong> la misma forma<br />
G.723 se usa para producir voz codificada <strong>con</strong> tasa <strong>de</strong> bits reducida para<br />
aplicaciones <strong>de</strong> telefonía IP, por ejemplo.<br />
• Contenedor (<strong>con</strong>tainer o <strong>con</strong>tent-type): es la estructura en que los datos son<br />
enviados o almacenados, en el segundo caso irán asociados a una extensión <strong>de</strong><br />
archivo. Cada tipo <strong>de</strong> <strong>con</strong>tenedor pue<strong>de</strong> llevar <strong>de</strong>ntro pistas en diferentes<br />
formatos, y ser manejado por unas u otras herramientas. Algunos ejemplos <strong>de</strong><br />
<strong>con</strong>tenedores habituales son AVI, MP3, WAV, MPG o 3GP, entre otros.<br />
• Transcodificación (transcoding): es el proceso <strong>con</strong>sistente en cambiar el<br />
formato <strong>de</strong> una pista. Para <strong>con</strong>seguirlo se usan los co<strong>de</strong>cs (códificadores-<br />
<strong>de</strong>codificadores), que son programas que incorporan algoritmos capaces <strong>de</strong><br />
hacerlo. Cada tipo <strong>de</strong> co<strong>de</strong>c pue<strong>de</strong> manejar ciertos formatos <strong>de</strong> entrada y salida.<br />
• Ren<strong>de</strong>rización: es el proceso mediante el cual se presenta el multimedia al<br />
3.2. Java<br />
usuario. Normalmente implica la transferencia <strong>de</strong>l <strong>con</strong>tenido digital a algún<br />
dispositivo <strong>de</strong> salida como un monitor o altavoz.<br />
El lenguaje <strong>de</strong> programación elegido ha sido Java, al ser <strong>con</strong>si<strong>de</strong>rado la mejor<br />
opción para este proyecto. Java es un lenguaje multiplataforma, cuyos programas se<br />
pue<strong>de</strong>n ejecutar en cualquier sistema operativo que tenga instalada la máquina virtual <strong>de</strong><br />
Java. Sin embargo y como se verá más a<strong>de</strong>lante, habrá que <strong>con</strong>si<strong>de</strong>rar ciertas
circunstancias que nos obligarán a <strong>de</strong>cantarnos por un sistema operativo. Tiene ciertas<br />
características que le hacen ser a<strong>de</strong>cuado para el problema que se preten<strong>de</strong> resolver:<br />
• Simplicidad y alto nivel: es un lenguaje más sencillo que otras opciones como<br />
C++, y libera al programador <strong>de</strong> preocuparse <strong>de</strong> ciertas tareas <strong>de</strong> bajo nivel,<br />
como por ejemplo el uso <strong>de</strong> la memoria y el manejo <strong>de</strong> punteros.<br />
• Orientación a objetos: Java es un programa orientado a objetos, en el que la<br />
unidad principal <strong>de</strong> programación es la clase. Esta característica será útil para,<br />
tal y como se preten<strong>de</strong>, implementar un servidor <strong>de</strong> carácter <strong>modular</strong>. Por<br />
ejemplo si se <strong>de</strong>sea po<strong>de</strong>r generar un flujo <strong>de</strong> stream <strong>de</strong> varias maneras<br />
diferentes, habrá que <strong>de</strong>finir una interfaz (<strong>con</strong>junto <strong>de</strong> métodos que una clase<br />
<strong>de</strong>be implementar) y <strong>de</strong>spués implementar varias clases que cumplan la<br />
funcionalidad especificada en ella. A la hora <strong>de</strong> arrancar el servidor se podrá<br />
elegir entre alguna <strong>de</strong> estas clases, instanciando objetos a partir <strong>de</strong> ellas. A<strong>de</strong>más<br />
la orientación a objetos también facilita la escalabilidad, ya que si es necesario<br />
aten<strong>de</strong>r a varios clientes a la vez, esto será posible creando varias instancias <strong>de</strong><br />
las clases involucradas en el proceso.<br />
• Orientación a la red: la API <strong>de</strong> Java proporciona clases que facilitan el uso <strong>de</strong><br />
<strong>con</strong>exiones <strong>de</strong> red y el envío y recepción <strong>de</strong> datos a través <strong>de</strong> las mismas. En<br />
particular, los sockets.<br />
• Posibilidad <strong>de</strong> usar línea <strong>de</strong> comandos: Java permite la ejecución <strong>de</strong><br />
programas <strong>de</strong> forma similar a si lo hiciéramos escribiendo comandos a través <strong>de</strong><br />
una <strong>con</strong>sola <strong>de</strong>l sistema operativo. Como se verá posteriormente, esto<br />
posibilitará el uso <strong>de</strong> <strong>de</strong>terminadas aplicaciones <strong>de</strong> <strong>streaming</strong> ajenas a Java.<br />
La elección <strong>de</strong> Java tendrá como <strong>con</strong>secuencia la necesidad <strong>de</strong> elegir<br />
herramientas <strong>de</strong> <strong>de</strong>sarrollo que sean compatibles <strong>con</strong> este lenguaje <strong>de</strong> programación.<br />
Posteriormente en el capítulo sobre tecnologías <strong>de</strong> <strong>streaming</strong> se mencionarán algunas <strong>de</strong><br />
ellas.
3.3. Protocolos y tecnologías <strong>de</strong> <strong>streaming</strong><br />
En este capítulo se van a enumerar algunos <strong>de</strong> los <strong>protocolo</strong>s y tecnologías <strong>de</strong><br />
<strong>streaming</strong> existentes, repasando sus características principales. También se justificará<br />
por qué se han elegido algunos <strong>de</strong> ellos para la implementación <strong>de</strong>l servidor.<br />
3.3.1. Protocolos<br />
3.3.1.1. <strong>RTSP</strong><br />
El <strong>protocolo</strong> <strong>de</strong> flujo <strong>de</strong> datos en tiempo real (<strong>de</strong>l inglés Real Time Streaming<br />
Protocol) establece y <strong>con</strong>trola uno o varios flujos sincronizados <strong>de</strong> datos, ya sean <strong>de</strong><br />
audio o <strong>de</strong> ví<strong>de</strong>o. <strong>RTSP</strong> actúa como un mando a través <strong>de</strong> la red para servidores<br />
multimedia, y se sitúa en el nivel <strong>de</strong> aplicación <strong>de</strong>ntro <strong>de</strong>l mo<strong>de</strong>lo OSI 1 .<br />
<strong>RTSP</strong> es un <strong>protocolo</strong> no orientado a <strong>con</strong>exión, en lugar <strong>de</strong> esto el servidor<br />
almacena el estado asociado a las diferentes sesiones <strong>de</strong> los clientes, y para diferenciar<br />
dichas sesiones se usa un i<strong>de</strong>ntificador <strong>de</strong> sesión. Debido a esto en el transcurso <strong>de</strong> una<br />
sesión <strong>RTSP</strong> un cliente pue<strong>de</strong> abrir y cerrar varias <strong>con</strong>exiones a nivel <strong>de</strong> transporte, sin<br />
que la sesión <strong>RTSP</strong> se vea afectada.<br />
Es a<strong>de</strong>más un <strong>protocolo</strong> <strong>de</strong> carácter textual, es <strong>de</strong>cir que los mensajes están<br />
formados por ca<strong>de</strong>nas <strong>de</strong> caracteres en texto plano (estándar UTF-8). Esto ofrece varias<br />
ventajas, como la posibilidad <strong>de</strong> añadir nuevos parámetros fácilmente, teniendo en<br />
cuenta a<strong>de</strong>más que los parámetros son auto-explicativos, gracias al uso <strong>de</strong> palabras que<br />
<strong>de</strong>scriben su función. Como el número <strong>de</strong> parámetros es pequeño y la frecuencia en el<br />
envío <strong>de</strong> mensajes es baja, la eficiencia no resulta un problema.<br />
Estas son sus principales propieda<strong>de</strong>s:<br />
1 El mo<strong>de</strong>lo OSI es una <strong>de</strong>scripción abstracta y por capas <strong>de</strong> los <strong>protocolo</strong>s <strong>de</strong> comunicaciones en las<br />
re<strong>de</strong>s <strong>de</strong> or<strong>de</strong>nadores.
• Seguridad: <strong>RTSP</strong> reutiliza mecanismos <strong>de</strong> seguridad. Todas las formas <strong>de</strong><br />
autentificación HTTP son directamente aplicables.<br />
• In<strong>de</strong>pen<strong>de</strong>ncia <strong>de</strong>l <strong>protocolo</strong> <strong>de</strong> transporte: <strong>RTSP</strong> pue<strong>de</strong> usar indistintamente<br />
<strong>protocolo</strong>s <strong>de</strong> datagrama no fiables (UDP) o fiables (RDP, no muy extendido) o<br />
un <strong>protocolo</strong> fiable orientado a <strong>con</strong>exión como TCP.<br />
• Capacidad multi-servidor: cada flujo multimedia <strong>de</strong>ntro <strong>de</strong> una presentación<br />
pue<strong>de</strong> residir en servidores diferentes, el cliente automáticamente establece<br />
varías sesiones <strong>con</strong>currentes <strong>de</strong> <strong>con</strong>trol <strong>con</strong> los diferentes servidores y la<br />
sincronización la lleva a término la capa <strong>de</strong> transporte.<br />
• Posibilidad <strong>de</strong> <strong>con</strong>trolar dispositivos <strong>de</strong> grabación: el <strong>protocolo</strong> pue<strong>de</strong><br />
<strong>con</strong>trolar dispositivos <strong>de</strong> grabación y reproducción, por ejemplo cámaras IP<br />
<strong>RTSP</strong>.<br />
• A<strong>de</strong>cuado para aplicaciones profesionales: <strong>RTSP</strong> soporta resolución a nivel <strong>de</strong><br />
frame 2 mediante marcas temporales SMPTE 3 para permitir edición digital.<br />
Hay que resaltar que <strong>RTSP</strong> es únicamente un <strong>protocolo</strong> <strong>de</strong> <strong>con</strong>trol, y el envío <strong>de</strong><br />
los datos <strong>de</strong> <strong>streaming</strong> se <strong>de</strong>berá realizar mediante algún otro <strong>protocolo</strong> <strong>de</strong>stinado a tal<br />
efecto. En la mayoría <strong>de</strong> los casos <strong>RTSP</strong> usará TCP como <strong>protocolo</strong> <strong>de</strong> transporte, y el<br />
<strong>protocolo</strong> para la transmisión usará UDP. A <strong>con</strong>tinuación se muestra un ejemplo <strong>de</strong><br />
mensaje <strong>RTSP</strong>:<br />
DESCRIBE rtsp://193.147.59.231:10000/vi<strong>de</strong>o.mp4 <strong>RTSP</strong>/1.0<br />
CSeq: 1<br />
Accept: application/sdp<br />
Bandwidth: 384000<br />
Accept-Language: en-US<br />
Intencionadamente el <strong>protocolo</strong> es similar en sintaxis y operación a HTTP <strong>de</strong><br />
forma que los mecanismos <strong>de</strong> expansión añadidos a HTTP pue<strong>de</strong>n en muchos casos<br />
2 Una frame es una imagen in<strong>de</strong>pendiente que forma parte <strong>de</strong> una animación. Aunque la traducción en<br />
castellano significa literalmente “fotograma”, también pue<strong>de</strong> aplicarse al sonido.<br />
3 Las marcas SMPTE (Society of Motion Picture and Television Engineers) se usan para etiquetar frames<br />
individuales <strong>de</strong> un <strong>con</strong>tenido multimedia <strong>con</strong> códigos <strong>de</strong> tiempo.
añadirse a <strong>RTSP</strong>. Los códigos <strong>de</strong> estado son muy parecidos, valga como ejemplo el<br />
familiar ‘404 Not Found’ que todos hemos visto en nuestro navegador alguna vez. En<br />
cualquier caso <strong>RTSP</strong> difiere en un número significativo <strong>de</strong> aspectos <strong>de</strong> HTTP:<br />
• <strong>RTSP</strong> introduce nuevos métodos y tiene un i<strong>de</strong>ntificador <strong>de</strong> <strong>protocolo</strong> diferente.<br />
• Un servidor <strong>RTSP</strong> necesita mantener el estado <strong>de</strong> la <strong>con</strong>exión al <strong>con</strong>trario que<br />
HTTP.<br />
• Tanto el servidor como el cliente pue<strong>de</strong>n lanzar peticiones (aunque el cliente<br />
solo pue<strong>de</strong> lanzar peticiones en el caso <strong>de</strong> las <strong>con</strong>exiones persistentes, esto es,<br />
cuando <strong>de</strong>ntro <strong>de</strong> una sesión <strong>RTSP</strong> no se producen múltiples <strong>con</strong>exiones a nivel<br />
<strong>de</strong> la capa <strong>de</strong> transporte).<br />
• Los datos son transportados por un <strong>protocolo</strong> diferente.<br />
Dadas sus características el <strong>protocolo</strong> <strong>RTSP</strong> se usa fundamentalmente en tres<br />
<strong>con</strong>textos diferentes:<br />
• Invitación <strong>de</strong> un servidor multimedia a una <strong>con</strong>ferencia: Un servidor pue<strong>de</strong> ser<br />
invitado a unirse a una <strong>con</strong>ferencia existente en lugar <strong>de</strong> reproducir la<br />
presentación o grabar todo o una parte <strong>de</strong>l <strong>con</strong>tenido. Este modo es útil para<br />
aplicaciones <strong>de</strong> enseñanza distribuida dón<strong>de</strong> diferentes partes <strong>de</strong> la <strong>con</strong>ferencia<br />
van tomando parte en la discusión.<br />
• Adición multimedia a una presentación existente: Particularmente para<br />
presentaciones en vivo, útil si el servidor pue<strong>de</strong> avisar al cliente sobre los<br />
nuevos <strong>con</strong>tenidos disponibles.<br />
• Recuperar <strong>con</strong>tenidos multimedia <strong>de</strong>l servidor: Típicamente, el cliente pedirá al<br />
servidor datos sobre el <strong>con</strong>tenido multimedia <strong>de</strong>seado, y <strong>de</strong>spués especificará los<br />
parámetros <strong>de</strong> transporte para que el servidor envíe el flujo <strong>de</strong> stream al <strong>de</strong>stino<br />
correcto. El cliente pue<strong>de</strong> solicitar la <strong>de</strong>scripción <strong>de</strong> una presentación por HTTP<br />
o cualquier otro método. Si la presentación es multicast, la <strong>de</strong>scripción <strong>con</strong>tiene<br />
los puertos y las direcciones que serán usados. Si la presentación es unicast el<br />
cliente es el que proporciona el <strong>de</strong>stino por motivos <strong>de</strong> seguridad.
Tal y como reza el título <strong>de</strong>l proyecto, <strong>RTSP</strong> es el <strong>protocolo</strong> <strong>de</strong> <strong>con</strong>trol que se ha<br />
implementado en el servidor. Se ha <strong>con</strong>si<strong>de</strong>rado que es el más a<strong>de</strong>cuado para alcanzar<br />
los objetivos propuestos, fundamentalmente por dos razones. En primera lugar dadas<br />
sus características es el más a<strong>de</strong>cuado para la recuperación <strong>de</strong> <strong>con</strong>tenidos multimedia <strong>de</strong><br />
un servidor, como se menciona en el párrafo anterior. Por otra parte, existen varios<br />
reproductores multimedia domésticos que soportan el <strong>protocolo</strong>, como VLC y<br />
QuickTime. Cuando se abor<strong>de</strong> la implementación <strong>de</strong>l <strong>protocolo</strong> en el servidor se<br />
explicará su funcionamiento en <strong>de</strong>talle.
3.3.1.2. SIP<br />
Dentro <strong>de</strong>l campo <strong>de</strong> los <strong>protocolo</strong>s para el <strong>con</strong>trol <strong>de</strong> <strong>streaming</strong>, uno <strong>de</strong> los que<br />
más se pue<strong>de</strong> comparar <strong>con</strong> <strong>RTSP</strong> es SIP. El objetivo <strong>de</strong>l Session Initiation Protocol es<br />
la iniciación, modificación y finalización <strong>de</strong> sesiones interactivas <strong>de</strong> usuario don<strong>de</strong><br />
intervienen elementos multimedia como el vi<strong>de</strong>o, voz, mensajería instantánea, juegos<br />
online y realidad virtual. Es por tanto un <strong>protocolo</strong> <strong>de</strong> <strong>con</strong>trol cuya funcionalidad es<br />
similar a <strong>RTSP</strong>, y a<strong>de</strong>más también se parece a este que está basado en texto plano y es<br />
similar a HTTP.<br />
Es un <strong>protocolo</strong> <strong>de</strong>sarrollado por el IETF 4 , y en noviembre <strong>de</strong>l año 2000 fue<br />
aceptado como el <strong>protocolo</strong> <strong>de</strong> señalización <strong>de</strong> 3GPP 5 y elemento permanente <strong>de</strong> la<br />
arquitectura IMS 6 . SIP es a<strong>de</strong>más uno <strong>de</strong> los <strong>protocolo</strong>s <strong>de</strong> señalización para voz sobre<br />
IP.<br />
SIP funciona en colaboración <strong>con</strong> otros muchos <strong>protocolo</strong>s pero sólo interviene<br />
en la parte <strong>de</strong> negociación al establecer, modificar y finalizar la sesión <strong>de</strong> comunicación.<br />
En un uso normal, las sesiones SIP se apoyan en el <strong>protocolo</strong> RTP, que es el verda<strong>de</strong>ro<br />
portador para lo <strong>con</strong>tenidos <strong>de</strong> audio y ví<strong>de</strong>o. SIP es un es una alternativa a <strong>RTSP</strong> en el<br />
sentido <strong>de</strong> ser igualmente un <strong>protocolo</strong> <strong>de</strong> <strong>con</strong>trol, pero está más orientado a<br />
dispositivos móviles y por lo tanto <strong>RTSP</strong> es más a<strong>de</strong>cuado en nuestro caso.<br />
3.3.1.3. RTP<br />
4 El IETF (Internet Engineering Task Force) es una organización internacional <strong>de</strong> carácter abierto que<br />
tiene como objetivo <strong>con</strong>tribuir a la ingeniería <strong>de</strong> Internet. Sus miembros velan porque la arquitectura <strong>de</strong> la<br />
red y sus <strong>protocolo</strong>s técnicos funcionen correctamente. Es la organización que se <strong>con</strong>si<strong>de</strong>ra <strong>con</strong> más<br />
autoridad para establecer modificaciones <strong>de</strong> los parámetros técnicos bajo los que funciona la red.<br />
5 3GGP (3rd Generation Parthership Project) es un acuerdo <strong>de</strong> colaboración entre grupos <strong>de</strong><br />
comunicaciones, <strong>con</strong> el objetivo <strong>de</strong> <strong>con</strong>seguir una especificación <strong>de</strong> sistema global para todos los<br />
teléfonos móviles <strong>de</strong> tercera generación (3G).<br />
6 IMS (IP Multimedia Subsystem) es una arquitectura para el <strong>de</strong>sarrollo <strong>de</strong> <strong>protocolo</strong>s para dispositivos<br />
móviles que posibilite la transferencia <strong>de</strong> multimedia a través <strong>de</strong> Internet.
RTP son las siglas <strong>de</strong> Real-time Transport Protocol (Protocolo <strong>de</strong> Transporte <strong>de</strong><br />
Tiempo real). Es un <strong>protocolo</strong> <strong>de</strong> nivel <strong>de</strong> aplicación (no <strong>de</strong> nivel <strong>de</strong> transporte, como su<br />
nombre podría hacer pensar) utilizado para la transmisión <strong>de</strong> información en tiempo<br />
real, como por ejemplo audio y ví<strong>de</strong>o en una vi<strong>de</strong>o<strong>con</strong>ferencia. Se sitúa sobre UDP en<br />
el mo<strong>de</strong>lo OSI. Está <strong>de</strong>sarrollado por el grupo <strong>de</strong> trabajo <strong>de</strong> transporte <strong>de</strong> audio y vi<strong>de</strong>o<br />
<strong>de</strong>l IETF, publicado por primera vez como estándar en 1996 y actualizado<br />
posteriormente en 2003 mediante la RFC 3550, que <strong>con</strong>stituye el actual estándar.<br />
Inicialmente se publicó como <strong>protocolo</strong> multicast, aunque se ha usado en varias<br />
aplicaciones unicast. Se usa frecuentemente en sistemas <strong>de</strong> <strong>streaming</strong>, junto a <strong>RTSP</strong>,<br />
SIP, vi<strong>de</strong>o<strong>con</strong>ferencia y aplicaciones similares. Existe una extensión <strong>de</strong>l perfil <strong>de</strong> RTP<br />
llamada SRTP (Secure Real-time Transport Protocol) que se usa para <strong>con</strong>ferencias <strong>de</strong><br />
audio y ví<strong>de</strong>o en entornos que necesiten <strong>de</strong> <strong>con</strong>fi<strong>de</strong>ncialidad, autenticación <strong>de</strong> mensajes<br />
y protección <strong>de</strong> reenvío para flujos <strong>de</strong> audio y ví<strong>de</strong>o.<br />
Va <strong>de</strong> la mano <strong>de</strong>l <strong>protocolo</strong> RTCP (RTP Control Protocol), este es un <strong>protocolo</strong><br />
<strong>de</strong> comunicación que proporciona información <strong>de</strong> <strong>con</strong>trol que está asociado <strong>con</strong> un flujo<br />
<strong>de</strong> datos para una aplicación multimedia (flujo RTP). Trabaja junto <strong>con</strong> RTP en el<br />
transporte y empaquetado <strong>de</strong> datos multimedia, pero no transporta ningún dato por sí<br />
mismo. Se usa habitualmente para transmitir paquetes <strong>de</strong> <strong>con</strong>trol a los participantes <strong>de</strong><br />
una sesión RTP, siendo su función principal la <strong>de</strong> informar <strong>de</strong> la calidad <strong>de</strong> servicio<br />
proporcionada por RTP. Este <strong>protocolo</strong> recoge estadísticas <strong>de</strong> la <strong>con</strong>exión y también<br />
información como por ejemplo bytes enviados, paquetes enviados o paquetes perdidos<br />
entre otros. Una aplicación pue<strong>de</strong> usar esta información para incrementar la calidad <strong>de</strong><br />
servicio, ya sea limitando el flujo o usando un co<strong>de</strong>c <strong>de</strong> compresión diferente. RTCP por<br />
sí mismo no ofrece ninguna clase <strong>de</strong> cifrado <strong>de</strong> flujo o <strong>de</strong> autenticación. Para tales<br />
propósitos se pue<strong>de</strong> usar una extensión llamada SRTCP. A partir <strong>de</strong> este punto, siempre<br />
que se hable <strong>de</strong> RTP se estará haciendo referencia implícitamente al binomio <strong>de</strong><br />
<strong>protocolo</strong>s RTP/RTCP.<br />
3.3.1.3.1. Arquitectura RTP
Una sesión RTP es la asociación <strong>de</strong> un <strong>con</strong>junto <strong>de</strong> aplicaciones que se<br />
comunican a través <strong>de</strong> RTP. Un participante <strong>de</strong> la sesión se i<strong>de</strong>ntifica mediante una<br />
dirección <strong>de</strong> red y un par <strong>de</strong> puertos. El primero se usará para los paquetes <strong>de</strong> datos<br />
(RTP) y el segundo para los paquetes <strong>de</strong> <strong>con</strong>trol (RTCP), siendo siempre el primero un<br />
número par y el segundo un número impar. Los participantes pue<strong>de</strong>n enviar datos,<br />
recibirlos o enviar y recibir a la vez. Cada tipo <strong>de</strong> <strong>con</strong>tenido es transmitido en sesiones<br />
diferentes. Por ejemplo si en una vi<strong>de</strong>o<strong>con</strong>ferencia se usan a la vez audio y vi<strong>de</strong>o, se<br />
usará una sesión separada para cada uno <strong>de</strong> ellos. Esto ofrece la posibilidad a los<br />
clientes <strong>de</strong> elegir qué tipos <strong>de</strong> <strong>con</strong>tenidos quieren recibir. Por ejemplo un cliente <strong>con</strong><br />
ancho <strong>de</strong> banda escaso, podría preferir la opción <strong>de</strong> recibir solo el sonido <strong>de</strong> la<br />
vi<strong>de</strong>o<strong>con</strong>ferencia.<br />
El <strong>con</strong>tenido es enviado en forma <strong>de</strong> flujos <strong>de</strong> paquetes <strong>de</strong> datos. Cada paquete<br />
<strong>con</strong>sta <strong>de</strong> dos partes: una cabecera estructurada y los propios datos. En la figura 3.1 se<br />
pue<strong>de</strong> ver el esquema <strong>de</strong> un paquete RTP.<br />
Figura 3.1: paquete RTP<br />
Hay varias cabeceras y no tiene sentido analizar la estructura <strong>de</strong> los paquetes a<br />
muy bajo nivel, baste señalar que algunas <strong>de</strong> las cabeceras incluyen números <strong>de</strong><br />
secuencia, etiquetas <strong>de</strong> tiempo para tareas <strong>de</strong> sincronización y un flag para indicar el<br />
tipo <strong>de</strong> <strong>con</strong>tenido.
3.3.1.3.2. Alternativas a RTP<br />
Existen algunas alternativas a RTP para la transferencia <strong>de</strong> <strong>streaming</strong>, si bien<br />
ninguna es realmente parecida. El <strong>protocolo</strong> HTTP pue<strong>de</strong> ser usado tanto para la<br />
negociación como para la transmisión <strong>de</strong> la información, aunque su principal cometido<br />
es la petición y respuesta <strong>de</strong> páginas HTML. También se pue<strong>de</strong> mencionar el <strong>protocolo</strong><br />
MMS (Microsoft Media Services), que el reproductor Windows Media Player utiliza<br />
para tareas <strong>de</strong> <strong>streaming</strong> en unicast. Este <strong>protocolo</strong> acabó cayendo en <strong>de</strong>suso, y<br />
finalmente Microsoft <strong>de</strong>jó <strong>de</strong> darle soporte <strong>con</strong> la aparición <strong>de</strong>l Windows Media Player<br />
11 en el año 2006.<br />
RTP es claramente la mejor alternativa, <strong>de</strong> hecho es prácticamente la única para<br />
usar junto <strong>con</strong> <strong>protocolo</strong>s <strong>de</strong> <strong>con</strong>trol como <strong>RTSP</strong> o SIP. La mayoría <strong>de</strong> reproductores<br />
multimedia soportan el <strong>protocolo</strong>, y es el más extendido para <strong>streaming</strong> en Internet.<br />
A<strong>de</strong>más existen tecnologías accesibles que permiten a los <strong>de</strong>sarrolladores la creación y<br />
recepción <strong>de</strong> flujos RTP, algunas <strong>de</strong> esas tecnologías se usarán en la implementación <strong>de</strong>l<br />
servidor.
3.3.1.3. SDP<br />
El Session Description Protocol (SDP), es un <strong>protocolo</strong> para <strong>de</strong>scribir los<br />
parámetros <strong>de</strong> inicialización <strong>de</strong> los flujos multimedia. Fue publicado por el IETF en el<br />
RFC 2327. Es un <strong>protocolo</strong> textual, y se pue<strong>de</strong> usar en <strong>con</strong>junción <strong>con</strong> <strong>RTSP</strong> o SIP para<br />
informar al cliente <strong>de</strong> las características <strong>de</strong>l flujo <strong>de</strong> <strong>streaming</strong> que se va a enviar, tanto<br />
en lo referente al <strong>con</strong>tenido como a la manera en que se va a transmitir.<br />
Más <strong>con</strong>cretamente, un SDP <strong>con</strong>siste en una ca<strong>de</strong>na <strong>de</strong> texto don<strong>de</strong> se informa<br />
<strong>de</strong> las pistas disponibles, en qué formato se encuentran, y otros parámetros relacionados<br />
<strong>con</strong> el <strong>con</strong>tenido, como por ejemplo la duración. Con esta información los clientes<br />
tendrán <strong>con</strong>stancia <strong>de</strong> las pistas disponibles y qué formato, pudiendo seleccionar las que<br />
<strong>de</strong>seen y elegir los co<strong>de</strong>cs a<strong>de</strong>cuados para que la reproducción sea correcta. Si el<br />
reproductor no dispone <strong>de</strong> ellos, <strong>de</strong>bería <strong>de</strong>sistir. A <strong>con</strong>tinuación se muestra un ejemplo<br />
<strong>de</strong> SDP.<br />
v=0<br />
o=- 5710093000 3 IN IP4 193.147.59.231<br />
c=IN IP4 0.0.0.0<br />
t=0 0<br />
a=tool:vlc 0.8.6a<br />
a=range:npt=0-151.700<br />
m=vi<strong>de</strong>o 0 RTP/AVP 32<br />
a=rtpmap:32 MPV/90000<br />
a=<strong>con</strong>trol:rtsp://193.147.59.231:10000/intro.mpg/trackID=0<br />
m=audio 0 RTP/AVP 14<br />
a=rtpmap:14 MPA/90000<br />
a=<strong>con</strong>trol:rtsp://193.147.59.231:10000/intro.mpg/trackID=1<br />
Para compren<strong>de</strong>r la estructura <strong>de</strong>l SDP se mencionará el significado <strong>de</strong> algunas<br />
<strong>de</strong> las líneas <strong>de</strong> texto. El texto a=range:npt=0-151.700 indica que el SDP correspon<strong>de</strong><br />
a un archivo que tiene una duración <strong>de</strong> 151.7 segundos. Las tres siguientes líneas<br />
informan <strong>de</strong> la existencia <strong>de</strong> una pista <strong>de</strong> ví<strong>de</strong>o, que será transmitida por RTP. Se<br />
proporciona información sobre su formato, y finalmente la URL <strong>de</strong> <strong>con</strong>trol asociada a<br />
ella. Por último se informa análogamente sobre las características <strong>de</strong> la pista <strong>de</strong> audio<br />
disponible.<br />
SDP será el <strong>protocolo</strong> usado para anunciar a los clientes las características <strong>de</strong> los<br />
<strong>con</strong>tenidos multimedia que ofrecerá el servidor <strong>RTSP</strong>.
3.3.2. Tecnologías para la creación <strong>de</strong> <strong>streaming</strong> RTP<br />
Se han elegido los <strong>protocolo</strong>s <strong>RTSP</strong> y SDP para el <strong>con</strong>trol <strong>de</strong> las sesiones <strong>de</strong><br />
<strong>streaming</strong> y la <strong>de</strong>scripción <strong>de</strong> los <strong>con</strong>tenidos. Dado el carácter textual <strong>de</strong> ambos, su<br />
implementación en el servidor se hará <strong>de</strong> forma manual. La tercera pieza <strong>de</strong>l servidor es<br />
la generación <strong>de</strong> datos RTP, y en este caso será necesaria la utilización <strong>de</strong> alguna<br />
tecnología que lo permita. En este capítulo se <strong>de</strong>scriben las características principales <strong>de</strong><br />
algunas <strong>de</strong> estas tecnologías, incluyendo las que finalmente se van a usar<br />
3.3.2.1. Java Media Framework<br />
Java Media Framework (JMF a partir <strong>de</strong> ahora) es una interfaz <strong>de</strong> programación<br />
<strong>de</strong> aplicaciones, (API por sus siglas en inglés). Es un paquete opcional que no forma<br />
parte <strong>de</strong> la plataforma estándar <strong>de</strong> Java, y permite a los <strong>de</strong>sarrolladores añadir a sus<br />
programas en java el manejo <strong>de</strong> <strong>con</strong>tenido multimedia. Con esta API es posible realizar<br />
varias tareas <strong>con</strong> el <strong>con</strong>tenido multimedia: capturar, reproducir, grabar y por último y<br />
más importante para este proyecto, crear flujos <strong>de</strong> <strong>streaming</strong>. A<strong>de</strong>más <strong>de</strong> forma<br />
simultánea a estas tareas es capaz <strong>de</strong> realizar funciones <strong>de</strong> procesamiento, como por<br />
ejemplo cambiar el formato <strong>de</strong> las pistas. Es una API gratuita pero no libre.<br />
Los principales objetivos <strong>de</strong> JMF son:<br />
• Ser fácil <strong>de</strong> programar.<br />
• Permitir la captura <strong>de</strong> datos multimedia.<br />
• Permitir el <strong>de</strong>sarrollo <strong>de</strong> aplicaciones <strong>de</strong> <strong>streaming</strong> y <strong>con</strong>ferencia.<br />
Específicamente, uno <strong>de</strong> los principales objetivos <strong>de</strong> JMF es permitir la<br />
transmisión y recepción <strong>de</strong> <strong>streaming</strong> usando el <strong>protocolo</strong> RTP.<br />
• Permitir a los <strong>de</strong>sarrolladores avanzados crear soluciones personalizadas a partir<br />
<strong>de</strong> la API existente, integrando fácilmente nuevas características.<br />
• Proporcionar acceso a los datos multimedia en crudo (sin formato).
• Permitir el <strong>de</strong>sarrollo <strong>de</strong> elementos personalizados a través <strong>de</strong> plugins<br />
(multiplexadores/<strong>de</strong>multiplexadores, co<strong>de</strong>cs, ren<strong>de</strong>rizadores, etc.<br />
La primera versión apareció en 1997 y las últimas modificaciones por parte <strong>de</strong><br />
Sun Microsystems fueron añadidas en 2004. A día <strong>de</strong> hoy esto <strong>de</strong>nota cierto abandono,<br />
pero sigue siendo una herramienta válida usada por muchos <strong>de</strong>sarrolladores, y prueba <strong>de</strong><br />
ello es la actividad que hay en los foros <strong>de</strong> Internet. A<strong>de</strong>más <strong>de</strong> la propia API, se<br />
incluyen una serie <strong>de</strong> herramientas adicionales:<br />
• JMStudio: un reproductor básico <strong>con</strong> interfaz gráfica. Ha sido especialmente<br />
útil durante el <strong>de</strong>sarrollo porque permite abrir y reproducir un flujo <strong>de</strong> <strong>streaming</strong><br />
vía RTP, especificando la dirección IP y puerto correspondiente. Con esto es<br />
posible comprobar en un momento dado si se está creando un flujo <strong>de</strong> RTP, ya<br />
sea <strong>con</strong> el propio JMF u otra herramienta, siempre que el formato pueda ser<br />
reproducido.<br />
• JMFRegistry: una interfaz gráfica para gestionar las características <strong>de</strong> JMF,<br />
como preferencias y plugins.<br />
• JMFCustomizer: herramienta para crear archivos personalizados JAR (tipo <strong>de</strong><br />
archivo que permite ejecutar aplicaciones escritas en Java), únicamente <strong>con</strong> las<br />
clases JMF necesarias, permitiendo así a los <strong>de</strong>sarrolladores crear aplicaciones<br />
más reducidas. No se ha usado en este proyecto.<br />
• JMFInit: herramienta para el <strong>con</strong>trol <strong>de</strong> los dispositivos <strong>de</strong> captura audio y<br />
ví<strong>de</strong>o.<br />
A<strong>de</strong>más JMF proporciona los Performance Packs, paquetes específicos para una<br />
plataforma y que mejoran el rendimiento. Están disponibles para Windows, Linux y<br />
Solaris.<br />
Hay que señalar algunos in<strong>con</strong>venientes que acarrea el usar JMF. El principal es<br />
sin duda su estado <strong>de</strong> abandono. Esto provoca que no estén soportados muchos <strong>de</strong> los<br />
formatos y co<strong>de</strong>cs <strong>de</strong> uso actual, como por ejemplo MPEG-2, MPEG-4, Windows<br />
Media, Real Media, la mayoría <strong>de</strong> películas en QuickTime y Flash 2. A<strong>de</strong>más tampoco<br />
es posible manejar el popular formato <strong>de</strong> audio MP3.
3.3.2.2. Freedom for Media in Java<br />
Freedom for Media in Java (FMJ) es un intento para crear una implementación<br />
libre <strong>de</strong> JMF. Su principal objetivo es crear una librería <strong>de</strong> carácter totalmente libre que<br />
sea compatible <strong>con</strong> JMF e incluya todas sus funcionalida<strong>de</strong>s, incluyendo captura,<br />
procesamiento, reproducción y transmisión a través <strong>de</strong> gran variedad <strong>de</strong> medios. Este<br />
objetivo implica las siguientes metas a <strong>con</strong>seguir:<br />
• Crear una implementación sustituta <strong>de</strong> JMF, siendo compatible <strong>con</strong> el código<br />
que usa JMF.<br />
• Solucionar los problemas <strong>de</strong> JMF y añadir nuevas características, incluyendo:<br />
o Soporte para co<strong>de</strong>cs mo<strong>de</strong>rnos.<br />
o Encapsular varias librerías multimedia nativas.<br />
o Soporte dinámico para plugins, co<strong>de</strong>cs y dispositivos <strong>de</strong> captura.<br />
o Incluir un fichero <strong>de</strong> registro editable.<br />
o Conseguir que el uso <strong>de</strong> la API no requiera instalar ningún componente<br />
adicional al entorno <strong>de</strong> ejecución <strong>de</strong> Java.<br />
El proyecto se encuentra en sus primeras etapas <strong>de</strong> <strong>de</strong>sarrollo, y su estado es<br />
todavía bastante precario. El <strong>de</strong>sarrollo es llevado a cabo por personas que <strong>de</strong>ci<strong>de</strong>n<br />
<strong>de</strong>dicar parte <strong>de</strong> su tiempo al proyecto, y se basa en hacer pruebas <strong>de</strong>l tipo caja negra 7<br />
sobre la API <strong>de</strong> JMF y estudiar su especificación. No se usa ninguna información sobre<br />
el código fuente, ya que esto podría acarrear la aparición <strong>de</strong> problemas legales.<br />
De hecho, el <strong>de</strong>sarrollo es tan precario que todavía no soporta transferencia por<br />
RTP. Esta circunstancia lo elimina como opción para ser usado en el servidor <strong>RTSP</strong> que<br />
se va implementar, pero se ha mencionado esta tecnología porque pue<strong>de</strong> ser <strong>de</strong> notoria<br />
importancia en el futuro y <strong>con</strong>viene tenerla en cuenta.<br />
7 Este tipo <strong>de</strong> test se caracteriza por analizar la salida que cierto módulo software produce, en función <strong>de</strong><br />
los parámetros <strong>de</strong> entrada. No se analiza ni se tiene en cuenta la implementación interna <strong>de</strong> dicho módulo,<br />
solo se obtiene información sobre su comportamiento <strong>de</strong>s<strong>de</strong> el exterior.
Teniendo en cuenta estas circunstancias se ha elegido JMF como API que se<br />
utilizará para la creación <strong>de</strong> sesiones RTP. Cuando se explique en profundidad la<br />
implementación <strong>de</strong>l servidor, se mostrará el uso <strong>con</strong>creto que se ha hecho <strong>de</strong> las<br />
capacida<strong>de</strong>s que ofrece la API.<br />
3.3.2.3. VLC Media Player<br />
VLC Media Player (inicialmente Vi<strong>de</strong>oLan Client, VLC a partir <strong>de</strong> ahora) es un<br />
reproductor y servidor multimedia, distribuido como software libre. Soporta muchos<br />
formatos <strong>de</strong> audio y ví<strong>de</strong>o, y también los formatos <strong>de</strong> DVD y VCD 8 . A<strong>de</strong>más pue<strong>de</strong><br />
funcionar como servidor <strong>de</strong> <strong>streaming</strong>, usando varios <strong>de</strong> los <strong>protocolo</strong>s existentes en la<br />
actualidad.<br />
Siempre que se habla <strong>de</strong> software libre merece la pena hacer al menos un breve<br />
repaso <strong>de</strong> la historia y evolución <strong>de</strong>l producto. Inicialmente el objetivo <strong>de</strong>l proyecto<br />
VLC era crear un servidor capaz <strong>de</strong> enviar un flujo <strong>de</strong> <strong>streaming</strong> a través <strong>de</strong> la red. Fue<br />
inicialmente <strong>de</strong>sarrollado por estudiantes <strong>de</strong> la École Centrale Paris, y liberado bajo<br />
licencia GPL 9 el 1 <strong>de</strong> febrero <strong>de</strong> 2001. Debido a su éxito y popularización, actualmente<br />
<strong>de</strong>sarrolladores <strong>de</strong> todo el mundo <strong>con</strong>tribuyen a su evolución. En las primeras etapas el<br />
proyecto <strong>con</strong>staba <strong>de</strong> dos módulos bien diferenciados, un reproductor multimedia<br />
(Vi<strong>de</strong>oLan Client) y un servidor <strong>de</strong> <strong>streaming</strong> (Vi<strong>de</strong>oLan Server). Finalmente el<br />
segundo ha quedado obsoleto y toda la funcionalidad se ha unido en un solo producto,<br />
<strong>con</strong> la <strong>de</strong>nominación VLC Media Player. Sus principales características son:<br />
• Diseño muy <strong>modular</strong>: a<strong>de</strong>más <strong>de</strong>l uso <strong>de</strong> los módulos existentes facilita la<br />
incorporación <strong>de</strong> nuevos módulos para soportar más tipos <strong>de</strong> formatos, co<strong>de</strong>cs o<br />
métodos <strong>de</strong> <strong>streaming</strong>. Ofrece la posibilidad <strong>de</strong> elegir múltiples opciones para la<br />
interfaz, así como entradas y salidas <strong>de</strong> audio y ví<strong>de</strong>o, filtros para <strong>con</strong>seguir<br />
varios efectos, etc. Actualmente hay disponibles más <strong>de</strong> trescientos módulos<br />
para VLC.<br />
8 VCD o Vi<strong>de</strong>o CD es un formato estándar para el almacenamiento <strong>de</strong> ví<strong>de</strong>o en un disco compacto. Se<br />
pue<strong>de</strong>n reproducir en or<strong>de</strong>nadores personales y en muchos reproductores <strong>de</strong> DVD, a<strong>de</strong>más <strong>de</strong><br />
reproductores VCD específicos.<br />
9 La GPL (General Public License) es una licencia orientada a proteger la libre distribución, modificación<br />
y uso <strong>de</strong>l software, protegiéndolo a<strong>de</strong>más <strong>de</strong> intentos <strong>de</strong> apropiación que restrinjan estas liberta<strong>de</strong>s a los<br />
usuarios. Existen algunas variantes <strong>de</strong> la licencia.
• Disponible para múltiples plataformas: <strong>con</strong>tando <strong>con</strong> versiones para<br />
Windows, Linux, Mac OS X, BeOS, BSD, Pocket PC y Solaris. Incluso existe<br />
una versión portátil que pue<strong>de</strong> ser almacenada y usada directamente <strong>de</strong>s<strong>de</strong> una<br />
memoria USB sin necesidad <strong>de</strong> instalación alguna.<br />
• Utiliza la biblioteca libre libavco<strong>de</strong>c <strong>de</strong>l proyecto FFmpeg 10 para manejar los<br />
muchos formatos que soporta, y emplea la biblioteca <strong>de</strong> <strong>de</strong>scifrado DVD<br />
libdvdcss para po<strong>de</strong>r reproducir los DVDs cifrados. A<strong>de</strong>más soporta otros<br />
co<strong>de</strong>cs no incluidos en el proyecto FFmpeg.<br />
• Dispone <strong>de</strong> plugins para la Web: en Windows, Linux, y algunas otras<br />
plataformas, VLC incluye un plugin Mozilla, que permite ver algunos archivos<br />
QuickTime y Windows Media en las páginas Web sin tener que utilizar un<br />
reproductor <strong>de</strong> Microsoft o Apple. Des<strong>de</strong> la versión 0.8.2 en a<strong>de</strong>lante, VLC<br />
incorpora un plugin ActiveX, que permite ver algunos archivos QuickTime y<br />
Windows Media en las propias webs, cuando se navega <strong>con</strong> Internet Explorer.<br />
• Robustez: VLC es especialmente popular por su robustez, ya que es capaz <strong>de</strong><br />
reproducir archivos incompletos o dañados antes <strong>de</strong> que se hayan <strong>de</strong>scargado<br />
completamente, por ejemplo a través <strong>de</strong> programas <strong>de</strong> intercambio habituales<br />
como Emule o BitTorrent. Esto es <strong>de</strong>bido a que es un reproductor basado en<br />
paquetes.<br />
• Capaz <strong>de</strong> acce<strong>de</strong>r a archivos <strong>de</strong> imagen .iso y reproducir los archivos<br />
multimedia <strong>con</strong>tenidos en su interior, incluso si el sistema operativo no es capaz<br />
<strong>de</strong> trabajar directamente <strong>con</strong> archivos .iso.<br />
• Dispone <strong>de</strong> filtros: usando filtros se pue<strong>de</strong>n obtener multitud <strong>de</strong> efectos, como<br />
distorsionar la imagen, separarla en fragmentos, rotarla, añadir logos, etc.<br />
• Tiene otras funcionalida<strong>de</strong>s peculiares que le pue<strong>de</strong>n hacer atractivo para<br />
muchos usuarios, como por ejemplo reproducir ví<strong>de</strong>o como si fuera el fondo <strong>de</strong><br />
pantalla, reproducción en directo usando una <strong>con</strong>exión FireWire, etc.<br />
De cara a este proyecto, las capacida<strong>de</strong>s más relevantes que nos pueda ofrecer VLC<br />
son las relacionadas <strong>con</strong> el <strong>streaming</strong>, y la posibilidad <strong>de</strong> integrarlo <strong>con</strong> el servidor<br />
<strong>RTSP</strong> que se va a <strong>de</strong>sarrollar. En lo referente al primer punto, estudiando la<br />
10 FFmpeg es una colección <strong>de</strong> software libre que pue<strong>de</strong> realizar tareas <strong>de</strong> grabación, transcoding y<br />
<strong>streaming</strong> sobre <strong>con</strong>tenidos <strong>de</strong> audio y ví<strong>de</strong>o. Incluye libavco<strong>de</strong>c, una librería <strong>de</strong> có<strong>de</strong>cs. FFmpeg pue<strong>de</strong><br />
ser utilizada en varios sistemas operativos, incluyendo Linux y Windows.
documentación se ha comprobado que dispone <strong>de</strong> un módulo específico que permite la<br />
creación <strong>de</strong> flujos <strong>de</strong> <strong>streaming</strong> sobre RTP. En cuanto a lo segundo, VLC ofrece la<br />
posibilidad <strong>de</strong>l manejo a través <strong>de</strong> línea <strong>de</strong> comandos como alternativa a la interfaz<br />
gráfica, incluyendo el uso <strong>de</strong> dicho módulo. Esto es fundamental, puesto que si sólo se<br />
ofreciera la interfaz gráfica no sería posible el uso <strong>de</strong> VLC <strong>de</strong>s<strong>de</strong> una aplicación en<br />
Java. VLC ofrece una multitud <strong>de</strong> opciones y parámetros para lanzarlo a través <strong>de</strong> una<br />
terminal, usando sus capacida<strong>de</strong>s tanto <strong>de</strong> reproducción como <strong>de</strong> servicio <strong>streaming</strong>.<br />
Atendiendo a estas razones también se ha elegido VLC para la implementación<br />
<strong>de</strong> uno <strong>de</strong> los módulos <strong>de</strong>l servidor que se encargará <strong>de</strong> las sesiones RTP. Se ha elegido<br />
a<strong>de</strong>más como <strong>con</strong>traposición a JMF, <strong>de</strong> forma que existirá un módulo creado usando<br />
una API <strong>de</strong> programación y otro módulo equivalente basado en una herramienta <strong>de</strong><br />
<strong>streaming</strong> disponible, enriqueciendo la implementación <strong>de</strong>l servidor al abarcar éste más<br />
tecnologías diferentes.<br />
3.3.2.4. Gstreamer<br />
GStreamer es un framework multimedia libre y multiplataforma, escrito en el<br />
Lenguaje <strong>de</strong> programación C, usando la librería GObject 11 . GStreamer permite crear<br />
aplicaciones multimedia que usen ví<strong>de</strong>o, sonido, tareas <strong>de</strong> transcoding, etc. Esto incluye<br />
realizar tareas cotidianas como reproducir música o tareas más complejas como mezclar<br />
audio y ví<strong>de</strong>o. GStreamer proporciona un framework para plugins, flujo <strong>de</strong> datos y<br />
manejo/negociación <strong>de</strong> distintos tipos <strong>de</strong> medios. También provee una API para escribir<br />
aplicaciones.<br />
El proyecto fue fundado el año 1999 por Erik Walthinsen, tomando algunas i<strong>de</strong>as<br />
<strong>de</strong> un proyecto <strong>de</strong> investigación <strong>de</strong>sarrollado en la Universidad <strong>de</strong> Oregon. Inicialmente<br />
fue adoptado por el proyecto GNOME a partir <strong>de</strong> su versión 2.2, luego prosiguió su<br />
evolución y cada vez más aplicaciones lo utilizan, <strong>con</strong>tribuyendo <strong>de</strong>sarrolladores <strong>de</strong><br />
todo el mundo a su progreso.<br />
11 GObject (GLib Object System) es una librería <strong>de</strong> software libre que proporciona un sistema <strong>de</strong> objetos<br />
portable y que combina a<strong>de</strong>más interoperabilidad entre varios lenguajes <strong>de</strong> forma transparente. Está<br />
diseñada para ser usada directamente sobre C o indirectamente sobre otros lenguajes, mediante el uso <strong>de</strong><br />
<strong>de</strong>terminadas librerías intermedias.
Sus principales características son las siguientes:<br />
• Multiplataforma: está disponible para varios sistemas operativos (Linux,<br />
MacOS, Windows y Solaris).<br />
• basado en plugins: Gstreamer tiene una arquitectura basada en plugins, lo que<br />
provoca que la mayoría <strong>de</strong> la funcionalidad esté implementada en forma <strong>de</strong><br />
librerías compartidas. El núcleo básico <strong>con</strong>tiene funciones para cargar y registrar<br />
dinámicamente los plugins, que permiten el uso <strong>de</strong> un amplio abanico <strong>de</strong><br />
formatos y <strong>con</strong>tenedores, así como drivers <strong>de</strong> entrada y salida.<br />
• Diseño orientado a objetos.<br />
• Librería <strong>de</strong>l núcleo muy ligera, menos <strong>de</strong> 150 Kb.<br />
• Soporte para ejecución multihilo, <strong>de</strong> forma transparente al <strong>de</strong>sarrollador.<br />
• API simple, para el <strong>de</strong>sarrollo <strong>de</strong> aplicaciones y plugins.<br />
• Transferencia <strong>de</strong> datos extremadamente ligera, reduciendo así la latencia y<br />
aumentando el rendimiento.<br />
• Completo sistema <strong>de</strong> <strong>de</strong>puración.<br />
Gstreamer se pue<strong>de</strong> comparar <strong>con</strong> VLC atendiendo a dos aspectos: En primer<br />
lugar también hace uso <strong>de</strong> las librerías que ofrece el proyecto FFmpeg. Por otra parte,<br />
también admite el <strong>con</strong>trol a través <strong>de</strong> la línea <strong>de</strong> comandos.<br />
Al haber sido ya elegidos JMF y VLC para implementar los módulos RTP, no se<br />
va a hacer uso <strong>de</strong> Gstreamer por <strong>con</strong>si<strong>de</strong>rar que no aporta <strong>con</strong>tenido sustancialmente<br />
diferente al proyecto, pero sería posible usarlo para implementar un módulo adicional.<br />
3.3.2.5. IBM Toolkit for MPEG-4<br />
Es un <strong>con</strong>junto <strong>de</strong> clases y APIs Java, que permiten la creación <strong>de</strong> aplicaciones<br />
multimedia capaces <strong>de</strong> manejar <strong>con</strong>tenido MPEG-4 12 , incluyendo tareas <strong>de</strong> <strong>streaming</strong>.<br />
12 MPEG-4 es un <strong>con</strong>junto <strong>de</strong> estándares para la codificación <strong>de</strong> audio y ví<strong>de</strong>o, así como las tecnologías<br />
relacionadas. Esto incluye, entre otros, el <strong>con</strong>tenedor MPEG-4 (archivos <strong>con</strong> extensión .mp4), que como<br />
se llama igual pue<strong>de</strong> dar lugar a <strong>con</strong>fusión.
Es una librería propietaria, pero existe una versión <strong>de</strong> prueba que permite probar sus<br />
características durante noventa días.<br />
Se ofrece <strong>con</strong> cinco aplicaciones <strong>de</strong> ejemplo, tres <strong>de</strong>dicadas a reproducción y dos<br />
orientadas a la creación <strong>de</strong> <strong>con</strong>tenido multimedia. Son las siguientes:<br />
• AvGen: herramienta <strong>con</strong> interfaz gráfica que permite la creación <strong>de</strong> <strong>con</strong>tenidos<br />
multimedia (audio o ví<strong>de</strong>o pero no ambos simultáneamente), así como<br />
transmitirlos a través <strong>de</strong> los <strong>protocolo</strong>s <strong>RTSP</strong>/RTP para su recepción por<br />
dispositivos que cumplan los estándares 3GPP o ISMA 13<br />
• XMTBatch: esta herramienta permite la creación <strong>de</strong> <strong>con</strong>tenidos multimedia<br />
MPEG-4 más complejos, que no se limitan simplemente a audio y vi<strong>de</strong>o. Esto<br />
incluye interacción <strong>con</strong> el usuario y tareas <strong>de</strong> transcoding <strong>de</strong>s<strong>de</strong> varios formatos<br />
a MPEG-4.<br />
• M4Play: aplicación que reproduce <strong>con</strong>tenidos MPEG-4.<br />
• M4Applet for ISMA: reproduce <strong>con</strong>tenido que cumple el estándar ISMA, y que<br />
le llega a través <strong>de</strong> <strong>RTSP</strong>/RTP.<br />
• M4Applet for HTTP: applet 14 que reproduce <strong>con</strong>tenido MPEG-4 obtenido a<br />
través <strong>de</strong> HTTP.<br />
Aunque es una tecnología <strong>con</strong> bastantes posibilida<strong>de</strong>s, no se ha <strong>con</strong>templado su<br />
uso por no ser software libre.<br />
13 ISMA (Internet Streaming Media Alliance) es una organización sin ánimo <strong>de</strong> lucro cuya misión es<br />
facilitar la implantación en el mercado <strong>de</strong> estándares abiertos para la transmisión <strong>de</strong> multimedia sobre<br />
diferentes <strong>protocolo</strong>s <strong>de</strong> Internet.<br />
14 Un applet es un componente software que se ejecuta en el <strong>con</strong>texto <strong>de</strong> otro programa, generalmente un<br />
navegador web.
3.4. Entorno y herramientas<br />
3.4.1. Sistema operativo Windows XP<br />
El sistema operativo en el que el servidor <strong>de</strong>berá funcionar es Windows. Más<br />
<strong>con</strong>cretamente, el <strong>de</strong>sarrollo se ha hecho sobre Windows XP. La elección <strong>de</strong> un sistema<br />
operativo en <strong>con</strong>creto para una aplicación programada en un lenguaje multiplataforma<br />
como Java pue<strong>de</strong> resultar <strong>con</strong>tradictoria en un principio, pero existe fundamentalmente<br />
una circunstancia que ha obligado a tomar esta <strong>de</strong>cisión. La forma <strong>de</strong> lanzar procesos en<br />
Windows XP es diferente a Linux, por tanto, para lanzar la aplicación VLC es necesario<br />
<strong>de</strong>cantarse por un mecanismo <strong>con</strong>creto.<br />
No obstante, <strong>de</strong>bido a que los elementos utilizados son multiplataforma (Java,<br />
JMF y VLC) se podría adaptar fácilmente la aplicación a Linux y Solaris.<br />
3.4.2. Entorno <strong>de</strong> <strong>de</strong>sarrollo Eclipse<br />
El entorno <strong>de</strong> <strong>de</strong>sarrollo elegido para las tareas <strong>de</strong> programación ha sido Eclipse.<br />
Eclipse es una plataforma <strong>de</strong> software <strong>de</strong> Código abierto in<strong>de</strong>pendiente <strong>de</strong> una<br />
plataforma para <strong>de</strong>sarrollar lo que el proyecto llama "Aplicaciones <strong>de</strong> Cliente<br />
Enriquecido", opuesto a las aplicaciones "Cliente-liviano" basadas en navegadores.<br />
Se ha elegido este entorno <strong>de</strong> <strong>de</strong>sarrollo por las facilida<strong>de</strong>s específicas que<br />
ofrece para la programación en Java, como por ejemplo la <strong>de</strong>tección automática <strong>de</strong><br />
errores, el resaltado <strong>de</strong> elementos <strong>de</strong>l lenguaje (palabras reservadas, variables), etc.<br />
Estas características facilitan el <strong>de</strong>sarrollo y posterior comprensión <strong>de</strong>l código escrito.
3.4.3. Wireshark<br />
Una necesidad básica para po<strong>de</strong>r realizar pruebas era po<strong>de</strong>r capturar el tráfico<br />
que se estaba intercambiando a través <strong>de</strong> la red entre los diferentes elementos. La<br />
herramienta elegida ha sido Wireshark, anteriormente <strong>con</strong>ocida como Ethereal.<br />
Wireshark es una herramienta utilizada para realizar análisis y solucionar problemas en<br />
re<strong>de</strong>s <strong>de</strong> comunicaciones para <strong>de</strong>sarrollo <strong>de</strong> software y <strong>protocolo</strong>s, y también se usa<br />
como una herramienta didáctica para educación. Cuenta <strong>con</strong> todas las características<br />
estándar <strong>de</strong> un analizador <strong>de</strong> <strong>protocolo</strong>s.<br />
Incorpora una interfaz gráfica y muchas opciones <strong>de</strong> organización y filtrado <strong>de</strong><br />
información. Así, permite ver todo el tráfico que pasa a través <strong>de</strong> una red (usualmente<br />
una red Ethernet, aunque es compatible <strong>con</strong> algunas otras) estableciendo la<br />
<strong>con</strong>figuración en modo promiscuo. También incluye una versión basada en texto<br />
llamada Tshark. Permite examinar datos <strong>de</strong> una red viva o <strong>de</strong> un archivo <strong>de</strong> captura<br />
salvado en disco. Se pue<strong>de</strong> analizar la información capturada, a través <strong>de</strong> los <strong>de</strong>talles y<br />
sumarios por cada paquete. Wireshark incluye un completo lenguaje para filtrar lo que<br />
se <strong>de</strong>sea ver y la habilidad <strong>de</strong> mostrar el flujo re<strong>con</strong>struido <strong>de</strong> una sesión <strong>de</strong> TCP, esta<br />
característica lo hace especialmente útil para examinar los mensajes intercambiados a lo<br />
largo <strong>de</strong> una sesión <strong>RTSP</strong>.<br />
Wireshark es software libre, y se ejecuta sobre la mayoría <strong>de</strong> sistemas operativos<br />
Unix y compatibles, incluyendo Linux, Solaris, FreeBSD, NetBSD, OpenBSD, y Mac<br />
OS X, así como en Windows. Esta herramienta se usado para dos tareas <strong>con</strong>cretas:<br />
• Examinar el intercambio <strong>de</strong> mensajes <strong>RTSP</strong>. Esto incluye tanto el análisis <strong>de</strong> los<br />
mensajes enviados por servidores y clientes ya existentes para averiguar el uso<br />
real que hacen <strong>de</strong>l <strong>protocolo</strong>, como la <strong>con</strong>firmación <strong>de</strong> que el servidor<br />
implementado envía los mensajes correctamente.<br />
• Comprobar que los flujos <strong>de</strong> <strong>streaming</strong> a través <strong>de</strong> RTP se están creando<br />
correctamente, corroborando que los paquetes UDP están llegando a la dirección<br />
IP y puertos correspondientes.
3.4.4. JavaCC<br />
Como se ha mencionado se va a usar el <strong>protocolo</strong> <strong>RTSP</strong> para el <strong>con</strong>trol <strong>de</strong>l<br />
<strong>streaming</strong>, y este es un <strong>protocolo</strong> <strong>de</strong> carácter textual. Será por lo tanto necesario que el<br />
servidor sea capaz <strong>de</strong> interpretar correctamente los mensajes <strong>RTSP</strong> enviados por los<br />
clientes, i<strong>de</strong>ntificando el tipo <strong>de</strong> mensajes y los diferentes campos <strong>de</strong> información<br />
<strong>con</strong>tenidos en ellos. De ahí nace la necesidad <strong>de</strong> implementar algún tipo <strong>de</strong> analizador<br />
<strong>de</strong> lenguajes que pueda acometer estas tareas. Para ello se ha usado Java Compiler<br />
Compiler (JavaCC), un generador <strong>de</strong> analizadores sintácticos escrito en Java y que<br />
genera código en Java.<br />
Entrando ya en el campo <strong>de</strong> los lenguajes, cabe señalar que un analizador<br />
sintáctico lleva asociado un analizador léxico. El analizador léxico es capaz <strong>de</strong><br />
re<strong>con</strong>ocer los tokens o elementos unitarios <strong>de</strong>l lenguaje, mientras que posteriormente el<br />
analizador sintáctico analiza la forma en que estos elementos se combinan entre si.<br />
Finalmente el analizador será capaz <strong>de</strong> <strong>de</strong>terminar si una <strong>de</strong>terminada entrada pertenece<br />
o no al lenguaje especificado. En el caso <strong>de</strong>l <strong>protocolo</strong> <strong>RTSP</strong>, los tokens serán las<br />
diferentes ca<strong>de</strong>nas <strong>de</strong> texto incluidas <strong>de</strong>ntro <strong>de</strong> los mensajes, y el analizador sintáctico<br />
comprobará que dichas ca<strong>de</strong>nas se combinan para crear un mensaje <strong>RTSP</strong> correcto.<br />
JavaCC funciona <strong>de</strong> esta manera: siguiendo unas <strong>de</strong>terminadas reglas <strong>de</strong><br />
sintaxis, se pue<strong>de</strong> escribir un fichero que <strong>de</strong>scriba la gramática <strong>de</strong> un cierto lenguaje, en<br />
este caso el lenguaje será el formado por los diferentes mensajes <strong>RTSP</strong> que se preten<strong>de</strong>n<br />
re<strong>con</strong>ocer. Después usando un compilador <strong>de</strong> JavaCC, obtendremos un código en Java<br />
capaz <strong>de</strong> recibir una ca<strong>de</strong>na <strong>de</strong> entrada y <strong>de</strong>cidir si dicha ca<strong>de</strong>na cumple o no la<br />
especificación <strong>de</strong>l lenguaje. A<strong>de</strong>más se pue<strong>de</strong> añadir código java combinado <strong>con</strong> el<br />
análisis, <strong>de</strong> forma que se realice cualquier acción que programemos al <strong>de</strong>tectar cada<br />
elemento.
3.4.5. Reproductores multimedia<br />
Se ha señalado que el servidor <strong>RTSP</strong> <strong>de</strong>berá ser compatible <strong>con</strong> los<br />
reproductores VLC y QuickTime. Evi<strong>de</strong>ntemente, una característica común a ambos es<br />
que son capaces <strong>de</strong> establecer sesiones <strong>RTSP</strong> y recibir <strong>con</strong>tenido a través <strong>de</strong> la red por<br />
RTP. Sin embargo, existen ligeras diferencias en cuanto a la implementación <strong>de</strong>l<br />
<strong>protocolo</strong> <strong>RTSP</strong>, que se irán señalando en su momento. A<strong>de</strong>más se pretendió incluir el<br />
reproductor Windows Media Player, <strong>de</strong> cierta importancia <strong>de</strong>bido a su popularidad entre<br />
muchos usuarios. Sin embargo esta opción se acabó <strong>de</strong>sestimando, <strong>de</strong>bido a problemas<br />
que se expondrán más a<strong>de</strong>lante.<br />
3.4.5.1. Reproductor VLC<br />
A<strong>de</strong>más <strong>de</strong> sus capacida<strong>de</strong>s <strong>de</strong> generar <strong>streaming</strong>, VLC resulta ser un potente<br />
reproductor multimedia. Potente por la variedad <strong>de</strong> formatos y medios <strong>de</strong> entrada que<br />
soporta, y por su robustez a la hora <strong>de</strong> reproducir <strong>con</strong>tenido dañado o incompleto.<br />
A<strong>de</strong>más también soporta la reproducción <strong>de</strong> archivos <strong>de</strong> subtítulos y efectos <strong>de</strong> ví<strong>de</strong>o<br />
añadidos. La versión que se ha usado es la 0.8.6a.<br />
Los medios <strong>de</strong> entrada que se pue<strong>de</strong>n abrir incluyen ficheros almacenados en<br />
local, discos DVD, VCD o <strong>de</strong> música, aparatos externos <strong>de</strong> captura o flujo <strong>de</strong> <strong>streaming</strong><br />
proveniente <strong>de</strong> la red. En cuanto a esto último pue<strong>de</strong> establecer sesiones <strong>RTSP</strong>, o<br />
directamente leer el <strong>con</strong>tenido RTP que llega a un puerto en <strong>con</strong>creto. También pue<strong>de</strong><br />
usar los <strong>protocolo</strong>s HTTP, HTTPS, FTP y MMS.<br />
Incluye una barra <strong>de</strong> <strong>de</strong>splazamiento para <strong>con</strong>trolar la reproducción, en el<br />
<strong>con</strong>texto <strong>de</strong> una sesión <strong>RTSP</strong> el uso <strong>de</strong> esta barra provoca el envío <strong>de</strong> mensajes al<br />
servidor. Se tratará <strong>de</strong> aten<strong>de</strong>r a estas <strong>de</strong>mandas. En la figura 3.2 se muestra una captura<br />
<strong>de</strong> la interfaz <strong>de</strong>l reproductor VLC.
Figura 3.2: interfaz <strong>de</strong>l reproductor VLC<br />
El reproductor se pue<strong>de</strong> manejar a través <strong>de</strong> la línea <strong>de</strong> comandos, remotamente<br />
mediante una <strong>con</strong>exión Telnet o usando la interfaz <strong>de</strong> usuario. Es esta última posibilidad<br />
la que se va a usar para hacer las pruebas, por resultar más inmediata y más habitual<br />
<strong>de</strong>s<strong>de</strong> el punto <strong>de</strong> vista <strong>de</strong> los usuarios.<br />
3.4.5.2. Reproductor QuickTime Player<br />
El reproductor QuickTime Player forma parte <strong>de</strong> QuickTime, que es la<br />
arquitectura multimedia estándar <strong>de</strong>sarrollada por Apple, formada por un <strong>con</strong>junto <strong>de</strong><br />
bibliotecas y el propio reproductor. Se ha usado la versión básica 7.1.6, existe una<br />
versión “Pro” no gratuita que aña<strong>de</strong> diversas funcionalida<strong>de</strong>s como la edición <strong>de</strong> ví<strong>de</strong>o<br />
y codificación a variados formatos como AVI, MOV, MP4. Con la versión Pro, también<br />
es posible grabar audio <strong>con</strong> un micrófono <strong>con</strong>ectado al or<strong>de</strong>nador.<br />
QuickTime permite la reproducción <strong>de</strong> archivos en local y también <strong>con</strong>tenido a<br />
través <strong>de</strong> la red, incluyendo el <strong>protocolo</strong> <strong>RTSP</strong>. A<strong>de</strong>más también pue<strong>de</strong> reproducir<br />
<strong>con</strong>tenidos empotrado en los navegadores Web. Actualmente se encuentra disponible<br />
para los sistemas operativos Windows y Mac Os X. Se pue<strong>de</strong> observar la interfaz <strong>de</strong><br />
QuickTime en la figura 3.3.
Figura 3.3: interfaz <strong>de</strong>l reproductor QuickTime<br />
El efecto <strong>de</strong>l uso <strong>de</strong> la barra <strong>de</strong> <strong>de</strong>splazamiento durante las sesiones <strong>RTSP</strong> tiene<br />
un efecto similar que en el caso <strong>de</strong> VLC. A diferencia <strong>de</strong> VLC, sin embargo, no soporta<br />
la reproducción a través <strong>de</strong> RTP directamente, si no que obligatoriamente <strong>de</strong>be<br />
producirse en el <strong>con</strong>texto <strong>de</strong> una sesión <strong>RTSP</strong> iniciada <strong>de</strong>s<strong>de</strong> el reproductor.<br />
Cabe señalar que existe un <strong>con</strong>tenedor multimedia llamado QuickTime<br />
(extensión <strong>de</strong> archivo “.mov”) capaz <strong>de</strong> almacenar pistas <strong>de</strong> audio, ví<strong>de</strong>o, efectos y<br />
texto. Posibilita a<strong>de</strong>más tareas <strong>de</strong> edición.
3.5. Diseño e Implementación<br />
En este capítulo se aborda el diseño y la implementación <strong>de</strong>l servidor <strong>RTSP</strong>. Se<br />
ofrecerá primeramente una visión global <strong>de</strong> la arquitectura, <strong>con</strong> los elementos<br />
fundamentales que componen el servidor. Se explicará el mo<strong>de</strong>lo <strong>de</strong> <strong>de</strong>sarrollo que ha<br />
servido como guía.<br />
Posteriormente se <strong>de</strong>tallará cómo se ha implementado la funcionalidad <strong>RTSP</strong>,<br />
incluyendo a<strong>de</strong>más información general sobre el <strong>protocolo</strong> y qué partes <strong>de</strong> este se han<br />
incluido o no. El resto <strong>de</strong> elementos a explicar serán el mantenimiento <strong>de</strong>l estado <strong>de</strong> las<br />
sesiones en el servidor y finalmente la implementación <strong>de</strong> los diferentes módulos<br />
SdpGenerator y RtpSen<strong>de</strong>r usando las tecnologías sobre las que ya se ha hablado en<br />
los primeros capítulos.<br />
3.5.1. Arquitectura <strong>de</strong>l sistema<br />
Una vez elegidas las tecnologías y <strong>protocolo</strong>s que se van a utilizar, hay que<br />
diseñar la arquitectura <strong>de</strong>l servidor. Tal y como se especificó en los objetivos, el<br />
servidor <strong>de</strong>be ser capaz <strong>de</strong> <strong>con</strong>testar las peticiones <strong>RTSP</strong> <strong>de</strong> los clientes, obtener los<br />
SDP asociados a un <strong>con</strong>tenido multimedia y crear sesiones RTP para el envío <strong>de</strong> los<br />
datos. Las dos últimas tareas podrán ser llevadas a cabo por módulos diferentes que<br />
emplearán diferentes tecnologías, y el servidor se podrá <strong>con</strong>figurar en el momento <strong>de</strong>l<br />
arranque. Se ha <strong>de</strong>finido una interfaz java (especificación <strong>de</strong> los métodos que una clase<br />
<strong>de</strong>be implementar) para los módulos encargados <strong>de</strong> obtener los SDP (SdpGenerator) y<br />
los que crearán las sesiones RTP (RtpSen<strong>de</strong>r):<br />
• La interfaz SdpGenerator <strong>de</strong>fine un solo método, getSdpContent, que <strong>de</strong>vuelve<br />
un SDP recibiendo como parámetro el nombre <strong>de</strong>l <strong>con</strong>tenido multimedia<br />
correspondiente. Lanza una excepción si no se encuentra.<br />
• Por su parte la interfaz RtpSen<strong>de</strong>r <strong>de</strong>fine tres métodos:
o startTransmission, comienza en envío <strong>de</strong> información por RTP y<br />
recibe como parámetro el instante inicial expresado en segundos.<br />
o pauseTransmission, <strong>de</strong>tiene la transmisión.<br />
o tearDownTransmission, libera los recursos asociados a la sesión RTP.<br />
Por lo tanto el esquema a alto nivel <strong>de</strong>l servidor y su relación <strong>con</strong> el cliente es el<br />
representado en la figura 3.4.<br />
Figura 3.4: arquitectura <strong>de</strong>l sistema<br />
Tras analizar las capacida<strong>de</strong>s ofrecidas por las diferentes tecnologías estudiadas,<br />
se ha <strong>de</strong>terminado que se implementarán dos versiones <strong>de</strong>l módulo SdpGenerator otras<br />
dos <strong>de</strong>l RtpSen<strong>de</strong>r. El servidor será <strong>con</strong>figurable, <strong>de</strong> forma que al arrancar se podrá<br />
elegir cuales <strong>de</strong> estos módulos usar. Por lo tanto, el servidor se podrá arrancar <strong>con</strong><br />
cuatro <strong>con</strong>figuraciones diferentes posibles. Se usarán las siguientes tecnologías en la<br />
implementación <strong>de</strong> los módulos:<br />
• SdpGenerator: habrá una versión básica que se limitará a leer los SDPs <strong>de</strong> un<br />
fichero <strong>de</strong> texto, es <strong>de</strong>cir, los SDPs habrán sido obtenidos previamente <strong>de</strong> otra<br />
forma ajena al servidor (FileSdpGenerator). Otra versión usará VLC para<br />
obtener el SDP asociado a los archivos guardados en disco, aprovechando la<br />
posibilidad <strong>de</strong> usar esta herramienta como servidor <strong>RTSP</strong> (VlcSdpGenerator).<br />
• RtpSen<strong>de</strong>r: Una versión usará JMF aprovechando las capacida<strong>de</strong>s que ofrece su<br />
API para generar flujos RTP (JmfRtpSen<strong>de</strong>r). Una segunda implementación se
servirá <strong>de</strong> VLC y su posibilidad <strong>de</strong> ser lanzado mediante línea <strong>de</strong> comandos,<br />
generando también un flujo RTP (VlcRtpSen<strong>de</strong>r).<br />
Para terminar <strong>con</strong> la visión general <strong>de</strong> la arquitectura <strong>de</strong>l servidor, hay que<br />
señalar cómo se ha abordado el objetivo referente a la escalabilidad en cuanto al soporte<br />
simultáneo a varios clientes. El servidor esperará peticiones en un <strong>de</strong>terminado puerto, y<br />
para cada <strong>con</strong>exión abrirá un hilo <strong>de</strong> ejecución que aten<strong>de</strong>rá las peticiones. Más<br />
<strong>con</strong>cretamente, la clase que esperará las <strong>con</strong>exiones y sirve para lanzar el servidor es<br />
RtspServer, y cada vez que reciba una nueva <strong>con</strong>exión se lanzará una instancia <strong>de</strong> la<br />
clase RequestHandler que interactuará <strong>con</strong> el cliente. Habrá un único SdpGenerator,<br />
pero como es lógico se podrá instanciar un RtpSen<strong>de</strong>r para cada cliente, posibilitando<br />
así el envío simultáneo <strong>de</strong> datos a todos ellos. A<strong>de</strong>más mantendrá una estructura <strong>de</strong><br />
datos que guardará el estado <strong>de</strong> cada sesión <strong>RTSP</strong>, llamada RtspSessionData (una<br />
instancia para cada sesión). Es importante tener en cuenta que el número <strong>de</strong> sesiones no<br />
es igual al número <strong>de</strong> <strong>con</strong>exiones <strong>con</strong> los clientes, ya que al tratarse <strong>de</strong> un servidor <strong>con</strong><br />
estado, durante una única sesión <strong>RTSP</strong> se podrán producir varias <strong>con</strong>exiones y<br />
<strong>de</strong>s<strong>con</strong>exiones a nivel <strong>de</strong> transporte.<br />
3.5.1.1. Diagrama <strong>de</strong> clases Java<br />
Se muestra el diagrama <strong>de</strong> clases Java en la figura 3.5, <strong>con</strong> todas las clases e<br />
interfaces que <strong>con</strong>stituyen el servidor <strong>RTSP</strong> salvo algunas clases auxiliares <strong>de</strong>l<br />
analizador sintáctico creado <strong>con</strong> JavaCC, cuya clase principal es RtspRequestParser.<br />
Estas clases auxiliares se omiten para facilitar la comprensión global <strong>de</strong> la estructura <strong>de</strong><br />
clases, baste <strong>de</strong>cir que RtspRequestParser las usa para el análisis. También se omiten<br />
algunos atributos y métodos, mostrando solo los más relevantes para compren<strong>de</strong>r el<br />
funcionamiento.<br />
A medida que se vaya explicando el funcionamiento interno <strong>de</strong>l servidor se irán<br />
mencionando todos estos elementos y explicando su papel.
Figura 3.5: diagrama <strong>de</strong> clases java
3.5.2. Proceso <strong>de</strong> <strong>de</strong>sarrollo<br />
Como metodología para el <strong>de</strong>sarrollo <strong>de</strong>l proyecto se ha seguido el mo<strong>de</strong>lo <strong>de</strong><br />
ciclo <strong>de</strong> vida en espiral representado en la figura 3.6. Este mo<strong>de</strong>lo <strong>con</strong>sta <strong>de</strong> iteraciones,<br />
cada una <strong>de</strong> las cuales <strong>con</strong>sta <strong>de</strong> ciertas etapas que culminarán en un prototipo más<br />
avanzado. Estas etapas son el análisis <strong>de</strong> objetivos y requisitos para la iteración, diseño<br />
e implementación, pruebas, y por último se planificará la siguiente fase en caso <strong>de</strong> que<br />
se vaya a <strong>con</strong>tinuar <strong>con</strong> el <strong>de</strong>sarrollo.<br />
Figura 3.6: mo<strong>de</strong>lo <strong>de</strong> <strong>de</strong>sarrollo en espiral<br />
Consi<strong>de</strong>rando la evolución <strong>de</strong>l servidor a lo largo <strong>de</strong> todo el <strong>de</strong>sarrollo, po<strong>de</strong>mos<br />
enumerar algunos hitos o iteraciones claramente diferenciadas. Cada una <strong>de</strong> ellas ha<br />
culminado <strong>con</strong> la obtención <strong>de</strong> un prototipo más avanzado que el anterior, en el cual se<br />
ha añadido alguna funcionalidad o módulo <strong>con</strong>creto. Las iteraciones son las siguientes:
• Una primera versión <strong>de</strong>l servidor <strong>con</strong> la capacidad <strong>de</strong> <strong>con</strong>testar a las peticiones<br />
<strong>RTSP</strong> <strong>de</strong> los clientes. Es <strong>de</strong>cir, esta versión no generaba ningún flujo <strong>de</strong><br />
<strong>streaming</strong>, y se ha utilizado un SDP insertado directamente en el código, que era<br />
enviado a los reproductores en el mensaje oportuno. Esta versión se limitaba a ir<br />
<strong>con</strong>testando a los sucesivos mensajes <strong>RTSP</strong> <strong>de</strong> los clientes, creando respuestas<br />
válidas que los clientes aceptaban como correctas, dando paso así a las<br />
peticiones subsiguientes. Finalmente se llegaba a un estado don<strong>de</strong> todos los<br />
mensajes <strong>de</strong> inicialización se habían intercambiado correctamente, y el cliente se<br />
quedaba a la espera <strong>de</strong> recibir el flujo <strong>de</strong> <strong>streaming</strong> por RTP. La tarea <strong>de</strong> análisis<br />
en esta fase ha incluido tanto el estudio <strong>de</strong>l <strong>protocolo</strong> <strong>RTSP</strong> a nivel teórico a<br />
través <strong>de</strong> su RFC 2326 y otros documentos, como el estudio <strong>de</strong> sesiones <strong>RTSP</strong><br />
reales para comprobar el uso <strong>de</strong>l <strong>protocolo</strong> que hacen los distintos reproductores<br />
a la hora <strong>de</strong> solicitar un archivo.<br />
• La segunda etapa <strong>de</strong> <strong>de</strong>sarrollo <strong>con</strong>sistió en la implementación <strong>de</strong>l módulo<br />
FileSdpGenerator, y su integración en el servidor <strong>de</strong> forma que se hacía uso <strong>de</strong><br />
él cuando el cliente solicitaba un SDP.<br />
• La tercera versión <strong>de</strong>l servidor <strong>con</strong>sistió en la implementación <strong>de</strong>l módulo<br />
JmfRtpSen<strong>de</strong>r. Esto incluyó el estudio <strong>de</strong> la API, el <strong>de</strong>sarrollo <strong>de</strong> una aplicación<br />
aislada capaz <strong>de</strong> enviar un flujo RTP, y finalmente su integración en el servidor<br />
para que iniciara el envío <strong>de</strong> los flujos RTP en el momento que el cliente lo<br />
solicitara, y a la dirección y puertos indicados por este. Se pue<strong>de</strong> <strong>de</strong>cir que al<br />
final <strong>de</strong> esta iteración ya se disponía <strong>de</strong> un servidor <strong>RTSP</strong> <strong>con</strong> funcionalidad<br />
completa, capaz <strong>de</strong> aten<strong>de</strong>r las peticiones <strong>de</strong> los reproductores y enviarles los<br />
datos <strong>de</strong> una forma completamente autónoma.<br />
• El paso posterior <strong>con</strong>sistió en la implementación <strong>de</strong>l módulo VlcRtpSen<strong>de</strong>r.<br />
Primero se estudió la documentación y se hicieron las pruebas pertinentes hasta<br />
<strong>con</strong>seguir crear flujos <strong>de</strong> <strong>streaming</strong> lanzando VLC por línea <strong>de</strong> comandos, y<br />
<strong>de</strong>spués se incluyó un módulo en el servidor que, al igual que en el caso <strong>de</strong> JMF,<br />
era capaz <strong>de</strong> iniciar la transmisión en los términos a<strong>de</strong>cuados.<br />
• Llegados a este punto y aprovechando el <strong>con</strong>ocimiento adquirido sobre el<br />
manejo <strong>de</strong> VLC por línea <strong>de</strong> comandos, se creó el módulo VlcSdpGenerator.<br />
Este módulo supone un salto <strong>de</strong> calidad bastante importante, porque <strong>con</strong> el<br />
módulo FileSdpGenerator era necesario obtener <strong>de</strong> alguna manera un nuevo
SDP cada vez que se pretendía añadir un nuevo archivo a la lista <strong>de</strong> los<br />
disponibles en el servidor (esta manera solía ser la adaptación <strong>de</strong> un SDP<br />
perteneciente a otro archivo multimedia cuyas características eran similares, <strong>de</strong><br />
forma que la información <strong>con</strong>tenida era igualmente válida). A partir <strong>de</strong> este<br />
punto no hay que hacer nada para servir nuevos archivos, ya que este módulo se<br />
encargará <strong>de</strong> obtener el SDP asociado a cada uno <strong>de</strong> ellos.<br />
Una vez <strong>de</strong>scritas las tecnologías y <strong>protocolo</strong>s empleados, la arquitectura general<br />
<strong>de</strong>l servidor y el proceso que se ha seguido durante todo el <strong>de</strong>sarrollo, <strong>de</strong> aquí en<br />
a<strong>de</strong>lante se va a explicar <strong>de</strong>talladamente el funcionamiento <strong>de</strong> cada uno <strong>de</strong> estos<br />
elementos y qué soluciones <strong>de</strong> implementación se han adoptado.<br />
3.5.3. Arranque <strong>de</strong>l servidor<br />
La clase principal que engloba al servidor <strong>RTSP</strong> es RtspServer. El <strong>con</strong>structor <strong>de</strong><br />
esta clase recibe como parámetros toda la información <strong>de</strong> <strong>con</strong>figuración necesaria, a<br />
saber:<br />
• SdpGenerator: (FileSdpGenerator o VlcSdpGenerator)<br />
• RtpSen<strong>de</strong>r: (JmfRtpSen<strong>de</strong>r o VlcRtpSen<strong>de</strong>r)<br />
• Puerto en el que el servidor espera peticiones.<br />
• Ruta al directorio don<strong>de</strong> se encuentran los archivos multimedia servidos.<br />
• Ruta al directorio don<strong>de</strong> se encuentran los archivos SDP. En el caso <strong>de</strong> que se<br />
use el módulo VlcSdpGenerator, el directorio <strong>de</strong>berá ser el mismo en el que se<br />
encuentran los archivos, ya que los SDP se obtienen directamente <strong>de</strong> estos.<br />
A<strong>de</strong>más el propio <strong>con</strong>structor creará el objeto SdpGenerator correspondiente, y<br />
esta instancia será la única <strong>de</strong> dicho tipo que haya en el servidor, al <strong>con</strong>trario <strong>de</strong> los<br />
objetos RTPSen<strong>de</strong>r, <strong>de</strong> los cuales se podrán crear múltiples instancias <strong>de</strong>pendiendo <strong>de</strong><br />
las sesiones <strong>de</strong> <strong>streaming</strong> que se mantengan simultáneamente.
Una vez creado el servidor se arrancará llamando a su método start(). Esto<br />
hará que el servidor empiece a esperar <strong>con</strong>exiones en el puerto correspondiente. Por<br />
cada nueva <strong>con</strong>exión se creará una instancia <strong>de</strong> la clase RequestHandler. Esta clase<br />
crea un hilo <strong>de</strong> ejecución <strong>con</strong>sistente en un bucle que atien<strong>de</strong> a las los mensajes <strong>RTSP</strong><br />
<strong>de</strong> los clientes, realizando las acciones necesarias <strong>de</strong>pendiendo <strong>de</strong>l tipo <strong>de</strong> mensaje y<br />
enviando las respuestas correspondientes.
3.5.4. Implementación <strong>de</strong>l <strong>protocolo</strong> <strong>RTSP</strong><br />
La especificación <strong>de</strong>l <strong>protocolo</strong> <strong>RTSP</strong> es bastante amplia, y viene <strong>de</strong>scrita<br />
exhaustivamente en la RFC 2326, documento que <strong>con</strong>sta <strong>de</strong> 96 páginas. Dicho<br />
documento abarca más aspectos <strong>de</strong> los que se van a tener en cuenta en este servidor, y<br />
no tiene sentido <strong>de</strong>scribir todos y cada uno <strong>de</strong> ellos en el presente documento. Las<br />
características generales <strong>de</strong>l <strong>protocolo</strong> fueron <strong>de</strong>scritas en el capítulo 3.3.1.1., y a partir<br />
<strong>de</strong> ahora la explicación se va a centrar en los aspectos relevantes para este caso.<br />
Conviene recordar que se trata <strong>de</strong> un <strong>protocolo</strong> textual similar a HTTP, en el cual el<br />
servidor mantiene información <strong>de</strong> estado y las sesiones tienen una estructura secuencial<br />
<strong>de</strong> petición-respuesta. Sirve para <strong>con</strong>trolar la transferencia <strong>de</strong> <strong>streaming</strong>, incluyendo la<br />
inicialización, modificación y finalización <strong>de</strong> la sesión.<br />
Primeramente se van a <strong>de</strong>scribir las peticiones y respuestas <strong>RTSP</strong>. Después se<br />
explicará el proceso <strong>de</strong> arranque <strong>de</strong>l servidor y cómo comienza a respon<strong>de</strong>r a las<br />
peticiones <strong>RTSP</strong> <strong>de</strong> un reproductor que preten<strong>de</strong> reproducir un archivo multimedia<br />
almacenado en el servidor. Se <strong>de</strong>tallarán dichas peticiones, mostrando capturas <strong>de</strong> las<br />
mismas y explicando simultáneamente los aspectos <strong>de</strong>l <strong>protocolo</strong> que se están<br />
utilizando. A<strong>de</strong>más se señalarán las diferencias en el uso <strong>de</strong>l servidor que se han<br />
en<strong>con</strong>trado entre los reproductores VLC y QuickTime.<br />
3.5.4.1. Petición <strong>RTSP</strong><br />
Una petición <strong>RTSP</strong> está formada por los siguientes elementos, siendo todos ellos<br />
ca<strong>de</strong>nas <strong>de</strong> caracteres:<br />
• Línea <strong>de</strong> petición: incluye el tipo <strong>de</strong> petición, el recurso multimedia al que hace<br />
referencia (habitualmente una URL) y la versión <strong>de</strong>l <strong>protocolo</strong>. En lugar <strong>de</strong> la<br />
URL también se pue<strong>de</strong> usar un asterisco, en este caso la petición no hace<br />
referencia a ningún recurso multimedia en particular si no a alguna cuestión<br />
referente al servidor.
• Una o varias líneas <strong>de</strong> cabecera, algunas serán obligatorias para cada tipo <strong>de</strong><br />
mensaje, mientras que muchas serán opcionales.<br />
• Una línea en blanco<br />
• Opcionalmente, un cuerpo <strong>de</strong>l mensaje formado por varias líneas. Por lo general<br />
Ejemplo:<br />
las peticiones carecen <strong>de</strong> cuerpo.<br />
DESCRIBE rtsp://193.147.59.231:10000/vi<strong>de</strong>o.mp4 <strong>RTSP</strong>/1.0<br />
CSeq: 1<br />
Accept: application/sdp<br />
Bandwidth: 384000<br />
Accept-Language: en-US<br />
User-Agent: QuickTime E-/7.1.6 (qtver=7.1.6;os=Windows NT<br />
5.1Service Pack 2)<br />
3.5.4.2. Respuesta <strong>RTSP</strong><br />
Análogamente una respuesta <strong>RTSP</strong> está formada por los siguientes elementos,<br />
nótese la similitud <strong>con</strong> las respuestas HTTP:<br />
• Línea <strong>de</strong> estado (<strong>protocolo</strong>, código <strong>de</strong> estado y frase <strong>de</strong> estado).<br />
• Una o varias líneas <strong>de</strong> cabecera.<br />
• Una línea en blanco.<br />
• Cuerpo <strong>de</strong>l mensaje.<br />
Ejemplo:<br />
<strong>RTSP</strong>/1.0 200 OK<br />
Content-type: application/sdp<br />
Server: VLC Server<br />
Cseq: 1<br />
Cache-Control: no-cache
Las similitu<strong>de</strong>s <strong>con</strong> el <strong>protocolo</strong> HTTP son más que evi<strong>de</strong>ntes. Obsérvese por<br />
ejemplo la línea <strong>de</strong> estado en la respuesta o el uso <strong>de</strong> la cabecera Content-type,<br />
idénticas en ambos <strong>protocolo</strong>s. Cada línea termina a<strong>de</strong>más <strong>con</strong> un retorno <strong>de</strong> carro.<br />
Una característica importante es que cada petición <strong>de</strong>be incluir una cabecera <strong>con</strong><br />
un número <strong>de</strong> secuencia, i<strong>de</strong>ntificada como CSeq. La respuesta a la petición <strong>de</strong>berá<br />
incluir el mismo número <strong>de</strong> secuencia y <strong>de</strong> esta forma la respuesta será asociada<br />
correctamente a la petición a la que correspon<strong>de</strong>. Esto es importante puesto que aunque<br />
normalmente se use TCP como <strong>protocolo</strong> <strong>de</strong> transporte (<strong>protocolo</strong> fiable que entrega los<br />
mensajes <strong>de</strong> forma or<strong>de</strong>nada), pue<strong>de</strong>n establecerse varias <strong>con</strong>exiones diferentes.<br />
A<strong>de</strong>más, aunque es lo habitual, el uso <strong>de</strong> TCP no es obligatorio.<br />
3.5.4.3. Funcionamiento <strong>de</strong>l <strong>protocolo</strong> <strong>RTSP</strong><br />
Se ha realizado un estudio <strong>de</strong>l <strong>protocolo</strong> <strong>con</strong> el objetivo <strong>de</strong> <strong>de</strong>terminar qué<br />
mensajes mínimos son necesarios para <strong>con</strong>seguir la reproducción en un cliente <strong>de</strong> un<br />
recurso multimedia almacenado en un servidor. Como complemento se han analizado<br />
las trazas <strong>de</strong> sesiones <strong>RTSP</strong> reales, <strong>con</strong>ectándose <strong>con</strong> los reproductores QuickTime y<br />
VLC a servidores <strong>RTSP</strong> alojados en Internet y extrayendo los mensajes intercambiados<br />
<strong>con</strong> la herramienta Wireshark, resultando ser este análisis el más útil. Con esta<br />
información se ha programado el servidor para que <strong>con</strong>teste a los clientes <strong>de</strong> la forma<br />
a<strong>de</strong>cuada.<br />
En primer lugar se van a mostrar los mensajes básicos necesarios para la<br />
visualización <strong>de</strong> un archivo multimedia en el cliente. Después se va a hablar <strong>de</strong> otros<br />
mensajes que aña<strong>de</strong>n alguna otra característica al servidor y que se ha optado por incluir<br />
en la implementación. Finalmente se mencionan el resto <strong>de</strong> mensajes <strong>RTSP</strong> que no se<br />
han implementado, para ofrecer <strong>de</strong> esta forma una visión completa <strong>de</strong>l <strong>protocolo</strong>. Una<br />
vez <strong>de</strong>scrito el <strong>protocolo</strong> se comentarán algunas cuestiones sobre su implementación.<br />
Las siguientes trazas correspon<strong>de</strong>n a peticiones enviadas por el reproductor<br />
QuickTime y las respuestas correspondientes enviadas por nuestro servidor <strong>RTSP</strong>.
3.5.4.3.1. Mensajes básicos para la reproducción <strong>de</strong> un archivo<br />
El <strong>con</strong>junto <strong>de</strong> mensajes mínimos es el siguiente, y generalmente <strong>de</strong>berán<br />
enviarse en el or<strong>de</strong>n establecido aunque algunos se pue<strong>de</strong>n repetir para modificar algún<br />
parámetro.<br />
• DESCRIBE: la petición DESCRIBE solicita la <strong>de</strong>scripción <strong>de</strong> un recurso<br />
multimedia almacenado en el servidor, i<strong>de</strong>ntificado por una URL. Pue<strong>de</strong> incluir<br />
la cabecera Accept para especificar los formatos <strong>de</strong> <strong>de</strong>scripción que el cliente es<br />
capaz <strong>de</strong> enten<strong>de</strong>r. El servidor <strong>de</strong>berá respon<strong>de</strong>r <strong>con</strong> un mensaje que incluirá en<br />
el cuerpo la <strong>de</strong>scripción solicitada. En caso <strong>de</strong> que el recurso solicitado no<br />
exista, el servidor <strong>de</strong>berá respon<strong>de</strong>r <strong>con</strong> el mensaje <strong>de</strong>stinado a tal efecto, cuya<br />
línea <strong>de</strong> estado es <strong>RTSP</strong>/1.0 404 Not Found. La petición Describe y su<br />
respuesta <strong>con</strong>stituyen la inicialización <strong>de</strong> la sesión <strong>RTSP</strong>.<br />
En el siguiente ejemplo se envía una petición DESCRIBE sobre un<br />
archivo multimedia llamado “vi<strong>de</strong>o.mpg”. Obsérvese la cabecera Accept en la<br />
que se indica que el cliente acepta <strong>de</strong>scripciones en formato SDP.<br />
DESCRIBE rtsp://192.168.1.2:20000/vi<strong>de</strong>o.mpg <strong>RTSP</strong>/1.0<br />
CSeq: 1<br />
Accept: application/sdp<br />
Bandwidth: 384000<br />
Accept-Language: en-US<br />
User-Agent: QuickTime E-/7.1.6 (qtver=7.1.6;os=Windows NT<br />
5.1Service Pack 2)<br />
La respuesta <strong>con</strong>tiene el SDP solicitado, se pue<strong>de</strong> ver que el recurso<br />
<strong>con</strong>tiene una pista <strong>de</strong> audio y otra <strong>de</strong> ví<strong>de</strong>o.
<strong>RTSP</strong>/1.0 200 OK<br />
Content-type: application/sdp<br />
Content-Length: 304<br />
Cseq: 1<br />
v=0<br />
o=- 20070859581 3 IN IP4 127.0.0.1<br />
c=IN IP4 0.0.0.0<br />
t=0 0<br />
a=tool:vlc 0.8.6a<br />
a=range:npt=0-151.700<br />
m=vi<strong>de</strong>o 0 RTP/AVP 32<br />
a=rtpmap:32 MPV/90000<br />
a=<strong>con</strong>trol:rtsp://192.168.1.2:20000/vi<strong>de</strong>o.mpg/trackID=0<br />
m=audio 0 RTP/AVP 14<br />
a=rtpmap:14 MPA/90000<br />
a=<strong>con</strong>trol:rtsp://192.168.1.2:20000/vi<strong>de</strong>o.mpg/trackID=1<br />
• SETUP: Mediante la petición SETUP el cliente indica al servidor los parámetros<br />
<strong>de</strong> transporte que <strong>de</strong>berá usar para la transmisión <strong>de</strong> un <strong>de</strong>terminado flujo <strong>de</strong><br />
<strong>streaming</strong>, i<strong>de</strong>ntificado mediante una URL que habrá sido obtenida <strong>de</strong> la<br />
<strong>de</strong>scripción <strong>de</strong>l recurso multimedia. Deberá incluir obligatoriamente la cabecera<br />
Transport, en la que se especifican estos parámetros. Por ejemplo se indicará el<br />
<strong>protocolo</strong> que se va a usar para enviar los datos (RTP en nuestro caso), la IP <strong>de</strong><br />
<strong>de</strong>stino (si no se especifica se <strong>de</strong>berá usar la misma que la <strong>de</strong>l cliente), así como<br />
los puertos en los que el cliente va a esperar los datos.<br />
La petición SETUP es la primera que cambia el estado <strong>de</strong>l servidor,<br />
haciendo que este reserve los recursos necesarios para la posterior transmisión.<br />
A<strong>de</strong>más <strong>de</strong>spués <strong>de</strong> recibir la primera petición SETUP el servidor <strong>de</strong>berá generar<br />
un i<strong>de</strong>ntificador <strong>de</strong> sesión, que generalmente será un número aleatorio. Este<br />
i<strong>de</strong>ntificador irá incluido en la respuesta, así como en todas las <strong>de</strong>más peticiones<br />
y respuestas que se produzcan posteriormente <strong>de</strong>ntro <strong>de</strong> la misma sesión <strong>RTSP</strong>.<br />
Por otra parte hay que señalar que cuando un recurso multimedia <strong>con</strong>sta<br />
<strong>de</strong> varias pistas (por ejemplo audio y ví<strong>de</strong>o), el envío <strong>de</strong> los datos pue<strong>de</strong><br />
realizarse <strong>de</strong>ntro <strong>de</strong> la misma transmisión RTP (entrelazado) o en transmisiones<br />
diferentes. En el caso <strong>de</strong> nuestro servidor, el SDP que se envía al cliente le indica<br />
que <strong>de</strong>be solicitar una sesión RTP diferente para cada pista, puesto que cada una
<strong>de</strong> ellas viene i<strong>de</strong>ntificada <strong>con</strong> una URL diferente. Por lo tanto si un cliente<br />
<strong>de</strong>sea reproducir el audio y el ví<strong>de</strong>o <strong>de</strong> un recurso multimedia, <strong>de</strong>berá hacer dos<br />
peticiones SETUP, especificando en cada una <strong>de</strong> ellas la pista a la que se hace<br />
referencia a través <strong>de</strong> la URL, y los puertos RTP/RTCP en los que se esperan los<br />
datos.<br />
La respuesta al mensaje SETUP <strong>de</strong>berá <strong>con</strong>firmar la <strong>con</strong>figuración <strong>de</strong><br />
transporte pretendida por el cliente, o bien indicar una <strong>con</strong>figuración alternativa<br />
si el servidor no pue<strong>de</strong> satisfacer las <strong>de</strong>mandas <strong>de</strong>l reproductor. Opcionalmente<br />
también pue<strong>de</strong> <strong>con</strong>tener algunos parámetros <strong>de</strong> transporte relativos al servidor,<br />
por ejemplo los puertos origen <strong>de</strong> cada flujo RTP. Como <strong>con</strong>clusión, tras los<br />
mensajes SETUP el servidor sabe que pistas <strong>de</strong>sea el cliente, el <strong>protocolo</strong> <strong>de</strong><br />
<strong>streaming</strong> que <strong>de</strong>be utilizar, y cuales son la IP y puertos <strong>de</strong> <strong>de</strong>stino.<br />
En el siguiente ejemplo se envía una petición SETUP sobre una <strong>de</strong> las<br />
pistas <strong>de</strong>scritas en el SDP <strong>de</strong>l ejemplo anterior, obsérvese que la URL<br />
correspon<strong>de</strong> a la pista <strong>de</strong> vi<strong>de</strong>o. Si se quisiera activar también la pista <strong>de</strong> audio<br />
habría que enviar un segundo mensaje SETUP haciendo referencia a la URL<br />
correspondiente. Se pue<strong>de</strong> ver a<strong>de</strong>más en la cabecera Transport que el cliente<br />
espera un flujo <strong>de</strong> datos a través <strong>de</strong> RTP, y que los puertos RTP/RTCP en que<br />
esperará los datos son 6970 y 6971 respectivamente.<br />
SETUP rtsp://192.168.1.2:20000/vi<strong>de</strong>o.mpg/trackID=0 <strong>RTSP</strong>/1.0<br />
CSeq: 2<br />
Transport: RTP/AVP;unicast;client_port=6970-6971<br />
x-retransmit: our-retransmit<br />
x-dynamic-rate: 1<br />
x-transport-options: late-tolerance=2.900000<br />
User-Agent: QuickTime E-/7.1.6 (qtver=7.1.6;os=Windows NT<br />
5.1Service Pack 2)<br />
Accept-Language: en-US<br />
Como se pue<strong>de</strong> observar la cabecera Transport <strong>de</strong> la respuesta <strong>con</strong>firma<br />
los parámetros <strong>de</strong> transporte que el cliente había especificado. A<strong>de</strong>más se<br />
incluye la cabecera Session <strong>con</strong> el número aleatorio que el servidor ha<br />
generado, y que se <strong>de</strong>berá incluir en el resto <strong>de</strong> peticiones y respuestas.
<strong>RTSP</strong>/1.0 200 OK<br />
Cseq: 2<br />
Transport: RTP/AVP;unicast;client_port=6970-6971<br />
Session: 902818185<br />
Hay que hacer notar que aunque las URL <strong>de</strong> las peticiones SETUP tienen<br />
aspecto <strong>de</strong> dirección <strong>de</strong> red y puerto, en realidad no tienen ninguna relación <strong>con</strong><br />
el <strong>protocolo</strong> <strong>de</strong> transporte. El servidor las trata simplemente como ca<strong>de</strong>nas <strong>de</strong><br />
texto, y se limita a compararlas <strong>con</strong> las URL que venían especificadas en el SDP<br />
para comprobar a qué pista hacen referencia.<br />
• PLAY: <strong>con</strong> la petición PLAY el cliente solicita al servidor el envío <strong>de</strong> los datos,<br />
usando como parámetros <strong>de</strong> transporte los indicados en las peticiones SETUP<br />
previas. El cliente no <strong>de</strong>be enviar el mensaje PLAY antes <strong>de</strong> haber enviado todos<br />
los mensajes SETUP necesarios y haber recibido las respuestas<br />
correspondientes.<br />
El mensaje <strong>de</strong>be <strong>con</strong>tar obligatoriamente <strong>con</strong> la cabecera Range, que<br />
especifica el rango <strong>de</strong> tiempo que <strong>de</strong>sea ser reproducido. Por ejemplo, pue<strong>de</strong><br />
solicitarse el envío <strong>de</strong> un <strong>de</strong>terminado intervalo <strong>de</strong>limitado por su instante inicial<br />
e instante final, o bien reproducción in<strong>de</strong>finida a partir <strong>de</strong> un momento dado.<br />
Estas marcas <strong>de</strong> tiempo pue<strong>de</strong>n en<strong>con</strong>trarse en diferentes formatos, en este caso<br />
tanto VLC como QuickTime usan el formato npt, en el cual el tiempo se expresa<br />
en segundos.<br />
Opcionalmente la cabecera Range pue<strong>de</strong> incluir el campo Time, que<br />
incluye el momento en que la reproducción <strong>de</strong>be comenzar en formato UTC 15 . Si<br />
no se indica este campo la reproducción <strong>de</strong>be comenzar inmediatamente. Los<br />
clientes VLC y QuickTime no incluyen el campo Time, sin embargo el servidor<br />
está preparado para re<strong>con</strong>ocerlo. Es interesante el hecho <strong>de</strong> que los dos<br />
reproductores difieren en el uso <strong>de</strong>l <strong>protocolo</strong>, aunque en este caso sea una<br />
diferencia que no afecta al funcionamiento: VLC no especifica el instante final<br />
15 UTC es el tiempo universal coordinado. Es la zona horaria <strong>de</strong> referencia respecto a la cual se calculan<br />
todas las otras zonas <strong>de</strong>l mundo
<strong>de</strong> la reproducción, mientras que QuickTime sí (el instante final es la duración<br />
<strong>de</strong>l archivo).<br />
En este ejemplo se pue<strong>de</strong> observar el uso <strong>de</strong> la cabecera Range, y cómo el<br />
instante final correspon<strong>de</strong> al tamaño <strong>de</strong>l archivo que se había indicado en el SDP<br />
(ver ejemplo <strong>de</strong> la petición DESCRIBE). En el caso <strong>de</strong>l VLC el formato <strong>de</strong> la<br />
cabecera Range sería simplemente: Range: npt=0.000-<br />
PLAY rtsp://192.168.1.2:20000/vi<strong>de</strong>o.mpg <strong>RTSP</strong>/1.0<br />
CSeq: 3<br />
Range: npt=0.000000-151.700000<br />
x-prebuffer: maxtime=2.000000<br />
Session: 902818185<br />
User-Agent: QuickTime E-/7.1.6 (qtver=7.1.6;os=Windows NT<br />
5.1Service Pack 2)<br />
<strong>RTSP</strong>/1.0 200 OK<br />
Cseq: 4<br />
Session: 902818185<br />
• TEARDOWN: este mensaje se usa para <strong>de</strong>tener la transmisión. A<strong>de</strong>más el<br />
servidor <strong>de</strong>be liberar todos los recursos y la información <strong>de</strong> estado asociados <strong>con</strong><br />
la sesión <strong>RTSP</strong>. De hecho, si tras un mensaje TEARDOWN el cliente <strong>de</strong>sea<br />
volver a recibir el mismo <strong>con</strong>tenido, <strong>de</strong>berá volver a enviar los mensajes SETUP<br />
a<strong>de</strong>cuados antes <strong>de</strong> po<strong>de</strong>r usar el mensaje PLAY.<br />
TEARDOWN rtsp://192.168.1.2:20000/vi<strong>de</strong>o.mpg <strong>RTSP</strong>/1.0<br />
CSeq: 4<br />
Session: 902818185<br />
User-Agent: QuickTime E-/7.1.6 (qtver=7.1.6;os=Windows NT<br />
5.1Service Pack 2)<br />
Como se pue<strong>de</strong> apreciar la respuesta al mensaje TEARDOWN ya no<br />
<strong>con</strong>tiene un número <strong>de</strong> sesión, <strong>de</strong>notando <strong>de</strong> esta manera que la sesión <strong>RTSP</strong> ha<br />
terminado.
<strong>RTSP</strong>/1.0 200 OK<br />
Cseq: 4<br />
3.5.4.3.2. Otros mensajes implementados<br />
Ahora se enumeran otros mensajes que se han implementado en el servidor y<br />
que aña<strong>de</strong>n alguna característica adicional.<br />
• PAUSE: este mensaje no es estrictamente necesario para la transmisión pero<br />
también se ha implementado en el servidor, para añadir funcionalidad en el<br />
cliente y por resultar su implementación posible. Evi<strong>de</strong>ntemente, sirve para<br />
<strong>de</strong>tener temporalmente el envío <strong>de</strong> información. Para reanudarla posteriormente<br />
no habrá que enviar un nuevo mensaje PAUSE, si no PLAY. Hay que tener en<br />
cuenta que en el caso <strong>de</strong> transmisión en vivo, pausarla significa per<strong>de</strong>r parte <strong>de</strong>l<br />
<strong>con</strong>tenido. En el caso <strong>de</strong> nuestro servidor simplemente se <strong>de</strong>tiene el envío <strong>de</strong> los<br />
datos RTP.<br />
PAUSE rtsp://192.168.1.2:20000/vi<strong>de</strong>o.mpg <strong>RTSP</strong>/1.0<br />
CSeq: 10<br />
Session: 902818185<br />
User-Agent: QuickTime E-/7.1.6 (qtver=7.1.6;os=Windows NT<br />
5.1Service Pack 2)<br />
<strong>RTSP</strong>/1.0 200 OK<br />
Cseq: 10<br />
Session: 902818185<br />
• OPTIONS: Ha sido necesario incluir este tipo <strong>de</strong> mensajes entre los que el<br />
servidor es capaz <strong>de</strong> re<strong>con</strong>ocer, ya que el reproductor VLC lo utiliza para<br />
empezar las sesiones <strong>de</strong> <strong>streaming</strong>. QuickTime por el <strong>con</strong>trario no lo usa, lo cual<br />
es otro ejemplo <strong>de</strong> cómo los diferentes reproductores (y servidores) pue<strong>de</strong>n<br />
hacer un uso diferente <strong>de</strong>l <strong>protocolo</strong>. El mensaje OPTIONS es enviado por un<br />
cliente al servidor <strong>con</strong> el objetivo <strong>de</strong> obtener información acerca <strong>de</strong> algún<br />
<strong>con</strong>tenido multimedia o <strong>de</strong>l propio servidor. En el segundo caso, como el
mensaje no se refiere a ningún <strong>con</strong>tenido multimedia en particular, la primera<br />
línea <strong>de</strong> la petición <strong>con</strong>tendrá un asterisco en lugar <strong>de</strong> una URL.<br />
El servidor pue<strong>de</strong> <strong>con</strong>testar <strong>con</strong> diferentes tipos <strong>de</strong> información,<br />
<strong>de</strong>pendiendo este extremo <strong>de</strong> la implementación <strong>de</strong> cada servidor en <strong>con</strong>creto.<br />
Por ejemplo en el caso <strong>de</strong> que la URL sea un asterisco, pue<strong>de</strong> informar <strong>de</strong> los<br />
tipos <strong>de</strong> mensajes <strong>RTSP</strong> que admite, que es la solución que se ha adoptado en el<br />
caso que nos ocupa aunque se reciba una URL que haga referencia a algún<br />
archivo en <strong>con</strong>creto. De esta forma se <strong>con</strong>sigue evitar que el cliente envíe al<br />
servidor mensajes que este no sea capaz <strong>de</strong> re<strong>con</strong>ocer. Por último hay que<br />
señalar que el servidor también pue<strong>de</strong> enviar una petición OPTIONS al cliente,<br />
aunque esta opción es infrecuente.<br />
En este ejemplo se muestra el mensaje OPTIONS que el cliente VLC le<br />
envía al servidor como paso previo a la petición DESCRIBE.<br />
OPTIONS rtsp://192.168.1.2:20000/vi<strong>de</strong>o.mpg <strong>RTSP</strong>/1.0<br />
CSeq: 1<br />
User-Agent: VLC media player (LIVE555 Streaming Media<br />
v2006.10.27)<br />
La solución adoptada ha sido informar en la respuesta <strong>de</strong> los otros<br />
mensajes <strong>RTSP</strong> que el servidor es capaz <strong>de</strong> enten<strong>de</strong>r, mediante la cabecera<br />
Public.<br />
<strong>RTSP</strong>/1.0 200 OK<br />
Cseq: 1<br />
Public: DESCRIBE, SETUP, PLAY, PAUSE, TEARDOWN<br />
3.5.4.3.3. Resto <strong>de</strong> mensajes <strong>RTSP</strong>
En los apartados anteriores se han <strong>de</strong>scrito los mensajes necesarios para la<br />
reproducción <strong>de</strong> <strong>streaming</strong> y los mensajes adicionales implementados en este servidor.<br />
Para ofrecer una visión más completa <strong>de</strong>l <strong>protocolo</strong> <strong>RTSP</strong> en su <strong>con</strong>junto, a<br />
<strong>con</strong>tinuación se enumeran el resto <strong>de</strong> mensajes disponibles, <strong>de</strong>scribiendo brevemente su<br />
utilidad.<br />
• ANNOUNCE: el mensaje ANNOUNCE pue<strong>de</strong> ser enviado <strong>de</strong>l cliente al<br />
servidor o <strong>de</strong>l servidor al cliente, y su objetivo varía en cada caso.<br />
o Si se envía <strong>de</strong>l cliente al servidor, sirve para <strong>de</strong>positar en éste último<br />
información <strong>de</strong> <strong>de</strong>scripción sobre un <strong>con</strong>tenido multimedia asociado a<br />
una URL. Es <strong>de</strong>cir, sirve para cambiar el estado <strong>de</strong>l servidor, por ejemplo<br />
<strong>con</strong>siguiendo que asocie un nuevo SDP a un <strong>de</strong>terminado archivo.<br />
o Enviándolo <strong>de</strong>l servidor al cliente, se <strong>con</strong>siguen actualizar los datos <strong>de</strong><br />
<strong>de</strong>scripción en tiempo real, sin <strong>de</strong>tener la transmisión <strong>de</strong> datos. Por<br />
ejemplo si en un instante <strong>de</strong>terminado se cambia una pista por otra cuyo<br />
formato es diferente, es posible informar <strong>de</strong> ello al reproductor mediante<br />
un mensaje ANNOUNCE que <strong>con</strong>tendrá el SDP actualizado, sin<br />
necesidad <strong>de</strong> reiniciar la sesión.<br />
• GET_PARAMETER: El cliente pue<strong>de</strong> usar este mensaje para solicitar algún<br />
tipo <strong>de</strong> información <strong>con</strong>creta asociada a la <strong>de</strong>scripción <strong>de</strong> un <strong>con</strong>tenido, aunque<br />
esto no es muy frecuente puesto que la mayoría <strong>de</strong> la información <strong>de</strong>bería venir<br />
<strong>con</strong>tenida en la respuesta a la petición DESCRIBE. En realidad la<br />
implementación <strong>de</strong> la respuesta a este mensaje <strong>de</strong>pen<strong>de</strong> mucho <strong>de</strong> cada servidor.<br />
• SET_PARAMETER: Se pue<strong>de</strong>n enviar en ambos sentidos y sirven para<br />
establecer el valor <strong>de</strong> algún parámetro en el otro miembro <strong>de</strong> la sesión. Esto no<br />
pue<strong>de</strong> incluir parámetros acerca <strong>de</strong>l transporte <strong>de</strong> los datos, cuyos valores se<br />
<strong>de</strong>ben establecer exclusivamente por medio <strong>de</strong> los mensajes SETUP. Al igual<br />
que en el caso <strong>de</strong>l mensaje GET_PARAMETER, la implementación varía <strong>de</strong><br />
unos servidores a otros y a<strong>de</strong>más su uso no está muy extendido.
• REDIRECT: Mediante este mensaje un servidor es capaz <strong>de</strong> indicarle al cliente<br />
que <strong>de</strong>berá realizar una nueva <strong>con</strong>exión a otra dirección <strong>de</strong> red y/o puerto para<br />
<strong>con</strong>tinuar usando el servidor <strong>RTSP</strong>. Opcionalmente podrá indicar a<strong>de</strong>más en qué<br />
momento se va a producir este cambio, <strong>de</strong> lo <strong>con</strong>trario se interpretará que el<br />
cambio se produce inmediatamente. Cuando el momento llegue el cliente <strong>de</strong>berá<br />
terminar la actual sesión <strong>con</strong> un mensaje TEARDOWN y establecerá una<br />
<strong>con</strong>exión en la nueva localización.<br />
• RECORD: Es posible que el servidor disponga <strong>de</strong> algún dispositivo <strong>de</strong><br />
grabación, esto es, que le permita crear un archivo multimedia en local<br />
obteniendo los datos <strong>de</strong> alguna fuente externa. En este caso el cliente podrá<br />
enviarle un mensaje RECORD para que el servidor realice dicha grabación. El<br />
mensaje pue<strong>de</strong> incluir el rango <strong>de</strong> tiempo que se <strong>de</strong>be grabar, en caso <strong>con</strong>trario<br />
la grabación <strong>de</strong>berá empezar inmediatamente. Los datos también podrían<br />
obtenerse <strong>de</strong> algún recurso <strong>de</strong> red, en este caso el mensaje RECORD <strong>de</strong>berá<br />
incluir la localización <strong>de</strong> dicho recurso.<br />
Como apunte final respecto a los mensajes <strong>RTSP</strong> hay que hacer notar lo fácil que<br />
resultaría exten<strong>de</strong>r el <strong>protocolo</strong> <strong>con</strong> nuevos mensajes por ser un <strong>protocolo</strong> puramente<br />
textual, bastaría que el servidor y el cliente fueran capaces <strong>de</strong> enten<strong>de</strong>rlos.<br />
También cabe señalar que a<strong>de</strong>más <strong>de</strong> los reproductores VLC y QuickTime se<br />
trató <strong>de</strong> que el servidor fuera compatible <strong>con</strong> el reproductor Windows Media Player,<br />
posibilidad que se <strong>con</strong>si<strong>de</strong>ró interesante <strong>de</strong>bido a su popularidad. Sin embargo esto<br />
resultó no ser posible, <strong>de</strong>bido al uso que hace este reproductor <strong>de</strong>l <strong>protocolo</strong>.<br />
Observando los mensajes intercambiados <strong>con</strong> servidores <strong>RTSP</strong> alojados en Internet, se<br />
comprobó que ignora el <strong>protocolo</strong> en su mayoría, ya que si bien la secuencia <strong>de</strong><br />
mensajes es similar, ignora la mayoría <strong>de</strong> cabeceras <strong>de</strong>scritas en la RFC y usa las suyas<br />
propias. Para que un servidor sea compatible <strong>con</strong> Windows Media Player <strong>de</strong>be ser capaz<br />
<strong>de</strong> enten<strong>de</strong>r sus cabeceras particulares más allá <strong>de</strong> la especificación <strong>de</strong>l <strong>protocolo</strong>, esto<br />
se comprobó observando servidores <strong>RTSP</strong> comerciales, los cuales necesitan algún tipo<br />
<strong>de</strong> <strong>con</strong>figuración especial para aten<strong>de</strong>r las peticiones <strong>de</strong> este reproductor. Debido a estas<br />
circunstancias fue <strong>de</strong>scartado.
3.5.4.4. Aspectos <strong>de</strong> la implementación <strong>de</strong>l <strong>protocolo</strong><br />
Para la interpretación <strong>de</strong> los mensajes se utiliza un analizador sintáctico<br />
generado <strong>con</strong> la herramienta JavaCC, que es capaz <strong>de</strong> i<strong>de</strong>ntificar el tipo <strong>de</strong> mensaje a<br />
partir <strong>de</strong> su primera línea y <strong>de</strong>spués extraer el <strong>con</strong>tenido <strong>de</strong> las cabeceras y el cuerpo. En<br />
el caso <strong>de</strong> que el mensaje <strong>con</strong>tenga cuerpo, será necesario tener en cuenta el número <strong>de</strong><br />
caracteres que lo componen para po<strong>de</strong>r leerlo, dato que vendrá indicado en la cabecera<br />
Content-Length. Se ha implementado una clase abstracta llamada RtspRequest, que<br />
engloba a todos los tipos <strong>de</strong> peticiones y almacena los elementos comunes a todos los<br />
tipos <strong>de</strong> mensajes, comunes en el sentido <strong>de</strong> que pue<strong>de</strong>n aparecer en cualquier mensaje<br />
aunque no siempre es obligatorio. Son los siguientes:<br />
• Url: se utiliza para indicar el recurso multimedia o pista <strong>con</strong>creta a la que se<br />
hace referencia, pue<strong>de</strong> referirse al servidor en general si es un asterisco.<br />
• Versión: indica el <strong>protocolo</strong> <strong>RTSP</strong> utilizado, actualmente solo existe el 1.0 pero<br />
se almacena pensando en la evolución futura <strong>de</strong>l <strong>protocolo</strong>.<br />
• Cabecera Cseq: número <strong>de</strong> secuencia, que se irá incrementando en cada<br />
mensaje <strong>de</strong>l cliente. Las respuestas <strong>de</strong>berán <strong>con</strong>tener el mismo número <strong>de</strong><br />
secuencia que la petición a la que correspon<strong>de</strong>n.<br />
• Cabecera Session: i<strong>de</strong>ntificador <strong>de</strong> <strong>de</strong> sesión.<br />
• Cabecera Content-Length: aparece si el mensaje incluye un cuerpo, y es su<br />
tamaño en número <strong>de</strong> caracteres.<br />
• Cabecera User-Agent: informa sobre qué cliente está enviando la petición, no<br />
se tiene en cuenta.<br />
• Cabecera Accept-Language: en esta cabecera establece un idioma, por ejemplo<br />
podría tener utilidad si para un <strong>de</strong>terminado recurso existen pistas <strong>de</strong> audio en<br />
diferentes idiomas, en este servidor no se tiene en cuenta<br />
Por cada tipo <strong>de</strong> petición hay una clase que extien<strong>de</strong> a la clase abstracta<br />
RtspRequest, e incorpora los campos necesarios para almacenar las cabeceras
particulares <strong>de</strong>l tipo <strong>de</strong> mensaje, en caso <strong>de</strong> haber alguna. A <strong>con</strong>tinuación se listan estas<br />
clases y en su caso los campos particulares.<br />
• OptionsRequest<br />
• DescribeRequest<br />
o Accept: Indica el tipo <strong>de</strong> <strong>de</strong>scripción solicitada por el cliente (por<br />
ejemplo SDP). Se utiliza una lista, ya que se pue<strong>de</strong>n incluir varios tipos<br />
<strong>de</strong> <strong>de</strong>scripciones.<br />
o Bandwidth: cabecera <strong>con</strong> un valor numérico relacionado <strong>con</strong> el ancho <strong>de</strong><br />
• SetupRequest<br />
banda que envía el reproductor QuickTime.<br />
o Transport: es la cabecera que <strong>con</strong>tiene los datos <strong>de</strong> transporte. Para<br />
almacenar su <strong>con</strong>tenido se utiliza una estructura anidada, ya que los<br />
diferentes campos <strong>con</strong>tenidos en ella pue<strong>de</strong>n tener a<strong>de</strong>más su propio<br />
valor. Por ejemplo un campo <strong>de</strong>ntro <strong>de</strong> la cabecera Transport será<br />
Client-Port, y su valor la pareja <strong>de</strong> puertos RTP/<strong>RTSP</strong>. Otros datos<br />
habituales <strong>de</strong>ntro <strong>de</strong> esta cabecera son el <strong>protocolo</strong> <strong>de</strong> datos y si se trata<br />
<strong>de</strong> una transmisión unicast o multicast.<br />
o Se almacenan otras cabeceras relacionadas que el reproductor<br />
• PlayRequest<br />
QuickTime incluye en el mensaje y <strong>de</strong> las cuales no se hace uso, se<br />
<strong>de</strong>s<strong>con</strong>oce su utilidad puesto que no vienen <strong>de</strong>finidas en la RFC que<br />
<strong>de</strong>fine el <strong>protocolo</strong> <strong>RTSP</strong>. Son x-retransmit, x-dynamic-rate y x-<br />
transport-options.<br />
o Range: esta cabecera <strong>con</strong>tiene varios campos relativos al fragmento <strong>de</strong>l<br />
<strong>con</strong>tenido multimedia que se <strong>de</strong>sea reproducir, algunos <strong>de</strong> ellos<br />
opcionales. En primer lugar <strong>con</strong>tiene el rango <strong>de</strong> tiempo que se <strong>de</strong>sea<br />
reproducir, incluyendo el instante inicial y el final, en caso <strong>de</strong> no existir<br />
este último la reproducción es in<strong>de</strong>finida. A<strong>de</strong>más esta información<br />
pue<strong>de</strong> venir indicada en diferentes formatos, por ejemplo en segundos u<br />
otros. Por lo tanto se almacenan estos tres campos: formato <strong>de</strong> tiempo,<br />
instante inicial e instante final. La implementación también está<br />
preparada para re<strong>con</strong>ocer el campo Time si existiera, aunque ni VLC ni
• PauseRequest<br />
QuickTime hacen uso <strong>de</strong> él. En el mensaje play nuevamente QuickTime<br />
incluye una cabecera no <strong>de</strong>scrita en la RFC: x-prebuffer.<br />
• TearDownRequest<br />
Como nota final sobre el almacenamiento <strong>de</strong> las peticiones en estas clases Java,<br />
hay que hacer notar el hecho <strong>de</strong> que se almacenan algunos parámetros que luego no se<br />
tienen en cuenta a la hora <strong>de</strong> generar la respuesta. Se ha <strong>con</strong>si<strong>de</strong>rado que esta es la<br />
implementación más correcta, ya que cabe la posibilidad <strong>de</strong> que el servidor evolucione y<br />
se tengan en cuenta en el futuro. A<strong>de</strong>más a modo <strong>de</strong> trazas, los sucesivos mensajes <strong>de</strong><br />
petición y respuesta se muestran por pantalla, y su <strong>con</strong>tenido se extrae <strong>de</strong> estas clases,<br />
así que es necesario almacenar todos los datos para reproducir fielmente todas las<br />
peticiones.<br />
Con esta separación entre clases <strong>de</strong>pendiendo <strong>de</strong>l tipo <strong>de</strong> petición, la clase<br />
RequestHandler sabrá qué tipo <strong>de</strong> petición habrá llegado e invocará un método<br />
diferente para aten<strong>de</strong>r a cada una <strong>de</strong> ellas. Estas clases habrán sido generadas por el<br />
analizador obtenido mediante JavaCC, cuyo código java se encuentra en la clase<br />
RtspRequestParser y algunas otras clases auxiliares asociadas.<br />
En cuanto a las respuestas, se ha implementado una única clase RtspResponse.<br />
Esta clase ofrece los métodos necesarios para especificar la primera línea <strong>con</strong> su código<br />
<strong>de</strong> estado correspondiente, cuantas cabeceras sean necesarias y finalmente el cuerpo <strong>de</strong>l<br />
mensaje. Para garantizar la fiabilidad en el envío <strong>de</strong> las respuestas a los reproductores,<br />
estas se pasan a formato <strong>de</strong> texto plano usando el juego <strong>de</strong> estándar <strong>de</strong> caracteres UTF-<br />
8, y finalmente se envían en forma <strong>de</strong> ristra <strong>de</strong> bytes.
3.5.5. Mantenimiento <strong>de</strong>l estado en el servidor<br />
Como se ha mencionado, un servidor <strong>RTSP</strong> <strong>de</strong>be mantener información <strong>de</strong><br />
estado acerca <strong>de</strong> todas las sesiones activas, y el servidor que se ha creado cumple dicho<br />
requisito. En este apartado se van a <strong>de</strong>scribir qué métodos y estructuras <strong>de</strong> datos se han<br />
utilizado para <strong>con</strong>seguir este objetivo, y cómo se relacionan los mensajes <strong>RTSP</strong> <strong>con</strong> la<br />
información <strong>con</strong>tenida en estas estructuras.<br />
3.5.5.1. Estructura <strong>de</strong> datos<br />
Las principales clases involucradas son RtspSeverStatus y RtspSessionData.<br />
El servidor llevará asociado un solo objeto RtspServerStatus, que <strong>con</strong>tendrá ciertos<br />
aspectos <strong>de</strong>l estado general <strong>de</strong>l servidor, y a<strong>de</strong>más <strong>con</strong>tendrá un <strong>con</strong>junto <strong>de</strong> instancias<br />
<strong>de</strong> la clase RtspSessionData, cada una <strong>de</strong> ellas almacenará la información <strong>de</strong> una<br />
sesión <strong>RTSP</strong>.<br />
siguientes:<br />
Los campos <strong>de</strong> información que almacena la clase RtspServerStatus son los<br />
• SdpGenerator: referencia al objeto que implementa esta interfaz y se encargará<br />
<strong>de</strong> obtener los SDP.
• Tipo <strong>de</strong> RtpSen<strong>de</strong>r: una variable que indica qué implementación <strong>de</strong> esta interfaz<br />
se va a usar, <strong>de</strong> este modo se sabrá qué clase habrá que instanciar cuando sea<br />
necesario crear un nuevo flujo <strong>de</strong> datos RTP.<br />
• Un <strong>con</strong>junto <strong>de</strong> referencias a objetos RtspSessionData, almacenadas en una<br />
tabla Hash e in<strong>de</strong>xadas mediante el número <strong>de</strong> sesión.<br />
• Ruta al directorio don<strong>de</strong> se encuentran los archivos servidos, esta información<br />
será necesaria a la hora <strong>de</strong> crear los flujos RTP para <strong>con</strong>ocer la ubicación <strong>de</strong>l<br />
archivo origen.<br />
• Información auxiliar sobre el analizador sintáctico: el analizador creado <strong>con</strong><br />
JavaCC es una clase estática que necesita inicialización la primera vez que se va<br />
a usar y una re-inicialización cada vez que se vaya a volver a usar <strong>con</strong><br />
posterioridad mediante la llamada a un método diferente, así que aquí se<br />
almacena un flag que indica si ha sido inicializado por primera vez.<br />
Se creará un objeto RtspSessionData por cada sesión <strong>RTSP</strong>, y tendrá los<br />
siguientes campos:<br />
• Flag indicando si el cliente <strong>de</strong>sea la pista <strong>de</strong> ví<strong>de</strong>o.<br />
• Flag indicando si el cliente <strong>de</strong>sea la pista audio.<br />
• Dirección Ip <strong>de</strong>stino para el ví<strong>de</strong>o.<br />
• Dirección Ip <strong>de</strong>stino para el audio (no parece tener sentido que las direcciones<br />
<strong>de</strong> red para audio y ví<strong>de</strong>o sean diferentes, pero la especificación <strong>de</strong>l <strong>protocolo</strong> lo<br />
permite así que se ha tenido en cuenta).<br />
• Puerto <strong>de</strong>stino para el ví<strong>de</strong>o.<br />
• Puerto <strong>de</strong>stino para el audio.<br />
• Referencia al objeto que implementa RtpSen<strong>de</strong>r.<br />
• Contenido SDP <strong>de</strong>l archivo que se está sirviendo.<br />
• Variable que indica el estado <strong>de</strong> la transmisión RTP, que pue<strong>de</strong> ser Deallocated<br />
(no inicializada), Playing (reproduciendo) y Paused (pausada).<br />
En la figura 3.7 se muestra un esquema <strong>de</strong> la estructura <strong>de</strong> datos que usa el<br />
servidor para el mantenimiento <strong>de</strong>l estado.
Figura 3.7: estructura <strong>de</strong> datos para el estado <strong>de</strong>l servidor<br />
3.5.5.2. Relación entre los mensajes <strong>RTSP</strong> y el estado <strong>de</strong>l servidor<br />
Una vez <strong>de</strong>scrita la estructura <strong>de</strong> datos en la que se almacena el estado <strong>de</strong>l<br />
servidor, ahora se explicará cuándo y cómo se modifican sus datos, y en qué momento<br />
se hará uso <strong>de</strong> ellos, en función <strong>de</strong> los mensajes <strong>RTSP</strong>.<br />
• Al recibir el mensaje DESCRIBE, el servidor pedirá al módulo SdpGenerator<br />
el SDP asociado a la URL <strong>de</strong>l mensaje. En realidad el módulo SdpGenerator<br />
<strong>de</strong>vuelve un objeto <strong>de</strong> la clase SdpContent, que incluye toda la información<br />
relevante sobre el SDP:<br />
o URL asociada a la pista <strong>de</strong> ví<strong>de</strong>o.<br />
o URL asociada a la pista <strong>de</strong> audio.<br />
o El propio SDP en forma <strong>de</strong> ca<strong>de</strong>na <strong>de</strong> caracteres, se incluirá en la<br />
respuesta al cliente.<br />
Si el archivo solicitado no existe, el SdpGenerator lanzará una<br />
excepción, que será capturada y provocará el envío al cliente <strong>de</strong> un mensaje<br />
informando <strong>de</strong> tal circunstancia<br />
• Cuando el servidor reciba el primer mensaje SETUP, creará primeramente un<br />
número <strong>de</strong> sesión aleatorio, y <strong>de</strong>spués un objeto RtspSessionData. Dicho<br />
objeto será almacenado en la tabla Hash <strong>con</strong>tenida en la clase
RtspServerStatus, siendo in<strong>de</strong>xado mediante el propio i<strong>de</strong>ntificador <strong>de</strong> sesión.<br />
El servidor sabrá que se trata <strong>de</strong>l primer mensaje SETUP porque no incluirá<br />
i<strong>de</strong>ntificador <strong>de</strong> sesión alguno.<br />
Después comparará la URL <strong>de</strong>l mensaje <strong>con</strong> el <strong>con</strong>tenido <strong>de</strong>l objeto<br />
SdpContent, y así sabrá si el mensaje hace referencia a la pista <strong>de</strong> audio o ví<strong>de</strong>o,<br />
activando el flag correspondiente. Posteriormente extraerá la información <strong>de</strong><br />
transporte, <strong>con</strong>tenida en la cabecera Transport <strong>de</strong>l mensaje. Los puertos <strong>de</strong><br />
<strong>de</strong>stino RTP/RTCP estarán en el campo Client-Port. Se comprobará si existe<br />
el campo Client-Ip-Address, en caso afirmativo se extraerá <strong>de</strong> él la dirección<br />
IP <strong>de</strong> <strong>de</strong>stino y <strong>de</strong> lo <strong>con</strong>trario será la propia dirección <strong>de</strong> la <strong>con</strong>exión <strong>con</strong> el<br />
cliente.<br />
Inicialmente a<strong>de</strong>más el valor <strong>de</strong>l estado <strong>de</strong> la transmisión RTP es<br />
<strong>de</strong>allocated, puesto que ni siquiera se ha creado el objeto RtpGenerator. Todos<br />
estos datos son almacenados en el objeto RtspSessionData.<br />
• Si existe otra pista y el cliente la <strong>de</strong>sea activar, enviará un segundo mensaje<br />
SETUP. Este mensaje incorporará un número <strong>de</strong> sesión igual al <strong>de</strong>vuelto en la<br />
respuesta anterior, así que en lugar <strong>de</strong> crear un nuevo objeto <strong>de</strong> estado, se<br />
acce<strong>de</strong>rá al objeto RtspSessionData correspondiente, y se almacenarán los<br />
parámetros <strong>de</strong> transporte <strong>de</strong> forma análoga al caso anterior. Si por alguna razón<br />
el cliente necesitara cambiar nuevamente los parámetros <strong>de</strong> alguna pista, podría<br />
hacerlo sin problemas enviando nuevos mensajes SETUP, sobrescribiendo el<br />
servidor los valores <strong>de</strong> transporte.<br />
• Una vez que el cliente haya enviado todos los mensajes SETUP y recibido sus<br />
correspondientes respuestas, es <strong>de</strong> esperar que envíe la petición PLAY. En este<br />
caso el servidor seguirá un flujo <strong>de</strong> <strong>con</strong>trol diferente <strong>de</strong>pendiendo <strong>de</strong> si se está<br />
usando el módulo JmfRtpSen<strong>de</strong>r o VlcRtpSen<strong>de</strong>r para el stream. Sin embargo<br />
la estructura <strong>de</strong> las acciones a realizar serán las mismas en los dos casos:<br />
o Si el estado <strong>de</strong> la transmisión era Deallocated (sin inicializar), se tendrá<br />
que crear el objeto correspondiente que se encargará <strong>de</strong> generación <strong>de</strong> los<br />
flujos RTP hacia el cliente, que será una instancia <strong>de</strong> la clase<br />
JmfRtpSen<strong>de</strong>r o VlcRtpSen<strong>de</strong>r, ambos implementan la interfaz<br />
RtpSen<strong>de</strong>r. Para ello se tendrán en cuenta los parámetros <strong>de</strong> <strong>con</strong>trol<br />
almacenados previamente al recibir los mensajes SETUP: qué pistas
están activadas, dirección y puerto <strong>de</strong> <strong>de</strong>stino para cada una <strong>de</strong> ellas,<br />
nombre <strong>de</strong>l fichero multimedia y directorio en el que se encuentra.<br />
También se pasa como parámetro una referencia al objeto<br />
RtspSessionData para que el propio encargado <strong>de</strong> la transmisión <strong>de</strong><br />
datos pueda modificar el estado <strong>de</strong> la transmisión. Una vez que el objeto<br />
RtpSen<strong>de</strong>r esté creado, se comenzará la transmisión llamando al método<br />
startTransmission, pasándole como parámetro el instante <strong>de</strong> tiempo<br />
inicial indicado en la cabecera Range <strong>de</strong>l mensaje PLAY.<br />
o Si el estado <strong>de</strong> la transmisión era Paused o Playing, querrá <strong>de</strong>cir que<br />
reinicia la transmisión tras haber sido pausada, o que el usuario ha<br />
movido la barra <strong>de</strong> <strong>de</strong>splazamiento en el reproductor, lo que provoca que<br />
éste envíe un nuevo mensaje PLAY indicando el nuevo momento inicial<br />
a partir <strong>de</strong>l cual se <strong>de</strong>be reproducir. En ambos casos el comportamiento<br />
será el mismo, iniciar la transmisión <strong>de</strong>s<strong>de</strong> el momento dado mediante el<br />
método startTransmission.<br />
Como es lógico, en cualquiera <strong>de</strong> las circunstancias anteriormente citadas<br />
el estado <strong>de</strong> la transmisión pasa a ser Playing. Hay que resaltar que nuevamente<br />
aparece una diferencia significativa entre el comportamiento <strong>de</strong> los<br />
reproductores QuickTime y VLC. Cuando se mueve la barra <strong>de</strong> <strong>de</strong>splazamiento,<br />
VLC simplemente envía un mensaje PLAY <strong>con</strong> el nuevo instante inicial,<br />
mientras que QuickTime envía primero un mensaje PAUSE e inmediatamente<br />
<strong>de</strong>spués el mensaje PLAY. En todo caso el resultado es el mismo.<br />
• Eventualmente es posible recibir un mensaje PAUSE <strong>de</strong>l reproductor. El servidor<br />
se limita a llamar al método pauseTransmission <strong>de</strong>l RtpSen<strong>de</strong>r. El estado <strong>de</strong><br />
la transmisión pasa a ser paused.<br />
• Finalmente, en algún momento dado el reproductor enviará un mensaje<br />
TEARDOWN. Se ha comprobado que esto suce<strong>de</strong> si se cierra la ventana <strong>de</strong>l<br />
reproductor, o si se llega al final <strong>de</strong> la reproducción y se <strong>de</strong>ja pasar un tiempo.<br />
En primer lugar el servidor llamará al método tearDownTransmission <strong>de</strong>l<br />
RtpSen<strong>de</strong>r para que este libere internamente sus recursos. Después borrará el<br />
objeto RtspSessionData <strong>de</strong> la estructura guardada en RtspServerStatus,<br />
borrando así el estado <strong>de</strong> la sesión en el servidor. En el momento en que se cierre
la <strong>con</strong>exión a nivel <strong>de</strong> transporte <strong>con</strong> el cliente el hilo <strong>de</strong> ejecución <strong>de</strong>l objeto<br />
RequestHandler llegará a su fin, <strong>de</strong>struyéndose también este objeto. En<br />
<strong>con</strong>clusión, cualquier recurso asociado <strong>con</strong> la sesión que ha finalizado habrá<br />
sido eliminado <strong>de</strong>l servidor.<br />
Para facilitar la comprensión <strong>de</strong> esta secuencia <strong>de</strong> mensajes y acciones a<br />
<strong>con</strong>tinuación se muestra en la figura 3.8 un diagrama <strong>de</strong> secuencia que correspon<strong>de</strong> a<br />
una sesión <strong>RTSP</strong>, en la cual se reproduce un archivo que <strong>con</strong>sta <strong>de</strong> una sola pista (un<br />
solo mensaje SETUP). A<strong>de</strong>más se incluye una pausa durante la transmisión.
Figura 3.8: secuencia <strong>de</strong> mensajes <strong>RTSP</strong> y cambios <strong>de</strong> estado en el servidor
3.5.6. Módulo JmfRtpSen<strong>de</strong>r<br />
En este capítulo se va a <strong>de</strong>scribir el funcionamiento <strong>de</strong> esta clase, la cual pue<strong>de</strong><br />
ser utilizada por el servidor <strong>RTSP</strong> si se <strong>con</strong>figura a tal efecto. Para la implementación se<br />
ha usado la API Java Media Framework, cuyas características generales ya han sido<br />
<strong>de</strong>scritas. A partir <strong>de</strong> ahora se explicará más <strong>de</strong>talladamente el proceso <strong>de</strong> <strong>streaming</strong> a<br />
través <strong>de</strong> RTP usando JMF, y cómo se ha integrado <strong>con</strong> el resto <strong>de</strong>l servidor. Se hará<br />
especial hincapié en las clases relacionadas <strong>con</strong> la transmisión a través <strong>de</strong> RTP. Hay que<br />
tener en cuenta que la API está formada por multitud <strong>de</strong> clases y estructuras, y no es<br />
posible abarcar todas en este documento. Por ello se tratará <strong>de</strong> mencionar solo las más<br />
relevantes para tratar <strong>de</strong> ofrecer una i<strong>de</strong>a global <strong>de</strong> cómo funciona la API, y se<br />
explicarán <strong>de</strong>talladamente las relacionadas <strong>con</strong> la solución que se ha implementado.<br />
3.5.6.1. Arquitectura <strong>de</strong> Java Media Framework<br />
Des<strong>de</strong> el punto <strong>de</strong> vista <strong>con</strong>ceptual, JMF abstrae el <strong>con</strong>tenido multimedia en<br />
DataSources (fuentes <strong>de</strong> datos, a través <strong>de</strong> las cuales se lee el <strong>con</strong>tenido <strong>de</strong>s<strong>de</strong> el<br />
exterior) y DataSinks (<strong>de</strong>stinos para el volcado <strong>de</strong> datos, a través <strong>de</strong> los cuales se<br />
exporta el <strong>con</strong>tenido al exterior). Los DataSources pue<strong>de</strong>n ser un fichero almacenado en<br />
disco, un dispositivo <strong>de</strong> captura o un flujo que llega a través <strong>de</strong> la red. Análogamente los<br />
DataSinks pue<strong>de</strong>n <strong>con</strong>llevar la grabación en un fichero <strong>de</strong> <strong>de</strong>stino, la reproducción a<br />
través <strong>de</strong> un dispositivo <strong>de</strong> salida o el envío <strong>de</strong> un flujo por la red. Entre medias se<br />
pue<strong>de</strong>n realizar diversas tareas <strong>de</strong> procesamiento como compresión/<strong>de</strong>scompresión,<br />
cambio <strong>de</strong>l formato <strong>de</strong> las pistas y aplicación <strong>de</strong> efectos, utilizando entida<strong>de</strong>s llamadas<br />
Processors. Esta estructura se pue<strong>de</strong> ver en la figura 3.9.
Figura 3.9: estructura <strong>de</strong> entrada, procesamiento y salida <strong>de</strong> datos en JMF<br />
A<strong>de</strong>más utilizando los DataSources y DataSinks se pue<strong>de</strong>n enca<strong>de</strong>nar unos<br />
Processors <strong>con</strong> otros, realizando múltiples tareas <strong>de</strong> procesamiento simultáneas,<br />
creando flujos a partir <strong>de</strong> otros, etc. En la figura 3.10 se muestra un ejemplo. Esta<br />
arquitectura encaja bastante bien <strong>con</strong> la estructura <strong>modular</strong> <strong>de</strong>l servidor que se preten<strong>de</strong><br />
implementar en este trabajo.<br />
Figura 3.10: ejemplo <strong>de</strong> estructura <strong>modular</strong> en JMF<br />
Los DataSources, Processors y DataSinks forman parte <strong>de</strong> la API <strong>de</strong> alto nivel<br />
que ofrece JMF, dicha API está orientada a la captura, proceso y presentación <strong>de</strong> la<br />
multimedia. JMF ofrece otra API <strong>de</strong> más bajo nivel <strong>de</strong>stinada a la implementación <strong>de</strong><br />
extensiones y elementos <strong>de</strong> procesamiento más personalizados. En este proyecto se ha<br />
hecho uso <strong>de</strong> la API <strong>de</strong> más alto nivel, puesto que es la ofrece las posibilida<strong>de</strong>s<br />
necesarias para esta tarea. En la figura 3.11, las clases implementadas en el servidor<br />
<strong>RTSP</strong> se en<strong>con</strong>trarían en el nivel más alto, mientras que en el segundo están las clases<br />
JMF que se han utilizado.
Figura 3.11: niveles <strong>de</strong> la API <strong>de</strong> JMF<br />
A <strong>con</strong>tinuación se va a explicar la forma en que JMF aborda ciertos aspectos<br />
relacionados <strong>con</strong> la multimedia, como el manejo <strong>de</strong>l tiempo, eventos, datos y formatos,<br />
a<strong>de</strong>más <strong>de</strong> los mecanismos para <strong>con</strong>trolarlos.<br />
• Mo<strong>de</strong>lo <strong>de</strong> tiempo: JMF <strong>con</strong>trola el tiempo <strong>con</strong> una precisión <strong>de</strong> nanosegundos.<br />
Internamente, JMF lleva cuenta <strong>de</strong>l tiempo transcurrido para cualquier flujo<br />
multimedia. Esto se usa para tareas <strong>de</strong> sincronización tanto interna como entre<br />
varios flujos simultáneos. A<strong>de</strong>más posibilita el <strong>con</strong>trol <strong>de</strong>l tiempo por parte <strong>de</strong>l<br />
<strong>de</strong>sarrollador, por ejemplo alterando la velocidad original <strong>de</strong> un ví<strong>de</strong>o.<br />
• Mo<strong>de</strong>lo <strong>de</strong> eventos: JMF usa una estructura <strong>de</strong> reporte <strong>de</strong> eventos, <strong>con</strong> el<br />
objetivo <strong>de</strong> tener <strong>con</strong>stancia <strong>de</strong>l estado actual <strong>de</strong> cada elemento multimedia y<br />
recibir notificaciones <strong>de</strong> los cambios que puedan experimentar. Existen multitud<br />
<strong>de</strong> tipos <strong>de</strong> eventos diferentes para comunicar diferentes circunstancias. Esto<br />
incluye notificaciones y estados <strong>de</strong> error.<br />
A gran<strong>de</strong>s rasgos, siempre que un objeto <strong>de</strong> JMF necesita comunicar un<br />
evento, lo hace introduciéndolo en la estructura <strong>de</strong> eventos. Este evento podrá<br />
ser recogido por el resto <strong>de</strong> objetos JMF que estén preparados para ello,<br />
<strong>de</strong>pendiendo ya esta circunstancia <strong>de</strong> la implementación <strong>de</strong> cada uno <strong>de</strong> ellos.<br />
Pensando en el servidor objetivo <strong>de</strong> este proyecto, un evento a tener en cuenta<br />
será el llegar al final <strong>de</strong>l fichero que se está sirviendo.<br />
• Mo<strong>de</strong>lo <strong>de</strong> datos: Como se ha mencionado, los DataSources se usan para<br />
representar el origen <strong>de</strong> un <strong>con</strong>tenido multimedia. Un DataSource encapsula<br />
tanto la localización <strong>de</strong>l <strong>con</strong>tenido como el software y el <strong>protocolo</strong> necesarios
para transmitir su <strong>con</strong>tenido. Una vez obtenido un DataSource, no se pue<strong>de</strong><br />
reutilizar para manejar un <strong>con</strong>tenido diferente.<br />
Un DataSource pue<strong>de</strong> estar i<strong>de</strong>ntificado por un MediaLocator o una<br />
URL. Un MediaLocator es similar a una URL y pue<strong>de</strong> ser <strong>con</strong>struido a partir <strong>de</strong><br />
ella, pero ofrece la ventaja <strong>de</strong> que pue<strong>de</strong> ser <strong>con</strong>struido incluso si el<br />
correspondiente manejador <strong>de</strong> <strong>protocolo</strong> no está instalado en el sistema (en Java<br />
una URL solo pue<strong>de</strong> ser <strong>con</strong>struida si el sistema dispone <strong>de</strong> su manejador <strong>de</strong><br />
<strong>protocolo</strong>). Un MediaLocator pue<strong>de</strong> ser, por ejemplo, la ruta <strong>de</strong>l archivo. Existen<br />
dos categorías <strong>de</strong> DataSources que varían en la forma en que se va a extraer la<br />
información, y están asociados al uso <strong>con</strong> <strong>de</strong>terminados <strong>protocolo</strong>s.<br />
o Pull DataSources: se suele usar en el <strong>con</strong>texto <strong>de</strong> sesiones HTTP.<br />
o Push DataSources: Más a<strong>de</strong>cuado para tareas <strong>de</strong> <strong>streaming</strong>, como<br />
sesiones RTP.<br />
A<strong>de</strong>más in<strong>de</strong>pendientemente <strong>de</strong> la categorización anterior, existen unos<br />
DataSources especiales:<br />
o Cloneable DataSources: se utilizan para obtener nuevos DataSources a<br />
partir <strong>de</strong> uno dado, por ejemplo se pue<strong>de</strong>n utilizar para replicar flujos <strong>de</strong><br />
<strong>streaming</strong> y enviarlos a diferentes <strong>de</strong>stinos.<br />
o Merging DataSources: son la opción inversa a los anteriores, y sirven<br />
para unir diferentes fuentes en una sola. Por ejemplo se pue<strong>de</strong>n combinar<br />
dos DataSources diferentes <strong>de</strong> audio y ví<strong>de</strong>o para obtener un solo<br />
DataSource que maneje ambos flujos, y po<strong>de</strong>r grabar un fichero en disco<br />
que los combine.<br />
• Mo<strong>de</strong>lo <strong>de</strong> formatos: JMF proporciona una jerarquía <strong>de</strong> clases para <strong>de</strong>finir el<br />
tipo <strong>de</strong> formatos <strong>de</strong> cada pista multimedia. A grosso modo, existen dos tipos <strong>de</strong><br />
formatos, <strong>de</strong>pendiendo <strong>de</strong> si son <strong>de</strong> audio o ví<strong>de</strong>o. Para estos últimos hay una<br />
subclase particular para cada tipo <strong>de</strong> formato, y cada una <strong>de</strong> ellas ofrece métodos<br />
para modificar los parámetros a los que el <strong>de</strong>sarrollador pue<strong>de</strong> acce<strong>de</strong>r. Por<br />
ejemplo la clase H263Format correspon<strong>de</strong> al formato <strong>de</strong> ví<strong>de</strong>o H263.<br />
Para Audio existe un solo formato AudioFormat, que permite acce<strong>de</strong>r a<br />
varios parámetros relacionados <strong>con</strong> la transmisión <strong>de</strong> sonido: frecuencia, bitrate,<br />
número <strong>de</strong> canales (mono o estéreo), etc.
• Controladores: son clases que proporcionan los mecanismos para introducir y<br />
extraer el valor <strong>de</strong> los atributos <strong>de</strong> los objetos JMF. Existen multitud <strong>de</strong> estas<br />
clases y todas implementan la interfaz Contol <strong>de</strong> JMF, el <strong>de</strong>sarrollador pue<strong>de</strong><br />
implementar nuevos <strong>con</strong>troladores teniendo en cuenta dicha interfaz. Por<br />
ejemplo si se <strong>de</strong>sea cambiar el valor <strong>de</strong> algún atributo <strong>de</strong> la clase AudioFormat,<br />
habrá que obtener primero el <strong>con</strong>trol correspondiente.<br />
• Managers: los Managers son los “intermediarios” que ofrece la API para<br />
<strong>con</strong>trolar a todos los elementos <strong>de</strong>scritos anteriormente en este capítulo, y por<br />
tanto es fundamental que el <strong>de</strong>sarrollador los <strong>con</strong>ozca. Los Managers<br />
implementan las interfaces que especifica JMF para <strong>de</strong>finir el comportamiento y<br />
la interacción <strong>con</strong> los objetos <strong>de</strong> captura, proceso e implementación <strong>de</strong> la<br />
multimedia. Existen cuatro Managers:<br />
o Manager: se encargan <strong>de</strong> la <strong>con</strong>strucción <strong>de</strong> Processors, DataSources y<br />
DataSinks.<br />
o PackageManager: mantiene un registro <strong>de</strong> los paquetes que <strong>con</strong>tienen<br />
clases JMF.<br />
o CaptureDeviceManager: mantiene un registro <strong>de</strong> los dispositivos <strong>de</strong><br />
captura disponibles.<br />
o PlugInManager: mantiene un registro <strong>de</strong> los plugins disponibles para<br />
3.5.6.2. Processors<br />
JMF, como multiplexadores, <strong>de</strong>multiplexadores, co<strong>de</strong>cs, etc.
Los Processors son objetos que permiten <strong>con</strong>trolar la información multimedia, y<br />
más <strong>con</strong>cretamente los formatos <strong>de</strong> las diferentes pistas. Como se verá más a<strong>de</strong>lante es<br />
necesario cambiar los formatos <strong>de</strong> las pistas antes <strong>de</strong> crear una transmisión RTP, ya que<br />
los formatos originales no serán válidos y será necesario usar formatos equivalentes<br />
válidos para RTP. Des<strong>de</strong> este punto <strong>de</strong> vista, la actividad <strong>de</strong> un Processor se pue<strong>de</strong><br />
separar en tres fases, representadas en la figura 3.12.<br />
• Demultiplexación: las diferentes pistas se extraen <strong>de</strong> forma in<strong>de</strong>pendiente, por<br />
ejemplo <strong>de</strong> un archivo se extraen las pistas <strong>de</strong> audio y ví<strong>de</strong>o. La<br />
<strong>de</strong>multiplexación se realiza automáticamente siempre que existan varias pistas.<br />
• Transcoding: cada pista se cambia <strong>de</strong> un formato a otro. Se pue<strong>de</strong>n modificar<br />
otros parámetros, <strong>de</strong>pendiendo <strong>de</strong>l formato específico <strong>de</strong> cada pista. El<br />
transcoding incluye una etapa previa <strong>de</strong> pre-procesamiento y una posterior <strong>de</strong><br />
post-procesamiento, en las cuales se aplican algunos algoritmos <strong>de</strong> efecto<br />
<strong>de</strong>pendiendo <strong>de</strong>l tipo <strong>de</strong> formato.<br />
• Multiplexación: Las pistas se vuelven a unir en un solo <strong>con</strong>tenedor.<br />
Figura 3.12: fases <strong>de</strong> procesamiento en un Processor<br />
A<strong>de</strong>más <strong>de</strong> ren<strong>de</strong>rizar el <strong>con</strong>tenido para presentarlo por diferentes dispositivos<br />
<strong>de</strong> salida, los Processors se pue<strong>de</strong>n enca<strong>de</strong>nar unos a otros mediante el uso <strong>de</strong><br />
DataSources. Es <strong>de</strong>cir, un Processor pue<strong>de</strong> volcar su salida a un DataSource, y éste<br />
servir <strong>de</strong> entrada a un nuevo Processor. De este modo se pue<strong>de</strong>n realizar múltiples<br />
tareas <strong>de</strong> <strong>con</strong>trol, replicar los <strong>con</strong>tenidos multimedia para enviarlos a varios <strong>de</strong>stinos<br />
simultáneamente, etc. En la figura 3.13 se pue<strong>de</strong>n ver las alternativas para los datos <strong>de</strong><br />
salida <strong>de</strong> un Processor.
Figura 3.13: alternativas <strong>de</strong> salida para los datos <strong>de</strong> un Processor<br />
ESTADOS DEL PROCESSOR<br />
Un Processor pasa por diferentes estados <strong>de</strong>s<strong>de</strong> el momento en que es creado<br />
hasta que es <strong>de</strong>struido. Algunos cambios <strong>de</strong> estado son provocados explícitamente por el<br />
programador mientras que otros se producen por si solos, <strong>de</strong>bido a algún evento o<br />
porque el Processor ha completado cierta tarea. Cuando un processor cambia <strong>de</strong> estado<br />
pue<strong>de</strong> publicar un evento informando <strong>de</strong> ello, que <strong>de</strong>berá ser recogido por los objetos<br />
interesados. A <strong>con</strong>tinuación se enumeran los diferentes estados por los que pasa el<br />
Processor, y qué circunstancias provocan el paso <strong>de</strong> un estado a otro. La figura 3.14<br />
muestra un esquema a este respecto.<br />
• Cuando un Processor se instancia, se encuentra inicialmente en el estado<br />
unrealized. No tiene ninguna información sobre la fuente <strong>de</strong> multimedia que<br />
<strong>de</strong>berá manejar.<br />
• Eventualmente el programador hará que el Processor entre en estado<br />
<strong>con</strong>figuring. En este estado el Processor se <strong>con</strong>ecta a su DataSink <strong>de</strong> entrada, el<br />
cual <strong>de</strong>berá haber sido <strong>con</strong>figurado previamente <strong>con</strong> el recurso multimedia al<br />
que se va a acce<strong>de</strong>r. El Processor extraerá las diferentes pistas, y acce<strong>de</strong>rá al<br />
formato <strong>de</strong> cada una <strong>de</strong> ellas. Si no se produce ningún error, el Processor llegará<br />
al estado <strong>con</strong>figured. Llegado este punto, el programador pue<strong>de</strong> realizar las<br />
tareas <strong>de</strong> transcoding que <strong>de</strong>see sobre cada pista, utilizando los <strong>con</strong>troles que<br />
JMF provee para ello.<br />
• Cuando las tareas <strong>de</strong> transcoding estén completas, el programador podrá hacer<br />
que el Processor pase a estado realizing. Durante este estado el processor<br />
<strong>de</strong>termina los recursos que serán necesarios, y los adquiere. Esto hace referencia<br />
a los recursos que sólo será necesario adquirir una vez. Por ejemplo recursos <strong>de</strong>
en<strong>de</strong>rizado, o <strong>de</strong>terminados dispositivos hardware. Una vez adquiridos los<br />
recursos, el Processor llegará estado realized, en el cual se encuentra<br />
completamente <strong>con</strong>struido.<br />
• A partir <strong>de</strong> este estado el programador no dispone <strong>de</strong> métodos que hagan<br />
referencia explícita a los siguientes estados que el Processor alcanzará. En lugar<br />
<strong>de</strong> ellos dispone <strong>de</strong> ciertos métodos para su <strong>con</strong>trol, y <strong>de</strong>pendiendo <strong>de</strong> la<br />
situación el Processor cambiará <strong>de</strong> estado internamente. Se mencionan los<br />
siguientes cuatro métodos, por ser los que se han usado en la implementación<br />
<strong>de</strong>l objeto JmfRtpSen<strong>de</strong>r:<br />
o start: comienza la transmisión <strong>de</strong>s<strong>de</strong> el Processor. Si el Processor se<br />
en<strong>con</strong>traba en el estado realized, pasará al estado prefetching, durante el<br />
cual se prepara realizando una precarga <strong>de</strong> los datos multimedia y<br />
obtiene los recursos exclusivos necesarios que necesite. Si todo va bien<br />
llegará al estado prefetched. En este momento el Processor está<br />
preparado para comenzar la transmisión. Cuando lo haga pasará al estado<br />
started, y esto pue<strong>de</strong> suce<strong>de</strong>r inmediatamente o <strong>con</strong> posterioridad,<br />
<strong>de</strong>pendiendo <strong>de</strong> parámetros <strong>de</strong> tiempo y sincronización que es posible<br />
establecer.<br />
o stop: Si estando en el estado started se llama al método stop, la<br />
actividad <strong>de</strong>l Processor se <strong>de</strong>tiene, y vuelve al estado prefetched. Por lo<br />
tanto sucesivas llamadas a los métodos start y stop harán el que<br />
Processor alterne entre los estados prefetched y started. Como se verá,<br />
esto resultará útil para implementar la funcionalidad <strong>de</strong> pausa.<br />
o setMediaTime: Este método se pue<strong>de</strong> usar para establecer el punto <strong>de</strong>l<br />
<strong>con</strong>tenido multimedia a partir <strong>de</strong>l cual <strong>de</strong>be realizar su actividad el<br />
Processor, recibiendo como parámetro el instante <strong>de</strong> tiempo expresado<br />
en segundos. El Processor volverá al estado realized, y para reanudar la<br />
transmisión será necesario volver a invocar el método start, implicando<br />
todas las operaciones internas <strong>de</strong>scritas anteriormente.<br />
o <strong>de</strong>allocate: aborta la operación actual y cesa toda actividad que esté<br />
<strong>con</strong>sumiendo recursos. Es ilegal invocar este método en un Processor<br />
que esté en estado started, así que habrá que llamar primero al método
stop. Después se podrá invocar al método <strong>de</strong>allocate, lo que hará<br />
retroce<strong>de</strong>r al Processor hasta el estado realized.<br />
o close: <strong>de</strong>spués <strong>de</strong> invocar el método anterior se podrá usar el método<br />
close para liberar <strong>de</strong>finitivamente el resto <strong>de</strong> recursos asociados al<br />
Processor, <strong>de</strong> forma que éste no podrá volver a utilizarse.<br />
Figura 3.14: estados <strong>de</strong> un Processor
3.5.6.3. API para RTP<br />
JMF incluye una API específica para RTP, <strong>de</strong> forma que las tareas <strong>de</strong> captura,<br />
procesamiento y envío <strong>de</strong> datos a través <strong>de</strong> este <strong>protocolo</strong> se pue<strong>de</strong>n integrar <strong>de</strong> forma<br />
equivalente a como se hace <strong>con</strong> el resto <strong>de</strong> <strong>con</strong>tenidos multimedia. La situación <strong>de</strong> la<br />
API RTP en relación a JMF se pue<strong>de</strong> ver en la figura 3.15.<br />
Figura 3.15: API para RTP en JMF<br />
La clase RTPManager es la que <strong>con</strong>trola toda la sesión RTP, <strong>de</strong>s<strong>de</strong> el punto <strong>de</strong><br />
vista <strong>de</strong>l participante local. Será necesario instanciar un objeto RTPManager por cada<br />
flujo RTP que se <strong>de</strong>see enviar o recibir. A<strong>de</strong>más también maneja el canal <strong>de</strong> <strong>con</strong>trol a<br />
través <strong>de</strong> RTCP. Esta clase a<strong>de</strong>más proporciona los métodos necesarios para inicializar y<br />
comenzar las sesiones RTP (en función <strong>de</strong> las direcciones <strong>de</strong> red y puertos origen y<br />
<strong>de</strong>stino), así como para <strong>de</strong>tenerlas y liberar los recursos.<br />
Siguiendo el esquema general <strong>de</strong> JMF que se ha <strong>de</strong>scrito anteriormente, existe<br />
una familia <strong>de</strong> eventos y <strong>con</strong>troladores relacionados <strong>con</strong> las sesiones RTP. A<strong>de</strong>más<br />
existe un mo<strong>de</strong>lo <strong>de</strong> datos particular para RTP, <strong>con</strong> clases para manejar los flujos <strong>de</strong><br />
entrada y salida.
3.5.6.4. Sesión RTP<br />
Hasta ahora se han <strong>de</strong>scrito todos los componentes involucrados en la<br />
generación <strong>de</strong> flujos RTP <strong>con</strong> JMF. En este apartado se va a explicar cómo se combinan<br />
entre ellos, para obtener finalmente una visión global <strong>de</strong>l proceso en su <strong>con</strong>junto.<br />
Téngase en cuenta que esta vez se explican los pasos simplificadamente, y que<br />
realmente involucran todos los <strong>de</strong>talles explicados anteriormente.<br />
• Generación <strong>de</strong> un Processor: Primeramente será necesaria la creación <strong>de</strong> un<br />
Processor, a partir <strong>de</strong> un DataSource que haga referencia al archivo multimedia<br />
<strong>de</strong>s<strong>de</strong> el que se va a obtener el flujo RTP.<br />
• Cambio <strong>de</strong> formato: Para posibilitar el envío a través <strong>de</strong> RTP no serán válidos<br />
en ningún caso los formatos originales, ya que es necesario usar unos formatos<br />
específicos <strong>de</strong> JMF. Por tanto, habrá que realizar un cambio <strong>de</strong> formato para<br />
cada pista, tarea que como se ha explicado es posible realizar <strong>con</strong> un Processor.<br />
En el caso que nos ocupa, este proceso se habrá <strong>de</strong> dividir en dos fases:<br />
primeramente se establecerá el <strong>con</strong>tenedor <strong>de</strong>l Processor como RAW_RTP (RTP<br />
en crudo). Después utilizando ciertos métodos que proporciona la API se<br />
obtendrá para cada pista una lista <strong>de</strong> formatos a los que es posible cambiar la<br />
misma. Por haber establecido el <strong>con</strong>tenedor como RAW_RTP, todos los formatos<br />
<strong>de</strong> esta lista serán válidos para la transmisión RTP. Cada pista se cambiará al<br />
primero <strong>de</strong> los formatos <strong>de</strong> esta lista. Si todo ha ido bien el Processor se<br />
en<strong>con</strong>trará en el estado realized, pero la transmisión no se inicia todavía.<br />
Como resultado, se obtendrá un Processor <strong>con</strong> un <strong>con</strong>tenido multimedia<br />
cuyas pistas son parecidas a las originales y válidas para la transmisión RTP.<br />
• Creación <strong>de</strong> las sesiones RTP: se usa la clase RTPManager para crear las<br />
sesiones RTP, una por cada pista. La fuente <strong>de</strong> información será el Processor,<br />
<strong>de</strong>l cual es posible obtener su salida <strong>de</strong> datos en forma <strong>de</strong> DataSource a través<br />
<strong>de</strong>l método a<strong>de</strong>cuado. De esta forma el Processor y los RTPManager quedan<br />
“enca<strong>de</strong>nados”. Para cada sesión RTP inicializada se obtiene un objeto que<br />
representa la estructura <strong>de</strong> datos que va a enviar el flujo RTP (sendStream).
A partir <strong>de</strong> este punto, la transferencia RTP está lista para comenzar, y el<br />
manejo se hará a través <strong>de</strong>l Processor, <strong>con</strong> los métodos start y stop mencionados<br />
anteriormente.<br />
FINALIZACIÓN<br />
La finalización <strong>de</strong> la sesión RTP se pue<strong>de</strong> realizar en cualquier momento,<br />
in<strong>de</strong>pendientemente <strong>de</strong> que la transmisión <strong>de</strong> datos haya finalizado o no. Si el <strong>con</strong>tenido<br />
<strong>de</strong> un archivo multimedia ha sido completamente transmitido, lo único que suce<strong>de</strong> es<br />
que pasa <strong>de</strong>l estado started al prefetched, siendo posible volver a reiniciar la<br />
transmisión.<br />
Para finalizar la transmisión se libera el Processor <strong>con</strong> los métodos <strong>de</strong>allocate<br />
y close, y posteriormente se <strong>de</strong>struyen las sesiones RTPManager <strong>con</strong> los métodos<br />
apropiados para ello.<br />
Por último cabe señalar que existe una alternativa al uso <strong>de</strong> la clase RTPManager<br />
para el envío <strong>de</strong> los datos a través <strong>de</strong> RTP. Es el uso <strong>de</strong> un Datasink <strong>con</strong>figurado <strong>de</strong> una<br />
manera específica (recuér<strong>de</strong>se en la <strong>de</strong>scripción general <strong>de</strong> JMF, que los DataSink son<br />
abstracciones que se usan para indicar el <strong>de</strong>stino <strong>de</strong> los datos). Se ha <strong>de</strong>sechado esta<br />
opción porque solo permite transmitir la primera pista <strong>de</strong> un <strong>con</strong>tenido multimedia,<br />
aunque existan más pistas.
3.5.6.5. Implementación <strong>de</strong> la clase JmfRtpSen<strong>de</strong>r<br />
Todos los mecanismos <strong>de</strong> JMF que se han expuesto han sido plasmados en la<br />
clase JmfRtpSen<strong>de</strong>r, que es la que va a formar parte <strong>de</strong>l servidor <strong>RTSP</strong>. Recuér<strong>de</strong>se que<br />
esta clase implementa la interfaz RtpSen<strong>de</strong>r que ya se <strong>de</strong>scribió en su momento. En<br />
este apartado se explica cómo se ha hecho, incluyéndose fragmentos <strong>de</strong> código para<br />
facilitar la comprensión.<br />
• Inicialización: Las sesiones RTP se inicializan en el propio <strong>con</strong>structor <strong>de</strong> la<br />
clase. El <strong>con</strong>structor recibe como parámetros:<br />
o Ruta al directorio <strong>con</strong> los archivos multimedia <strong>de</strong>l servidor.<br />
o Nombre <strong>de</strong>l archivo que se preten<strong>de</strong> transmitir.<br />
o Direcciones Ip origen y <strong>de</strong>stino.<br />
o Puertos <strong>de</strong> <strong>de</strong>stino para la o las pistas.<br />
o Flags indicando qué pistas se <strong>de</strong>sean transmitir (aunque un archivo<br />
<strong>con</strong>tenga pistas <strong>de</strong> audio y ví<strong>de</strong>o, podría darse la circunstancia <strong>de</strong> que<br />
solo se quiera transmitir una <strong>de</strong> ellas).<br />
o Referencia al objeto RtspSessionData que <strong>con</strong>tiene el estado <strong>de</strong> la<br />
sesión en el servidor <strong>RTSP</strong>.<br />
Dentro <strong>de</strong>l <strong>con</strong>structor se realizarán todas las tareas <strong>de</strong> inicialización<br />
explicadas anteriormente. Se i<strong>de</strong>ntificará el archivo fuente a partir <strong>de</strong> su nombre<br />
y la ruta que han sido pasados como parámetros, obteniendo un MediaLocator y<br />
<strong>con</strong>struyendo <strong>con</strong> este un DataSource. Posteriormente se creará un Processor<br />
que recibirá como entrada este DataSource.<br />
Para la creación <strong>de</strong> las sesiones RTP <strong>con</strong> RTPManager se usarán los<br />
parámetros <strong>de</strong> transporte especificados, pero nótese que no se ha indicado<br />
ningún puerto origen. Estos son obtenidos <strong>de</strong> forma aleatoria, asegurándose <strong>de</strong><br />
que son puertos disponibles, y que son números pares (requisito necesario para<br />
RTP).
Si toda la ejecución <strong>de</strong>l <strong>con</strong>structor se realiza correctamente se obtendrá<br />
un Processor en estado prefetched listo para comenzar la transmisión, y<br />
<strong>con</strong>ectado a las sesiones RTP necesarias. En el objeto RtspSessionData se<br />
cambia el estado <strong>de</strong> la transmisión <strong>de</strong> <strong>de</strong>allocated a paused. En caso <strong>de</strong> que se<br />
produzca algún error <strong>de</strong>ntro <strong>de</strong>l <strong>con</strong>structor (por ejemplo tratar <strong>de</strong> utilizar un<br />
archivo <strong>con</strong> formatos que JMF no es capaz <strong>de</strong> manejar), el propio <strong>con</strong>structor<br />
elevará una excepción que será recogida por la clase RequestHandler.<br />
• Método startTransmission: recibe como parámetro el instante <strong>de</strong> tiempo a<br />
partir <strong>de</strong>l cual se <strong>de</strong>sea transmitir, expresado en segundos. Realiza tres llamadas<br />
<strong>con</strong>secutivas a los métodos <strong>de</strong>l Processor:<br />
o stop: <strong>de</strong>tiene el Processor si estuviera en estado started, si no la llamada<br />
no tiene efecto.<br />
o setMediaTime: se le indica al Processor el instante a partir <strong>de</strong>l cual<br />
<strong>de</strong>berá <strong>con</strong>tinuar, usando el parámetro <strong>de</strong>l método startTransmission.<br />
No se pue<strong>de</strong> invocar este método sobre un Processor en estado started,<br />
<strong>de</strong> ahí la llamada anterior a stop.<br />
o start: se comienza la transmisión, y este paso provocará el comienzo<br />
<strong>de</strong>l envío <strong>de</strong> los datos RTP a través <strong>de</strong> la red.<br />
Por último, el estado <strong>de</strong> la transmisión en el objeto<br />
RtspSessionData se cambia a playing.<br />
• Método pauseTransmission: se <strong>de</strong>tiene el Processor <strong>con</strong> el método stop, y el<br />
estado <strong>de</strong> la transmisión en el objeto RtspSessionData se cambia a paused.<br />
• Método tearDownTransmission: se liberan el Processor y los RTPManager <strong>de</strong><br />
la forma <strong>de</strong>scrita en el apartado anterior.<br />
El estado <strong>de</strong> la transmisión (<strong>de</strong>allocated, paused, playing) no se tiene en cuenta<br />
<strong>de</strong>ntro <strong>de</strong> la propia clase JmfRtpSen<strong>de</strong>r, pero se almacenan para que la clase<br />
RequestHandler tenga <strong>con</strong>stancia <strong>de</strong>l estado <strong>de</strong> la transmisión, información necesaria<br />
en algunos casos. Por ejemplo cuando llegue un mensaje PLAY sabrá si tiene que<br />
<strong>con</strong>struir o no el objeto JmfRtpSen<strong>de</strong>r, <strong>de</strong>pendiendo <strong>de</strong> si el estado <strong>de</strong> la transmisión<br />
era <strong>de</strong>allocated o no.
Por último, se ha implementado un método interno que es capaz <strong>de</strong> recoger<br />
eventos lanzados por el Processor. El único evento que realmente importa es el que se<br />
lanza cuando se llega al final <strong>de</strong>l archivo (EndOfMediaEvent). Entonces<br />
automáticamente se <strong>de</strong>tiene el Processor <strong>con</strong> el método stop, y la transmisión se<br />
cambia <strong>de</strong>l estado playing al paused.<br />
3.5.6.6. Problema <strong>de</strong> JMF: sincronización <strong>de</strong> las pistas<br />
Para terminar la <strong>de</strong>scripción <strong>de</strong> JMF, se va a comentar el principal problema que<br />
se ha en<strong>con</strong>trado. Este problema <strong>con</strong>siste en que si se transmiten las dos pistas <strong>de</strong> un<br />
archivo que <strong>con</strong>tenga audio y ví<strong>de</strong>o, habitualmente estas pistas no se reproducen <strong>con</strong> la<br />
sincronización a<strong>de</strong>cuada. En lugar <strong>de</strong> ello, el sonido se reproduce <strong>con</strong> un ligero retraso<br />
respecto al ví<strong>de</strong>o, llegando a haber un <strong>de</strong>sfase en ocasiones <strong>de</strong> 1 segundo<br />
aproximadamente. No es un problema <strong>de</strong>l reproductor puesto que este fenómeno se<br />
manifiesta igualmente <strong>con</strong> QuickTime y VLC.<br />
Se estudió profundamente la API y la documentación, pero no se en<strong>con</strong>tró forma<br />
alguna <strong>de</strong> solucionar este problema. Teóricamente, JMF usa internamente los paquetes<br />
RTCP y el mo<strong>de</strong>lo <strong>de</strong> tiempo para mantener la sincronía en la transmisión <strong>de</strong> las pistas,<br />
y el <strong>de</strong>sarrollador no tiene forma <strong>de</strong> influir en el ajuste. En los foros <strong>de</strong> <strong>de</strong>sarrollo <strong>de</strong><br />
JMF se comprobó que otras personas sufren el mismo problema, sin que nadie haya sido<br />
capaz <strong>de</strong> aportar una solución.<br />
Por último se estudió la base <strong>de</strong> datos <strong>de</strong> JMF que <strong>con</strong>tiene la información sobre<br />
los bugs. Se en<strong>con</strong>tró un bug que precisamente habla sobre el retardo <strong>de</strong>l ví<strong>de</strong>o respecto<br />
al audio en la transmisión RTP, <strong>con</strong>cretamente el bug número 4369079. Así que se llegó<br />
a la <strong>con</strong>clusión <strong>de</strong> que esta es la causa <strong>de</strong>l problema y se abandonó la búsqueda <strong>de</strong> una<br />
solución.<br />
Sin embargo sí se ha <strong>con</strong>jeturado la causa. El <strong>de</strong>sfase es variable (a veces incluso<br />
el sincronismo es perfecto), y se produce al inicio <strong>de</strong> la reproducción, manteniéndose el<br />
mismo <strong>de</strong>sfase <strong>con</strong>stante durante toda la reproducción hasta el final <strong>de</strong>l archivo. Pue<strong>de</strong><br />
que la causa sea algún tipo <strong>de</strong> problema <strong>de</strong> rendimiento al inicio <strong>de</strong> la sesión RTP,
teniendo en cuenta las múltiples tareas y cambios <strong>de</strong> estado <strong>de</strong>l Processor, ya que se<br />
observa que el procesador <strong>de</strong>l or<strong>de</strong>nador trabaja al 100% durante unos segundos. Esta<br />
i<strong>de</strong>a se refuerza <strong>con</strong> el hecho <strong>de</strong> que si <strong>de</strong>spués <strong>de</strong> la reproducción completa <strong>de</strong>l archivo<br />
se vuelve a reiniciar la transmisión <strong>de</strong>s<strong>de</strong> el principio (no hace falta realizar las tareas <strong>de</strong><br />
inicialización), entonces invariablemente el sincronismo es correcto<br />
3.5.7. Módulo VlcRtpSen<strong>de</strong>r<br />
Esta clase <strong>con</strong>stituye la segunda posibilidad que se ha implementado para la<br />
transmisión <strong>de</strong> datos RTP. En el capítulo sobre la <strong>de</strong>scripción <strong>de</strong> las tecnologías <strong>de</strong><br />
<strong>streaming</strong> ya se han mencionado sus características principales, entre las que <strong>de</strong>staca la<br />
posibilidad <strong>de</strong> manejarlo utilizando la línea <strong>de</strong> comandos, posibilitando <strong>de</strong> esta forma la<br />
integración <strong>de</strong> VLC <strong>con</strong> un programa java, en este caso nuestro servidor <strong>RTSP</strong>. En este<br />
sentido, la creación <strong>de</strong> los datos RTP no ha implicando tanto trabajo <strong>de</strong> <strong>de</strong>sarrollo como<br />
en el caso <strong>de</strong> JMF, pero ha sido necesario solventar ciertos problemas que se<br />
comentarán en su momento. La mayoría <strong>de</strong>l tiempo <strong>de</strong>dicado a esta parte <strong>de</strong>l proyecto<br />
ha <strong>con</strong>sistido en la realización <strong>de</strong> pruebas y la investigación en documentos <strong>de</strong> VLC y<br />
en los foros <strong>de</strong> <strong>de</strong>sarrollo en Internet para resolver esos problemas.<br />
En los apartados siguientes se <strong>de</strong>scribirá el manejo <strong>de</strong> VLC por línea <strong>de</strong><br />
comandos, se explicará cómo es posible integrar este manejo en un programa en Java, y<br />
por último se <strong>de</strong>tallará la adaptación <strong>de</strong> estos mecanismos en la clase VlcRtpSen<strong>de</strong>r.<br />
3.5.7.1. Módulos VLC para <strong>streaming</strong><br />
VLC permite el envío <strong>de</strong> datos a través <strong>de</strong> la red y/o su volcado a un archivo.<br />
Durante este proceso se pue<strong>de</strong>n realizar diferentes tareas <strong>de</strong> procesamiento como<br />
transcoding, aplicación <strong>de</strong> filtros, modificación <strong>de</strong>l tamaño <strong>de</strong> la imagen, etc. Existen<br />
diferentes módulos que proporcionan varias funcionalida<strong>de</strong>s, y se pue<strong>de</strong>n usar<br />
simultáneamente enca<strong>de</strong>nando unos <strong>con</strong> otros. Cada módulo <strong>con</strong>sta <strong>de</strong> varios campos<br />
que se pue<strong>de</strong>n usar para establecer ciertos parámetros, pero su cantidad es muy gran<strong>de</strong> y
no se van a citar. A <strong>con</strong>tinuación se enumeran los módulos disponibles y se explica su<br />
función<br />
• standard: permite el volcado <strong>de</strong> un <strong>con</strong>tenido <strong>streaming</strong> a un fichero o a través<br />
<strong>de</strong> la red. Algunas <strong>de</strong> sus opciones son el <strong>con</strong>tenedor en que se van a encapsular<br />
lo datos, y el <strong>protocolo</strong> <strong>de</strong> red, por ejemplo HTTP o UDP.<br />
• transco<strong>de</strong>: permite cambiar el formato <strong>de</strong> los datos que el módulo recibe como<br />
entrada. Si la fuente es un <strong>con</strong>tenido en vivo (proveniente <strong>de</strong> la red o <strong>de</strong> algún<br />
dispositivo <strong>de</strong> captura), el transcoding se hace “al vuelo”, pudiéndose necesitar<br />
mucho trabajo <strong>de</strong> la CPU <strong>de</strong>pendiendo <strong>de</strong> los parámetros. Si la fuente es un<br />
archivo o un disco externo, se hace a la mayor velocidad que sea posible.<br />
Incluye una gran variedad <strong>de</strong> opciones y efectos, <strong>de</strong>stacando la<br />
posibilidad <strong>de</strong> elegir la librería <strong>de</strong> co<strong>de</strong>cs que se va a utilizar. También permite<br />
<strong>de</strong>finir el número <strong>de</strong> imágenes por segundo, escalar la imagen por algún factor,<br />
multiplexar o <strong>de</strong>multiplexar las pistas, etc.<br />
• duplicate: duplica los datos <strong>de</strong> entrada, permitiendo el manejo <strong>de</strong> 2 flujos <strong>de</strong><br />
datos iguales a partir <strong>de</strong>l flujo origen. Por ejemplo, se podrían enviar datos a<br />
través <strong>de</strong> la red y volcarlos localmente a un archivo <strong>de</strong> forma simultánea.<br />
• display: permite reproducir los datos <strong>de</strong> entrada <strong>de</strong> igual forma que lo hace el<br />
reproductor VLC. Permite elegir qué pistas se van a reproducir y también es<br />
posible introducir un retardo. Este módulo podría ser útil, por ejemplo, para<br />
monitorizar el <strong>con</strong>tenido que se está enviando a algún <strong>de</strong>stino.<br />
• rtp: permite el envío <strong>de</strong> datos a través <strong>de</strong>l <strong>protocolo</strong> RTP <strong>de</strong> forma no<br />
entrelazada, es <strong>de</strong>cir que cada pista se envía a un puerto <strong>de</strong>stino diferente.<br />
Permite establecer varios parámetros <strong>de</strong> transporte como la dirección <strong>de</strong> <strong>de</strong>stino<br />
y los puertos <strong>de</strong> <strong>de</strong>stino para audio y ví<strong>de</strong>o, entre otros. También pue<strong>de</strong> poner a<br />
disposición el SDP asociado al <strong>con</strong>tenido, por ejemplo a través <strong>de</strong>l servidor<br />
HTTP integrado <strong>de</strong> VLC. Otra posibilidad es establecer el <strong>con</strong>tendor para los<br />
datos.<br />
• elementary stream: permite separar las diferentes pistas que <strong>con</strong>tengan los<br />
datos <strong>de</strong> entrada. Por ejemplo se podría usar para guardar los datos <strong>de</strong> ví<strong>de</strong>o a un<br />
fichero y los <strong>de</strong> audio a otro fichero diferente. Entre sus opciones está la
posibilidad <strong>de</strong> especificar <strong>con</strong>tenedores y parámetros <strong>de</strong> <strong>de</strong>stino diferentes para<br />
cada pista.<br />
3.5.7.2. Comandos para el envío <strong>de</strong> datos RTP<br />
Al empezar a estudiar la documentación y los ejemplos <strong>de</strong>l manejo <strong>de</strong> VLC por<br />
línea <strong>de</strong> comandos para generar el envío <strong>de</strong> datos por RTP, lo primero que se observó es<br />
que la funcionalidad <strong>de</strong> algunos módulos parece solaparse, <strong>de</strong> tal forma que no se sabe<br />
<strong>con</strong> certeza cual es la mejor manera <strong>de</strong> realizar ciertas tareas. Parece lógico pensar que<br />
se <strong>de</strong>bería usar el módulo rtp, pero teóricamente el módulo Elementary stream<br />
también <strong>de</strong>bería ser válido puesto que ofrece una cabecera que permite establecer el<br />
método <strong>de</strong> envío <strong>de</strong> los datos, y entre las distintas posibilida<strong>de</strong>s se encuentra el<br />
<strong>protocolo</strong> RTP.<br />
Tras realizar varias pruebas se <strong>de</strong>cidió el uso <strong>de</strong>l módulo rtp, <strong>de</strong>bido a que el<br />
módulo Elementary stream parecía no funcionar bien; se comprobó <strong>con</strong> Wireshark<br />
que efectivamente se estaban enviado datos, pero los reproductores simplemente no<br />
mostraban ningún <strong>con</strong>tenido. El módulo rtp sí generaba datos capaces <strong>de</strong> ser<br />
interpretados por los clientes.<br />
El comando se <strong>con</strong>struye como sigue: el primer parámetro es el nombre <strong>de</strong>l<br />
archivo origen <strong>de</strong> los datos. Después se incluyen los caracteres --sout=, que hacen<br />
referencia a la característica <strong>de</strong> VLC que permite el envío <strong>de</strong> <strong>streaming</strong>, llamada stream<br />
output. A <strong>con</strong>tinuación se aña<strong>de</strong> el nombre <strong>de</strong>l módulo rtp, y entre llaves se introducen<br />
los parámetros <strong>de</strong> transporte necesarios junto <strong>con</strong> sus correspondientes valores. Estos<br />
parámetros serán la dirección <strong>de</strong> <strong>de</strong>stino y los puertos <strong>de</strong> <strong>de</strong>stino para audio y/o ví<strong>de</strong>o.<br />
Un parámetro adicional es el método <strong>de</strong> encapsulación. Para RTP las opciones son<br />
MPEG2 o el envío en crudo (sin encapsulación). Si no se especifica este parámetro, se<br />
usa el método en crudo como encapsulado por <strong>de</strong>fecto. La sintaxis exacta varía<br />
ligeramente <strong>de</strong> un sistema operativo a otro, los ejemplos que se mostrarán correspon<strong>de</strong>n<br />
al sistema operativo Windows.
Este sería el comando necesario para ejecutar VLC e iniciar el envío <strong>de</strong> datos<br />
RTP, a partir <strong>de</strong> un archivo llamado “vi<strong>de</strong>o.mpg” que se encuentra en el directorio<br />
“C:/multimedia” y que <strong>con</strong>tiene dos pistas <strong>de</strong> audio y ví<strong>de</strong>o:<br />
vlc C:/multimedia/vi<strong>de</strong>o.mpg --sout="#rtp{dst=192.168.1.5;<br />
port-vi<strong>de</strong>o=5000;port-audio=5002}"<br />
3.5.7.3. Control <strong>de</strong> VLC a través <strong>de</strong> su interfaz Telnet<br />
Una vez arrancado VLC como servidor <strong>de</strong> datos RTP, se abre la cuestión <strong>de</strong><br />
cómo <strong>con</strong>trolarlo. Por ejemplo, cuando el cliente pause la transmisión o pretenda<br />
reiniciar la transmisión <strong>de</strong>s<strong>de</strong> un instante diferente porque se ha movido la barra <strong>de</strong><br />
<strong>de</strong>splazamiento, será necesario modificar la ejecución <strong>de</strong> VLC en <strong>con</strong>secuencia. Esto es<br />
posible ya que existe la opción <strong>de</strong> lanzar una <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol remoto en el momento<br />
<strong>de</strong> ejecutar VLC y posteriormente <strong>con</strong>ectarse a esta <strong>con</strong>sola a través <strong>de</strong> Telnet 16 , como<br />
se pue<strong>de</strong> ver en la figura 3.16.<br />
Figura 3.16: servidor RTP <strong>de</strong>s<strong>de</strong> VLC<br />
Existe la posibilidad <strong>de</strong> lanzar dos tipos <strong>de</strong> <strong>con</strong>solas remotas diferentes, varían<br />
en lo relativo a la cantidad <strong>de</strong> opciones que ofrecen. A<strong>de</strong>más será necesario indicar la<br />
dirección y puerto don<strong>de</strong> se realizará la <strong>con</strong>exión vía Telnet. En cuanto a las opciones <strong>de</strong><br />
16 Telnet es el nombre <strong>de</strong> un <strong>protocolo</strong> y <strong>de</strong>l programa que lo implementa. Sirve para manejar<br />
remotamente una máquina <strong>de</strong> igual forma que si se pudieran introducir comandos por el teclado.
<strong>con</strong>trol, existen más <strong>de</strong> veinte diferentes. Permiten <strong>con</strong>trolar la reproducción <strong>de</strong>l<br />
<strong>con</strong>tenido actual, añadir o quitar recursos multimedia a la lista <strong>de</strong> reproducción, cambiar<br />
el <strong>con</strong>tenedor, mostrar información <strong>de</strong> la reproducción, cargar y guardar perfiles <strong>de</strong><br />
<strong>con</strong>figuración, etc.<br />
Por ejemplo, si se quisiera lanzar la interfaz Telnet que ofrece mayor<br />
funcionalidad <strong>de</strong> forma que esperara las <strong>con</strong>exiones en el puerto 5000 <strong>de</strong> la máquina<br />
local, habría que añadir los siguientes caracteres al ejemplo anterior:<br />
--extraintf=rc --rc-host=localhost:5000<br />
3.5.7.4. Clase Runtime<br />
Todo programa java lleva implícitamente asociada una instancia <strong>de</strong> la clase<br />
Runtime, la cual permite al programa interaccionar <strong>con</strong> el entorno en el que se está<br />
ejecutando, mediante la ejecución <strong>de</strong> aplicaciones externas. Por ejemplo, uno <strong>de</strong> los<br />
usos más habituales es la apertura <strong>de</strong> un navegador <strong>con</strong> información <strong>de</strong> ayuda en<br />
HTML.<br />
Esta clase permite al programa java la adquisición <strong>de</strong> un objeto <strong>de</strong> la clase<br />
Process, que es la referencia al entorno don<strong>de</strong> el programa se está ejecutando. La clase<br />
Process es abstracta, ya que su implementación <strong>de</strong>pen<strong>de</strong> <strong>de</strong> cada sistema operativo.<br />
Esta referencia se obtiene <strong>con</strong> el método Runtime.exec, <strong>con</strong> este método se iniciará la<br />
ejecución <strong>de</strong>l proceso <strong>de</strong>finido por el comando y los parámetros, <strong>de</strong> forma similar a<br />
como se haría escribiendo a través <strong>de</strong> una <strong>con</strong>sola <strong>de</strong> línea <strong>de</strong> comandos. También se<br />
pue<strong>de</strong> establecer el valor <strong>de</strong> las variables <strong>de</strong> entorno.<br />
Intuitivamente se pue<strong>de</strong> pensar que esta clase permite realizar las mismas<br />
operaciones que una <strong>con</strong>sola <strong>de</strong>l sistema operativo, pero esto no es así y hay que tener<br />
en cuenta sus limitaciones, ya que sólo se pue<strong>de</strong> usar para la ejecución <strong>de</strong> programas<br />
ejecutables y scripts. No permite realizar el resto <strong>de</strong> tareas que sí permite una <strong>con</strong>sola,
por ejemplo un error muy común es tratar <strong>de</strong> usar comandos interpretados como dir en<br />
MS-DOS, esto no es posible ya que no se trata <strong>de</strong> un ejecutable si no <strong>de</strong> un comando<br />
interpretado por la <strong>con</strong>sola. Tampoco sería posible volcar la salida <strong>de</strong> un proceso a la<br />
entrada <strong>de</strong> otro, etc. Para interaccionar <strong>con</strong> el proceso externo una vez lanzada se pue<strong>de</strong><br />
hacer uso <strong>de</strong> su buffer <strong>de</strong> entrada y dos buffers <strong>de</strong> salida: la salida estándar y la salida <strong>de</strong><br />
error.<br />
3.5.7.5. Problemas en el uso <strong>de</strong> VLC <strong>con</strong> la clase Runtime<br />
Antes <strong>de</strong> explicar cómo se ha implementado el módulo VlcRtpSen<strong>de</strong>r es<br />
necesario comentar algunos problemas que necesariamente han tenido impacto en la<br />
solución final. La principal dificultad radica en que algunos <strong>de</strong> estos problemas no se<br />
pue<strong>de</strong>n explicar <strong>de</strong> forma lógica, y la forma <strong>de</strong> solucionarlos es la realización <strong>de</strong><br />
sucesivas pruebas.<br />
• Lanzamiento <strong>de</strong> la <strong>con</strong>sola: inicialmente se trató <strong>de</strong> ejecutar directamente VLC<br />
<strong>con</strong> los parámetros asociados, pero este método no funcionaba. Una opción más<br />
fiable es ejecutar el propio comando que crea una <strong>con</strong>sola (en el caso <strong>de</strong><br />
Windows es cmd.exe) pasándole como parámetros el proceso que realmente se<br />
quiere ejecutar y los parámetros <strong>de</strong> este último.<br />
• Caracteres <strong>de</strong> entrada: el método exec tiene problemas para re<strong>con</strong>ocer<br />
<strong>de</strong>terminados caracteres, por ejemplo las comillas dobles o simples. Según la<br />
documentación y como se muestra en el ejemplo sobre la llamada a VLC por<br />
línea <strong>de</strong> comandos, es necesario escribir comillas. Afortunadamente se<br />
comprobó que eliminando las comillas VLC también arranca correctamente,<br />
pero hay que tener presente que esta es una circunstancia arbitraria y en caso <strong>de</strong><br />
no funcionar podría haber supuesto un serio problema.<br />
También existen problemas en el uso <strong>de</strong> espacios en blanco.<br />
Teóricamente se le pue<strong>de</strong> pasar al método exec un array <strong>de</strong> ca<strong>de</strong>nas <strong>de</strong><br />
caracteres, y este lo <strong>de</strong>berá interpretar como ca<strong>de</strong>nas separadas por un espacio.<br />
Se trató <strong>de</strong> usar esta característica para incluir espacios en la ruta por <strong>de</strong>fecto<br />
don<strong>de</strong> se encuentra el ejecutable vlc.exe, pero esto no funciona bien. Por lo
tanto es necesario que el ejecutable (y los archivos que se vayan a servir) se<br />
encuentren en directorios cuyas rutas no <strong>con</strong>tengan espacios.<br />
• Conexión a la interfaz Telnet: El primer problema en cuanto a la <strong>con</strong>exión por<br />
Telnet <strong>con</strong> la <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol es el establecimiento <strong>de</strong> la propia <strong>con</strong>exión. Esta<br />
<strong>con</strong>exión no se establece siempre <strong>con</strong> éxito al primer intento, <strong>de</strong> tal forma que ha<br />
sido necesaria la implementación <strong>de</strong> bucles don<strong>de</strong> se reintenta la <strong>con</strong>exión<br />
repetidamente y se produce una pausa <strong>de</strong> dos segundos entre cada reintento,<br />
hasta que finalmente la <strong>con</strong>exión se establece. Esta no es una solución muy<br />
elegante, pero ha sido la única forma <strong>de</strong> garantizar que finalmente la <strong>con</strong>exión se<br />
acaba realizando, generalmente en dos o tres intentos.<br />
Un segundo problema apareció inmediatamente <strong>de</strong>spués <strong>de</strong> <strong>con</strong>seguir la<br />
<strong>con</strong>exión y era que se producía un error <strong>de</strong> autenticación <strong>de</strong> igual forma que si se<br />
introdujera una clave errónea. El hecho es que esta <strong>con</strong>exión no necesita <strong>de</strong><br />
clave, y a<strong>de</strong>más el error se producía inmediatamente sin que se introdujera clave<br />
alguna. En los foros <strong>de</strong> <strong>de</strong>sarrollo para VLC se leyó acerca <strong>de</strong> otras personas <strong>con</strong><br />
el mismo problema, y se llegó a la <strong>con</strong>clusión <strong>de</strong> que este es un error que se<br />
produce en ciertas circunstancias no <strong>de</strong>l todo claras y <strong>de</strong>pendiendo a<strong>de</strong>más <strong>de</strong> la<br />
versión <strong>de</strong> VLC que se utilice. Se <strong>con</strong>siguió evitar este problema usando la<br />
versión <strong>de</strong> VLC 0.8.6a, mientas que la versión actual en el momento <strong>de</strong> escribir<br />
este documento es la 0.8.6c.<br />
Por último, existía el problema <strong>de</strong> que al lanzar la <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol<br />
remoto esta aparecía en forma <strong>de</strong> ventana en la pantalla, <strong>de</strong> forma que no era<br />
posible capturar su buffer <strong>de</strong> entrada para enviar comandos ya que la entrada era<br />
el teclado <strong>de</strong>l or<strong>de</strong>nador. Esto se solucionó añadiendo un parámetro que permite<br />
lanzar la <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol en modo silencioso, este parámetro es --rc-quiet.<br />
• Robustez: en general, el uso <strong>de</strong> VLC <strong>con</strong> el método exec no es robusto, y el<br />
éxito <strong>de</strong> los comandos no siempre está garantizado. Esto quedó patente al<br />
afrontar otros dos problemas en cuanto al <strong>con</strong>trol <strong>de</strong> VLC.<br />
o Cierre <strong>de</strong> la aplicación: al lanzar VLC por línea <strong>de</strong> comandos, aparece<br />
en la pantalla una interfaz gráfica VLC <strong>con</strong> una barra <strong>de</strong> <strong>de</strong>splazamiento<br />
que se mueve a medida que avanza el envío <strong>de</strong> los datos. Surgió el
problema <strong>de</strong> cerrar esa ventana al finalizar la transmisión RTP, ya que<br />
incluso <strong>de</strong>struyendo el proceso lanzado <strong>con</strong> el método exec la ventana <strong>de</strong><br />
VLC permanecía. Esto provocaba que tras sucesivas transmisiones RTP<br />
la pantalla estuviera llena <strong>de</strong> ventanas VLC inactivas.<br />
El primer intento para solucionar esto fue el envío <strong>de</strong>l mensaje<br />
exit a la <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol remoto, al recibir un mensaje TEARDOWN<br />
<strong>de</strong>l reproductor. Esta solución funcionaba bien por línea <strong>de</strong> comandos,<br />
pero en el <strong>con</strong>texto <strong>de</strong> un programa java <strong>con</strong> el método exec no tenía<br />
efecto alguno.<br />
Un segundo intento fue el añadir a la lista <strong>de</strong> reproducción un<br />
objeto especial llamado vlc:quit, que provoca el cierre <strong>de</strong> la aplicación.<br />
Situado en la lista <strong>de</strong> reproducción a <strong>con</strong>tinuación <strong>de</strong>l archivo que se<br />
quiere transmitir, permitiría el cierre <strong>de</strong> la ventana al completarse la<br />
transmisión. Nuevamente esta solución funcionaba bien en una <strong>con</strong>sola<br />
pero no en el programa. Se probó la posibilidad <strong>de</strong> <strong>de</strong>tectar el fin <strong>de</strong> la<br />
transmisión leyendo las trazas <strong>de</strong> la salida estándar y el subsiguiente<br />
envío a la <strong>con</strong>sola remota <strong>de</strong>l mensaje goto vlc:quit que <strong>de</strong>bería saltar a<br />
este elemento y por <strong>con</strong>siguiente cerrar la ventana, pero resultaba<br />
igualmente inútil. Finalmente se en<strong>con</strong>tró una solución que funcionaba,<br />
<strong>con</strong>sistente en introducir la ca<strong>de</strong>na vlc:quit como último parámetro al<br />
lanzar VLC. Hay que hacer notar que según la documentación los<br />
elementos <strong>de</strong> la lista <strong>de</strong> reproducción <strong>de</strong>ben ir al principio <strong>de</strong> los<br />
parámetros y no se hace referencia alguna a su inclusión al final.<br />
o Salto a otro punto <strong>de</strong>l archivo: Se ha implementado esta funcionalidad<br />
mediante la <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol remoto. Cuando se mueva la barra <strong>de</strong><br />
<strong>de</strong>splazamiento en el reproductor este enviará un mensaje PLAY<br />
<strong>con</strong>teniendo el nuevo instante inicial <strong>de</strong> la transmisión. Entonces se le<br />
envía a la <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol el comando seek seguido <strong>de</strong>l instante en<br />
segundos. Desgraciadamente esto no siempre funciona, y no se ha<br />
<strong>con</strong>seguido en<strong>con</strong>trar una solución para que lo haga siempre.<br />
Aproximadamente el 25% <strong>de</strong> las veces que se envía este comando no se<br />
obtiene ningún efecto, y entonces se produce una incoherencia porque la
arra <strong>de</strong> <strong>de</strong>splazamiento en el reproductor no coinci<strong>de</strong> <strong>con</strong> los datos que<br />
realmente se <strong>de</strong>berían estar transmitiendo. En todo caso se ha mantenido<br />
su implementación ya que su uso no es obligatorio.<br />
• Captura <strong>de</strong> las salidas: <strong>de</strong>spués <strong>de</strong> afrontar los problemas anteriores por fin se<br />
<strong>con</strong>siguió ejecutar VLC <strong>de</strong>s<strong>de</strong> la propia clase VlcRtpSen<strong>de</strong>r, pero entonces<br />
apareció una nueva dificultad: pasado un <strong>de</strong>terminado tiempo la transmisión se<br />
bloqueaba sin motivo aparente. En este caso sí se obtuvo ayuda examinando la<br />
documentación <strong>de</strong> la clase Runtime.<br />
Como ya se ha mencionado la clase Runtime proporciona dos búferes<br />
para la salida <strong>de</strong> datos y la salida <strong>de</strong> errores. Eventualmente estos búferes se<br />
llenan y entonces la ejecución se bloquea. Esta circunstancia fue difícil <strong>de</strong><br />
<strong>de</strong>tectar ya que ejecutando VLC por línea <strong>de</strong> comandos no se produce salida<br />
alguna, sin embargo se comprobó que por alguna razón, si se lanzaba <strong>con</strong> la<br />
clase Runtime sí se producían abundantes mensajes <strong>de</strong> trazas tanto por la salida<br />
estándar como por la <strong>de</strong> error, aunque por esta última no se mostraba error<br />
alguno si no otro tipo <strong>de</strong> trazas. Por lo tanto ha sido necesario crear procesos<br />
in<strong>de</strong>pendientes que leen <strong>con</strong>stantemente <strong>de</strong> estas salidas para que nunca estén<br />
vacías, incluyendo las salidas <strong>de</strong>l proceso VLC y los mensajes <strong>de</strong>vueltos por la<br />
<strong>con</strong>exión Telnet.<br />
Como <strong>con</strong>clusión y tras solventar o tratar <strong>de</strong> paliar estos problemas, la ca<strong>de</strong>na<br />
exacta que se usa <strong>con</strong> el método exec para arrancar VLC es (extendiendo los ejemplos<br />
anteriores)<br />
cmd.exe /c C:/VLC/vlc.exe C:/multimedia/vi<strong>de</strong>o.mpg<br />
:sout=#{dst=192.168.1.5;<br />
port-vi<strong>de</strong>o=5000;port-audio=5002} --extraintf=rc --rchost=localhost::5000<br />
--rc-quiet vlc:quit<br />
Hay que hacer notar que si bien se realizó un estudio previo <strong>de</strong>l manejo <strong>de</strong> VLC<br />
y la clase Runtime, la implementación efectiva ha requerido <strong>de</strong> muchas pruebas, alguna<br />
<strong>de</strong> ellas siguiendo el método <strong>de</strong> prueba y error. Este no es un método <strong>de</strong> <strong>de</strong>sarrollo muy<br />
gratificante, sobre todo teniendo en cuenta que el logro <strong>de</strong> los objetivos propuestos no<br />
estaba garantizado. Finalmente se ha obtenido un resultado que proporciona fiabilidad
en el envío <strong>de</strong> los datos RTP, <strong>con</strong> la salvedad <strong>de</strong> que el salto a diferentes puntos <strong>de</strong>l<br />
<strong>con</strong>tenido no siempre funciona. Por otra parte, esta implementación no se pue<strong>de</strong><br />
extrapolar a otros sistemas operativos al ser el comportamiento <strong>de</strong> la clase Runtime<br />
diferente en cada uno <strong>de</strong> ellos.<br />
3.5.7.6. Implementación <strong>de</strong> la clase VlcRtpSen<strong>de</strong>r<br />
Una vez que se ha averiguado cómo enviar datos RTP mediante VLC <strong>de</strong>s<strong>de</strong> un<br />
programa Java, se ha procedido a la implementación <strong>de</strong> la clase VlcRtpSen<strong>de</strong>r, que es<br />
la alternativa a la clase JmfRtpSen<strong>de</strong>r para el envío <strong>de</strong> datos, y al igual que esta<br />
implementa la interfaz RtpSen<strong>de</strong>r. En esta implementación se han empleado las<br />
soluciones expuestas anteriormente para solucionar los problemas que <strong>con</strong>lleva el uso<br />
<strong>de</strong> VLC <strong>de</strong>s<strong>de</strong> un programa java.<br />
• Inicialización: El <strong>con</strong>structor recibe los mismos parámetros que la clase<br />
JmfRtpSen<strong>de</strong>r, a excepción <strong>de</strong> la dirección <strong>de</strong> red local ya que VLC no necesita<br />
<strong>de</strong> este dato. Des<strong>de</strong> el <strong>con</strong>structor se lanza un hilo <strong>de</strong> ejecución que será el<br />
encargado <strong>de</strong> lanzar VLC y su <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol, esto es necesario para que la<br />
clase pueda aten<strong>de</strong>r posteriormente a las llamadas a sus métodos. Se usa el<br />
método exec <strong>de</strong> la clase Runtime, <strong>de</strong> forma análoga al ejemplo anterior. Para<br />
<strong>con</strong>struir la ruta al fichero se usa el nombre <strong>de</strong> este <strong>con</strong>catenado <strong>con</strong> el directorio<br />
don<strong>de</strong> se encuentran los archivos servidos, que ha sido pasado como parámetro.<br />
Se tienen en cuenta los flags <strong>de</strong> las pistas <strong>de</strong> audio y ví<strong>de</strong>o para incluir o no los<br />
campos port-vi<strong>de</strong>o y port-audio. En cuanto al puerto para la <strong>con</strong>sola <strong>de</strong><br />
<strong>con</strong>trol remoto, este habrá sido obtenido previamente mediante un método<br />
interno que <strong>de</strong>vuelve un puerto libre.<br />
Una vez arrancado VLC se establece la <strong>con</strong>exión Telnet a su <strong>con</strong>sola <strong>de</strong><br />
<strong>con</strong>trol. Después se guarda la referencia a su búfer <strong>de</strong> entrada en una variable<br />
global <strong>de</strong> la clase, para que el resto <strong>de</strong> métodos puedan hacer uso <strong>de</strong> él. Por<br />
último se crean los procesos auxiliares que leerán <strong>de</strong> las salidas <strong>de</strong>l proceso VLC<br />
y <strong>de</strong> la <strong>con</strong>exión Telnet para evitar que se produzcan bloqueos.
Cuando VLC se cierre por si mismo al haber terminado la transmisión <strong>de</strong><br />
datos, el estado <strong>de</strong> la transmisión volverá a Deallocated <strong>de</strong>s<strong>de</strong> el estado en que<br />
se en<strong>con</strong>trara y el hilo abierto inicialmente se <strong>de</strong>struirá.<br />
• Método startTransmission: Primero se comprueba si el hilo <strong>de</strong> ejecución<br />
creado en el <strong>con</strong>structor está activo, si no lo está se activa (esto solo se hará la<br />
primera vez que se invoque este método). Después se comprueba si el estado <strong>de</strong><br />
la transmisión RTP es Paused, circunstancia que se dará si se ha invocado el<br />
método pauseTransmission anteriormente. En caso afirmativo se <strong>con</strong>tinúa <strong>con</strong><br />
la transmisión enviando el mensaje pause a la <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol remoto (los<br />
mensajes pause alternan entre pausa y reproducción). La funcionalidad <strong>de</strong> pausa<br />
sí funciona <strong>de</strong> forma fiable<br />
Por último se envía a la <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol remoto un mensaje seek<br />
seguido <strong>de</strong>l parámetro recibido por el método startTransmission, que es el<br />
instante <strong>de</strong>l <strong>con</strong>tenido a partir <strong>de</strong>l cual se <strong>de</strong>sea enviar datos. En este caso existe<br />
el problema <strong>de</strong> fiabilidad que ya se ha explicado. Finalmente el estado <strong>de</strong> la<br />
transmisión pasa a Playing.<br />
• Método pauseTransmission: Se envía a la <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol un mensaje<br />
pause para <strong>de</strong>tener el envío <strong>de</strong> datos. Después se pasa el estado <strong>de</strong> la transmisión<br />
a Paused. Previamente a estas acciones se comprueba que el estado <strong>de</strong> la<br />
transmisión no sea Deallocated, y en caso <strong>de</strong> que sí lo sea se omiten todas ellas.<br />
Esto es <strong>de</strong>bido a que QuickTime envía un mensaje PAUSE cuando llega al final<br />
<strong>de</strong> la reproducción, en tal caso se invocaría el método pauseTransmission<br />
cuando el proceso VLC ya se habría cerrado por si solo, como <strong>con</strong>secuencia se<br />
produciría un error al intentar enviar un mensaje a la <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol ya que<br />
la sesión Telnet ya no existirá.<br />
• Método tearDownTransmission: El método se limita a comprobar si la<br />
transmisión RTP está pausada, en dicho caso la transmisión <strong>con</strong>tinúa. Aunque el<br />
cliente ya no estará esperando datos RTP, esto se hace para que VLC acabe<br />
llegando al final <strong>de</strong> la transmisión y se cierre por si solo. De no tomar esta<br />
medida el proceso VLC quedaría abierto in<strong>de</strong>finidamente.
3.5.8. Módulo VlcSdpGenerator<br />
Aprovechando la experiencia adquirida en cuanto al manejo <strong>de</strong> VLC <strong>de</strong>s<strong>de</strong> un<br />
programa Java se procedió a implementar un módulo capaz <strong>de</strong> obtener una <strong>de</strong>scripción<br />
<strong>de</strong> archivo multimedia en formato SDP, aprovechando la posibilidad <strong>de</strong> usar VLC como<br />
servidor <strong>de</strong> <strong>RTSP</strong>. El método <strong>con</strong>sistirá en arrancar VLC <strong>con</strong> dicha <strong>con</strong>figuración y<br />
posteriormente enviarle una petición DESCRIBE sobre el archivo en cuestión, <strong>de</strong> forma<br />
que VLC <strong>con</strong>testará <strong>con</strong> una respuesta cuyo cuerpo <strong>con</strong>tendrá el SDP.<br />
La implementación <strong>de</strong> este módulo implica la necesidad <strong>de</strong> resolver nuevamente<br />
todos los problemas asociados al uso <strong>de</strong> VLC <strong>con</strong> la clase Runtime que se han <strong>de</strong>scrito<br />
en el capítulo sobre el módulo VlcRtpSen<strong>de</strong>r. Como estos problemas ya se <strong>con</strong>ocen no<br />
se va a volver a incidir sobre ellos. Hay que <strong>de</strong>stacar que se ha <strong>con</strong>seguido que el<br />
funcionamiento <strong>de</strong> este módulo sea robusto.<br />
3.5.8.1. Ejecución <strong>de</strong> VLC como servidor <strong>RTSP</strong><br />
La ejecución <strong>de</strong> VLC en este caso requiere la utilización <strong>de</strong> los parámetros<br />
a<strong>de</strong>cuados para que funcione como servidor <strong>de</strong> <strong>RTSP</strong>. Igual que en el caso <strong>de</strong> la<br />
generación <strong>de</strong> <strong>con</strong>tenido RTP, al método exec se le pasa como primer parámetro el<br />
comando cmd.exe que arranca una <strong>con</strong>sola <strong>de</strong> línea <strong>de</strong> comandos, y a <strong>con</strong>tinuación la<br />
ruta al ejecutable que arranca VLC junto <strong>con</strong> sus parámetros. A <strong>con</strong>tinuación se<br />
enumeran cuales son estos parámetros:
• ttl: este parámetro junto <strong>con</strong> un valor numérico indica el número <strong>de</strong> saltos que<br />
los paquetes <strong>de</strong> <strong>streaming</strong> podrán dar a través <strong>de</strong> la red, como realmente no se va<br />
a usar VLC para recibir datos RTP este campo es irrelevante, pero es necesario<br />
incluirlo.<br />
• color: no se ha en<strong>con</strong>trado información en la documentación sobre este<br />
parámetro pero aparece en los ejemplos y sin él se produce un error.<br />
• I telnet: <strong>con</strong> este parámetro se indica que el servidor <strong>RTSP</strong> se <strong>con</strong>trolará a<br />
través <strong>de</strong> una <strong>con</strong>exión Telnet. A diferencia <strong>de</strong>l módulo VlcRtpSen<strong>de</strong>r, en este<br />
caso no es necesario lanzar una <strong>con</strong>sola <strong>de</strong> <strong>con</strong>trol remoto si no que la <strong>con</strong>exión<br />
Telnet se realiza directamente sobre el proceso VLC.<br />
• telnet-password: <strong>con</strong> este parámetro y su valor se establece la clave <strong>de</strong><br />
autentificación para la <strong>con</strong>exión Telnet, que en este caso sí será necesaria. Lo<br />
lógico sería pensar que se pue<strong>de</strong> establecer cualquier clave, pero hay que<br />
introducir vi<strong>de</strong>olan ya que si se introduce una diferente no será posteriormente<br />
aceptada al intentar establecer la <strong>con</strong>exión.<br />
• rtsp-host: finalmente este parámetro sirve para especificar la dirección IP y<br />
puerto en don<strong>de</strong> el servidor esperará las <strong>con</strong>exiones <strong>con</strong> los clientes.<br />
Experimentalmente se ha comprobado que hay que introducir la dirección<br />
0.0.0.0, ya que si se intenta usar la dirección local 127.0.0.1 las <strong>con</strong>exiones no<br />
llegarán a producirse. El puerto se pue<strong>de</strong> elegir libremente.<br />
En el siguiente ejemplo se muestra la ca<strong>de</strong>na <strong>de</strong> comandos completa que se le pasa<br />
al método exec. El número <strong>de</strong> puerto y el valor ttl son arbitrarios.<br />
cmd.exe /c C:/VLC/vlc.exe -–ttl 1 --color –I telnet --telnetpassword<br />
vi<strong>de</strong>olan --rtsp-host 0.0.0.0:10000
3.5.8.2. Implementación <strong>de</strong> la clase VlcSdpGenerator<br />
Esta clase implementa la interfaz SdpGenerator, que <strong>con</strong>sta <strong>de</strong> un solo método que<br />
<strong>de</strong>vuelve el SDP correspondiente a un archivo multimedia recibiendo su nombre como<br />
parámetro.<br />
• Inicialización: el <strong>con</strong>structor recibe como parámetro el directorio don<strong>de</strong> se<br />
encuentran los archivos multimedia servidos. Se encarga <strong>de</strong> lanzar el hilo <strong>de</strong><br />
ejecución para el proceso VLC. Este hilo arranca VLC como servidor <strong>de</strong> <strong>RTSP</strong><br />
<strong>de</strong> la forma <strong>de</strong>scrita en el apartado anterior, previamente se habrá obtenido un<br />
puerto libre para el último parámetro, el valor <strong>de</strong> este puerto se almacena en una<br />
variable global para su posterior uso.<br />
Una vez arrancado VLC se establece la <strong>con</strong>exión por Telnet, el puerto<br />
<strong>de</strong>berá ser el 4212, que es el puerto por <strong>de</strong>fecto para el servidor <strong>RTSP</strong> <strong>de</strong> VLC.<br />
Se guarda la referencia al búfer <strong>de</strong> escritura en una variable global, y se inicia la<br />
sesión Telnet <strong>con</strong> el envío <strong>de</strong> la clave, vi<strong>de</strong>olan.<br />
En <strong>con</strong>clusión, el resultado <strong>de</strong> este proceso <strong>de</strong> inicialización es el<br />
servidor <strong>RTSP</strong> <strong>de</strong> VLC arrancado, el puerto en el que espera las peticiones <strong>RTSP</strong><br />
y una referencia al búfer para enviarle comandos a través <strong>de</strong> Telnet.<br />
• Método getSdpContent: este método obtiene el SDP, recibiendo como<br />
parámetro el nombre <strong>de</strong>l archivo. Como el <strong>con</strong>structor almacenó el directorio<br />
que <strong>con</strong>tiene los archivos multimedia que se sirven, ya se dispone <strong>de</strong> la ruta<br />
completa.<br />
Para que el servidor <strong>RTSP</strong> <strong>de</strong> VLC pueda servir un archivo <strong>de</strong>terminado,<br />
es necesario <strong>con</strong>figurar a tal efecto el servidor mediante el envío <strong>de</strong> comandos a
través <strong>de</strong> la interfaz Telnet, <strong>con</strong>cretamente dos mensajes. El primero es una<br />
ca<strong>de</strong>na compuesta por new, seguido <strong>de</strong> un i<strong>de</strong>ntificador arbitrario y por último<br />
vod enabled. El segundo mensaje estará formado por setup, el i<strong>de</strong>ntificador<br />
anterior, input y finalmente la ruta completa al archivo. Este i<strong>de</strong>ntificador <strong>de</strong>berá<br />
estar incluido en la URL <strong>de</strong> los mensajes que los clientes envíen cuando hagan<br />
referencia a este archivo. Por lo tanto, se usa como i<strong>de</strong>ntificador el propio<br />
nombre <strong>de</strong>l archivo, y así los clientes se podrán referir a los archivos <strong>de</strong>seados<br />
por su propio nombre. Así pues, para <strong>con</strong>figurar un archivo llamado vi<strong>de</strong>o.mpg<br />
se le envían al servidor por Telnet estos dos mensajes:<br />
new vi<strong>de</strong>o.mpg vod enabled<br />
setup vi<strong>de</strong>o.mpg input c:/multimedia/vi<strong>de</strong>o.mpg<br />
Una vez <strong>con</strong>figurado el archivo, se comprueba si se ha establecido una<br />
<strong>con</strong>exión al puerto don<strong>de</strong> el servidor espera las peticiones <strong>RTSP</strong>. En caso<br />
negativo se establece dicha <strong>con</strong>exión, esta <strong>con</strong>exión no se cerrará así que este<br />
paso solamente se produce la primera vez que se invoca al método<br />
getSdpContent. Se pue<strong>de</strong> pensar que hubiera sido más lógico establecer esta<br />
<strong>con</strong>exión al realizar las tareas <strong>de</strong> inicialización, en lugar <strong>de</strong> almacenar el puerto<br />
y esperar hasta este momento. Esto no es posible ya que es necesario haber<br />
<strong>con</strong>figurado el servidor para servir al menos un archivo antes <strong>de</strong> intentar<br />
<strong>con</strong>ectarse <strong>con</strong> él, en caso <strong>con</strong>trario dicha <strong>con</strong>exión fallará.<br />
En este momento ya es posible enviarle el mensaje <strong>RTSP</strong> al servidor <strong>de</strong><br />
VLC. Será un mensaje DESCRIBE cuya URL <strong>con</strong>tendrá el nombre <strong>de</strong>l archivo,<br />
que es el i<strong>de</strong>ntificador que se ha usado para <strong>con</strong>figurar el servidor en los pasos<br />
previos. De esta forma se simula ser un cliente <strong>RTSP</strong>. El mensaje se envía en<br />
formato <strong>de</strong> texto plano (juego <strong>de</strong> caracteres UTF-8). El mensaje cumple<br />
completamente <strong>con</strong> el <strong>protocolo</strong> <strong>RTSP</strong>, incluyendo el número <strong>de</strong> secuencia y la<br />
línea en blanco.<br />
DESCRIBE rtsp://127.0.0.1:10000/vi<strong>de</strong>o.mpg <strong>RTSP</strong>/1.0<br />
Cseq: 1
Inmediatamente <strong>de</strong>spués <strong>de</strong> enviar el mensaje se recibe la respuesta <strong>de</strong><br />
VLC, es la respuesta típica a una petición DESCRIBE. Lo que realmente<br />
interesa es el cuerpo <strong>de</strong> la respuesta <strong>con</strong> el SDP, y la cabecera Content-Length<br />
para <strong>con</strong>ocer su tamaño y leerlo correctamente. Así pues se leen las sucesivas<br />
cabeceras <strong>de</strong> la respuesta y cuando se <strong>de</strong>tecta la cabecera Content-Length se<br />
almacena su valor. Después se siguen <strong>de</strong>scartando otras posibles cabeceras hasta<br />
leer una línea en blanco. El <strong>con</strong>tenido a partir <strong>de</strong> este punto será el SDP, y<br />
<strong>con</strong>ociendo el tamaño no hay más que leer los siguientes caracteres necesarios.<br />
El método getSdpContent <strong>de</strong>vuelve un objeto <strong>de</strong> la clase SdpContent,<br />
que <strong>con</strong>tiene el SDP, la URL <strong>de</strong> <strong>con</strong>trol <strong>de</strong> ví<strong>de</strong>o y la URL <strong>de</strong> <strong>con</strong>trol <strong>de</strong> audio.<br />
Se buscan estas URLs en el SDP y se crea el objeto SdpContent <strong>con</strong> estos tres<br />
elementos. Para buscar las URLs hay que buscar las cabeceras <strong>de</strong> audio y vi<strong>de</strong>o<br />
en el SDP m=vi<strong>de</strong>o, m=audio y a <strong>con</strong>tinuación las líneas <strong>con</strong> las URL, que<br />
empiezan por a=<strong>con</strong>trol. Si no existe una <strong>de</strong> las pistas su valor en el objeto será<br />
null. Finalmente el método <strong>de</strong>vuelve este objeto.<br />
Por último hay que tener en cuenta que es posible que el archivo pedido<br />
no exista. En este caso VLC <strong>de</strong>vuelve un SDP incompleto que solo <strong>con</strong>tiene las<br />
primeras líneas obligatorias pero ninguna información sobre las pistas. Esta<br />
circunstancia se comprueba, y en este caso el método <strong>de</strong>vuelve una excepción.<br />
Esta excepción es capturada por la clase RequestHandler, que en tal caso<br />
informará al cliente que el archivo solicitado no existe.
3.5.9. Módulo FileSdpGenerator<br />
Este módulo <strong>con</strong>stituye la alternativa al módulo VlcSdpGenerator e<br />
implementa la interfaz SdpGenerator al igual que este. Como se mencionó en el<br />
capítulo sobre la metodología <strong>de</strong> <strong>de</strong>sarrollo este módulo se implementó durante las<br />
primeras etapas, permitiendo al servidor usar SDPs almacenados en disco y así po<strong>de</strong>r<br />
realizar pruebas. Des<strong>de</strong> el punto <strong>de</strong> vista <strong>con</strong>ceptual no aporta gran <strong>con</strong>tenido al<br />
proyecto y es el <strong>de</strong> implementación más sencilla, pero pue<strong>de</strong> resultar útil cuando el<br />
módulo VlcSdpGenerator no es válido, por ejemplo si se quiere servir un archivo cuyo<br />
formato VLC no es capaz <strong>de</strong> manejar.<br />
• Inicialización: El <strong>con</strong>structor <strong>de</strong> la clase FileSdpGenerator recibe como<br />
parámetro la ruta al directorio don<strong>de</strong> se encuentran los archivos SDP, y lo<br />
almacena.<br />
• Método getSdpContent: este método leerá el <strong>con</strong>tenido <strong>de</strong>l archivo SDP y<br />
creará un objeto SdpContent <strong>de</strong> forma análoga a la <strong>de</strong>scrita en el capítulo sobre<br />
la clase VlcSdpGenerator. La única <strong>de</strong>cisión <strong>de</strong> diseño relevante es elegir una<br />
<strong>con</strong>vención para el nombre <strong>de</strong> los archivos SDP, <strong>de</strong> forma que se sepa qué<br />
archivo SDP correspon<strong>de</strong> al archivo multimedia cuyo nombre se ha pasado<br />
como parámetro al método. Se ha escogido esta solución: el nombre <strong>de</strong>l archivo<br />
SDP será el nombre <strong>de</strong>l archivo multimedia <strong>con</strong>catenado <strong>con</strong> su extensión<br />
original, y nueva extensión será sdp. Por ejemplo, si se recibe como parámetro el<br />
nombre multimedia.mpg, se intentará leer el SDP <strong>de</strong>l archivo<br />
multimediampg.sdp. Siguiendo esta <strong>con</strong>vención es imposible que dos archivos<br />
multimedia diferentes tengan un archivo SDP <strong>con</strong> el mismo nombre.<br />
Si no se encuentra el archivo SDP, se eleva una excepción <strong>de</strong> igual<br />
forma que en la clase VlcSdpGenerator.
4. Conclusiones y líneas futuras<br />
4.1. Conclusiones<br />
Se ha <strong>con</strong>seguido implementar el servidor <strong>de</strong> <strong>streaming</strong> mediante <strong>protocolo</strong><br />
<strong>RTSP</strong>. Este servidor es capaz <strong>de</strong> servir ví<strong>de</strong>os almacenados localmente y es compatible<br />
<strong>con</strong> los reproductores VLC y QuickTime. Este servidor se pue<strong>de</strong> <strong>con</strong>figurar al<br />
arrancarlo <strong>de</strong> forma que use diferentes módulos a la hora <strong>de</strong> obtener las <strong>de</strong>scripciones <strong>de</strong><br />
los <strong>con</strong>tenidos multimedia y envío <strong>de</strong> los datos por <strong>protocolo</strong> RTP. Por lo tanto, el<br />
objetivo principal <strong>de</strong>l proyecto se ha cubierto.<br />
Durante la etapa inicial se realizó un estudio <strong>de</strong> las tecnologías actuales<br />
relacionadas <strong>con</strong> el <strong>streaming</strong>, y la <strong>con</strong>clusión más importante es que existe una gran<br />
variedad <strong>de</strong> tecnologías y formatos, y a<strong>de</strong>más la rápida evolución en esta área provoca<br />
que sigan apareciendo nuevos elementos a tener en cuenta a gran velocidad. Aunque el<br />
<strong>streaming</strong> es <strong>con</strong>ceptualmente sencillo, esta variedad <strong>de</strong> tecnologías dificultan las tareas<br />
<strong>de</strong> <strong>de</strong>sarrollo, ya que es necesario estudiar sus características y <strong>de</strong>cantarse por algunas<br />
<strong>de</strong> ellas.<br />
Otro factor a tener en cuenta son las <strong>de</strong>mandas en cuanto a robustez y<br />
rendimiento. El <strong>streaming</strong> está estrechamente relacionado <strong>con</strong> el tiempo, la transmisión<br />
<strong>de</strong> <strong>con</strong>tenidos multimedia requiere <strong>de</strong> gran ancho <strong>de</strong> banda, capacidad <strong>de</strong> proceso e<br />
implementación eficiente. Las ralentizaciones o <strong>de</strong>fectos en general durante la<br />
reproducción no son admisibles por el usuario actual. En este proyecto se han<br />
mencionado algunos problemas como la pérdida <strong>de</strong> sincronismo entre el audio y el<br />
vi<strong>de</strong>o en JMF o la falta <strong>de</strong> robustez <strong>de</strong> VLC al usarlo <strong>de</strong>s<strong>de</strong> un programa Java. Estos<br />
problemas no serían tolerables en un entorno <strong>con</strong> usuarios reales. Prueba <strong>de</strong> la dificultad<br />
<strong>de</strong> alcanzar un rendimiento alto es la existencia <strong>de</strong> productos comerciales que ofrecen
una funcionalidad similar a la <strong>de</strong> este proyecto, por los que hay que pagar dinero. Este<br />
proyecto ofrece la ventaja <strong>de</strong> no estar atado a ninguna tecnología <strong>de</strong> <strong>streaming</strong> en<br />
<strong>con</strong>creto <strong>de</strong>bido a su estructura basada en módulos, lo que podría permitir su mejora.<br />
En cuanto al <strong>protocolo</strong> <strong>RTSP</strong>, se ha implementado la funcionalidad necesaria<br />
para el cumplimiento <strong>de</strong> los objetivos. Se han hecho patentes las ventajas <strong>de</strong> un<br />
<strong>protocolo</strong> basado en texto a la hora <strong>de</strong> compren<strong>de</strong>rlo y hacer uso <strong>de</strong> él. Un <strong>protocolo</strong><br />
textual no <strong>de</strong>staca por su eficiencia en cuanto a <strong>de</strong>manda <strong>de</strong> procesamiento, pero en este<br />
caso ese factor es irrelevante por el pequeño tamaño <strong>de</strong> los mensajes y su escasa<br />
frecuencia.<br />
También resalta la importancia <strong>de</strong> seguir los estándares a la hora <strong>de</strong> implementar<br />
los <strong>protocolo</strong>s. Precisamente el objetivo <strong>de</strong> la estandarización es la puesta en común <strong>de</strong><br />
las características <strong>de</strong>l <strong>protocolo</strong>, para que los diferentes productos puedan interaccionar<br />
entre ellos. Mientras que ha sido posible compatibilizar el servidor <strong>con</strong> los<br />
reproductores VLC y QuickTime (este último usa algunas cabeceras no <strong>de</strong>scritas en la<br />
especificación pero es posible ignorarlas), no ha sido así <strong>con</strong> Windows Media Player.<br />
Esto es <strong>de</strong>bido al amplio uso <strong>de</strong> cabeceras no estándar, que un servidor <strong>de</strong>be ser capaz<br />
<strong>de</strong> compren<strong>de</strong>r para interaccionar <strong>con</strong> este reproductor. Seguramente esto obe<strong>de</strong>zca a<br />
motivaciones <strong>de</strong> índole comercial, siguiendo la tradición <strong>de</strong> Microsoft <strong>con</strong> otros<br />
productos como su navegador Internet Explorer. El <strong>de</strong>sarrollo <strong>de</strong>l software y su<br />
difusión se ven perjudicados por estas prácticas.<br />
En cuanto a este proyecto, para <strong>con</strong>tribuir a la difusión <strong>de</strong> las tecnologías <strong>de</strong><br />
<strong>streaming</strong> se ha optado por liberar el código como software libre <strong>con</strong> licencia GPL.<br />
4.2. Líneas futuras<br />
En cuanto al <strong>protocolo</strong> <strong>RTSP</strong>, las posibilida<strong>de</strong>s <strong>de</strong> ampliación son prácticamente<br />
ilimitadas. Por una parte se pue<strong>de</strong> ampliar su implementación añadiendo las<br />
funcionalida<strong>de</strong>s que ofrece y no han sido tenidas en cuenta en este proyecto. En el<br />
capítulo sobre la <strong>de</strong>scripción <strong>de</strong> los mensajes <strong>RTSP</strong> se habló <strong>de</strong>l mensaje RECORD que
permite al servidor realizar una grabación, si está <strong>con</strong>ectado a algún dispositivo <strong>de</strong><br />
captura. También se habló <strong>de</strong>l mensaje REDIRECT que permitiría indicar al cliente el<br />
cambio <strong>de</strong> localización <strong>de</strong>l servidor, por ejemplo esto se podría usar si se tuvieran varias<br />
instancias <strong>de</strong>l servidor arrancadas en diferentes sitios. Los mensajes<br />
GET_PARAMETER y SET_PARAMETER permiten en general establecer valores y<br />
solicitar su <strong>con</strong>tenido, su implementación es abierta y se podría añadir alguna otra<br />
funcionalidad que se <strong>con</strong>si<strong>de</strong>rara interesante. Algunos servidores comerciales, por<br />
ejemplo, envían un mensaje SET_PARAMETER al final <strong>de</strong> la sesión <strong>con</strong> estadísticas<br />
sobre la transmisión.<br />
A<strong>de</strong>más <strong>de</strong> estos mensajes la especificación <strong>de</strong>l <strong>protocolo</strong> <strong>de</strong>scribe otras<br />
cabeceras, así como mensajes <strong>de</strong> estado en las respuestas para informar <strong>de</strong><br />
circunstancias sucedidas en el servidor. También se podrían mejorar algunas <strong>de</strong> las<br />
cabeceras que se han usado. Por ejemplo la implementación <strong>de</strong> la cabecera Range está<br />
preparada para re<strong>con</strong>ocer los intervalos <strong>de</strong> tiempo expresados en segundos, pero es<br />
posible usar otros formatos. Una característica especialmente interesante podría ser el<br />
servicio <strong>de</strong> <strong>con</strong>tenidos multimedia en vivo, <strong>con</strong>ectando el servidor a algún tipo <strong>de</strong><br />
dispositivo <strong>de</strong> entrada. Por último, recuér<strong>de</strong>se que <strong>RTSP</strong> es un <strong>protocolo</strong> extensible, así<br />
que se podría aumentar la funcionalidad incluso más allá <strong>de</strong> lo especificado en su RFC.<br />
En cuanto al envío <strong>de</strong> datos se podría ampliar el servidor mediante la<br />
implementación <strong>de</strong> nuevos módulos que usen otras tecnologías, por ejemplo alguna <strong>de</strong><br />
las <strong>de</strong>scritas en esta memoria y <strong>de</strong> las cuales no se han hecho uso. Bastaría <strong>con</strong><br />
programar clases que cumplan la interfaz RtpSen<strong>de</strong>r, que se ha establecido como<br />
patrón para la funcionalidad que los generadores <strong>de</strong> datos RTP <strong>de</strong>ben cumplir. Tal vez<br />
sería posible alcanzar un mejor rendimiento <strong>con</strong> alguna otra herramienta, superando los<br />
problemas aparecidos <strong>con</strong> JMF y VLC. A<strong>de</strong>más esto posibilitaría actualizar el servidor,<br />
ya que muy probablemente en el futuro aparezcan nuevos formatos multimedia, y sería<br />
una manera <strong>de</strong> evitar que el servidor se quedara obsoleto.
Bibliografía<br />
[1]