Não consegui encontrar materiais sobre streaming verdadeiramente RESTful - parece que os resultados são principalmente sobre delegar streaming a outro serviço (o que não é uma solução ruim). Portanto, farei o meu melhor para resolver isso sozinho - observe que streaming não é meu domínio, mas tentarei adicionar meus 2 centavos.
No aspecto de streaming, acho que precisamos separar o problema em duas partes independentes:
- acesso a recursos de mídia (metadados)
- acesso ao próprio meio / fluxo (dados binários)
1.) Acesso aos recursos de mídia
Isso é bastante direto e pode ser tratado de uma forma limpa e com REST. Como exemplo, digamos que teremos uma API baseada em XML que nos permite acessar uma lista de fluxos:
GET /media/
<?xml version="1.0" encoding="UTF-8" ?>
<media-list uri="/media">
<media uri="/media/1" />
<media uri="/media/2" />
...
</media-list>
... e também para fluxos individuais:
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.) Acesso ao próprio meio / fluxo
Esta é a parte mais problemática. Você já apontou uma opção em sua pergunta, que é permitir o acesso aos frames individualmente por meio de uma API RESTful. Mesmo que isso funcione, concordo com você que não é uma opção viável.
Eu acho que há uma escolha a ser feita entre:
- delegar streaming a um serviço dedicado por meio de um protocolo de streaming especializado (por exemplo, RTSP)
- utilizando opções disponíveis em HTTP
Acredito que o primeiro seja a escolha mais eficiente, embora requeira um serviço de streaming dedicado (e / ou hardware). Pode ser um pouco no limite do que é considerado RESTful, no entanto, observe que nossa API é RESTful em todos os aspectos e mesmo que o serviço de streaming dedicado não adira à interface uniforme (GET / POST / PUT / DELETE), nossa API faz. Nossa API nos permite o controle adequado sobre os recursos e seus metadados via GET / POST / PUT / DELETE, e fornecemos links para o serviço de streaming (aderindo assim ao aspecto de conexão do REST).
A última opção - streaming via HTTP - pode não ser tão eficiente quanto a anterior, mas é definitivamente possível. Tecnicamente, não é muito diferente de permitir o acesso a qualquer forma de conteúdo binário via HTTP. Nesse caso, nossa API forneceria um link para o recurso binário acessível via HTTP e também nos informa sobre o tamanho do 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>
O cliente pode acessar o recurso via HTTP usando GET /media/1.3gp
. Uma opção é o cliente baixar todo o recurso - download progressivo HTTP . Uma alternativa mais limpa seria o cliente acessar o recurso em partes usando cabeçalhos de intervalo HTTP . Para buscar o segundo fragmento de 256 KB de um arquivo de 1 MB, a solicitação do cliente ficaria assim:
GET /media/1.3gp
...
Range: bytes=131072-262143
...
Um servidor que oferece suporte a intervalos responderia com o cabeçalho Content-Range , seguido pela representação parcial do recurso:
HTTP/1.1 206 Partial content
...
Content-Range: bytes 131072-262143/1048576
Content-Length: 1048576
...
Observe que nossa API já informa ao cliente o tamanho exato do arquivo em bytes (1 MB). No caso de o cliente não saber o tamanho do recurso, ele deve primeiro chamar HEAD /media/1.3gp
para determinar o tamanho, caso contrário, estará arriscando uma resposta do servidor com 416 Requested Range Not Satisfiable
.