RTSP DVR¶
media.play.rtsp_dvr
O Sapsan fornece o arquivo gravado por RTSP. O cliente obtém os períodos de gravação disponíveis, seleciona um horário UTC e controla a reprodução na mesma sessão. A leitura de um arquivo existente não exige uma fonte de entrada ativa.
Transporte¶
RTSP 1.0 e RTP/RTCP interleaved compartilham uma conexão TCP. UDP não é suportado: SETUP com UDP retorna 461.
Codecs compatíveis¶
- H.264
- HEVC / H.265
- AV1
- AAC
- Opus
- PCMA
- PCMU
A lista corresponde à packetização RTSP; o cliente deve suportar os codecs selecionados.
AAC usa MPEG4-GENERIC com cabeçalhos AU; AV1 usa fragmentação RTP e um sequence header. Há declarações SDP para MP4A-LATM e MPEG Audio (MPA, MP2/MP3), mas a saída atual não oferece a respectiva packetização RTP completa; eles não fazem parte da lista acima. Se necessário, converta o áudio para AAC ou Opus. O nome de um codec no SDP, por si só, não garante compatibilidade.
Protocolo e URL¶
O controle utiliza RTSP 1.0: RFC 2326. A descrição das trilhas utiliza SDP: RFC 4566. A mídia utiliza RTP/RTCP: RFC 3550. Para H.264, aplica-se o formato de payload RTP do RFC 6184.
A lista de períodos do arquivo em um único atributo SDP e o parâmetro position são extensões da interface de arquivo do Sapsan. Seus formatos estão descritos abaixo. As capacidades suportadas e as diferenças conhecidas são indicadas explicitamente; o suporte a RTSP 1.0 não implica suporte a todos os modos desses RFCs.
O acesso exige um arquivo DVR gravado, um listener RTSP configurado e uma licença que permita media.play.rtsp_dvr.
rtsp://sapsan.example.com:554/camera?dvr=true
A URL é estática: o horário é informado no cabeçalho Range, não na URL. O valor dvr=true é obrigatório; outros valores são rejeitados. Uma URL comum sem esse parâmetro fornece reprodução ao vivo e não aceita um Range: clock=... de arquivo. Se houver autorização por token, acrescente &token=<token>.
Licença¶
O recurso media.play.rtsp_dvr usa o limite de licença separado media_play_rtsp_dvr. RTSP ao vivo usa media_play_rtsp; a permissão para reproduzir ao vivo não concede acesso ao arquivo.
A admissão é verificada antes da leitura do arquivo, inclusive em um PLAY direto sem DESCRIBE anterior. Um limite zero proíbe o acesso, e um limite numérico esgotado impede novas sessões: o servidor responde 453 Not Enough Bandwidth.
A sessão de arquivo mantém sua admissão por licença após o fim do intervalo selecionado. O próximo PLAY na mesma conexão usa essa sessão. Libere-a com TEARDOWN ou fechando a conexão; EOF por si só não libera a vaga ocupada. Consulte licenciamento.
Períodos de gravação disponíveis¶
O cliente começa com DESCRIBE:
DESCRIBE rtsp://sapsan.example.com:554/camera?dvr=true RTSP/1.0
CSeq: 1
Accept: application/sdp
A resposta 200 OK tem um corpo application/sdp. Antes das descrições de trilhas m=, inclui este atributo de sessão:
a=range:clock=20261019T080000Z-20261019T093000Z;clock=20261019T100000Z-
O exemplo mostra dois períodos de gravação separados por uma lacuna. O formato de horário é YYYYMMDDThhmmssZ, em segundos inteiros UTC. A ausência de horário após o hífen no último período indica gravação em andamento.
- Ordem. Os períodos são apresentados em ordem cronológica crescente.
- União. Períodos adjacentes são unidos; lacunas de até 10 segundos inclusive também são unidas ao construir a lista. Esse período não garante quadros em cada segundo abrangido.
- Quantidade. São anunciados no máximo os 100 períodos mais recentes. Gravações anteriores ainda existentes podem ser solicitadas por um
PLAYexplícito, mesmo quando não aparecem na lista. - Arquivo vazio. O atributo
a=rangeé omitido. O servidor pode usar uma fonte ao vivo disponível para descrever as trilhas.
Quando existem gravações, a descrição das trilhas vem do arquivo. Assim, DESCRIBE e a reprodução permanecem disponíveis após a desconexão da fonte de entrada.
Preparação do transporte¶
Envie SETUP para cada trilha necessária usando seu identificador no SDP. RTP/RTCP é transportado na mesma conexão TCP do RTSP — interleaved TCP. No exemplo, <track-url> representa a URL da trilha selecionada:
SETUP <track-url> RTSP/1.0
CSeq: 2
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
Cabeçalhos relevantes da resposta:
RTSP/1.0 200 OK
CSeq: 2
Session: example-session;timeout=60
Transport: RTP/AVP/TCP;unicast;interleaved=0-1
Use o Session recebido nas próximas solicitações. Escolha outro par de canais interleaved para a próxima trilha. O transporte UDP é rejeitado com 461.
Os exemplos mostram os campos relevantes da troca. Na rede, as linhas terminam em CRLF, uma linha vazia separa os cabeçalhos do corpo e Content-Length informa o tamanho do corpo em bytes.
Seleção de horário e busca¶
Para reproduzir um intervalo, envie PLAY para a URL de toda a sessão:
PLAY rtsp://sapsan.example.com:554/camera?dvr=true RTSP/1.0
CSeq: 3
Session: example-session
Range: clock=20261019T081000Z-20261019T081500Z
Scale: 1
Campos essenciais da resposta:
RTSP/1.0 200 OK
CSeq: 3
Session: example-session;timeout=60
Range: clock=20261019T081000Z-20261019T081500Z
Scale: 1
A resposta RTP-Info contém seq e rtptime para as trilhas preparadas que estão sendo entregues, inclusive no início do arquivo e após uma busca. Na retomada após uma pausa, rtptime corresponde ao próximo quadro real, inclusive em um salto sobre uma lacuna de gravação.
Solicitação PLAY |
Comportamento do Sapsan |
|---|---|
Range: clock=<from>-<to> |
Começar em um fragmento independente e entregar quadros com DTS inferior a <to> |
Range: clock=<from>- |
Selecionar fragmentos existentes a partir do horário indicado, sem limite superior |
Novo Range: clock=... na mesma sessão |
Mudar imediatamente de posição; não é necessário outro SETUP |
Range: npt=now- |
Mudar para a reprodução ao vivo |
Sem Range, com uma fonte já selecionada |
Continuar a reprodução, inclusive após PAUSE |
Sem Range, no primeiro início |
Selecionar a fonte ao vivo |
NPT numérico aberto, como npt=10- |
451 Parameter Not Understood; a reprodução atual continua |
O Range da resposta informa os limites selecionados. Se <from> estiver dentro de um fragmento independente, a reprodução começa no início desse fragmento, que pode ser anterior ao solicitado. A busca para trás é limitada a 60 segundos; se não houver um início adequado, o próximo fragmento independente é selecionado. O fim é limitado por <to> e pela gravação disponível. Quadros com DTS igual ou superior a <to> não são entregues.
O hífen é mantido mesmo com o fim aberto. As solicitações aceitam segundos UTC inteiros, mas um limite real na resposta pode incluir milissegundos, por exemplo clock=20261019T081000.250Z-20261019T081500Z.
A reprodução ocorre para a frente na velocidade normal. Omita Scale ou indique 1; uma solicitação com Scale: 1 recebe Scale: 1. Outras velocidades e a forma inversa clock=-<to> retornam 451 Parameter Not Understood, mantendo a reprodução atual.
Se houver uma lacuna de gravação entre os fragmentos selecionados, o servidor passa ao próximo fragmento disponível sem esperar toda a duração da lacuna. As marcas de tempo saltam o período ausente.
Um intervalo aberto lê a seleção de fragmentos disponível ao receber PLAY e termina quando ela se esgota. Não incorpora novos fragmentos nem muda automaticamente para a transmissão ao vivo. A reprodução ao vivo exige um PLAY explícito com npt=now-.
Posição atual¶
Para obter a posição de entrega, envie GET_PARAMETER com position no corpo:
GET_PARAMETER rtsp://sapsan.example.com:554/camera?dvr=true RTSP/1.0
CSeq: 4
Session: example-session
Content-Type: text/parameters
Content-Length: 10
position
O corpo é position seguido de CRLF, totalizando 10 bytes. Resposta:
RTSP/1.0 200 OK
CSeq: 4
Session: example-session;timeout=60
Range: clock=20261019T081012Z
Supported: position
O horário é retornado em um cabeçalho, não no corpo da resposta. É uma única marca de tempo sem hífen, diferente do intervalo da resposta PLAY. O valor corresponde ao DTS do último quadro entregue, truncado para segundos inteiros, e não ao momento em que o cliente o exibe.
Antes do primeiro quadro entregue da fonte selecionada, inclusive após uma busca, position retorna 503 Service Unavailable sem Range, com Supported: position. Durante uma pausa e após EOF do arquivo, retorna 200 OK e a última posição confirmada. O código 200 por si só não indica se os quadros continuam sendo entregues. Um parâmetro desconhecido em um corpo não vazio retorna 200 OK e Supported: position, sem Range.
Pausa e encerramento da sessão¶
PAUSE na URL da sessão suspende a entrega preservando a posição dentro do fragmento. O próximo PLAY sem Range retoma os quadros restantes. Um novo Range: clock=... muda imediatamente a posição, inclusive ao enviar várias solicitações PLAY em pipeline; não é criada uma fila de intervalos.
Durante a pausa, mantenha a sessão ativa com um GET_PARAMETER vazio. O servidor anuncia timeout=60; envie solicitações keepalive com frequência maior que esse intervalo. Solicitações RTSP e pacotes RTCP recebidos contam como atividade.
Quando um intervalo que já entregou mídia RTP chega ao fim natural, o servidor envia RTCP BYE para as trilhas preparadas e encerra a entrega atual. A conexão e a sessão permanecem abertas: outro intervalo pode ser solicitado sem repetir SETUP.
Para liberar a sessão, envie TEARDOWN com seu Session. Após 200 OK, a conexão é fechada e a vaga de licença é liberada.
Mídia e limites de compatibilidade¶
Para H.264, os parâmetros do decodificador são transmitidos no SDP, e SPS/PPS ausentes são inseridos antes dos quadros-chave. Os parâmetros são atualizados quando a configuração dos fragmentos do arquivo muda. As marcas RTP são calculadas a partir do DTS do arquivo; RTCP Sender Report as relaciona ao horário NTP.
RTCP Sender Report contém as contagens acumuladas de pacotes RTP e octetos da carga útil. Cabeçalhos RTP e o encapsulamento interleaved não entram nos octetos. Uma busca com o mesmo SSRC não reinicia os contadores.
O perfil suportado tem os seguintes limites:
- Transporte. Somente interleaved TCP; UDP retorna
461. - Velocidade. Somente reprodução normal para a frente; outros valores de
Scaleretornam451. - Escala de tempo. Para buscar no arquivo, use
clockcom segundos UTC inteiros. NPT numérico e SMPTE não são suportados. Frações de segundo só são permitidas nas respostas. - Sequência de intervalos. Cada novo
PLAYde arquivo muda a posição imediatamente; não há fila de intervalos. - Gravação em andamento. Um intervalo aberto não lê fragmentos criados após o início da reprodução.
Códigos de resposta¶
| Código | Causa |
|---|---|
400 Bad Request |
dvr ou URL inválidos; falta Transport em SETUP |
403 Forbidden |
Autorização negada ou stream criptografado indisponível para entrega RTSP |
404 Not Found |
Stream, arquivo ou trilha não encontrados |
451 Parameter Not Understood |
Range ou Scale não suportados; arquivo solicitado por uma URL comum de transmissão ao vivo |
453 Not Enough Bandwidth |
Função proibida pela licença ou limite de sessões atingido |
454 Session Not Found |
Falta o contexto de sessão necessário |
457 Invalid Range |
Janela vazia ou invertida; nenhum fragmento de arquivo adequado |
461 Unsupported Transport |
Foi solicitado um transporte diferente de interleaved TCP |
503 Service Unavailable |
Fonte indisponível; position solicitado antes do primeiro quadro da fonte selecionada. EOF do arquivo por si só não causa 503 para position |
Verificação do cliente¶
Verifique a integração com uma gravação de limites temporais conhecidos e uma lacuna:
- Obtenha o SDP e compare
a=rangecom os períodos de gravação, considerando a união de lacunas curtas. - Envie
SETUPpara as trilhas necessárias. Confira os pares de canais interleaved e o identificador da sessão. - Solicite
positionantes do primeiro quadro: espera-se503semRange. - Inicie
PLAYdentro de um fragmento comScale: 1. Confira oRangeescolhido, oScaleretornado e sertptime/seqcorrespondem ao primeiro pacote RTP. Nenhum quadro deve ter DTS >=<to>. - Pause dentro de um fragmento e retome com
PLAYsemRange. Confira se os quadros restantes e a posição são preservados. - Verifique
451para velocidade não suportada e NPT numérico: a reprodução atual deve continuar. - Aguarde EOF e RTCP BYE e solicite outro intervalo na mesma conexão. Confira a posição após EOF e os contadores acumulados de Sender Report.
- Verifique a recusa por licença
453com limite zero ou esgotado e finalize comTEARDOWN.