Transmisor multimedia
El transmisor multimedia se controla configurando una canalización. El componente de origen de flujo y el componente de destino de flujo se especifican pasando una cadena al método roMediaStreamer.SetPipeline() . Esta cadena contiene tanto los componentes de origen como de destino concatenados; las diferentes etapas de la canalización están delimitadas por comas.
La canalización se inicia llamando al método start() (sin argumentos adicionales). El método stop() se puede utilizar para detener la canalización. Sin embargo, algunas de las etapas de la canalización (descritas en la sección Máquina de estados del transmisor multimedia a continuación) continuarán ejecutándose internamente, por lo que el método reset() puede ser preferible para finalizar el flujo.
Los reproductores XD5 no admiten codificación. Puede transmitir archivos existentes a otros reproductores y clientes, pero no puede cambiar la tasa de bits ni la resolución del archivo usando la codificación del transmisor multimedia.
Los reproductores XT5 tienen entrada HDMI solo con audio. La entrada protegida con HDCP no se transmite. No tienen fuente de pantalla, ni roStreamQueue ni eventos de fin de flujo.
Transmisión simple de archivos
El siguiente ejemplo muestra cómo transmitir desde un origen de archivo a un único cliente:
m = CreateObject("roMediaStreamer")
m.SetPipeline("file:///data/clip.ts, udp://239.192.0.0:1234/")
m.Start()Para detener el flujo, llame a m.reset().
El origen archivo y los destinos udp/rtp no funcionan de la misma manera que en el firmware 4.7. Sin embargo, el método de transmisión de archivos de 4.7 sigue estando disponible usando los componentes filesimple, udpsimple y rtpsimple . El siguiente ejemplo funciona exactamente igual que la transmisión multimedia en 4.7:
m.SetPipeline("filesimple:///data/clip.ts, udpsimple://239.192.0.0:1234/")
Tenga en cuenta que el componente filesimple solo funciona con udpsimple/rtpsimple, y viceversa.
No utilice los puertos 8888 o 9999, ya que estos puertos pueden ser utilizados por BrightSignOS.
Máquina de estados del transmisor multimedia
El transmisor multimedia, representado por el método SetPipeline() , tiene cuatro estados:
- RESET: El transmisor multimedia se ha creado, pero no se ha asignado ni ejecutado nada.
- INITIALISED: Puede que se haya realizado alguna asignación y que algunos recursos estén reservados, pero nada está en ejecución.
- CONNECTED: Todas las estructuras se han creado y todos los componentes de la canalización están conectados entre sí. Aunque la canalización no produce salida, algunas partes internas de esta ya pueden estar ejecutándose.
- RUNNING: La canalización está en ejecución.
Cuando se crea un transmisor multimedia, comienza en el estado RESET. Después de llamar a SetPipeline(), los estados pueden progresar usando los siguientes métodos de roMediaStreamer: Initialise(), Conectar(), y Start(). Pasar a un estado posterior hace que cualquier estado intermedio se recorra automáticamente, por lo que una canalización puede iniciarse simplemente llamando a Start().
Cuando un transmisor multimedia está en el estado RUNNING, puede retroceder por los estados llamando respectivamente a Stop(), Disconnect(), y Reset(). Como antes, los estados intermedios pueden omitirse, por lo que es posible detener el transmisor multimedia y liberar todos sus recursos simplemente llamando a Reset(). Aunque Stop() detiene cualquier salida de la canalización, aún puede haber cierta actividad interna.
Llamar a SetPipeline() siempre hace que el transmisor multimedia vuelva al estado RESET. Todas las funciones de interfaz anteriores, aparte de SetPipeline(), no aceptan argumentos.
Componentes de origen
Esta sección enumera los componentes de origen disponibles actualmente para una canalización de transmisión. Tenga en cuenta que algunos componentes de origen (es decir, mem:/ y memsimple:/) no pueden llamarse hasta que primero se creen usando componentes de destino, los cuales se describen en la siguiente sección.
filesimple:///filename
Este componente lee el archivo especificado desde el almacenamiento local. El archivo debe ser un flujo de transporte MPEG-2 (generalmente con un sufijo .ts). Este componente solo puede conectarse a componentes udpsimple:, rtpsimple:, o memsimple: . El parámetro opcional bucle puede añadirse para hacer que el archivo de entrada se repita en bucle:
m.SetPipeline("filesimple:///file.ts?loop, udpsimple://239.192.0.0:1234/")
file:///filename
Este componente puede actuar como origen o destino. Como origen, lee desde un archivo de flujo de transporte MPEG-2 y puede conectarse de forma más general a otros componentes. Este componente no simple debe usarse cuando se conecta a componentes de destino hls: (porque utiliza un flujo indexado). Debido a que utiliza menos recursos, recomendamos usar el componente filesimple: en lugar del componente archivo: siempre que sea suficiente.
Este componente acepta los parámetros opcionales clave y iv para cifrado / descifrado de archivos.
El parámetro opcional loop puede añadirse para hacer que el archivo de entrada se repita en bucle:
m.SetPipeline("file:///file.ts?loop, hls:///file?duration=3")
hdmi:[///]
Este componente recibe audio y video desde la entrada HDMI®. Luego puede enviarse a través de un componente esencoder de Media Streamer mostrado a continuación y transmitirse o escribirse en un archivo.
display:[///]
Este componente recibe el audio y video de la presentación actual, lo que permite al reproductor codificar y transmitir la salida de visualización actual. Consulte la página Codificación de pantallaDisplay Encoding para obtener más información sobre el uso de este componente.
udp://IP_address:port/
Este componente recibe un flujo usando el protocolo UDP.
rtp://IP_address:port/
Este componente recibe un flujo usando el protocolo RTP.
rtsp://IP_address:port/path
Este componente recibe un flujo usando el protocolo RTSP. Puede incluirse un parámetro opcional dtcp.port para especificar una sesión cifrada DTCP-IP:
rtsp://10.1.243:554/stream1?dtcp.port=8888
http://IP_address:port/path
Este componente recibe un flujo usando el protocolo HTTP.
https://IP_address:port/path
Este componente recibe un flujo usando el protocolo HTTPS.
gst://IP_address:port/path
Este componente recibe una canalización GStreamer y genera un flujo no simple usándola.
gstsimple://IP_address:port/path
Este componente recibe una canalización GStreamer y genera un flujo simple usándola.
memsimple:/name/stream.ts
Este componente lee desde un componente de flujo de memoria previamente creado (destino) con el nombre especificado y reenvía los resultados a otros componentes simples. Tenga en cuenta que /stream.ts se añade para denotar "el búfer de memoria completo". El siguiente ejemplo realizará multidifusión de un flujo de memoria:
m.SetPipeline("memsimple:/livestream/stream.ts, rtpsimple://239.192.0.0:5004/")
Un componente de origen memsimple: puede originarse a partir de un flujo de memoria simple (usando el componente de destino memsimple:) o de un flujo de memoria no simple e "indexado" (usando el componente de destino mem:).
Consulte la página Streaming de memoriaMemory Streaming para obtener más detalles.
mem:/name/stream.ts
Este componente lee desde un flujo de memoria de destino creado previamente con el nombre dado; luego puede reenviar los resultados a otros componentes no simples. Tenga en cuenta que /stream.ts se agrega para indicar "el búfer de memoria completo". Suponiendo recursos suficientes, el siguiente ejemplo transcodificará y transmitirá un flujo de memoria:
m.SetPipeline("mem:/livestream/stream.ts, decoder:, encoder:, rtp://239.192.0.0:5004/")
Componentes de destino
Esta sección enumera los componentes de destino disponibles actualmente.
udpsimple://IP_address:port/
Este componente transmite su entrada a través de UDP a la dirección IP y puerto proporcionados. Este destino solo funciona con el componente fuente filesimple: o memsimple: como entrada.
rtpsimple://IP_address:port/
Este componente transmite su entrada a través de RTP a la dirección IP y puerto proporcionados. Este destino solo funciona con el componente fuente filesimple: o memsimple: como entrada.
httpsimple:///socket=num
Este componente transmite su entrada a través de una conexión HTTP. Este destino solo funciona con el componente fuente filesimple: o memsimple: como entrada. Está diseñado para utilizarse como un servidor de medios HTTPHTTP media server y no puede utilizarse para transmitir directamente a un cliente.
udp://IP_address:port/
Este componente transmite su entrada a través de UDP a la dirección IP y puerto proporcionados.
rtp://IP_address:port/
Este componente transmite su entrada a través de RTP a la dirección IP y puerto proporcionados.
http:///socket=num
Este componente transmite su entrada a través de una conexión HTTP. Este componente está diseñado para utilizarse como un servidor de medios HTTPHTTP media server y no puede utilizarse para transmitir directamente a un cliente.
file:///filename
Este componente escribe su entrada en el archivo especificado, que se guardará como un archivo de flujo de transporte MPEG-2. Este componente acepta los parámetros opcionales clave y iv para cifrado de archivos.
display:[///]
Este componente le permite ver lo que hay en un flujo (a menudo junto con el componente decoder) y se proporciona únicamente para depuración: BrightScript utiliza principalmente los objetos roVideoPlayer y roAudioPlayer para reproducir contenido de streaming.
memsimple:/name
Este componente funciona únicamente con el componente filesimple: . Escribe su entrada en un flujo de memoriamemory stream llamado /name. Esto constituye un flujo de memoria simple, lo que significa que no está indexado y no puede utilizarse como entrada para una fuente mem:, solo otra fuente memsimple:. Este componente toma un parámetro de tamaño opcional que especifica el tamaño del búfer de memoria en megabytes. El tamaño predeterminado del búfer de memoria es de 5MB.
m.SetPipeline("filesimple:///file.ts, memsimple:/file?size=2")
mem:/name
Este componente crea un flujo de memoria con el /name especificado. Este componente puede recibir entrada de componentes generales y escribe en un flujo de memoriamemory stream indexado (en lugar de simple), que puede volver a leerse mediante el componente fuente mem: . Por lo tanto, puede utilizarse para admitir streaming HLS.
m.SetPipeline("file:///file.ts, mem:/file?duration=3&size=25")
El componente de destino mem: acepta dos parámetros opcionales:
- talla: El tamaño del búfer de memoria en MB (megabytes). Para streaming HLS, este debe ser un búfer grande.
- duración: La duración objetivo de los puntos de índice (que se convierten en segmentos HLS).
hls:///path
Este componente segmenta el flujo entrante y lo escribe en la ruta indicada. Los segmentos escritos tendrán el nombre "path_000000.ts", "path_0000001.ts", etc., y el archivo de índice se llamará "path_index.m3u8".
El componente de destino HLS acepta el parámetro duración, que especifica la longitud objetivo aproximada, en segundos, de los segmentos HLS. El valor predeterminado es 5, por lo que para segmentar un archivo en duraciones de 3 segundos podría usar código similar al siguiente:
m.SetPipeline("file:///file.ts, hls:///file?duration=3")
La función anterior dividiría el archivo file.ts en segmentos de aproximadamente 3 segundos cada uno, llamados "file_000000.ts", "file_000001.ts", "file_000002.ts", etc.
Opciones del componente de destino
Las siguientes opciones se aplican a los componentes de destino udpsimple, rtpsimple, udp y rtp .
maxbitrate
El parámetro maxbitrate limita el bitrate instantáneo máximo (en Kbps) de un flujo. Por ejemplo, el siguiente componente nunca transmitiría a una velocidad superior a aproximadamente 2 Mbps:
rtp://IP_address:port/?maxbitrate=2000
Este número necesita ajustarse tanto para el contenido que se transmite como para la red a través de la cual se envía. Tenga en cuenta que puede ser difícil configurar bitrates para algunas redes inalámbricas.
ttl
El parámetro ttl especifica cuántas veces los paquetes multicast pueden reenviarse a través de switches y otra infraestructura de red. El valor predeterminado para este parámetro es 1.
Ejemplo:
rtp://IP_address:port/?ttl=64
Otros componentes
encoder:[///][param=value]
Este componente recibe una entrada sin codificar y genera datos de audio/video codificados como un flujo de transporte MPEG-2. Los siguientes son parámetros válidos:
- retardoaudio=[retraso_en_ms]: El desfase de sincronización de audio en milisegundos. El valor predeterminado es 0. Un valor positivo retrasará el audio con respecto al video, mientras que un valor negativo retrasará el video con respecto al audio.
- delay=[delay_in_ms]: El retraso A2P en milisegundos. Si este parámetro se establece en 0 (el valor predeterminado), el codificador determina el retraso.
- pframes=[frames]: El número de P-slices entre I-slices en el GOP
- bframes=[frames]: El número de B-slices entre P-slices en el GOP
- vbitrate=[bitrate]: El bitrate de video especificado en Kbps
- vformat=[format]: La resolución y la velocidad de fotogramas de la salida de video. El formato puede especificarse como cualquiera de los siguientes:
- 480i50
- 480p25
- 720p24
- 720p25
- 720p30
- 720p50
- 720p60
- 1080i50
- 1080i60
- 1080p24
- 1080p25
- 1080p30
- 1080p50
- 1080p60
Este componente utiliza H.264 para video y AAC para audio. El formato de video predeterminado es 720p30 y la tasa de bits predeterminada es 6Mbps.
Con las versiones de firmware 6.2.63 y posteriores, el video H.264 se codifica en perfil High con B-frames. Con versiones anteriores del firmware, el video se codifica en nivel 4.1 sin B-frames.
El siguiente ejemplo codifica video desde HDMI Input y lo escribe en el almacenamiento local como un archivo .ts:
m.SetPipeline("hdmi:, encoder:vformat=480p25&vbitrate=1000, file:///hdmi.ts")
esencoder:[///][param=value]
Este componente recibe una entrada sin codificar y genera datos de video como un flujo H.264 elemental (a diferencia del componente estándar codificador: que genera un flujo de transporte MPEG-2). El flujo H.264 no contiene datos de audio. Este componente acepta los mismos parámetros audiodelay, vformat y vbitrate que el componente encoder:.
Dado que los componentes no simples esperan un flujo de transporte MPEG-2, este componente solo funciona con los siguientes: rtpsimple:, udpsimple:, httpsimple:, y memsimple:.
decoder:[///]
Este componente recibe una entrada codificada y la decodifica. Los usos principales de este componente son pasar un flujo de video al destino mostrar: para reproducción o pasar un archivo de video a un componente codificador: para transcodificación.
HDCP
El objeto roMediaStreamer respetará el estado de protección contra copia de sus entradas asignando el mismo estado a sus salidas. Cada flujo puede tener uno de los siguientes niveles de protección contra copia:
- Ninguno: No hay protección contra copia habilitada. Estos flujos pueden guardarse en archivos o transmitirse a través de la red sin restricciones.
- HDCP: La entrada está protegida con HDCP. No puede guardarse ni transmitirse, pero puede enviarse a una pantalla autenticada con HDCP.
Flujo de trabajo de HDCP
El objeto roMediaStreamer gestionará la autenticación y desautenticación HDCP de la siguiente manera:
- Si un flujo no autenticado con HDCP pasa a estar autenticado con HDCP, cualquier componente de destino de archivo o transmisión IP se detendrá inmediatamente y enviará un evento EOS_ERROR. Si la pantalla conectada no puede autenticarse con HDCP, el destino de pantalla ocultará la salida de video.
- Si un flujo que anteriormente estaba autenticado con HDCP deja de estar protegido, los componentes de destino de archivo y transmisión IP no se reanudarán. Sin embargo, si el destino de pantalla no está autenticado con HDCP, comenzará a mostrar video. Una pantalla autenticada con HDCP no se verá afectada en ninguno de los casos.
Indicadores de cifrado
El nivel de cifrado puede forzarse indicándolo en el componente de origen. Por ejemplo, el siguiente componente de origen forzará que cualquier pantalla conectada que reciba entrada HDMI esté autenticada con HDCP:
hdmi:encryption=hdcp
Importante
El estado de cifrado HDCP de un flujo no puede eliminarse estableciendo el parámetro encryption en none.
Cifrado de archivos
Los componentes de origen y destino file:/// aceptan los parámetros opcionales clave e iv, que pueden utilizarse para cifrar o descifrar un archivo mediante el algoritmo AES CTR. Los valores de clave e iv deben especificarse como cadenas hexadecimales de 16 bytes.
Tenga en cuenta que este proceso de cifrado de archivos es distinto de la autenticación HDCP. No hay restricciones sobre cómo pueden utilizarse los archivos cifrados en un pipeline, pero no puede usar esta forma de cifrado en un flujo que originalmente estaba protegido con HDCP.
El siguiente ejemplo guarda un flujo HLS como un archivo cifrado. Una vez que se escribe el archivo, puede descifrarse desde un componente de origen file:/// utilizando los mismos valores de clave e iv:
m = CreateObject("roMediaStreamer")
m.SetPipeline("http://<ip-address>/playlist.m3u8,file:///file.ts?key= 30313233343536373839616263646566&iv=30313233343536373839616263646566")
m.Start()Ejemplos de streaming
Los siguientes fragmentos de código proporcionan ejemplos de tipos comunes de transmisión multimedia.
Transmitir un archivo MPEG-2 TS mediante UDP
Para inicializar la instancia de roMediaStreamer y comenzar la transmisión, use lo siguiente:
m = CreateObject("roMediaStreamer")
m.SetPipeline("file:///data/clip.ts, udp://239.192.0.0:1234/")
m.Start()Para detener la transmisión, use lo siguiente:
m.reset()
También puede usar la forma simple de los componentes para las tareas de transmisión más comunes. Lo siguiente funcionará de forma idéntica a la transmisión anterior, mientras utiliza menos recursos:
m.SetPipeline("filesimple:///data/clip.ts, udpsimple://239.192.0.0:1234/")
Transmitir una entrada HDMI codificada mediante RTP
La resolución y la tasa de bits del video transmitido pueden cambiarse agregando parámetros al componente codificador: . Use el siguiente código para transmitir la entrada usando la resolución nativa y la tasa de bits predeterminada:
m = CreateObject("roMediaStreamer")
m.SetPipeline("hdmi:, encoder:, rtp://239.192.0.0:1234/")
m.Start()Para detener la transmisión, use lo siguiente:
m.reset()
Grabar un archivo
El siguiente código grabará una entrada HDMI y la guardará como un archivo llamado hdmi.ts:
m = CreateObject("roMediaStreamer")
m.SetPipeline("hdmi:, encoder:, file:///hdmi.ts")
m.Start()Para detener el proceso de grabación, use lo siguiente:
m.reset()
Transcodificar y transmitir un archivo
La salida de un componente decodificador: puede conectarse a la entrada de un componente codificador: para transcodificar los datos. Esto es útil si desea modificar la tasa de bits del video antes de transmitirlo a través de la red. El siguiente código transcodificará el video file.ts antes de transmitirlo mediante RTP:
m = CreateObject("roMediaStreamer")
m.SetPipeline("file:///file.ts, decoder:, encoder:vbitrate=1000, rtp://239.192.0.0:5004/")
m.Start()Para detener el proceso de transcodificación, use lo siguiente:
m.reset()
Retransmisión
El reproductor puede usarse para emitir una entrada de transmisión utilizando un protocolo diferente conectando un componente cliente IP a un componente servidor IP. El siguiente código recibirá una transmisión HTTP y luego la transmitirá usando RTP:
m = CreateObject("roMediaStreamer")
m.SetPipeline("http://172.30.1.37/file.ts, rtp://239.192.0.0:5004/")
m.Start()Para detener la transmisión, use lo siguiente:
m.reset()
Segmentar un archivo usando HLS
Un archivo .ts existente puede segmentarse para transmisión usando el protocolo HLS. Los segmentos de archivo resultantes pueden luego transmitirse directamente realizando solicitudes HTTP a un HTTP Media Server. El siguiente código usará el video file.ts para generar segmentos con una duración aproximada de 10 segundos:
m = CreateObject("roMediaStreamer")
m.SetPipeline("file:///file.ts, hls:///media_segment?duration=10")
m.Start()En este caso, los archivos comenzarán con media_segment_000000.ts, y el contador se incrementará una vez por cada segmento. El archivo de índice se escribirá como "media_segment_index.m3u8".
Componentes simples y no simples
Para conservar los recursos del sistema, recomendamos usar las versiones simples de los componentes siempre que sea posible. Use las siguientes pautas para determinar si deben usarse componentes simples o no simples:
- Use componentes simples al transmitir un archivo desde almacenamiento local usando protocolos UDP, RTP o HTTP (sin ninguna codificación o transcodificación involucrada en la canalización).
- Use componentes no simples siempre que la canalización incluya codificación, transcodificación o transmisión HLS.
- Al ingerir una transmisión desde una fuente remota y retransmitirla, use los componentes de destino udpsimple:, rtpsimple:, y httpsimple: . Si necesita modular la transmisión (o retransmitir usando HLS), use componentes no simples.
- Dado que un componente de origen memsimple: puede leer desde un componente de destino mem:, use el componente de origen memsimple: junto con udpsimple:, rtpsimple:, o httpsimple: cuando use transmisión de memoriatransmisión de memoria. El componente de origen mem: solo debe usarse con el componente de destino hls: (o archivo: si está depurando).