Ответ 1
Мне не удалось найти материалы о действительно RESTful streaming - кажется, что результаты в основном касаются делегирования потоковой передачи на другую услугу (которая не является плохое решение). Поэтому я сделаю все возможное, чтобы справиться с этим сам - обратите внимание, что потоковая передача - это не мой домен, но я постараюсь добавить свои 2 цента.
В аспекте потоковой передачи, я думаю, что нам нужно разделить проблему на две независимые части:
- доступ к медиаресурсам (метаданные)
- доступ к самому средству/потоку (двоичные данные)
1.) Доступ к медиа-ресурсам
Это довольно просто, и его можно обрабатывать чистым и RESTful способом. В качестве примера предположим, что у нас будет API на основе XML, который позволит нам получить доступ к списку потоков:
GET /media/
<?xml version="1.0" encoding="UTF-8" ?>
<media-list uri="/media">
<media uri="/media/1" />
<media uri="/media/2" />
...
</media-list>
... а также отдельным потокам:
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.) Доступ к самому средству/потоку
Это более проблематичный бит. Вы уже указали один из вариантов в своем вопросе, и это означает, что доступ к кадрам осуществляется индивидуально через API RESTful. Хотя это может сработать, я согласен с вами в том, что это не жизнеспособный вариант.
Я думаю, что есть выбор между:
- делегирование потоковой передачи выделенной службе через специализированный потоковый протокол (например, RTSP)
- использование опций, доступных в HTTP
Я считаю, что первое было более эффективным выбором, хотя для него требуется выделенный потоковый сервис (и/или аппаратное обеспечение). Это может быть немного на грани того, что считается RESTful, однако обратите внимание, что наш API RESTful во всех аспектах и даже несмотря на то, что специализированная служба потоковой передачи не придерживается единого интерфейса (GET/POST/PUT/DELETE), наш API делает. Наш API позволяет нам правильно контролировать ресурсы и их метаданные через GET/POST/PUT/DELETE, и мы предоставляем ссылки на потоковое обслуживание (таким образом, придерживаясь аспекта связности REST).
Последний вариант - потоковая передача по HTTP - может быть не так эффективен, как указано выше, но это определенно возможно. Технически это не то, что отличается от разрешения доступа к любой форме двоичного контента через HTTP. В этом случае наш API предоставит ссылку на двоичный ресурс, доступный через HTTP, а также сообщит нам о размере ресурса:
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>
Клиент может получить доступ к ресурсу через HTTP, используя GET /media/1.3gp
. Один из вариантов заключается в том, чтобы клиент загрузил весь ресурс - HTTP-прогрессивная загрузка. Более чистой альтернативой было бы для клиента получить доступ к ресурсу в кусках, используя HTTP Заголовки диапазона. Для получения второго блока размером 256 Кбайт файла размером 1 МБ запрос клиента будет выглядеть следующим образом:
GET /media/1.3gp
...
Range: bytes=131072-262143
...
Затем сервер, который поддерживает диапазоны, отвечает заголовок Content-Range, за которым следует частичное представление ресурса:
HTTP/1.1 206 Partial content
...
Content-Range: bytes 131072-262143/1048576
Content-Length: 1048576
...
Обратите внимание, что наш API уже сообщил клиенту точный размер файла в байтах (1 МБ). В случае, когда клиент не знает размер ресурса, он должен сначала вызвать HEAD /media/1.3gp
, чтобы определить размер, в противном случае он рискует ответом сервера с помощью 416 Requested Range Not Satisfiable
.