El protocolo de mensajería en tiempo real ( RTMP ) es un protocolo de comunicación para la transmisión de audio, vídeo y datos a través de Internet. Originalmente desarrollado como un protocolo propietario por Macromedia para la transmisión entre Flash Player y Flash Communication Server, Adobe (que adquirió Macromedia) ha publicado una versión incompleta de la especificación del protocolo para uso público.
El protocolo RTMP tiene múltiples variaciones:
Si bien la motivación principal de RTMP era ser un protocolo para reproducir video Flash , también se utiliza en otras aplicaciones, como Adobe LiveCycle Data Services ES .
RTMP es un protocolo basado en TCP que mantiene conexiones persistentes y permite comunicaciones de baja latencia. Para entregar transmisiones sin problemas y transmitir la mayor cantidad de información posible, divide las transmisiones en fragmentos, y su tamaño se negocia dinámicamente entre el cliente y el servidor. A veces, se mantiene sin cambios; los tamaños de fragmento predeterminados son 64 bytes para datos de audio y 128 bytes para datos de video y la mayoría de los demás tipos de datos. Luego, los fragmentos de diferentes transmisiones se pueden intercalar y multiplexar en una sola conexión. Con fragmentos de datos más largos, el protocolo solo lleva un encabezado de un byte por fragmento, por lo que incurre en muy poca sobrecarga . Sin embargo, en la práctica, los fragmentos individuales no suelen intercalarse. En cambio, el intercalado y la multiplexación se realizan a nivel de paquete, y los paquetes RTMP en varios canales activos diferentes se intercalan de tal manera que se garantiza que cada canal cumpla con su ancho de banda, latencia y otros requisitos de calidad de servicio. Los paquetes intercalados de esta manera se tratan como indivisibles y no se intercalan a nivel de fragmento.
El protocolo RTMP define varios canales virtuales por los que se pueden enviar y recibir paquetes y que funcionan de forma independiente entre sí. Por ejemplo, hay un canal para gestionar solicitudes y respuestas RPC, un canal para datos de flujo de vídeo, un canal para datos de flujo de audio, un canal para mensajes de control fuera de banda (negociación del tamaño de fragmentos, etc.), etc. Durante una sesión RTMP típica, varios canales pueden estar activos simultáneamente en un momento dado. Cuando se codifican datos RTMP, se genera un encabezado de paquete. El encabezado de paquete especifica, entre otras cosas, el ID del canal por el que se enviará, una marca de tiempo de cuándo se generó (si es necesario) y el tamaño de la carga útil del paquete. A continuación, este encabezado va seguido del contenido de la carga útil real del paquete, que se fragmenta según el tamaño de fragmento acordado actualmente antes de enviarse a través de la conexión. El encabezado del paquete en sí nunca se fragmenta y su tamaño no cuenta para los datos del primer fragmento del paquete. En otras palabras, solo la carga útil real del paquete (los datos multimedia) está sujeta a fragmentación.
En un nivel superior, el RTMP encapsula transmisiones multimedia de audio MP3 o AAC y de video FLV1 , y puede realizar llamadas a procedimientos remotos (RPC) utilizando el formato de mensaje de acción . Todos los servicios RPC necesarios se realizan de forma asincrónica, utilizando un único modelo de solicitud/respuesta cliente/servidor, de modo que no se requiere comunicación en tiempo real. [ aclaración necesaria ] [2] [3]
Las sesiones RTMP se pueden cifrar mediante cualquiera de dos métodos:
En RTMP Tunneled (RTMPT), los datos RTMP se encapsulan y se intercambian a través de HTTP , y los mensajes del cliente (el reproductor multimedia, en este caso) se dirigen al puerto 80 (el predeterminado para HTTP) en el servidor.
Si bien los mensajes en RTMPT son más grandes que los mensajes RTMP no tunelizados equivalentes debido a los encabezados HTTP, RTMPT puede facilitar el uso de RTMP en escenarios donde el uso de RTMP no tunelizado de otra manera no sería posible, como cuando el cliente está detrás de un firewall que bloquea el tráfico saliente que no es HTTP ni HTTPS.
El protocolo funciona enviando comandos a través de la URL POST y mensajes AMF a través del cuerpo POST. Un ejemplo es
POST/abierto/1 HTTP/1.1
para que se abra una conexión.
Adobe ha publicado una especificación para la versión 1.0 del protocolo, con fecha del 21 de diciembre de 2012. [4] La página web que lleva a esa especificación señala que "Para beneficiar a los clientes que desean proteger su contenido, la especificación RTMP abierta no incluye las medidas RTMP seguras exclusivas de Adobe". [5]
Un documento que acompaña a la especificación de Adobe otorga una licencia de patente "no exclusiva, libre de regalías, intransferible, no sublicenciable, personal y mundial" para todas las implementaciones del protocolo, con dos restricciones: una prohíbe el uso para interceptar datos de transmisión ("cualquier tecnología que intercepte contenido de video, audio y/o datos en tiempo real para su almacenamiento en cualquier dispositivo o medio"), y otra prohíbe la elusión de "medidas tecnológicas para la protección de contenido de audio, video y/o datos, incluidas cualquiera de las medidas RTMP seguras de Adobe". [6]
Stefan Richter, autor de algunos libros sobre Flash , señaló en 2008 que, si bien Adobe no es claro en cuanto a qué patentes se aplican a RTMP, la patente estadounidense 7.246.356 parece ser una de ellas. [2]
En 2011, Adobe demandó a Wowza Media Systems alegando, entre otras cosas, la infracción de sus patentes RTMP. [7] [8] [9] En 2015, Adobe y Wowza anunciaron que las demandas habían sido resueltas y desestimadas con perjuicio. [10]
Los paquetes se envían a través de una conexión TCP, que se establece primero entre el cliente y el servidor. Contienen un encabezado y un cuerpo que, en el caso de comandos de conexión y control, se codifica utilizando el formato de mensaje de acción (AMF). El encabezado se divide en el encabezado básico (que se muestra separado del resto en el diagrama) y el encabezado de mensaje de fragmento . El encabezado básico es la única parte constante del paquete y generalmente está compuesto por un solo byte compuesto , donde los dos bits más significativos son el tipo de fragmento ( fmt en la especificación) y el resto forman el ID de flujo. Dependiendo del valor del primero, se pueden omitir algunos campos del encabezado del mensaje y su valor se puede derivar de paquetes anteriores, mientras que dependiendo del valor del segundo, el encabezado básico se puede ampliar con uno o dos bytes adicionales (como en el caso del diagrama que tiene tres bytes en total (c)). Si el valor de los seis bits restantes del encabezado básico (BH) (menos significativo) es 0, entonces el BH es de dos bytes y representa desde el ID de flujo 64 hasta el 319 (64+255); si el valor es 1, entonces el BH es de tres bytes (con los dos últimos bytes codificados como Little Endian de 16 bits) y representa desde el ID de flujo 64 hasta el 65599 (64+65535); si el valor es 2, entonces el BH es de un byte y está reservado para mensajes y comandos de control de protocolo de bajo nivel. El encabezado de mensaje de fragmento contiene información de metadatos como el tamaño del mensaje (medido en bytes), el delta de marca de tiempo y el tipo de mensaje . Este último valor es un solo byte y define si el paquete es de audio, video, comando o paquete RTMP de "bajo nivel", como un ping RTMP.
A continuación se muestra un ejemplo capturado cuando un cliente flash ejecuta el siguiente código:
var flujo : NetStream = nuevo NetStream ( objeto de conexión );
Esto generará el siguiente fragmento:
El paquete comienza con un encabezado básico de un solo byte (0x03) donde los dos bits más significativos (b 00 000011) definen un tipo de encabezado de fragmento de 0 mientras que el resto (b00 000011 ) definen un ID de flujo de fragmento de 3. Los cuatro valores posibles del tipo de encabezado y su significado son:
El último tipo (b11) siempre se utiliza en el caso de mensajes agregados donde, en el ejemplo anterior, el segundo mensaje comenzará con un id de 0xC3 (b11000011) y significaría que todos los campos de encabezado de mensaje deberían derivarse del mensaje con un id de flujo de 3 (que sería el mensaje que se encuentra justo encima). Los seis bits menos significativos que forman el id de flujo pueden tomar valores entre 3 y 63. Algunos valores tienen un significado especial, como 1 que representa un formato de id extendido, en cuyo caso habrá dos bytes a continuación. Un valor de dos es para mensajes de bajo nivel como Ping y Set Client Bandwidth.
Los siguientes bytes del encabezado RTMP (incluidos los valores del paquete de ejemplo anterior) se decodifican de la siguiente manera:
El byte de identificación del tipo de mensaje define si el paquete contiene datos de audio o video, un objeto remoto o un comando. Algunos valores posibles son:
Después del encabezado, 0x02 denota una cadena de tamaño 0x000C y valores 0x63 0x72 ... 0x6D (comando "createStream"). A continuación tenemos un 0x00 (número) que es el identificador de transacción del valor 2.0. El último byte es 0x05 (nulo), lo que significa que no hay argumentos.
Algunos de los tipos de mensajes que se muestran arriba, como Ping y Establecer ancho de banda de cliente/servidor, se consideran mensajes de protocolo RTMP de bajo nivel que no utilizan el formato de codificación AMF. Por otro lado, los mensajes de comando, ya sean AMF0 (tipo de mensaje 0x14) o AMF3 (0x11), utilizan el formato y tienen la forma general que se muestra a continuación:
(Cadena) <Nombre del comando>(Número) <ID de transacción>(Mixto) <Argumento> ej. Nulo, Cadena, Objeto: {clave1:valor1, clave2:valor2 ... }
El identificador de transacción se utiliza para los comandos que pueden tener una respuesta. El valor puede ser una cadena como en el ejemplo anterior o uno o más objetos, cada uno compuesto por un conjunto de pares clave/valor donde las claves siempre se codifican como cadenas mientras que los valores pueden ser cualquier tipo de datos AMF, incluidos tipos complejos como matrices.
Los mensajes de control no están codificados en AMF. Comienzan con un identificador de flujo de 0x02, lo que implica un encabezado completo (tipo 0) y tienen un tipo de mensaje de 0x04. El encabezado va seguido de seis bytes, que se interpretan de la siguiente manera:
Los primeros dos bytes del cuerpo del mensaje definen el tipo de ping, que aparentemente [11] puede tomar seis valores posibles.
Pong es el nombre de una respuesta a un Ping, con los valores utilizados como se ve arriba.
Esto se relaciona con los mensajes que tienen que ver con la tasa de bits de subida del cliente y de bajada del servidor. El cuerpo está compuesto por cuatro bytes que muestran el valor del ancho de banda, con una posible extensión de un byte que establece el tipo de límite. Este puede tener uno de los tres valores posibles que pueden ser: duro, suave o dinámico (ya sea suave o duro).
El valor recibido en los cuatro bytes del cuerpo. Existe un valor predeterminado de 128 bytes y el mensaje se envía solo cuando se desea un cambio.
Después de establecer una conexión TCP, se establece primero una conexión RTMP, realizando un protocolo de enlace mediante el intercambio de tres paquetes de cada lado (también denominados fragmentos en la documentación oficial). Estos se denominan en la especificación oficial C0-2 para los paquetes enviados por el cliente y S0-2 para el lado del servidor respectivamente y no deben confundirse con los paquetes RTMP que se pueden intercambiar solo después de que se complete el protocolo de enlace. Estos paquetes tienen una estructura propia y C1 contiene un campo que establece la marca de tiempo de "época", pero como se puede establecer en cero, como se hace en las implementaciones de terceros, el paquete se puede simplificar. El cliente inicializa la conexión enviando el paquete C0 con un valor constante de 0x03 que representa la versión actual del protocolo. Sigue directamente con C1 sin esperar a que se reciba primero S0 que contiene 1536 bytes, con los primeros cuatro representando la marca de tiempo de época, los segundos cuatro siendo todos 0 y el resto aleatorio (y que se puede establecer en 0 en implementaciones de terceros). C2 y S2 son un eco de S1 y C1 respectivamente, excepto que los segundos cuatro bytes corresponden a la hora en que se recibió el mensaje respectivo (en lugar de 0). Una vez que se reciben C2 y S2, el protocolo de enlace se considera completo.
En este punto, el cliente y el servidor pueden negociar una conexión intercambiando mensajes codificados con AMF . Estos incluyen pares de valores clave que se relacionan con las variables necesarias para que se establezca una conexión. Un mensaje de ejemplo del cliente es:
( Invocar ) "conectar" ( ID de transacción ) 1.0 ( Objeto1 ) { aplicación : "muestra" , flashVer : "MAC 10,2,153,2" , swfUrl : null , tcUrl : "rtmpt://127.0.0.1/sample " , fpad : false , capacidades : 9947.75 , audioCodecs : 3191 , videoCodecs : 252 , videoFunction : 1 , pageUrl : null , objectEncoding : 3.0 }
El Flash Media Server y otras implementaciones utilizan el concepto de una "aplicación" para definir conceptualmente un contenedor para audio/video y otro contenido, implementado como una carpeta en la raíz del servidor que contiene los archivos multimedia que se van a transmitir. La primera variable contiene el nombre de esta aplicación como "muestra", que es el nombre proporcionado por el servidor Wowza para su prueba. La cadena es la misma que la devuelta por la función flashVer
Action-script . Los y están codificados como dobles y su significado se puede encontrar en la especificación original. Lo mismo es cierto para la variable, que en este caso es la constante autoexplicativa SUPPORT_VID_CLIENT_SEEK. De especial interés es la que definirá si el resto de la comunicación utilizará el formato AMF3 extendido o no. Como la versión 3 es la predeterminada actual, se le debe indicar explícitamente al cliente Flash en el código Action-script que utilice AMF0 si se lo solicita. Luego, el servidor responde con una secuencia de mensajes ServerBW, ClientBW y SetPacketSize, seguida finalmente por una Invoke, con un mensaje de ejemplo.getversion()
audioCodec
videoCodec
videoFunction
objectEncoding
( Invocar ) "_result" ( ID de transacción ) 1.0 ( Objeto1 ) { fmsVer : "FMS/3,5,5,2004" , capacidades : 31.0 , modo : 1.0 } ( Objeto2 ) { nivel : "estado" , código : "NetConnection.Connect.Success" , descripción : "Conexión exitosa" , datos : ( matriz ) { versión : "3,5,5,2004" }, clientId : 1728724019 , objectEncoding : 3.0 }
Algunos de los valores anteriores se serializan en propiedades de un objeto Action-script genérico, que luego se pasa al detector de eventos NetConnection. Esto clientId
establecerá un número para la sesión que se iniciará mediante la conexión. La codificación del objeto debe coincidir con el valor establecido previamente.
Para iniciar una transmisión de video, el cliente envía una invocación "createStream" seguida de un mensaje de ping, seguido de una invocación "play" con el nombre del archivo como argumento. El servidor responderá entonces con una serie de comandos "onStatus" seguidos de los datos de video encapsulados en mensajes RTMP.
Una vez establecida una conexión, el contenido multimedia se envía encapsulando el contenido de las etiquetas FLV en mensajes RTMP de tipo 8 y 9 para audio y video, respectivamente.
Se refiere a la versión HTTP tunelizada del protocolo. Se comunica a través del puerto 80 y pasa los datos AMF dentro de la solicitud y las respuestas HTTP POST. La secuencia de conexión es la siguiente:
POST /fcs/ident2 HTTP / 1.1 Tipo de contenido : aplicación/x-fcs\r\nHTTP/1.0 404 No encontrado
POST /open/1 HTTP / 1.1 Tipo de contenido : aplicación/x-fcs\r\nHTTP/1.1 200 OKTipo de contenido: aplicación/x-fcs\r\n 1728724019
La primera solicitud tiene una /fcs/ident2
ruta y la respuesta correcta es un error 404 Not Found. A continuación, el cliente envía una solicitud /open/1 en la que el servidor debe responder con un 200 ok y añadir un número aleatorio que se utilizará como identificador de sesión para dicha comunicación. En este ejemplo, se devuelve 1728724019 en el cuerpo de la respuesta.
POST /idle/1728724019/0 HTTP / 1.1 HTTP/1.1 200 OK 0x01
A partir de ahora, se /idle/<session id>/<sequence #>
trata de una solicitud de sondeo en la que se ha generado y devuelto el identificador de sesión desde el servidor y la secuencia es simplemente un número que se incrementa en uno para cada solicitud. La respuesta adecuada es 200 OK, con un entero devuelto en el cuerpo que indica el intervalo de tiempo. Los datos de AMF se envían a través de/send/<session id>/<sequence #>
RTMP se implementa en estas tres etapas:
La herramienta de línea de comandos de cliente RTMP de código abierto rtmpdump está diseñada para reproducir o guardar en disco el flujo RTMP completo, incluido el protocolo RTMPE que Adobe utiliza para el cifrado. RTMPdump funciona en Linux, Android, Solaris, Mac OS X y la mayoría de los demás sistemas operativos derivados de Unix, así como en Microsoft Windows. Originalmente compatible con todas las versiones de Windows de 32 bits, incluido Windows 98, a partir de la versión 2.2, el software solo se ejecutará en Windows XP y posteriores (aunque las versiones anteriores siguen siendo completamente funcionales).
Los paquetes de la suite de software rtmpdump están disponibles en los principales repositorios de código abierto (distribuciones Linux). Entre ellos se incluyen las aplicaciones de interfaz "rtmpdump", "rtmpsrv" y "rtmpsuck".
El desarrollo de RTMPdump se reinició en octubre de 2009, fuera de los Estados Unidos, en el sitio de MPlayer . [12] La versión actual presenta una funcionalidad muy mejorada y se ha reescrito para aprovechar los beneficios del lenguaje de programación C. En particular, la funcionalidad principal se incorporó a una biblioteca (librtmp) que otras aplicaciones pueden usar fácilmente. Los desarrolladores de RTMPdump también han escrito soporte para librtmp para MPlayer , FFmpeg , XBMC , cURL , VLC y varios otros proyectos de software de código abierto. El uso de librtmp proporciona a estos proyectos soporte completo de RTMP en todas sus variantes sin ningún esfuerzo de desarrollo adicional.
FLVstreamer es una bifurcación de RTMPdump, sin el código, que según Adobe viola la DMCA en los EE. UU. Esto se desarrolló como respuesta al intento de Adobe en 2008 de suprimir RTMPdump. FLVstreamer es un cliente RTMP que guardará una transmisión de contenido de audio o video desde cualquier servidor RTMP en un disco, si el cifrado (RTMPE) no está habilitado en la transmisión.
El contenedor de video Flash en RTMP está limitado al códec H264 en la mayoría de las implementaciones. Por este motivo, The Veovera Software Organization, que incluye a Adobe , Google , Twitch y Veriskope, publicó la especificación RTMP mejorada, [13] que agrega compatibilidad con los códecs VP9 , H265 y AV1 en el contenedor de video Flash FLV .
{{cite journal}}
: Requiere citar revista |journal=
( ayuda )