Emisión de medios
Last updated
Last updated
Vamos a estudiar en esta sesión la forma en la que podemos emitir vídeo desde los dispositivos móviles a través de Internet o a otros dispositivos.
El servidor Wowza, además de publicar contenido bajo demanda (VOD), nos permite realizar emisiones en directo. Para ello deberemos enviar desde el cliente un stream RTSP o RTMP, y el servidor de encargará de difundirlo al igual que en el caso del VOD (con HLS para dispositivos iOS, y con RTSP para Android).
En la sección Incoming Publishers de la aplicación live de Wowza podemos ver los datos que deberemos utilizar en la aplicación de emisión para publicar vídeo en directo en Wowza:
De esta pantalla necesitaremos la siguiente información para poder publicar vídeo en el servidor:
IP del servidor
Puerto del servicio de streaming
Nombre de la aplicación de streaming (live
por defecto)
Usuario y password del usuario publisher (deberemos recordar los datos del usuario que introdujimos al configurar Wowza).
A continuación veremos cómo podemos publicar en esta aplicación utilizando una aplicación Android.
Aunque el soporte para la emisión de medios de momento no forma parte de los SDKs de las principales plataformas móviles, podemos encontrar diferentes librerías y tecnologías que lo proporcionan. Vamos a revisar algunas de ellas:
libstreaming: Librería open source para Android que nos permite emitir vídeo vía RTSP.
Media Library for iOS: Librería open source para iOS que nos permite emitir vídeo vía RTMP.
Adobe AIR: Esta tecnología nos proporciona un SDK con el que podemos crear aplicaciones multiplataforma. Dentro de dicho SDK contamos con clases para la reproducción y captura de vídeo, y además para su emisión de forma sencilla mediante RTMP.
Kickflip: Plataforma para la emisión de vídeo desde dispositivos iOS y Android. Nos proporciona un SDK open source sencillo de utilizar que emite el vídeo a través de sus propios servidores y mediante sus propios protocolos.
Podemos utilizar la librería libstreaming para emitir vídeo RTSP desde un dispositivo Android:
Seguiremos los siguientes pasos para importar la librería en Eclipse:
Descargar la librería libstreaming.
Seleccionar File > New > Import module….
Seleccionar el directorio donde se encuentra libstreaming.
Deja todas las opciones por defecto del asitente.
Pulsar Finish.
Tras ejecutar el asistente es posible que haya que modificar el fichero
build.gradle
delibstreaming
para que utilice una versión de las build tools (buildToolsVersion
) que tengamos instalada. Tras hacer la corrección, se deberá volver a sincronizar con gradle.
Una vez tengamos la librería como módulo del proyecto, tendremos que añadirla como dependencia del módulo de nuestra aplicación para poder emitir desde ella vía streaming. Para ello seguiremos los siguientes pasos:
Seleccionamos File > Project Structure....
Seleccionamos el módulo de nuestra aplicación (por ejemplo app
) y vamos a la pestaña Dependencies.
Añadimos una dependencia de módulo (Module Dependency) y seleccionamos :libstreaming
.
En el build.gradle
del módulo de nuestra aplicación veremos la dependencia de la siguiente forma:
Con esto ya podremos utilizar la librería libstreaming desde nuestro proyecto. Al empaquetar la aplicación, la librería será incluida con ella.
Vamos a ver a continuación cómo utilizar esta librería en el código de nuestra aplicación.
En primer lugar, necesitaremos solicitar los siguientes permisos para poder utilizar la librería:
En la interfaz necesitaremos contar con una vista de tipo SurfaceView
para poder realizar el preview de la cámara. Suponemos que en el layout de la actividad hemos incluido esta vista con un identificador R.id.surfaceView
.
En el onCreate
de nuestra actividad obtenemos el SurfaceView
y el holder de dicha superficie:
La actividad deberá implementar la interfaz SurfaceHolder.Callback
.
¡CUIDADO! La vista
SurfaceView
que debemos utilizar no es la de Android, sino una versión alternativa suministrada por libstreaming, que se encuentra en el paquetenet.majorkernelpanic.streaming.gl
. Por lo tanto, para incluir esta vista en el layout deberemos indicar su nombre completo:
Tras la obtención de la superficie, creamos una sesión de captura que la utilice para mostrar el preview. La sesión será un objeto de tipo Session
(pertenece a la librería libstreaming):
En la sesión configuramos los codecs y la calidad del audio y del vídeo. Deberemos implementar en la actividad la interfaz Session.Callback
para recibir los eventos de la sesión.
Por último, crearemos un cliente RTSP que se encargará de enviar el stream de vídeo capturado en la sesión a Wowza. El cliente los crearemos con un objeto de la clase RtspClient
, pasándole como parámetro los datos de acceso al servidor:
Es importante poner en la ruta el nombre de la aplicación configurada en Wowza, y tras él el nombre del stream. Por ejemplo, si tenemos la aplicación live
en Wowza, podríamos crear el siguiente stream:
Deberemos implementar en la actividad la interfaz RtspClient.Callback
para tener constancia de los eventos de la conexión con el servidor de streaming.
Una vez terminado de configurar, podemos poner en marcha la captura y el envío de datos al servidor con:
En onDestroy
deberíamos destruir todos los objetos que hemos construido en onCreate
:
Nos falta únicamente definir los métodos de las distintas interfaces que hemos tenido que implementar.
SurfaceHolder.Callback
Cuando la superficie se crea podemos poner en marcha el preview de la sesión de captura, y al destruirse podemos detenerlo:
Session.Callback
Nos obliga a definir los siguientes métodos:
Con ellos podemos tener constancia de todos los cambios ocurridos en la sesión de captura. No es necesario introducir contenido en ellos para utilizar el streaming.
RtspClient.Callback
Nos obliga a definir el método onRtspUpdate
, que se invoca cuando hay algún evento en la comunicación por RTSP:
No es necesario introducir ningún contenido en este método, pero puede ser de utilidad introducir algún mensaje de log para depurar el funcionamiento de la conexión con el servidor (por ejemplo comprobar si los credenciales son correctos).
Si al poner en marcha la emisión con libstreaming tenemos un
IOException
(con mensaje Try again), puede que sea necesario aumentar el timeout en la clasenet.majorkernelpanic.streaming.MediaStream