No logré encontrar materiales sobre la transmisión verdaderamente RESTful ; parece que los resultados se tratan principalmente de delegar la transmisión a otro servicio (lo cual no es una mala solución). Así que haré todo lo posible para abordarlo yo mismo: tenga en cuenta que la transmisión no es mi dominio, pero intentaré agregar mis 2 centavos.
En el aspecto de la transmisión, creo que debemos separar el problema en dos partes independientes:
- acceso a recursos de medios (metadatos)
- acceso al medio / flujo en sí (datos binarios)
1.) Acceso a los recursos multimedia
Esto es bastante sencillo y se puede manejar de una manera limpia y REST. Como ejemplo, digamos que tendremos una API basada en XML que nos permitirá acceder a una lista de streams:
GET /media/
<?xml version="1.0" encoding="UTF-8" ?>
<media-list uri="/media">
<media uri="/media/1" />
<media uri="/media/2" />
...
</media-list>
... y también a corrientes individuales:
GET /media/1
<?xml version="1.0" encoding="UTF-8" ?>
<media uri="/media/1">
<id>1</id>
<title>Some video</title>
<stream>rtsp://example.com/media/1.3gp</stream>
</media>
2.) Acceso al medio / flujo en sí
Este es el bit más problemático. Ya señaló una opción en su pregunta, y es permitir el acceso a los marcos de forma individual a través de una API RESTful. Aunque esto podría funcionar, estoy de acuerdo contigo en que no es una opción viable.
Creo que hay que elegir entre:
- delegar la transmisión a un servicio dedicado a través de un protocolo de transmisión especializado (por ejemplo, RTSP)
- utilizando las opciones disponibles en HTTP
Creo que la primera es la opción más eficiente, aunque requiere un servicio de transmisión dedicado (y / o hardware). Puede estar un poco al borde de lo que se considera RESTful, sin embargo, tenga en cuenta que nuestra API es RESTful en todos los aspectos y, aunque el servicio de transmisión dedicado no se adhiere a la interfaz uniforme (GET / POST / PUT / DELETE), nuestra API hace. Nuestra API nos permite un control adecuado sobre los recursos y sus metadatos a través de GET / POST / PUT / DELETE, y proporcionamos enlaces al servicio de transmisión (cumpliendo así con el aspecto de conectividad de REST).
La última opción, la transmisión a través de HTTP , puede no ser tan eficiente como la anterior, pero definitivamente es posible. Técnicamente, no es tan diferente de permitir el acceso a cualquier forma de contenido binario a través de HTTP. En este caso, nuestra API proporcionaría un enlace al recurso binario accesible a través de HTTP y también nos informa sobre el tamaño del recurso:
GET /media/1
<?xml version="1.0" encoding="UTF-8" ?>
<media uri="/media/1">
<id>1</id>
<title>Some video</title>
<bytes>1048576</bytes>
<stream>/media/1.3gp</stream>
</media>
El cliente puede acceder al recurso a través de HTTP utilizando GET /media/1.3gp
. Una opción es que el cliente descargue todo el recurso: descarga progresiva HTTP . Una alternativa más limpia sería que el cliente acceda al recurso en fragmentos utilizando encabezados HTTP Range . Para obtener el segundo fragmento de 256 KB de un archivo de 1 MB de tamaño, la solicitud del cliente se vería así:
GET /media/1.3gp
...
Range: bytes=131072-262143
...
Un servidor que admita rangos respondería con el encabezado Content-Range , seguido de la representación parcial del recurso:
HTTP/1.1 206 Partial content
...
Content-Range: bytes 131072-262143/1048576
Content-Length: 1048576
...
Tenga en cuenta que nuestra API ya le dijo al cliente el tamaño exacto del archivo en bytes (1 MB). En el caso de que el cliente no conozca el tamaño del recurso, primero debe llamar HEAD /media/1.3gp
para determinar el tamaño; de lo contrario, corre el riesgo de que el servidor responda con 416 Requested Range Not Satisfiable
.