09.02.2013 Views

Servidor modular de streaming con protocolo RTSP

Servidor modular de streaming con protocolo RTSP

Servidor modular de streaming con protocolo RTSP

SHOW MORE
SHOW LESS

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]

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!