DVR / Arquivo¶
Desde a versão 1.13, Perfect Streamer inclui um DVR integrado — um arquivo de fluxo persistente em disco, paralelo à saída OTT normal (HLS / DASH). O arquivo é gravado automaticamente, sem processo separado, e reproduzido pelas mesmas URLs OTT que o live — única diferença: o parâmetro query.
Recursos:
Gravação de cada fluxo OTT ao arquivo no armazenamento escolhido.
Reprodução HLS, DASH e Low-Latency HLS do arquivo (VOD) nas mesmas URLs que o live (DASH e LL-HLS — em CMAF, no OTT/HLS/LL-HLS/LL-Dash).
Legendas (WebVTT) — gravadas junto com chunks TS.
Vários armazenamentos — um fluxo é vinculado a um; fluxos distintos podem gravar em discos distintos.
Limpeza automática por tempo de retenção e uso do disco.
EPG-aligned VOD — arquivo conforme evento EPG referenciado.
VOD adaptativo — suportado para grupos adaptativos.
O DVR não requer licença separada. Ativado por fluxo adicionando vinculação ao armazenamento.
O DVR não substitui a transmissão ao vivo. Se um fluxo possui arquivo, o cliente recebe uma playlist ao vivo com o mesmo comportamento de quando não há DVR. O arquivo só começa a reproduzir quando o cliente solicita explicitamente o modo VOD por meio de um parâmetro de consulta da URL (ver abaixo).
Configuração do armazenamento¶
Um armazenamento é um registro na seção Configuration / DVR Storage. Cada registro descreve um diretório em disco onde PSS grava arquivos. Um fluxo usa um armazenamento.
Ao adicionar um armazenamento, configura-se:
Name — nome exibido.
Dir Path — caminho do diretório em disco. Após criar o registro, o caminho não pode ser alterado — para mover o arquivo, apagar o registro e criar um novo. Os arquivos existentes não são tocados em disco ao apagar o registro.
Max Usage, % — limiar de uso do disco (padrão 90 %). Ao exceder, inicia limpeza size-based (ver abaixo). Mín 1 %, máx 100 %.
Cleanup Interval, seg — período da tarefa de limpeza (padrão 10 seg). A cada tick corta-se primeiro o mais antigo que a profundidade de retenção; depois, se exceder Max Usage, chunks antigos.
Disk Pressure Grace, seg — segundos que Used % deve exceder Max Usage continuamente antes do Size-based cleanup (padrão 60 seg). Filtra picos curtos.
Disk Pressure Cut, seg — limite superior por tick de limpeza: segundos de vídeo por fluxo apagáveis de uma vez (padrão 300 seg). O resto passa ao próximo tick.
Disk Emergency Bytes — limiar de espaço livre abaixo do qual o armazenamento entra em Error e a gravação para (padrão 2 GiB). Recuperação auto se espaço livre ≥ 2 × este valor.
Alarm Disk-Full Hysteresis, % — a margem abaixo de Max Usage até à qual a limpeza baseada em tamanho reduz o preenchimento, para que Used % não oscile mesmo junto ao limiar (2 % por padrão).
A maioria dos valores padrão serve para instalações típicas; geralmente basta ajustar Max Usage e Dir Path.
Faz sentido criar um armazenamento por disco. Se no mesmo disco forem indicados vários registros com subdiretórios distintos, eles competirão pelo espaço livre — o disco é compartilhado, mas a limpeza é própria de cada armazenamento.
Vinculação de um fluxo ao armazenamento¶
Nos ajustes Stream / OTT aparece uma seção DVR:
Storage — lista suspensa de armazenamentos; 0 significa «arquivo desativado para este fluxo».
Storage Hours — profundidade do arquivo para este fluxo, em horas, de 1 a 2160 (até 90 dias). Os chunks mais antigos que esse valor são apagados a cada tick da tarefa de limpeza (Rolling cleanup).
Storage Min Hour — limiar de proteção inferior (horas). A limpeza nunca apaga chunks mais novos, mesmo sob pressão Max Usage. Útil se a lógica de negócio exige gravação recente garantida, ex. «as últimas 2 horas sempre presentes».
Alteração de Storage em tempo real:
definir 0 — desativa o arquivo; os chunks em disco são mantidos, novos não são gravados. As sessões VOD passam a responder 404;
escolher outro armazenamento — o fluxo se desvincula do antigo e passa a gravar no novo. Os arquivos do antigo não são migrados.
Mudanças em Storage Hours e Storage Min Hour se aplicam de imediato — a limpeza usa o novo valor no próximo tick.
Após configuração, o fluxo grava o arquivo automaticamente ao entrar em Running.
VOD: reprodução do arquivo¶
O arquivo é reproduzido pelas mesmas URLs que o live HLS / DASH (ver seção OTT service) — só muda o parâmetro query.
URLs e parâmetros¶
URLs para HLS, DASH e Low-Latency HLS (DASH e LL-HLS — em CMAF, requerem o modo OTT/HLS/LL-HLS/LL-Dash):
Sem parâmetros query — live normal com janela deslizante. Com o parâmetro t — modo VOD.
Parâmetro |
Função |
|---|---|
|
Hora de início VOD (Unix epoch, seg). t=0 — desde o início do arquivo. A presença de t (mesmo t=0) ativa o modo VOD. |
|
Duração da janela VOD, seg. d=0 ou ausente — «até o momento atual». Só faz sentido com t. |
|
EPG-aligned VOD: o servidor localiza o evento EPG ativo no momento dado e usa seus start e duration como bordas da janela. Incompatível com t e d (substituição server-side). Ver abaixo. |
|
Parâmetros live padrão (ver OTT service); |
Comportamento conforme t e d:
t |
d |
Janela |
Condição 404 |
|---|---|---|---|
nenhum |
— |
live (janela deslizante) |
— |
0 |
nenhum / 0 |
[início arquivo, agora] |
DVR não vinculado |
0 |
> 0 |
[início arquivo, +d] |
DVR não vinculado |
> 0 |
nenhum / 0 |
[t, agora] |
DVR não vinculado |
> 0 |
> 0 |
[t, t+d] |
DVR não vinculado |
Normalização das bordas:
t anterior ao início do arquivo — start é alinhado automaticamente ao primeiro chunk disponível (a limpeza pode ter cortado). Não é 404 — entrega-se o que resta.
t no futuro ou janela toda antes do arquivo — playlist vazia mas válida (HLS: só header +
EXT-X-ENDLIST; DASH:@type="static",mediaPresentationDuration="PT0S").Os chunks são selecionados estritamente pelo instante de início do chunk que cai no intervalo semiaberto [t, t+d) — não há segmentos parciais.
VOD em um fluxo sem arquivo (ou cujo armazenamento está em Error) — 404 imediato em master playlist / MPD. Nenhuma sessão é criada.
Texto de erro no corpo 404 (visível em logs do servidor e HTTP body):
VOD: stream not running— o fluxo está na config mas não em Running.VOD: no DVR archive— o fluxo não tem armazenamento ou está em Error.VOD: DVR detached— o fluxo se desvinculou do armazenamento entre requisições.VOD: EPG event not found— sem evento para?epg=.
Playlist HLS VOD — fechada (o player vê a duração e pode buscar):
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:5.000,
...
#EXT-X-ENDLIST
Esses marcadores não estão na playlist live — essa é a única diferença.
MPD DASH VOD — estático: @type="static", mediaPresentationDuration fixo, <SegmentURL> explícitos. O DASH live permanece @type="dynamic".
Se o intervalo escolhido tem lacunas no arquivo (p. ex. reinício de gravação ou limpeza no meio), o MPD DASH é dividido em vários <Period> — um por trecho contíguo. Os players (VLC, dashjs, Shaka) cruzam os limites de período sem configuração especial.
EPG-aligned VOD¶
Se o fluxo está vinculado a uma fonte EPG (campos EPG Source e EPG Channel nos ajustes), o cliente pode solicitar o arquivo por um instante contido em um evento EPG:
http://host:port/hls/stream/login/password/index.m3u8?epg=1778500000
http://host:port/dash/stream/login/password/index.mpd?epg=1778500000
O servidor localiza o evento EPG ativo no epoch dado e usa seus start e duration como bordas da janela VOD. Útil para catálogos: a UI sabe a hora do evento mas não precisa calcular bordas exatas.
Se o fluxo não está vinculado a EPG ou não há evento ativo — 404 ``VOD: EPG event not found``. t e d são ignorados se há epg.
Fluxos adaptativos¶
Os grupos adaptativos (ver HLS Adaptive Multistream) aceitam os mesmos parâmetros VOD:
http://host:port/hls/adaptive/group/login/password/index.m3u8?t=0
http://host:port/dash/adaptive/group/login/password/index.mpd?t=0
Na master playlist (HLS) só entram variantes com armazenamento DVR configurado. As sem DVR são puladas (no log aparece VOD: variant N has no DVR); a montagem segue com as demais.
Na variante DASH, cada qualidade vira um <Representation> distinto em <Period> comuns; o player troca de qualidade sem reabrir o manifesto.
Comportamento do player¶
O VOD HLS / DASH do arquivo toca em players padrão: VLC, hls.js, dashjs, Shaka, ffmpeg. A busca na timeline funciona.
Se o player pede um segmento já apagado pela limpeza, o servidor retorna 404 para esse segmento (não 500). VLC, hls.js, dashjs pulam o segmento e seguem no próximo.
Recursos adicionais:
Proteção de sessões ativas: enquanto há sessão VOD aberta, a limpeza não apaga chunks na sua janela (ver abaixo).
Live-edge bridge: se um cliente em sessão VOD solicitar um segmento além do limite direito da janela VOD — por exemplo, avança na timeline ao atingir o fim do arquivo — o servidor entrega automaticamente o segmento da memória live. Sem redirecionamentos e sem reautenticação.
Cache de playlist: em requisições repetidas do mesmo VOD
index.m3u8/index.mpd, o servidor retorna resposta idêntica byte a byte — sem reconstruir. Adequado para CDN à frente do PSS.
Legendas no arquivo¶
Se o fluxo traz legendas (DVB Subtitling, Teletext ou WebVTT) e a opção OTT WebVTT está ativa, as legendas são arquivadas em paralelo aos chunks TS — em arquivos .vtt ao lado de .ts.
Em modo live, a master playlist contém EXT-X-MEDIA:TYPE=SUBTITLES; em modo VOD, o servidor retorna uma playlist VOD de legendas (com ENDLIST) e segmentos .vtt nas mesmas URLs.
Particularidades:
HLS: o cabeçalho
X-TIMESTAMP-MAPé preservado no início de cada.vtt(exigido pela spec HLS).DASH: o cabeçalho
X-TIMESTAMP-MAPé removido em tempo real (ligado ao PCR absoluto, conflita com a âncora DASH; senão, VLC mostra legendas vazias).Em grupo adaptativo: se o sub-stream ativo não grava legendas, os segmentos VTT retornam 404. Na próxima variante, o player pode receber legendas de novo.
As legendas se desativam via OTT WebVTT no fluxo, ou não ativando HLS em modo OTT/HLS.
Limpeza e retenção¶
PSS usa quatro estratégias de limpeza, executadas a cada tick da tarefa de limpeza (padrão a cada 10 seg):
Rolling cleanup (por fluxo): por fluxo, apagam-se chunks mais antigos que Storage Hours. Roda sempre, mesmo com disco semivazio.
Size-based cleanup (por armazenamento): quando Used % excede Max Usage continuamente por Disk Pressure Grace seg, os chunks mais antigos são cortados proporcionalmente entre fluxos vinculados. Por tick: Disk Pressure Cut seg de vídeo por fluxo. Nunca chunks mais novos que Storage Min Hour.
Emergency disk-full cut: se o espaço livre cai abaixo de Disk Emergency Bytes, a limpeza age agressivamente e pode apagar até chunks protegidos por sessão. A gravação para até o espaço livre voltar com histerese × 2.
Orphan scan: no disco podem permanecer arquivos não contabilizados no índice (após uma parada abrupta do PSS). O coletor percorre os subdiretórios dos fluxos e remove esses arquivos “esquecidos” — a primeira passagem pouco após o início do serviço, depois uma vez por hora e sempre que a pressão de disco for acionada. Como proteção contra uma corrida com a escrita, arquivos com menos de 60 s são ignorados.
Nota. As tarefas de limpeza rodam em segundo plano; o usuário normalmente não age. Se o arquivo cresce mais rápido do que é cortado, reduzir Storage Hours nos fluxos ou aumentar Disk Pressure Cut.
Proteção de sessões VOD ativas¶
Ao abrir uma sessão VOD, em cada armazenamento envolvido registra-se um «slot de proteção» com a hora de início da janela. As limpezas Rolling e size-based não tocam chunks na janela da sessão aberta. O slot é liberado automaticamente ao fechar (FIN, timeout).
Isso significa:
Se o cliente mantém a sessão VOD por muito tempo, pode buscar a qualquer instante na sua janela — os chunks não «somem sob ele».
A limpeza por Max Usage pode não levar Used % ao limiar enquanto a sessão estiver ativa; ao cliente sair, a limpeza alcança.
Emergency disk-full cut e Storage Min Hour contornam a proteção: se o disco está quase sem livre, os chunks são apagados e o cliente recebe 404 nos segmentos afetados (o player os pula).
Após reiniciar o PSS, os slots de proteção somem — a limpeza retoma de imediato.
Vários armazenamentos¶
Pode-se criar qualquer número de registros DVR Storage — um por diretório / disco. Os fluxos se vinculam a armazenamentos distintos de forma independente. A limpeza e limiares (Max Usage, Disk Pressure) operam por armazenamento.
Casos de uso:
Tiering por valor: armazenamento SSD rápido para canais premium com grande profundidade, HDD capacitivo para o resto.
Disco dedicado ao arquivo: para que a gravação DVR não concorra com o disco do sistema ou arquivos temporários.
Separação por projeto: um disco para o lote nº 1, outro para o nº 2 — simplifica migração e auditoria.
Trocar a vinculação do fluxo (campo Storage em Stream / OTT) comuta a gravação em tempo real. Os arquivos antigos ficam intactos no disco anterior — podem ser apagados manualmente ou retomar a gravação revertendo o fluxo.
Estado do armazenamento e monitoramento¶
A seção Data / DVR Storage List (e a API GET /data/dvr-storage-list) mostra por armazenamento:
State — Ready / Error (mais o estado intermediário Not Ready em um armazenamento recém-adicionado).
Total / Free / Used Bytes — espaço livre e ocupado no disco.
Used % — porcentagem atual de uso.
Archived Bytes — tamanho total dos chunks indexados de todos fluxos vinculados (sem orphans).
Pressure Since Sec — momento (epoch) em que Used % primeiro excedeu Max Usage neste episódio; 0 significa «sem pressão».
Active Task — a operação de manutenção em segundo plano em execução neste momento: gc-orphans (remoção de arquivos órfãos), disk-pressure-trim (corte sob pressão de disco) ou none, e há quantos segundos ela já está em execução. Operações de curta duração (< 2 s) não piscam na interface.
Last cleanup — um resumo das últimas execuções de limpeza: há quanto tempo ocorreu a anterior recolha de ficheiros órfãos (e quantos foram eliminados) e o último corte sob pressão de disco (quanto espaço foi libertado).
Attached streams — a lista dos fluxos associados; para cada um são exibidos o nome, o indicador de gravação em curso (active), a profundidade de arquivo configurada (retention-hours) e o preenchimento real (archived-sec e archived-bytes). A soma de archived-bytes de todos os fluxos é igual a Archived Bytes de todo o armazenamento.
Estados:
Ready — o diretório está disponível, a gravação e a limpeza ocorrem normalmente.
Error — o diretório de armazenamento está indisponível (desmontado, sem permissões, erro do sistema de arquivos) ou há espaço livre criticamente baixo no disco; a gravação é interrompida. A recuperação é automática — assim que o diretório fica novamente disponível e surge espaço livre suficiente.
Se o armazenamento entrou em Error, verifique se o diretório do arquivo está montado e se há espaço livre no disco — o PSS não sai sozinho desse estado até que o problema seja resolvido fisicamente.
Preenchimento do arquivo ao longo do tempo:
No nível do stream (Data / Stream) está disponível a métrica storage-gap-percent — a proporção de lacunas de tempo no arquivo acumulado: 0 % significa gravação contínua, valores mais altos significam que há descontinuidades no arquivo (reinícios da fonte, trechos cortados pela limpeza).
O endpoint
GET /data/dvrstatretorna um histograma do preenchimento do arquivo por intervalos de tempo, com a marcação de eventos de gravação (início/parada da fonte, mudança de PMT, comutações de embaralhamento, reconstrução do índice, execução de limpeza) e de atividade de legendas — para desenhar a linha do tempo do arquivo DVR na interface de administração.
Proteção contra perda acidental¶
Várias operações do admin causam perda do arquivo ou cessação da entrega VOD. Antes de executá-las, a UI mostra confirmação modal:
Excluir DVR Storage — todos os fluxos vinculados perdem acesso VOD; os arquivos ficam no disco mas são inacessíveis via PSS sem o registro.
Trocar o fluxo para outro armazenamento — o VOD sobre o arquivo antigo deixa de funcionar.
Desvincular o fluxo do armazenamento (Storage = 0) — mesmo efeito.
Reduzir Max Usage — pode disparar a limpeza size-based e apagar chunks antigos.
Reduzir Storage Hours / Storage Min Hour — pode tirar parte do arquivo do rolling-window.
Decisão deliberada do produto: a operação é possível mas com confirmação, e os arquivos apagados ficam no disco (restauráveis de backup). Colocar o arquivo em servidor de arquivos / RAID separado reduz muito o risco de perda irreversível.
Limitações da versão atual¶
Uma sessão VOD aberta pelo cliente não acompanha o live edge — se vieram chunks durante a sessão, o cliente deve repedir a playlist (comportamento padrão HLS / DASH).
Atribuir um armazenamento por disco é o recomendado — vários registros com subdiretórios distintos disputam o espaço.
Os segmentos são endereçados por hash (HLS sobre MPEG-TS) ou pelo modelo
$Number$.m4scom uminit.mp4comum (live DASH sobre CMAF) / por<SegmentURL>explícitas para.m4s(VOD DASH). Alterar o tamanho do chunk entre live e VOD não exige reabrir a URL.O orphan scanner roda por hora; para acelerar, reiniciar PSS.