Documentação do usuário

Planejamento e protocolos de transmissão de dados

O programa Perfect Streamer destina-se à transmissão de fluxos MPEG-TS pela Internet pública com perdas de pacotes e latência, sobre UDP.

Para cada fluxo MPEG-TS (Stream) configura-se um transmissor (Sender) e um ou mais receptores (Receiver); o conjunto é chamado de Peer.

A configuração do transmissor e receptor resume-se à entrada de uma lista de fluxos (Stream) e às configurações para cada Stream da lista de input e output. Vários input na lista garantem redundância de fontes. Vários output na lista permitem transmitir os fluxos para diferentes destinatários ao mesmo tempo.

Para o transmissor, input são as fontes de fluxos MPEG-TS, output é a transmissão dos fluxos para os receptores. Para os receptores, input é a recepção dos fluxos do transmissor. Estão disponíveis quatro protocolos Peer para transferência de fluxos entre transmissor e receptor:

  • Protocolo Perfect Stream (PS1).

  • SRT.

  • Pro-MPEG / RTP+FEC.

  • RIST.

Protocolo PS1

O protocolo PS1 funciona pelo princípio Automatic Repeat reQuest (ARQ). É leve em recursos e permite transmitir fluxos com alta taxa de bits.

No transmissor — configurado em output. Apenas uma instância está disponível para um stream. É necessário registrar em Peer os logins dos receptores. Define-se a UDP listen port, que deve ser única para cada stream.

No receptor — configura-se no input. Especifica-se o host e a porta do transmissor, além de login e senha.

Há criptografia de fluxos disponível (Crypto protection) usando AES-128. Para ativar em ambos os lados, informe Crypt Passphrase como chave compartilhada.

Em funcionamento, o receptor (cliente) envia suas estatísticas ao transmissor (servidor). É possível consultá-las na seção Peers ao selecionar o cliente.

A latência do fluxo e a capacidade de corrigir perdas dependem das configurações do receptor (cliente):

Round Trip Time — RTT em ms, padrão 300. Latência estimada (ping) do canal. Após iniciar o fluxo, o RTT real aparece nas estatísticas (PS1 recovery delay).

Client Latency (RTT multiplexor) — multiplicador do RTT (padrão 10) que define a latência do fluxo no buffer do emissor; no padrão dá 3000 ms.

No lado do emissor há o ajuste de latência (tamanho do buffer) Latency (ms). Ele deve ser maior do que as latências configuradas nos clientes.

A capacidade do protocolo de compensar perdas é determinada pelo número de solicitações de retransmissão e depende de Client Latency (RTT multiplexor). Grandes perdas geram tráfego adicional na rede. Para reduzir a latência convém ajustar esses parâmetros com mais detalhe.

Para conferir o funcionamento correto do protocolo, veja as estatísticas do cliente. PS1 recovery: Not found → aumentar o buffer do emissor; Dublicates → aumentar o RTT.

Since the connection is initiated from the side of the receiver, the transmitter requires authentication, the receivers are registered in the peers section. Login and password required.

Protocolo SRT

Protocolo aberto desenvolvido pela Haivision. Baseado no UDT; é amplamente difundido e oferece boas características de compensação de perdas de pacotes.

Casos de uso:

  • Peer between two Perfect Streamer instances. On transmitter - endpoint is configured as output, listen mode (default). For one stream only one such output can be configured. Multiple receivers can be connected in this mode. For authorization, it is required to register receivers logins in Peer. On receiver - endpoint is configured as input. The host and port of the transmitter, have to be set up as well as login and password. Streamer uses stream ID in format «login|password» to transmit login and password in SRT.

  • Peer between Perfect Streamer and third-part SRT streamer. On transmitter you can set up srt client mode, switching off listen. SRT stream ID is entered in login field, if needed. For listen mode, the IP-address authorization is available - entered in login field in Peer. On receiver it is available to turn on listen mode, enter the SRT stream ID in the login field, also you can specify the host from which the connection is allowed.

Trabalho no modo Listener: recepção e transmissão do fluxo do canal com indicação da porta de recepção.

As portas em modo listen devem ser únicas.

Há criptografia de fluxos disponível (Crypto protection) usando AES-128. Para ativar em ambos os lados, informe Crypt Passphrase como chave compartilhada.

Se o transmissor usa o modo listen (padrão), a iniciação da conexão acontece do lado do receptor, o transmissor exige autenticação e os receptores são registrados em peer. Login e senha são obrigatórios.

As opções do protocolo SRT seguem a descrição em https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md

Reorder (SRTO_LOSSMAXTTL) - Value up to which the reordering allowance can increase. Reordering allowance is the number of packets that must follow the detected «gap» in the order numbers of incoming packets, to send a report on loss (in the hope that the gap is caused by reordering of packets, not by loss). The reordering allowance starts at 0 and increases when reordering of packets is detected. This happens when a «late» packet with a sequence number older than the last received, but without the retransmission flag is received. At such detection, the reordering allowance is set to the value of the interval between the last number and the sequence number of this packet, but not more than the value set by the SRTO_LOSSMAXTTL parameter. By default, this value is 0, which means that this mechanism is disabled. https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#SRTO_LOSSMAXTTL

Overhead (SRTO_OHEADBW, %) — Sobrecarga para recuperação de banda além da taxa de entrada (ver SRTO_INPUTBW), em percentual da taxa de entrada. Atua somente se SRTO_MAXBW estiver definido como 0. Remetente: configurável pelo usuário; padrão: 25%.

Recommendations: Overhead is intended to provide additional bandwidth capacity in case a packet has taken up some bandwidth but is then lost and needs to be retransmitted. Therefore, the effective maximum bandwidth should be sufficiently higher than the bitrate of your stream to leave room for retransmissions, while being limited so that retransmitted packets do not lead to a sharp increase in bandwidth usage when large groups of packets are lost. Do not set too low a value and avoid 0 if the SRTO_INPUTBW parameter is set to 0 (automatic). Otherwise, your stream will quickly interrupt with any increase in packet loss. https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#SRTO_OHEADBW

Max Band (SRTO_MAXBW, bps) — Esta opção é efetiva apenas quando SRTO_MAXBW é igual a 0 (relativo). Ela controla a banda máxima em conjunto com o parâmetro SRTO_OHEADBW pela fórmula: MAXBW = INPUTBW * (100 + OHEADBW) / 100. Se esta opção for definida como 0 (automático), o valor real de INPUTBW será estimado com base na taxa do fluxo de entrada (casos em que a aplicação chama a função srt_send*) durante a transmissão. O valor mínimo admissível da estimativa é limitado pelo parâmetro SRTO_MININPUTBW, ou seja, INPUTBW = MAX(INPUTBW_ESTIMATE; MININPUTBW).

Recomendações: defina nesse parâmetro o bitrate esperado da sua transmissão e mantenha o valor padrão de 25% para SRTO_OHEADBW. https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#srto_inputbw

Timeout (SRTO_CONNTIMEO, ms) - Value of the connection timeout in milliseconds. This is the time during which the connecting object will try to connect and wait for a response from the remote endpoint, before terminating the connection with an error code. https://github.com/Haivision/srt/blob/master/docs/API/API-socket-options.md#SRTO_CONNTIMEO

Protocolo Pro-MPEG / RTP+FEC (COP3 / SMPTE 2022-1/2)

Entrega de MPEG-TS sobre RTP com correção antecipada de erros (FEC, Forward Error Correction). O mesmo protocolo aparece na literatura e nos equipamentos sob diferentes nomes:

  • Pro-MPEG / Pro-MPEG COP3 — Code of Practice #3 do fórum Pro-MPEG, descrito no padrão IEEE (https://ieeexplore.ieee.org/document/6738329);

  • RTP + FEC — nome funcional (fluxo RTP mais canais FEC);

  • SMPTE 2022-1 — Column FEC (mesmo esquema, publicado como padrão SMPTE);

  • SMPTE 2022-2 — Row + Column FEC (matriz bidimensional, implementada em PSS).

Достоинства — низкая задержка. Его недостаток — высокий дополнительный трафик (overhead), и он плохо работает при больших потерях пакетов (более 0.2%).

Этот протокол основан на RTP с добавлением 2-х каналов для FEC (кода коррекции ошибок). Два канала FEC используют порты port+2 и port+4, что надо учитывать при добавлении нескольких потоков на один хост или мультикаст группу.

No emissor, o fluxo de pacotes RTP é agrupado em uma matriz com Cols colunas e Rows linhas. Exemplo para cols=8 e rows=4 (padrão):

RTP01

RTP02

RTP03

RTP04

RTP05

RTP06

RTP07

RTP08

R1

RTP11

RTP12

RTP13

RTP14

RTP15

RTP16

RTP17

RTP18

R2

RTP21

RTP22

RTP23

RTP24

RTP25

RTP26

RTP27

RTP28

R3

RTP31

RTP32

RTP33

RTP34

RTP35

RTP36

RTP37

RTP38

R4

C1

C2

C3

C4

C5

C6

C7

C8

Os pacotes Rx e Cx formam os dados para FEC por linhas e colunas. Quanto menor o tamanho da matriz, melhor a capacidade de corrigir perdas, mas maior o tráfego adicional. Neste exemplo, há 12 pacotes FEC para cada 32 pacotes RTP do fluxo.

Доступно шифрование потоков (Crypto protection), используется AES-128, но это не включено в стандарт, поэтому не гарантируется совместимость со сторонним ПО или оборудованием.

Existem extensões não padronizadas do protocolo:

Multiplexing — мультиплексирование RTP каналов через один UDP порт. Может упростить настройку сети. Header XOR — обфускация RTP заголовка. Усложнит определение типа трафика в сети.

Protocolo RIST

Novo protocolo aberto baseado em RTP/RTCP. Funciona pelo princípio Automatic Repeat reQuest (ARQ) sem ACK, apenas NACK, o que garante alta eficiência.

Usa unicast e multicast.

Estão implementados os perfis Simple e Main. Simple usa duas portas UDP consecutivas — a porta configurada deve ser par. Main usa uma única porta RTP com multiplexação de dados.

On the transmitter - configured in output. For unicast, the address and port of the receiver are set. For multicast, the network interface through which the data will be transmitted must be set. Also, for multicast, authorization of receivers via IP address can be set if login is written in Peer.

No receptor — configura-se no input. Para unicast define-se a porta de recepção (listen) e obrigatoriamente a interface de rede. Para multicast indica-se apenas o grupo multicast e a porta.

O RIST suporta vários peers (endereços) separados. Com peso maior que 1 ativa-se o balanceamento de carga entre peers conforme o peso.

If the transmitter uses multicast, there may be many receivers. In this case, authentication of receivers by IP address is possible. To do this, enable authentication in the transmitter settings (by default disabled) and add the client to the peer list, in the login field write the IP address.

Outros protocolos

Além dos protocolos peer, existem outros para receber e transmitir fluxos:

Protocol

Input

Output

UDP

Yes

Yes

RTP

Yes

Yes

TCP

Yes

No

HLS

Yes

Yes

UDP (unicast ou multicast) — recepção e envio de MPEG-TS em pacote UDP, até 7 pacotes TS por UDP.

RTP (unicast ou multicast) — protocolo padrão baseado em RFC. Suportada a recuperação de pacotes reordenados.

TCP — recepção de MPEG-TS em conexão TCP, modo cliente TCP.

HLS — recepção e envio de MPEG-TS over HTTP ou o protocolo HLS padrão da Apple. Na recepção de playlist adaptativa é escolhido o fluxo de maior bitrate.

Fluxos com arquivos e dispositivos

Para input e output está disponível o protocolo file/device para arquivos e dispositivos.

output file/device — gravação em arquivo ou saída para dispositivo. A gravação em arquivo pode ser necessária para registrar em ts-file e posterior diagnóstico por outros analisadores. Saída para dispositivo — qualquer dispositivo (incluindo SDI) registrado em /dev.

input file/device — reprodução cíclica do vídeo de um arquivo TS.

Ao trabalhar com arquivos, indique o caminho completo do arquivo no campo File Path:

/catalog/stream.ts.

Ao trabalhar com dispositivos, ative também o indicador Is Device.

Lista de fluxos permitidos e restrição do peer

Para possibilitar a restrição de acesso aos fluxos de canais de TV no lado do cliente (Peer) nos modos SRT Listen, PS1, HLS e HTTP, o programa implementa a funcionalidade de lista de fluxos permitidos. Nas configurações do Peer no transmissor define-se a lista de canais disponíveis. Para isso, no campo Stream Access devem ser adicionados, da lista geral de canais do servidor, apenas aqueles destinados a este Peer. Por padrão, com lista vazia, todos os canais ficam disponíveis.

Para um Peer estão disponíveis limites de tempo e número de conexões por protocolo de transporte.

Anonymous peer

Por padrão, o login do peer é anonymous. O peer anônimo permite distribuir fluxos sem vínculo a IP ou login/senha. Aplicam-se restrições quanto ao número de fluxos entregues por protocolos de transporte, por data limite e pela lista de fluxos permitidos.

É possível criar um peer individual por login (nome) e senha.

Para autorizar um peer por IP, ative a opção «Login Is IP».

Opções de autorização:

  • Por IP único

  • Por faixa de IP, por exemplo: «192.168.1.10-192.168.1.20»

  • Variante combinada, sintaxe de listas IP: ip[-ip2][,…]

Integração de aplicações de terceiros

Para suportar outros protocolos não cobertos pelos recursos integrados, é possível receber e transmitir o fluxo através de aplicações de console externas. Para isso há um protocolo std separado para input e output. O fluxo MPEG-TS é recebido e transmitido através do fluxo de entrada/saída do sistema operacional.

Na configuração indica-se a aplicação console (caminho absoluto) e a linha de comando; é possível também definir variáveis de ambiente.

Para um input com aplicação externa, evite mensagens no stdout — apenas no stderr.

Para o output é possível definir o empacotamento de até 7 pacotes MPEG-TS.

Requisitos do fluxo de entrada

Conformidade com ISO 13818-1, Single Program (SPTS) ou Multi Program Transport Stream (MPTS). As particularidades do MPTS são descritas adiante; as configurações a seguir são para SPTS.

É necessária pelo menos uma trilha de áudio.

Fluxos sem vídeo são suportados, ativados pelo modo Radio.

Fluxos codificados são suportados; para isso é necessário ativar Scrambled Stream.

Para a sincronização o fluxo deve conter marcas de PCR válidas.

Configurações do Stream

Defina um nome único para o stream em letras latinas, dígitos e «_»/«-». Também é possível atribuir um nome de exibição que aceita russo e outros idiomas.

Stream Timeout — tempo limite global do stream. Se não chegar fluxo de entrada válido nesse intervalo, ocorre reinício completo.

Pause — coloca o stream e todos os input e output em estado inativo. Por padrão, novos stream, input e output ficam em pausa e inativos.

O programa verifica a validade do fluxo de entrada no input. Se a verificação falhar, o input é considerado defeituoso.

Check Interval — intervalo de re-verificação do fluxo.

Configurações de filtragem MPEG-TS:

Remove All Unnecessary Data — remove todos os dados desnecessários, exceto PAT/PMT, vídeo e áudio, e o que estiver nos filtros separados (veja abaixo)

Remove SDT — remover dados SDT (nome do canal, provedor etc.).

Remove EIT/EPG — remover os dados de EPG.

Remove Teletext — remover o teletexto.

Remove Subtitles — remover as legendas.

Controle de bitrate do fluxo:

Bitrate mode — modo de controle de bitrate.

  1. Origin (default) — o fluxo é transmitido sem alterações.

  2. VBR — remove pacotes NULL para minimizar o bitrate. Ative se os fluxos forem usados apenas para distribuição OTT.

  3. CBR auto — ativa o alinhamento de bitrate pela inserção de pacotes NULL (stuffing). O bitrate resultante é ajustado ao bitrate máximo do fluxo de entrada.

  4. CBR set stuffing bitrate — definir explicitamente o bitrate desejado. Se for menor que o fluxo de entrada, é nivelado como em CBR Auto.

Com o modo CBR ativado, a PCR Accuracy obedece à TR 101 290; o intervalo do PCR permanece como no fluxo original.

Correção de fluxos:

Fix PAT/PMT interval — corrige o intervalo para conformidade com TR 101 290 inserindo PAT/PMT adicionais.

Redundância de fontes

Pode-se listar vários input, mas apenas um fica ativo. Se ele falhar, é tentado o próximo da lista, e assim ciclicamente.

Se em stream for ativado Fallback Check, durante o funcionamento do input de reserva (não o primeiro da lista) será realizada uma reverificação dos itens superiores da lista no intervalo Check Interval. Se na reverificação o fluxo estiver válido, o stream alterna para ele.

Como a ordem dos input importa, ela pode ser alterada. Um input em pausa não é considerado em funcionamento.

Filtragem e modificação de MPEG-TS

Por padrão, o fluxo MPEG-TS é transmitido como está.

Para cada input estão disponíveis as seguintes opções de filtragem MPEG-TS:

PID Accept — lista de PIDs permitidos. Se vazia, tudo é permitido exceto PID Reject.

PID Reject — lista de PIDs proibidos. Tem prioridade sobre PID Accept.

É possível alterar PIDs. Para isso preencha as listas PID Old e PID New.

Mapping PID and Languages — reatribuição do idioma das trilhas de áudio.

Default Language — definir o idioma padrão quando a trilha de áudio não tiver idioma.

Para o stream é possível atribuir novos dados MPEG-TS (tabela SDT):

  • MPEG-TS Network ID

  • Service Name

  • Provider Name

  • Language

Fluxos MPTS

Fluxo MPTS — fluxo MPEG-TS com vários fluxos (serviços); cada serviço tem um número único (PNR). Usado para difusão DVB.

Para fluxos MPTS as opções de filtragem não estão disponíveis. Os fluxos são transmitidos como estão.

A função mosaic está desativada por padrão. Não é recomendado ativá-la em CPUs fracas — pode introduzir jitter.

Na diagnose do fluxo são exibidos os dados de cada programa separadamente e uma estatística global.

Demultiplexador

Extracts individual streams from MTPS stream. To do this, add input of demux type to the SPTS stream, select a source and a PNR service. If the source MPTS is active, then a list will be available when selecting the PNR, otherwise you need to set the PNR manually.

Multiplexador

Monta um fluxo MPTS a partir de fluxos SPTS individuais. Para configurar esse fluxo:

  • Criar um stream MPTS.

  • Adicionar um input do tipo muxer. Definir o bitrate para alinhar o fluxo CBR (stuffing, conformidade TR 101 290 e T-STD).

    Se for definido 0 (padrão), não haverá alinhamento — o bitrate corresponderá aos fluxos de entrada. Ali também é possível introduzir alguns parâmetros do fluxo MPEG-TS; para a maioria das aplicações os parâmetros padrão são adequados.

  • No Stream de origem adicione um output do tipo muxer. Informe o nome do serviço e, se necessário, o do provedor. Se usar caracteres não latinos, selecione o idioma nas configurações MPEG-TS do stream.

  • Repetir para todas as fontes.

O multiplexador gera para o fluxo SDT, NIT e TDT/TOT (marcas de tempo). O EIT (EPG) é obtido dos fluxos de origem. Novos PIDs são atribuídos.

Fluxos de teste

Test Stream generator - test stream (test card). It allows to create generated video streams as plugs for broadcasting or failures on main streams. It is possible to set the type of image, sound, overlay text and time.

Configura-se ativando o tipo de input correspondente no stream. É possível definir tipo de formato de vídeo, resolução, bitrate, volume e frequência de áudio, etc.

A lista de Test Streams disponíveis está no menu lateral esquerdo do programa.

Serviço OTT

Emite fluxos por protocolos baseados em HTTP — HLS, MPEG-DASH (desde a versão 1.12) e MPEG-TS over HTTP. Suporta HTTPS (SSL). A emissão é ativada na aba OTT das configurações de Stream.

As URLs de conexão têm o formato:

host e port são definidos nas configurações do http server.

streamID do stream. Não confundir com o número de ordem na lista de streams. O ID é exibido no topo da página de estatísticas do stream e na coluna ID da lista de streams; é definido na criação do stream e nunca muda.

Analogamente para HLS e DASH:

Na página de estatísticas do stream são exibidas as URLs dos protocolos conectados (como template) e seu status atual. O acesso não autorizado é proibido; os clientes devem estar registrados em Peers.

Para HLS estão disponíveis parâmetros adicionais na URL (opcionais):

[URL]?a=1&s=40&m=40&v=5

  • a: 1 — caminhos absolutos na playlist (padrão), 0 — caminhos relativos.

  • s: duração da playlist dinâmica (s), 40 s por padrão.

  • m: duração mínima do playlist dinâmico (s), por padrão 40 s. O tamanho máximo do playlist dinâmico é 60 s. Se o tamanho atual do buffer de chunks for menor que o mínimo solicitado, será retornado erro 404. Isso é feito para que o HLS inicie a partir de um buffer de chunks já preenchido no servidor.

  • v: versão do protocolo HLS na playlist. Por padrão 5; alguns clientes HLS podem exigir uma versão diferente.

Para compatibilidade com alguns clientes HLS é possível adicionar o nome de arquivo index.m3u8 à URL, ex.: http://host:port/hls/stream/login/password/index.m3u8.

O servidor HLS tem dois modos — Peer mode e OTT mode.

Peer mode — modo com segmentação (chunks) simples. Recomendado para peering / distribuição de fluxos.

OTT mode — modo com segmentação otimizada para transmissão OTT e início rápido dos players. A carga de CPU é maior; recomendado para transmissão.

É possível habilitar SSL (HTTPS) no servidor HTTP nas configurações do servidor.

Chunk Min Interval e Chunk Max Interval

In OTT mode, the stream is analyzed on PAT/PMT/SPS/PPS/IFrame and chunks are cut by the fast start players criterion. Analysis starts with min interval and if for some reason the data is not found, the chunk is forcibly cut by max interval.

HLS Adaptive Multistream

A partir da versão 1.10 há suporte a HLS Adaptive Multistream e, da 1.12, a DASH Adaptive Multistream

Para fluxos adaptativos é configurada uma playlist HLS separada. Para isso:

  • Nos fluxos que serão incluídos na playlist adaptativa, ative o HLS com OTT Mode.

  • No menu principal aparecerá a seção de fluxos adaptativos. Nela adicione um fluxo e indique todos os fluxos que devem entrar nessa playlist.

  • Para os fluxos pode ser definido um parâmetro de bitrate. Por padrão 0 significa usar o valor medido; caso contrário, pode ser definido explicitamente.

Para playlists adaptativas a URL é diferente:

Aos peers (clientes) pode-se impor restrições de acesso aos fluxos adaptativos, assim como aos comuns. A permissão para um fluxo adaptativo inclui a permissão para todos os fluxos que o compõem.

Modelo de cache para OTT HLS e DASH.

O servidor produz respostas em três categorias, distintas pelo tempo de vida do conteúdo e pela adequação ao cache em nós intermediários (reverse proxy, CDN, cache do cliente).

1. Modelo de cache

1.1. Recursos e cabeçalhos HTTP

Recurso

URL

Content-Type

Cache-Control

Segmento TS

/h<sess>/<keyID>.ts, /h<sess>/<subID>/<keyID>.ts

video/mp2t

public, max-age=60, immutable

DASH MPD

/h<sess>/index.mpd

application/dash+xml; charset=utf-8

public, max-age=1

HLS master

/hls/<stream>/<login>/<pass>/index.m3u8

application/vnd.apple.mpegurl

public, max-age=1

HLS media

/h<sess>/index.m3u8, /h<sess>/<subID>/index.m3u8

application/vnd.apple.mpegurl

public, max-age=1

302 Redirect

/dash/<stream>/<login>/<pass>/index.mpd

no-cache, no-store

Raw TS

/http/<stream>/<login>/<pass>

video/mp2t

não definido; não é cacheado

1.2. Características dos segmentos TS

O identificador keyID é formado como CRC64(startTime || streamID) e é globalmente único. A URL do segmento endereça conteúdo imutável — em requisições repetidas da mesma URL é retornado um fluxo de bytes idêntico (enquanto o segmento permanecer dentro da janela deslizante).

A diretiva immutable suprime a revalidação condicional pelo cliente (If-None-Match, If-Modified-Since). O valor max-age=60 é compatível com o típico timeShiftBufferDepth=40s.

1.3. Características dos manifestos

max-age=1 limita o limite superior de obsolescência do conteúdo no cache em um segundo. Em conjunto com proxy_cache_lock on (nginx), picos de requisições ao manifesto coalescem em uma única requisição ao origin por segundo.

1.4. Variabilidade do conteúdo

Com absPath=0 (padrão; sem o parâmetro de URL «a»), os manifestos HLS media e DASH MPD não contêm o identificador de sessão no corpo. O conteúdo do manifesto é idêntico entre sessões pertencentes a uma mesma combinação (stream, param). Isso permite que o cache do reverse-proxy reutilize a entrada entre sessões com a normalização da chave de cache.

Com absPath=1 (parâmetro de URL «a=1»), o corpo do manifesto contém URLs absolutas, incluindo esquema, host e identificador da sessão. O conteúdo torna-se específico da sessão; a possibilidade de reutilização do cache entre sessões deixa de existir.

2. Comportamento dos clientes

Cliente

URL de atualização do manifesto

Impacto no número de sessões

VLC 3.x HLS

/h<sess>/index.m3u8

Uma sessão por reprodução

VLC 3.x DASH

/dash/<stream>/.../index.mpd

Tratado por session reuse (ver 3.3)

ffmpeg 5.x HLS

/h<sess>/index.m3u8

Uma sessão por reprodução

ffmpeg 5.x DASH

/dash/<stream>/.../index.mpd (laço de repetição)

Tratado por session reuse (ver 3.3)

dash.js, hls.js

/h<sess>/... via <Location> / URL de sessão

Uma sessão por reprodução

3. Mecanismos especiais

3.1. HTTP 302 Redirect para DASH

Uma requisição da forma /dash/<stream>/<login>/<pass>/index.mpd retorna a resposta 302 Found com o cabeçalho Location: /h<sess>/index.mpd. O corpo da resposta é vazio. A autenticação e a alocação da sessão acontecem na fase de processamento do redirecionamento.

Clientes que suportam cache de redirecionamento acessam diretamente a URL da sessão nas requisições subsequentes. Clientes que não suportam repetem a requisição de redirecionamento. O custo do reprocessamento do redirecionamento limita-se à verificação de autenticação e às operações de session reuse.

3.2. Session reuse para DASH

No processamento da requisição /dash/.../index.mpd, executada sob login-id L para stream-id S e a flag adaptive=A, se em _ottClientList já existir uma sessão DASH com o mesmo (L, S, A), seu sessID é retornado. Não é criada nova sessão e nenhum slot maxConn é consumido.

Aplica-se apenas a DASH. Para HLS não é necessário um mecanismo de reuse separado: clientes HLS atualizam a media playlist via URL de sessão e não disparam applyNewOTTSess a cada refresh.

3.3. Reutilização de segmentos entre sessões

O caminho /h<sess>/<keyID>.ts é independente de sess na resolução do keyID em conteúdo: keyID identifica univocamente o segmento dentro das ChunkList registradas (ver _ottStreamList). O Nginx com cache key normalizada (removendo o prefixo /h<sess>/) atende todas as requisições do mesmo keyID a partir de uma única entrada de cache.

4. Parâmetros de requisição

Parâmetro

Valor padrão

Impacto

a

0

1 — URLs absolutas nos manifestos; 0 — relativas

s

40

timeShiftBufferDepth em segundos

m

40

Comprimento mínimo da janela para emitir o manifesto

v

3

#EXT-X-VERSION em HLS (ignorado pelo DASH)

Alterar o parâmetro via query string atualiza os valores armazenados na sessão na próxima chamada de applyNewOTTSess.

5. Características de carga

A carga no origin escala com o número de streams distintos assistidos simultaneamente. O aumento do número de clientes assistindo o mesmo stream não aumenta o número de requisições ao origin quando há reverse-proxy cache com chave de cache normalizada.

Cenário

Taxa de requisições ao origin (ref.)

1 cliente por fluxo X

MPD: 0.4 req/s, segment: 0.2 req/s

N clientes em um mesmo fluxo X (cache ativo)

MPD: 1 req/s, segment: 0.2 req/s

N clientes ffmpeg em modo replay no mesmo fluxo

MPD: 1 req/s (com proxy_cache_lock)

N clientes em N fluxos distintos

MPD: 0.4·N req/s, segment: 0.2·N req/s

6. Nginx como reverse proxy com cache

6.1. Configuração básica

proxy_cache_path /var/cache/nginx/pss_segments
    levels=1:2 keys_zone=pss_segments:100m
    max_size=20g inactive=30m use_temp_path=off;

proxy_cache_path /var/cache/nginx/pss_manifests
    levels=1:2 keys_zone=pss_manifests:10m
    max_size=256m inactive=5m use_temp_path=off;

upstream pss_backend {
    server 127.0.0.1:41972;
    keepalive 64;
}

map $uri $pss_cache_key {
    ~^/h[0-9a-f]{16}(?<tail>/.+\.(ts|m3u8))$  "stream:$tail";
    default                                     $uri;
}

server {
    listen 80;
    server_name stream.example.com;

    location ~* "^/h[0-9a-f]{16}(/[0-9]+)?/[0-9a-f]+\.ts$" {
        proxy_cache               pss_segments;
        proxy_cache_key           $pss_cache_key;
        proxy_cache_valid         200 60s;
        proxy_cache_valid         404 403 0s;
        proxy_cache_lock          on;
        proxy_cache_use_stale     updating error timeout;
        proxy_cache_revalidate    on;
        add_header                X-Cache-Status $upstream_cache_status;

        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
        proxy_buffering           on;
    }

    location ~* "(^/h[0-9a-f]{16}(/[0-9]+)?/index\.(m3u8|mpd)$|^/(hls|dash)/.*\.(m3u8|mpd)$)" {
        proxy_cache               pss_manifests;
        proxy_cache_key           $pss_cache_key;
        proxy_cache_valid         200 1s;
        proxy_cache_valid         404 403 0s;
        proxy_cache_lock          on;
        proxy_cache_lock_timeout  2s;
        proxy_cache_use_stale     updating;
        add_header                X-Cache-Status $upstream_cache_status;

        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
    }

    location / {
        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
        proxy_set_header          X-Forwarded-Proto $scheme;
        proxy_set_header          X-Forwarded-Host  $host;
        proxy_buffering           off;
        proxy_read_timeout        3600s;
    }
}

6.2. Finalidade das diretivas

Diretiva

Finalidade

proxy_cache_lock on

Serializa as requisições upstream em cache misses simultâneos para a mesma chave

proxy_cache_use_stale updating

Devolve a cópia obsoleta às requisições paralelas durante a atualização do cache

proxy_cache_revalidate on

Usa If-Modified-Since em cache miss com cópia salva

proxy_cache_valid 404 403 0s

Proíbe o cache de erros de autorização e 404

keepalive 64 no upstream

Mantém um pool de conexões persistentes ao origin

proxy_buffering on

Para segmentos; ativa o bufferização da resposta no nginx

proxy_buffering off

Para a seção /; desativa o bufferização (raw streaming)

6.3. Cálculo de max_size do cache de segmentos

Valor de referência: bitrate × timeShiftBufferDepth × distinct_streams × 2

Exemplo: 10 fluxos × 8 Mbps × 40 s × 2 ≈ 800 MB. Recomenda-se uma margem de 10× para absorver a variabilidade do bitrate.

6.4. Terminação TLS

O servidor do Perfect Streamer aceita conexões nas portas HTTP e HTTPS. Com terminação TLS no nginx, o upstream usa a porta HTTP. O encaminhamento dos cabeçalhos X-Forwarded-Proto e X-Forwarded-Host é obrigatório para a composição correta de URLs absolutas quando absPath=1.

server {
    listen 443 ssl http2;
    server_name stream.example.com;

    ssl_certificate           /etc/letsencrypt/live/stream.example.com/fullchain.pem;
    ssl_certificate_key       /etc/letsencrypt/live/stream.example.com/privkey.pem;
    ssl_protocols             TLSv1.2 TLSv1.3;
    ssl_session_cache         shared:SSL:10m;
    ssl_session_timeout       1d;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location ... {
        proxy_pass                http://pss_backend;
        proxy_set_header          X-Forwarded-Proto https;
        proxy_set_header          X-Forwarded-Host  $host;
        proxy_set_header          Host              $host;
        # + директивы кеширования из 6.1
    }
}

server {
    listen 80;
    server_name stream.example.com;
    return 301 https://$host$request_uri;
}

Para HTTPS entre nginx e origin aplicam-se proxy_ssl_verify e proxy_ssl_trusted_certificate. Em conexões loopback a criptografia é redundante.

6.5. Multi-host

Quando um único processo nginx atende vários server_name, $host é adicionado à cache key para isolar o conteúdo:

map $uri $pss_cache_key {
    ~^/h[0-9a-f]{16}(?<tail>/.+\.(ts|m3u8))$  "$host:stream:$tail";
    default                                     "$host:$uri";
}

O tamanho de keys_zone é dimensionado em 8000 chaves/MB. Para instalações multi-host com milhares de fluxos, recomenda-se keys_zone=...:300m ou mais.

7. Cache no cliente

Cache-Control: immutable é processado pelos navegadores Chrome/Firefox/Safari. O cache do cliente devolve o segmento sem requisição condicional em acessos repetidos (incluindo seek para trás dentro do buffer do player).

Service Workers podem aplicar a estratégia cache-first baseada no conteúdo de Cache-Control. Os players DASH (dash.js, Shaka) usam MSE através de SourceBuffer; o segmento colocado no buffer permanece disponível sem nova requisição HTTP até sair da janela deslizante.

Para requisições cross-domain, o cabeçalho Access-Control-Allow-Origin: * permite o cache em shared caches sem Vary: Origin. Ao trocar o valor ACAO para um Origin específico passa a ser necessário Vary: Origin, o que reduz a eficiência do shared cache.

8. Implantação via CDN

Perfect Streamer é compatível com CDNs em modo pull-from-origin (Cloudflare, Akamai, Fastly, BunnyCDN, Amazon CloudFront).

Origin shield. Recomenda-se colocar um ou mais nós shield entre o edge do CDN e o origin para reduzir a taxa de requisições ao origin quando os clientes estão distribuídos globalmente.

Purge. Segmentos content-addressed não precisam de purge. Quando os metadados do stream mudam (codec, resolução), os manifestos atualizam dentro de max-age=1 sem purge explícito.

Cache warming. Em caso de pico esperado em um stream específico, é admissível pré-aquecer a CDN a partir de vários pontos geográficos antes do início da transmissão.

Geodistribuição. Os segmentos (max-age=60) são bem adequados para cache geograficamente distribuído. Os manifestos (max-age=1) toleram atraso de entrega de até um segundo — aceitável para live non-low-latency.

9. Monitoramento

9.1. X-Cache-Status

Adicionar add_header X-Cache-Status $upstream_cache_status; em cada location com cache. Valores:

Valor

Descrição

HIT

Resposta do cache

MISS

Não estava em cache; obtido do origin e armazenado

EXPIRED

Expirado, atualizado

UPDATING

Cópia stale entregue à requisição paralela durante a atualização

STALE

use_stale retornou a cópia expirada (origin indisponível)

REVALIDATED

Origin retornou 304 Not Modified

BYPASS

proxy_cache_bypass foi acionado

9.2. Formato do access-log

log_format pss_cache '$remote_addr $status $request_method "$request" '
                     '$body_bytes_sent rt=$request_time ut=$upstream_response_time '
                     'cache=$upstream_cache_status key=$pss_cache_key';

server {
    access_log /var/log/nginx/pss.log pss_cache;
}

9.3. Métricas

O módulo nginx-vts exporta métricas por zona no formato Prometheus:

GET /status/format/prometheus

Limites recomendados para alertas:

Métrica

Limite

Causa possível

Segment HIT rate

< 90 % em 5 minutos

Normalização de cache key quebrada; max_size pequeno

Manifest MISS rate

> 50 % em 1 minuto

proxy_cache_lock não serializa as requisições

Upstream response time p95

> 500 ms em 1 minuto

Sobrecarga do origin

Cache zone fill

> 90 % em 10 minutos

Aproximação de max_size; eviction LRU prevista

10. Diagnóstico

Sintoma

Causa provável

Solução

Taxa HIT de segmento baixa

Vary: Origin com alta variabilidade do Origin; normalização quebrada em map

Verificar cabeçalhos e regex na diretiva map

404 em segmentos após sair da janela

404 em cache para segmento que saiu da janela deslizante

Adicionar proxy_cache_valid 404 0s na location de segments

Atraso do início da reprodução 2–5 s

proxy_cache_lock_timeout excede a latência alvo

Reduzir para 1–2 s; ativar proxy_cache_use_stale updating

O manifesto não atualiza

proxy_cache_valid sobrescreve max-age

Definir explicitamente proxy_cache_valid 200 1s

Crescimento de TIME_WAIT no upstream

Falta keepalive no bloco upstream

Adicionar keepalive 64, proxy_http_version 1.1, proxy_set_header Connection ""

403 em /dash/.../<segment>.ts do ffmpeg

O cliente resolve URLs relativas a partir da URL pré-redirect

O servidor emite <BaseURL>/h<sess>/</BaseURL> (caminho absoluto); compatível no build atual

11. Segurança

11.1. Session URL

A URL no formato /h<sess>/... cumpre a função de token de sessão — não exige reautenticação. O tempo de vida é limitado pelo idle timeout (valor 30 s). Em caso de inatividade, a sessão é removida pela tarefa cleaner.

Requisitos:

  • HTTPS em todos os caminhos OTT (/hls/, /dash/, /h<sess>/) em produção

  • O Session ID no cabeçalho Location do 302 não é cacheado (no-cache, no-store)

11.2. Rate limiting

limit_req_zone $binary_remote_addr zone=dash_top:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=hls_top:10m  rate=5r/s;

server {
    location /dash/ {
        limit_req zone=dash_top burst=20 nodelay;
        proxy_pass http://pss_backend;
    }
    location /hls/ {
        limit_req zone=hls_top burst=20 nodelay;
        proxy_pass http://pss_backend;
    }
}

URLs de sessão (/h<sess>/) não exigem rate limiting — o processamento é barato e as respostas são cacheadas.

11.3. Cache de respostas de erro

proxy_cache_valid 200 60s;
proxy_cache_valid 301 302 0s;
proxy_cache_valid 404 403 0s;
proxy_cache_valid any 1s;

Proíbe o cache de redirecionamentos (sess único em Location) e de respostas de erro de autorização ou recurso ausente.

11.4. Restrição do acesso de rede ao origin

A porta 41972 (41982 para HTTPS) deve estar fechada ao tráfego externo. Configurações aceitáveis:

  1. Bind do Perfect Streamer em 127.0.0.1 (com nginx local)

  2. Regra de firewall:

iptables -A INPUT -p tcp --dport 41972 ! -s 10.0.0.0/8 -j DROP

12. Integração com middleware

12.1. Modelo prefix-login

O Perfect Streamer permite delegar a identificação de usuário a middleware/sistema de billing via o mecanismo prefix-login. Um conector externo ao sistema de billing não está incluído nesta versão.

Configuração do usuário embedded:

{
  "id": 9,
  "login": "sub",
  "password": "xxx",
  "is-prefix": true,
  "max-conn-http-hls": 1,
  "accept-stream": [ ... ]
}

Com is-prefix: true o servidor aceita URLs cujo login segue <prefix><billing_user_id>:

/dash/test1/sub42/xxx/index.mpd
/hls/test1/sub43/xxx/index.m3u8

12.2. Formato das estatísticas

<clients>
  <client login-id="-1974387287" login="sub" match-login="sub42"
          sess-id="11331..." ott-type="dash" stream-id="10000" .../>
  <client login-id="-2147031294" login="sub" match-login="sub43"
          sess-id="11132..." ott-type="dash" stream-id="10000" .../>
</clients>

O campo login-id contém o hash do login URL. login é o valor configurado. match-login é o login URL usado pelo cliente.

12.3. Limitações do prefix-login

  • Senha compartilhada. Todos os subscribers do pool prefix usam uma mesma senha. O comprometimento dá acesso a qualquer <prefix><string>.

  • Granularidade de ACL. accept-stream aplica-se a todo o pool prefix; não há ACL por assinante sem billing externo.

  • Rotação da senha. Alterá-la desconecta todos os subscribers ativos. Para substituição gradual são necessários temporariamente dois prefix-logins.

13. Legendas WebVTT

A fonte das legendas é DVB Teletext / DVB Subtitling do MPEG-TS de entrada. As faixas de legendas Teletext devem estar presentes nas seções Media Information ou Original Media Information. A seção Analyzer também permite verificar se os pacotes dos PIDs correspondentes estão ativos.

Para OTT HLS/DASH o modo OTT deve estar ativado (em Peer mode as legendas WebVTT não estão disponíveis). Na seção Output # OTT o contador de chunks OTT WebVTT buffer chunk count deve ficar diferente de zero.

Para diagnosticar as legendas, ativar Analyze e Trace no stream. Ao iniciar o fluxo, o log do stream deve exibir:

Start Teletext subtitle decoder
[ttxsubdec] ttx: pid=331 magazine=8 page=0x88 lang=***

Em seguida, o log registra o texto decodificado das legendas.

13.1. URL dos segmentos VTT

Esquema

URL

Conteúdo

HLS master

/hls/.../index.m3u8

#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",...,URI="/h<sess>/sub/<pid>/index.m3u8"

HLS subtitle playlist

/h<sess>/sub/<pid>/index.m3u8

lista <keyHex>.vtt com #EXTINF

Segmento VTT HLS

/h<sess>/sub/<pid>/<keyHex>.vtt

VTT com X-TIMESTAMP-MAP estilo HLS

DASH MPD AdaptationSet

em index.mpd

contentType="text" mimeType="text/vtt" + <SegmentTemplate media="$Number$.vtt">

Segmento VTT DASH

/h<sess>/sub/<pid>/<seq>.vtt

VTT com X-TIMESTAMP-MAP estilo DASH

<keyHex> é o hex de 16 caracteres de CRC64(startTime, streamID, pid). <seq> é o número decimal do chunk no subtitle storage (contador separado do video storage).

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 e DASH do arquivo (VOD) nas mesmas URLs que o live.

  • 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 o live. Se um fluxo tem arquivo, o cliente recebe playlist live idêntica à sem DVR. O arquivo só toca se o cliente solicitar modo VOD via parâmetro query 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, % — largura da banda de histerese ao sair de DiskFullDegraded (padrão 2 %).

A maioria dos valores padrão serve para instalações típicas; geralmente basta ajustar Max Usage e Dir Path.

Um armazenamento por disco é o recomendado. Vários registros no mesmo disco com subdiretórios distintos disputam o espaço livre — statvfs dá a visão global, mas a limpeza é por registro.

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 do fluxo, em horas. Chunks mais antigos são apagados a cada tick. 0 desativa Rolling cleanup (só roda Size-based cleanup via Max Usage).

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 e DASH:

Sem parâmetros query — live normal com janela deslizante. Com o parâmetro t — modo VOD.

Parâmetro

Finalidade

t=<epoch>

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.

d=<sec>

Duração da janela VOD, seg. d=0 ou ausente — «até o momento atual». Só faz sentido com t.

epg=<epoch>

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.

a, s, m, v

Parâmetros live padrão (ver OTT service); s e m são ignorados em modo VOD.

Comportamento conforme t e d:

t

d

Janela

Condição 404

não

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 escolhidos estritamente por startTime ∈ [t, t+d) — sem 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:3
#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:

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:

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 pede um segmento além de vodEnd — p. ex. avança na timeline ao fim do arquivo — o servidor entrega o segmento da memória live. Sem redirecionamentos ou 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.

Limpeza e retenção

PSS usa duas estratégias de limpeza, executadas a cada tick (padrão a cada 10 seg):

  1. Rolling cleanup (por fluxo): por fluxo, apagam-se chunks mais antigos que Storage Hours. Roda sempre, mesmo com disco semivazio.

  2. 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.

  3. 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.

  4. Orphan scan (por hora): podem ficar arquivos não contabilizados no índice (após parada abrupta do PSS). Uma vez por hora, o scanner percorre subdiretórios dos fluxos e apaga esses arquivos «esquecidos». Anti-race com o writer — arquivos com menos de 60 seg são pulados.

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:

  • StateReady / DiskFullDegraded / Error.

  • Total / Free / Used Bytes — estatísticas do disco (statvfs).

  • Used % — porcentagem atual de uso.

  • Archived Bytes — tamanho total dos chunks indexados de todos fluxos vinculados (sem orphans).

  • Attached Streams — número de fluxos vinculados a este armazenamento.

  • Pressure Since Sec — momento (epoch) em que Used % primeiro excedeu Max Usage neste episódio; 0 significa «sem pressão».

Estados:

  • Ready — operação normal.

  • DiskFullDegraded — espaço livre < (Disk Emergency Bytes × 2); a gravação segue mas pode passar a Error a qualquer momento.

  • Error — espaço livre < Disk Emergency Bytes; gravação parada; reinício por histerese.

Se o armazenamento está em Error, verifique o espaço livre; PSS não sai sozinho desse estado até haver mais espaço físico.

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) ou template $Number$.ts (live DASH) / <SegmentURL> explícitos (VOD DASH). Trocar o tamanho do chunk entre live e VOD não exige reabrir a URL.

  • O orphan scanner roda por hora; para acelerar, reiniciar PSS.

Operações com fluxos

Remoção. Para remover um fluxo, abra suas configurações e clique em Delete stream.

Clonagem. Para clonar um fluxo, abra suas configurações e clique em Clone stream.

Ordenação. Para configurar a ordenação dos fluxos clique no botão Sort na janela da lista de fluxos. Em seguida indique a ordem desejada arrastando os fluxos para cima e para baixo na lista. Para salvar a ordem definida clique em Save order, ou em Cancel para descartar as alterações.

Filtragem da lista. Para filtrar a lista de fluxos clique no ícone de busca e digite a string de filtro. Para cancelar, clique na seta voltar.

Operações em grupo. No modo de filtragem da lista de fluxos é possível selecionar vários fluxos marcando as caixas na coluna esquerda. Se houver fluxos selecionados, ficam disponíveis os botões Excluir e Clonar para os fluxos selecionados.

Exportação e importação de fluxos por meio de um script em Python

A exportação e importação de configuração é feita por uma playlist .m3u via um script em Python.

É necessário Python 3 no caminho /usr/bin/python3.

Exportação e importação de fluxos pela interface web

Na lista de fluxos, ao clicar no botão Playlist, abre-se o diálogo de exportação dos fluxos para uma playlist no formato m3u8. São exportados apenas os fluxos atualmente exibidos, considerando os filtros aplicados na lista.

Configurações:

  • Host / IP — nome ou endereço do servidor usado para formar as URLs dos fluxos.

  • Protocols — tipos de protocolos para exportação.

  • Login — selecionar a conta que será usada para formar as URLs dos fluxos.

  • Use Display Names — usar o Display name do fluxo em vez do Stream name no arquivo m3u8.

A playlist é baixada como arquivo m3u8 ao clicar no botão Download.

Ao clicar no botão Import Playlist, o diálogo muda para o modo de importação de fluxos a partir de uma playlist no formato m3u8. Durante a importação, os fluxos existentes não são removidos. Em todos os fluxos importados o horário da importação é registrado no campo Note.

Configurações:

  • Playlist — seleção do arquivo de playlist para importação.

  • Create Outputs — escolha do protocolo para gerar automaticamente saídas para os fluxos importados.

  • Output Ports From — número de porta inicial para gerar as saídas.

  • Output IP — seleção da interface à qual os fluxos de saída são vinculados.

  • Tags — tags com que os fluxos importados são marcados. Úteis para operações em grupo, por exemplo, remover todos os fluxos importados.

Se no campo Playlist estiver indicado um arquivo a importar, o botão Load Playlist torna-se ativo. Ao clicar em Load Playlist ocorre o pré-carregamento da playlist, e o resultado do parsing é exibido na tabela. Após o parsing da playlist torna-se ativo o botão Import Streams: ao clicá-lo são importados os fluxos e gerados outputs para eles.

Relatórios e diagnóstico

A seção Streams exibe os dados de todos os stream em forma de tabela. Pausa está disponível para os papéis admin e restricted admin.

Para cada stream estão disponíveis estatísticas detalhadas e relatórios.

Peers — lista de receptores ativos (clientes). Para cada um há estatísticas separadas.

Análise de fluxos

O analisador de fluxos do streamer mede e analisa diversos parâmetros do fluxo MPEG-TS, permitindo avaliar a qualidade.

Input speed — taxa (bitrate) do fluxo em kbps. Muda após o filtro por marcas de PCR. Exibida como gráfico que também mostra o bitrate de saída após o sincronizador.

Raw data speed — velocidade de recepção pelo protocolo escolhido. Overhead — acréscimo em % devido à sobrecarga do protocolo.

CC errors — perdas de pacotes (CC, discontinuity). São exibidos contadores por período e contador acumulado pelo uptime do stream; também é mostrado um gráfico do histórico.

Scrambled — contadores de pacotes MPEG-TS ES criptografados. Se for ≠ 0, há falhas na decodificação de canais criptografados.

Sync by — fonte de sincronização, padrão PCR. Se o PCR estiver incorreto, é possível usar o PTS/DTS do vídeo (ver a configuração Force Sync by PTS no input).

PCR interval — intervalo entre as marcas de PCR. Recomendado: até 50 ms.

PCR jitter — caracteriza a precisão de sincronização do fluxo de saída; medido como a diferença entre o PCR e o tempo real.

Analyze PCR PMT Gap — ativado por configuração separada. Analisa-se a dispersão entre PCR e PTS/DTS para cada ES. O histórico é exibido na forma de gráfico. Uma dispersão excessiva pode causar problemas em players com buffer de sincronização pequeno. A análise é ativada pela configuração Analyze PAT/PMT/KF.

PAT interval e PMT interval — alteram o intervalo entre tabelas PAT (PMT). Recomendado: até 500 ms. A análise é ativada por Analyze PAT/PMT/KF.

Key Frame interval — mede o intervalo entre quadros-chave (KF). Para players que se conectam ao fluxo em ponto aleatório, recomenda-se no máximo 1 s. A análise é ativada pela configuração Analyze PAT/PMT/KF.

PAT/KF interval — mede o intervalo médio entre o início e o fim da sequência PAT/PMT/SPS/PPS/KF. Disso depende a velocidade de início da reprodução em players que se conectam ao fluxo em ponto aleatório. É medido pelo início do KF no fluxo, então o tempo real de início do player será maior. A análise é ativada pela configuração Analyze PAT/PMT/KF.

Ativar Analyze PAT/PMT/KF coloca o analisador do fluxo em modo permanente, aumentando a carga de CPU.

Controle do jitter

Para gerenciar o jitter existem várias configurações no stream:

  • Jitter Compensation Delay (ms) — função de compensação do jitter de rede; define o tamanho do buffer. Descrição detalhada: https://forum.pstreamer.tv/viewtopic.php?t=25

  • Jitter Auto sync — ativa 2000 ms para protocolos baseados em TCP (HTTP, HLS); para os protocolos UDP o valor permanece em 500 ms.

  • Limit PCR gap (ms) — verifica o quanto o PCR pode saltar; se ultrapassar, ocorre resincronização.

If PCR Accuracy errors appear after the transcoder, you need to set an even bitrate using stuffing for the encoded stream along the followingpath: «input - transcoder - Align Total Bitrate». The speed must be guaranteed to be greater than the bitrate of video and audio.

System Monitor

Controle dos principais parâmetros do sistema operacional.

Mosaic

Função de captura de tela do fluxo de entrada. Ativada individualmente para cada stream.

Se não for necessária, pode ser totalmente desativada em Settings/Server Settings para economizar recursos.

Administração

Em Configuration/Administration/Administrators List são adicionados os usuários para acessar a interface web — servidor HTTP embutido.

Aos usuários são atribuídos papéis:

admin — acesso total.

restricted admin — as configurações não estão acessíveis; apenas o valor pause pode ser alterado.

viewer — acesso apenas em modo de visualização.

Backup das configurações

Para fazer backup das configurações, salve o conteúdo da pasta /opt/pss/config.

Para restaurar as configurações, pare o serviço e substitua o conteúdo da pasta /opt/pss/config.

Integração de sistemas externos de monitoramento

pss-metrics — exportador universal de métricas para Perfect Streamer

Um único script CLI em Python 3 que obtém estatísticas da API HTTP do servidor web do PSS e gera saída para os sistemas de monitoramento mais comuns:

  • Zabbix (UserParameter, Low-Level Discovery, zabbix_sender trapper)

  • Prometheus (formato de exposição de texto para o textfile collector)

  • InfluxDB / Telegraf (line protocol ou JSON para o input exec)

  • JSON universal para scripts arbitrários e verificações de estado no estilo Nagios

O exportador é um arquivo único e autocontido, sem dependências de terceiros, e usa apenas a biblioteca padrão do Python 3.6+ (urllib, xml.etree, json, argparse).

Arquivos

pss-metrics.py                    основной CLI (исполняемый)
userparameter_pss.conf.example    шаблон UserParameter для Zabbix

Instalação

O exportador é entregue em /opt/pss/monitoring/pss-metrics.py. Verifique se o Python 3.6 ou posterior está instalado:

# RHEL / Rocky / AlmaLinux
yum install -y python3

# Debian / Ubuntu
apt-get install -y python3

Nenhum pacote adicional é necessário.

Configuração

Por padrão, pss-metrics conecta-se a http://127.0.0.1:43971 e detecta automaticamente a porta a partir de /opt/pss/config/pss.json (ou /opt/pss/config/pss_default.json). Os parâmetros podem ser sobrepostos por variáveis de ambiente, pelo arquivo /etc/pss-metrics.conf (formato chave=valor) ou por flags de linha de comando. Prioridade: CLI > env > arquivo > valores padrão.

Variáveis suportadas:

PSS_URL          полный URL, например http://10.0.0.1:43971  (по умолчанию авто)
PSS_USER         логин веб-сервера (если включена авторизация)
PSS_PASS         пароль веб-сервера
PSS_TIMEOUT      таймаут HTTP, в секундах                    (по умолчанию 5)
PSS_CACHE_DIR    каталог кеша                                (по умолчанию /run/pss-metrics)
PSS_CACHE_TTL    время жизни кеша, в секундах                (по умолчанию 10)
PSS_CA_BUNDLE    путь к CA bundle для HTTPS
PSS_INSECURE     1 — отключить проверку TLS-сертификата
PSS_VERBOSE      1 — логировать запросы в stderr

Cache: cada execução faz no máximo um HTTP GET por endpoint dentro da janela de TTL. Com TTL=10 s, mesmo centenas de verificações de UserParameter por minuto resultam em ~6 requisições HTTP por minuto ao PSS.

Início rápido

Verificação de estado (códigos de saída no estilo Nagios):

pss-metrics.py health
# OK: total=42 running=15 stopped=27 unhealthy=0 version=1.12.2.430d

Descoberta LLD do Zabbix:

pss-metrics.py discover streams
pss-metrics.py discover inputs --running-only
pss-metrics.py discover outputs

Obtenção de uma única métrica (para uso em UserParameter do Zabbix):

pss-metrics.py get summary.running
pss-metrics.py get stream.10031.bitrate
pss-metrics.py get input.10031.1.speed1
pss-metrics.py get output.10031.1.speed
pss-metrics.py get sysmon.cpu.self-usage
pss-metrics.py get server.server-version

Exportação completa:

pss-metrics.py dump --format=json
pss-metrics.py dump --format=prometheus
pss-metrics.py dump --format=influx
pss-metrics.py dump --format=zabbix-trapper --zabbix-host=streamer-01

Caminhos das métricas

pss-metrics get aceita um caminho separado por pontos. Saída vazia significa «valor ausente» (por exemplo, a métrica só existe para fluxos em execução).

server.<attr>                например server.server-version, server.uptime
summary.<key>                total | running | stopped | unhealthy |
                             input_bitrate_kbps | output_bitrate_kbps
sysmon.cpu.<attr>            self-usage | total-usage | cores
sysmon.memory.<attr>         self-usage-kb | available-kb | total-kb
sysmon.netbw.<iface>.<attr>  rx-bw | tx-bw  (имя интерфейса как в XML)
stream.<id>.<attr>           любой атрибут <stream>
input.<sid>.<iid>.<attr>     любой атрибут <input>
output.<sid>.<oid>.<attr>    любой атрибут <output>

Atributos úteis por fluxo (de /data/stream/detail):

stream:  state, state-str, bitrate, thread-usage, mpts
input:   speed1, recv-bytes, recv-packets, recv-err,
         stat-disc, stat-disc1, stat-scrambled, stat-scrambled1,
         health-state-good, health-status, check-status
output:  speed, sent-bytes, sent-packets, sent-err, uri, type

Integração com Zabbix

Dois cenários são suportados — escolha o que se adequa ao seu ambiente.

  1. UserParameter estático + LLD (agente Zabbix v1 / v2)

    Copie userparameter_pss.conf.example para /etc/zabbix/zabbix_agentd.d/pss.conf, reinicie o zabbix-agent e importe no servidor um template com protótipos LLD que utilizem as chaves pss.discover. Exemplos de associações:

    UserParameter=pss.discover[*],/opt/pss/monitoring/pss-metrics.py discover $1
    UserParameter=pss.get[*],/opt/pss/monitoring/pss-metrics.py get $1
    UserParameter=pss.health,/opt/pss/monitoring/pss-metrics.py health
    

    No servidor Zabbix:

    Ключ правила обнаружения:  pss.discover[streams]
    Ключи прототипов элементов: pss.get[input.{#STREAM_ID}.1.speed1]
                                pss.get[stream.{#STREAM_ID}.bitrate]
                                pss.get[summary.unhealthy]
    
  2. Trapper (push) por zabbix_sender

    Execute por temporizador (cron / systemd) e direcione a saída para um pipe:

    /opt/pss/monitoring/pss-metrics.py dump --format=zabbix-trapper \
        --zabbix-host="$(hostname)" \
      | zabbix_sender -z zabbix.example.com -i -
    

Integração com Prometheus

Duas opções.

  1. Textfile collector (recomendado para ambientes one-shot).

    Execute uma exportação periódica via systemd-timer ou cron:

    */1 * * * * /opt/pss/monitoring/pss-metrics.py dump --format=prometheus \
        > /var/lib/node_exporter/textfile_collector/pss.prom.$$ \
        && mv /var/lib/node_exporter/textfile_collector/pss.prom.$$ \
              /var/lib/node_exporter/textfile_collector/pss.prom
    

    O node_exporter disponibiliza o arquivo via –collector.textfile.directory.

  2. Scrape direto por meio de um pequeno wrapper (por exemplo socat + pss-metrics dump) ou qualquer proxy HTTP de terceiros à sua escolha.

Integração com Telegraf / InfluxDB

Telegraf inputs.exec:

[[inputs.exec]]
  commands = ["/opt/pss/monitoring/pss-metrics.py dump --format=influx"]
  interval = "10s"
  timeout  = "5s"
  data_format = "influx"

Para o parser JSON, use –format=json e configure data_format = «json» com os caminhos dos campos.

HTTPS e autenticação

Se o servidor web do PSS opera atrás de HTTPS ou é protegido por senha:

PSS_URL=https://streamer.example.com:8443 \
PSS_USER=monitor PSS_PASS=secret \
pss-metrics.py health

Certificados autoassinados: defina PSS_INSECURE=1 (não recomendado) ou informe PSS_CA_BUNDLE=/path/to/ca.pem.

Códigos de saída

pss-metrics segue a convenção do Nagios:

0  OK
1  WARNING       (например, у запущенных потоков unhealthy)
2  CRITICAL      (PSS недоступен)
3  UNKNOWN       (неверные аргументы / внутренняя ошибка)

get e dump produzem uma linha vazia e encerram com código 0 quando a entidade solicitada está ausente — isso corresponde à expectativa do Zabbix de que um valor vazio seja tratado como «NOT_SUPPORTED» e não como falha do agente.

Diagnóstico

pss-metrics.py -v health        # логировать каждый HTTP-запрос в stderr
pss-metrics.py --cache-ttl=0   # обойти кеш при отладке
rm -rf /run/pss-metrics         # очистить кеш

Let’s Encrypt e certbot para HTTPS

A partir da versão 1.9.2.340, o Perfect Streamer suporta renovação automática de certificados Let’s Encrypt para HTTPS no Web Server, HTTP Server e EPG Server.

Configuração do certbot para RHEL.

Limitação:

  • A porta TCP/80 deve estar livre e deve ser atribuído um IP público com nome de domínio público.

  • Todos os servidores HTTPS usam o mesmo nome de host (web server, http server, epg server).

Instalação do certbot (https://certbot.eff.org/instructions?ws=other&os=snap):

sudo yum install snapd
sudo systemctl enable --now snapd.socket
sudo ln -s /var/lib/snapd/snap /snap
sudo snap install certbot --classic

Configuração do certbot:

sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot certonly --standalone

Verificação do certbot:

sudo certbot renew --dry-run

Verificação do timer do certbot:

systemctl list-timers | grep certbot

No painel admin do Perfect Streamer, ative o HTTPS nos servidores (Web Server, HTTP Server, EPG Server).

Crie o script de hook (https://pstreamer.tv/distrib/scripts/cert_update.zip) e coloque-o no caminho:

/opt/pss/scripts/cert_update.sh

Ali, se necessário, indique o nome de domínio do host; por padrão é lido de /etc/hostname.

Tornar o arquivo executável.

chmod +x /opt/pss/scripts/cert_update.sh

Verificar a execução do script, não deve haver erros:

/opt/conf/scripts/cert_update.sh

As configurações HTTPS devem ser aplicadas; a mudança de status aparecerá nos logs.

Adicionar arquivo de hook ao certbot:

certbot renew --deploy-hook "/opt/conf/scripts/cert_update.sh"

Verificar o certbot novamente:

sudo certbot renew --dry-run

Configuração do certbot para Debian/Ubuntu.

A configuração no Debian é análoga ao RHEL; descrição breve no exemplo de Ubuntu 24.04.2 LTS.

Instalação do certbot:

apt install certbot
certbot certonly

Tornando o script executável:

chmod +x /opt/pss/scripts/cert_update.sh

Executando o script:

/opt/pss/scripts/cert_update.sh

Emite:

Select domain name (your domain name)

Verificar se os certificados foram renovados:

ls -lat /opt/pss/config/cert/
total 44
-rw------- 1 root root  241 May 26 07:52 epgserver.key
-rw------- 1 root root  241 May 26 07:52 httpserver.key
-rw------- 1 root root  241 May 26 07:52 webserver.key
-rw-r--r-- 1 root root 1338 May 26 07:52 epgserver.crt
-rw-r--r-- 1 root root 1338 May 26 07:52 httpserver.crt
-rw-r--r-- 1 root root 1338 May 26 07:52 webserver.crt

A data deve ser atual.

Adaptadores DVB

Perfect Streamer suporta qualquer adaptador DVB instalado no sistema. Padrões suportados: DVB-S, DVB-S2, DVB-T, DVB-T2, DVB-C, ATSC. Adicionalmente implementados: desencapsulamento T2-MI (ETSI TS 102 773) e descodificação BISS-1 / BISS-E.

A condição principal é um controlador de adaptador corretamente instalado e em funcionamento no sistema.

A secção DVB aparece apenas se o sistema possuir adaptadores DVB válidos. A reconfiguração em tempo de execução não é suportada; é necessário reiniciar o streamer.

Ligação do adaptador

Para adicionar um novo adaptador DVB, aceda à secção correspondente e adicione o adaptador:

  • Definir o nome do adaptador.

  • Selecionar um adaptador da lista dos disponíveis no sistema.

  • Selecionar o modo Stream.

  • Especificar o tipo de sistema de transmissão: DVB-S, DVB-S2, DVB-T, DVB-T2, DVB-C.

  • Especificar os parâmetros de receção: Frequência da portadora, Polarização, Taxa de símbolo, FEC, Modulação, ID do fluxo DVB, Frequência do oscilador, Oscilador da banda alta, Limite da banda alta, Modo DiSEqC 1.0 e outros parâmetros consoante o tipo.

Opcionalmente pode ativar-se o registo de EIT na base de dados EPG (Registar EIT na BD EPG).

Repetir a adição para cada adaptador presente no sistema.

Varredura DVB

Para evitar introduzir manualmente os parâmetros de receção (frequência, polarização, taxa de símbolo, FEC, modulação), o Perfect Streamer integra um scanner de transponders. O scanner percorre os transponders do satélite selecionado (DVB-S/S2) ou da banda regional (DVB-C, DVB-T/T2), efetua a sintonização e a captura de cada um, recolhe as tabelas PSI/SI (PAT, PMT, SDT) e constitui a lista final de multiplex com os respetivos programas. Qualquer multiplex encontrado pode ser adicionado à lista de adaptadores DVB com um único botão.

O scanner utiliza o adaptador físico na sua totalidade; para o iniciar é necessário um adaptador que não esteja a ser utilizado pelo kernel do sistema operativo nem por qualquer entrada de adaptador DVB ativa no Perfect Streamer.

Свободные адаптеры

Ao abrir o ecrã de varredura no painel de administração, é apresentada uma lista dos adaptadores DVB físicos do sistema com o respetivo estado de ocupação:

  • free — o adaptador está disponível para varredura.

  • kernel — o dispositivo está retido por outro processo do sistema operativo.

  • pss-id-N — o adaptador já está a ser utilizado por uma entrada de adaptador DVB no Perfect Streamer com o identificador indicado. Não é possível iniciar o scanner nele enquanto essa entrada estiver ativa. Para libertar o adaptador temporariamente, a entrada de adaptador DVB existente deve ser colocada em pausa (o indicador Pause nas suas definições).

Listas de transponders

O scanner baseia-se em listas de referência no formato Enigma2: a lista de satélites satellites.xml e as listas regionais cables.xml / terrestrial.xml. Cada ficheiro contém um conjunto de transponders para uma posição orbital conhecida ou para uma banda regional DVB-T/C (para mais detalhes, consulte o site do projeto oe-alliance-tuxbox-common).

Os ficheiros encontram-se no diretório sat/ relativo a pss.json (por predefinição /etc/pss/sat/). São fornecidos com a distribuição do Perfect Streamer e são carregados ao abrir o ecrã de varredura. Quando necessário, podem ser atualizados substituindo o ficheiro XML correspondente.

No painel de administração, as listas de referência são apresentadas em três listas:

  • Satélite — posições orbitais (por exemplo, Hot Bird 13.0°E, Astra 19.2°E).

  • Região cabo — país ou fornecedor DVB-C.

  • Região terrestre — região DVB-T/T2.

Se o satélite ou a região pretendidos não estiverem presentes nas listas de referência, é possível atualizar o XML ou utilizar em alternativa a varredura cega (ver abaixo).

Início

Na caixa de diálogo de varredura, definem-se sequencialmente os seguintes elementos:

  • Um adaptador físico livre.

  • Тип delivery system: DVB-S, DVB-S2, DVB-T, DVB-T2 или DVB-C.

  • Fonte:

    • para DVB-S/S2 — uma posição orbital da lista de satélites e os parâmetros LNB (frequências do oscilador local LO1 e LO2, limite da banda superior, porta DiSEqC);

    • para DVB-C — uma região cabo;

    • para DVB-T/T2 — uma região terrestre.

Após premir Iniciar, a varredura é executada em segundo plano. O progresso é apresentado no painel de administração:

  • a percentagem de progresso baseada no número de transponders processados;

  • a frequência e a polarização atuais;

  • os contadores Multiplex encontrados e Programas encontrados;

  • uma árvore dos multiplex já encontrados, expansível até aos programas.

O scanner é um recurso partilhado em todo o streamer: executa-se no máximo uma varredura de cada vez. Se for iniciada uma nova varredura enquanto outra está em curso, a anterior é automaticamente cancelada. O botão Cancelar interrompe a varredura e limpa a lista acumulada.

A duração da varredura depende do número de transponders na lista de referência selecionada (tipicamente até 5 segundos por transponder: até 2 segundos para o bloqueio do sinal e até 5 segundos para a recolha das PSI). Valores típicos:

  • DVB-S Hot Bird 13.0°E — cerca de 2 minutos (44 transponders).

  • DVB-S Astra 19.2°E — cerca de 1,5 minutos.

  • DVB-T região europeia — menos de um minuto.

Resultado

O resultado da varredura é apresentado como uma árvore multiplex → programas.

Parâmetros do multiplex:

  • frequência, polarização, taxa de símbolo;

  • FEC, modulação, delivery system;

  • identificador do fluxo de transporte (TSID);

  • as leituras do frontend no momento em que termina a recolha das PSI — SNR, Signal, BER;

  • os contadores pmt-total / pmt-recv — quantas tabelas PMT foram anunciadas pela PAT e quantas foram efetivamente recolhidas dentro do tempo limite.

Параметры программы:

  • PNR (program_number) — o identificador do serviço dentro do multiplex;

  • Nome e Fornecedor — obtidos da tabela SDT, em UTF-8;

  • scrambled — o indicador de codificação. A sua origem é determinada pela seguinte ordem: o bit free_CA_mode da SDT (declaração do broadcaster) → os indicadores de codificação de transporte da PMT. Se nem a SDT nem a PMT chegarem dentro do tempo limite, o valor predefinido é 0 («não codificado»); o estado real é apurado quando se tenta a receção;

  • video-pid, audio-pid, pcr-pid — os principais fluxos elementares do serviço.

Aplicação do resultado

O multiplex selecionado na árvore é adicionado à lista de adaptadores DVB com um único botão. É criada uma nova entrada com os parâmetros do resultado da varredura (frequência, polarização, taxa de símbolo, FEC, modulação, delivery system) juntamente com os parâmetros LNB e o par adapter/device especificados no arranque da varredura. O nome do adaptador é definido pelo utilizador; os parâmetros adicionais (chaves BISS para canais codificados, T2-MI, LNB partilhado, etc.) são preenchidos após a criação da entrada, nas suas definições.

Os programas dos multiplex encontrados são aplicados em separado — criando um fluxo (Stream) com uma fonte de entrada demuxer endereçada pelo PNR (ver a secção Ligação de um fluxo SPTS a um serviço de multiplex DVB).

Varredura cega

O modo cego é utilizado quando:

  • o satélite pretendido não consta das listas de referência (posição orbital não normalizada, uplink local);

  • as listas de referência regionais DVB-T/C são insuficientes ou estão desatualizadas para uma localização específica;

  • é necessário reverificar um troço da banda independentemente da lista de transponders conhecidos.

Neste modo, o scanner não consulta as listas de referência; sintetiza uma lista de transponders a partir de uma grelha de frequências. Por predefinição, são utilizadas as seguintes gamas típicas:

  • DVB-S/S2 Ku — 10700..12750 MHz, passo de 4 MHz, ambas as polarizações (H e V), taxas de símbolo típicas 22000 / 27500 / 30000 ksym/s.

  • DVB-C — 47000..862000 kHz, passo de 8000 kHz, QAM-64 e QAM-256, taxas de símbolo típicas 6875 / 6900 / 6952 ksym/s.

  • DVB-T/T2 — 174000..862000 kHz, passo de 8000 kHz.

Uma varredura cega completa da banda Ku demora cerca de 100 minutos (vários milhares de pontos de sintonização). Na prática, o intervalo é restringido manualmente no painel de administração — frequência mínima/máxima e passo da grelha. Por exemplo, uma varredura de 11700..11800 MHz com passo de 4 MHz para uma única banda LNB demora cerca de 5 minutos.

O formato do resultado de uma varredura cega é idêntico ao de uma varredura normal. Particularidades:

  • os campos FEC e Modulação dos multiplex encontrados ficam fixados no valor AUTO — o scanner não determina os seus valores exatos;

  • o delivery system é igual ao solicitado (DVB-S, DVB-S2, …). Para redes mistas, recomenda-se efetuar duas passagens — DVB-S e DVB-S2 em separado.

A aplicação de um multiplex proveniente de uma varredura cega é efetuada da mesma forma que num caso normal — através do botão que o adiciona à lista de adaptadores DVB. Os campos FEC e Modulação são geralmente deixados em AUTO e, se necessário, afinados após um bloqueio estável do sinal no transponder em causa.

Tamanho do buffer de receção do kernel

O parâmetro buffer-size (inteiro, valor predefinido 512) define o tamanho do buffer circular DVB demux do kernel em blocos de 65536 bytes.

  • 512 (32 MB) — valor predefinido recomendado. Cobre cenários DVB-S/S2 de transponder completo (>= 33 Mbit/s) com um ou vários consumidores MPTS. Selecionado com base em testes de bancada com um adaptador TBS sob carga total do transponder.

  • 8...64 (512 KB … 4 MB) — aceitável para sistemas embarcados com RAM limitada ou para adaptadores nos modos Scanner / Femon onde o tráfego é baixo.

  • 0 — manter o valor predefinido do controlador (normalmente 8…32 KB). Adequado apenas para cenários com muito pouca carga. Acima de 10 Mbit/s haverá perdas.

Quando uma mensagem da seguinte forma aparecer no registo:

DVB adapter X/Y dvr buffer overflow (NN so far, KK pids);
raise 'buffer-size' or reduce pid filter

aumentar buffer-size ou reduzir o número de PIDs que passam pelo filtro (por exemplo, eliminar a saída MPTS se não for necessária).

Custo de memória: o valor N consome N × 64 KB de memória do kernel por adaptador. Com muitos adaptadores (8 ou mais) convém tê-lo em conta (8 × 32 MB = 256 MB).

Ligação de um fluxo SPTS a um serviço de multiplex DVB

Ao adicionar um novo canal SPTS ao input do fluxo, selecionar:

  • Tipo: demuxer.

  • Fonte: adaptador DVB.

  • Multiplex criado no adaptador DVB, por nome do adaptador.

  • PNR — selecionado a partir da lista emergente de serviços detetados no multiplex ou introduzido manualmente.

Permissões de acesso aos dispositivos DVB

Se os adaptadores DVB não forem apresentados no Perfect Streamer, executar as seguintes ações:

sudo nano /etc/udev/rules.d/99-dvb-permissions.rules
SUBSYSTEM=="dvb", GROUP="video", MODE="0660"

sudo usermod -aG video pss
sudo chown -R root:video /dev/dvb/*
sudo reboot

Desencapsulamento T2-MI

T2-MI (T2-Modulator Interface, ETSI TS 102 773) é um formato para transportar fluxos DVB-T2 sobre DVB-S2 multistream. O transponder externo DVB-S/S2 transporta um ou mais T2-MI carrier-PIDs, cada um encapsulando BBFRAMEs com um ou mais PLPs (Physical Layer Pipe). Após o desencapsulamento, extrai-se do BBFRAME o MPEG-TS interno contendo os programas e as tabelas PSI/SI.

A implementação Perfect Streamer funciona no modo multi-carrier: um único adaptador físico entrega simultaneamente o multiplex DVB-S/S2 externo e todos os carriers T2-MI desencapsulados (um por cada carrier-PID encontrado no PMT do fluxo externo).

Parâmetros de configuração

t2mi-mode (Int, 0..2, valor predefinido 0) — modo de desencapsulamento:

  • 0 — Desativado. O MPEG-TS externo é transmitido sem processamento. Se for detetado um descritor T2-MI (tag 0x51) no PMT, é registada uma dica única.

  • 1 — Manual. O desencapsulamento está sempre ativo. Se t2mi-pid não for 0, é pré-criado um carrier nesse PID no arranque. Os carriers adicionais continuam a ser detetados automaticamente a partir do PMT.

  • 2 — Auto. Os carriers são detetados automaticamente a partir do PMT do multiplex externo para todos os ES que pareçam T2-MI (descritor 0x51 ou único ES com stream_type=0x06 num serviço sem outros ES A/V). Se não forem encontrados carriers, o adaptador funciona como um multiplex DVB normal.

t2mi-pid (Int, 0..8191, valor predefinido 0) — PID para pré-criar um carrier no arranque, antes da chegada do PMT:

  • 0 — sem pré-criação. Os carriers são detetados a partir do PMT (recomendado para o modo auto 2).

  • 1..8191 — pré-criar um carrier neste PID. Os T2-MI ES adicionais encontrados no PMT obtêm igualmente os seus próprios carriers.

No modo multi-carrier o parâmetro t2mi-pid não é um seletor de um único carrier — cada ES T2-MI detetado obtém o seu próprio carrier com o seu próprio desencapsulador. O parâmetro disponibiliza inicialização antecipada para um PID conhecido.

t2mi-plp (Int, 0..255, valor predefinido 0) — identificador do PLP extraído de cada carrier T2-MI no adaptador. Aplica-se a todos os carriers — a substituição por carrier não é suportada na versão atual. Se em produção diferentes carriers transportarem diferentes PLPs, convém:

  • especificar um PLP comum a todos os carriers, ou

  • configurar adaptadores separados para diferentes PLPs através de lnb-sharing.

Este é o identificador do campo plp_id do BBFRAME, não o ISI multistream DVB-S2 (definido pelo parâmetro dvb-stream-id). São identificadores diferentes em camadas diferentes.

Diagnóstico de seleção PLP:

  • Cinco segundos depois do arranque de um carrier, se não tiver sido recebida nenhuma BBFrame para o PLP configurado mas se observarem outros PLPs, é registado um aviso com a lista dos plp_id observados.

t2mi-tsid (Int, -1..255, valor predefinido -1) — reservado para uso futuro. Seletor do identificador de fluxo T2-MI quando vários fluxos T2-MI partilham um mesmo carrier-PID. Ignorado na versão atual.

PNR composto — ligação SPTS a partir de T2-MI

Um adaptador pode expor vários multiplex lógicos:

  • carrier-id = 0 — multiplex DVB-S/S2 externo (serviços A/V normais).

  • carrier-id = 1..N — carriers T2-MI desencapsulados (um por cada ES T2-MI externo).

Descodificação BISS

É suportada a descodificação de fluxos DVB cifrados com BISS-1 (modo E1) e BISS-E (modo E2). Aplicável aos sistemas de transmissão DVB-S, DVB-S2, DVB-T, DVB-T2.

A implementação permite manter vários descodificadores ativos em simultâneo num mesmo adaptador:

  • Por PNR no multiplex externo (serviço normal).

  • Por plp_id para decifrar o carrier-PID T2-MI antes do desencapsulamento (necessário para fluxos multistream cifrados — caso contrário o desencapsulador descarta cada pacote cifrado, ver contador <t2mi scrambledDropped>).

EPG

Importação EPG/XMLTV

Os dados de EPG são coletados na EPG Database a partir de várias fontes:

  • EIT dos fluxos recebidos (SPTS e MPTS). Ativado pela configuração Stream: Extract EIT to EPG Database.

  • Import in XMLTV format from different external sources. Set in Configuration/EPG/EPG Sources. Supported sources EPG in the form of a link to a web resource and a local file, with the full path specified.

O tempo de armazenamento dos eventos do EPG é definido pelo parâmetro EPG storage period (days).

Auto-clean database — programas sem eventos são removidos.

Na seção EPG são exibidas as fontes de EPG e dados associados. Para cada canal (EPG Channels List) pode-se definir:

  • Channel Name — nome usado na exportação para o servidor XMLTV.

  • Time Zone — é possível ajustar o fuso horário se na importação ele não foi vinculado ao UTC.

  • EPG Channel Sets — vincular o canal a um Channel Set (veja abaixo).

  • Icon — URL do ícone do canal (http://example.com/mychannel/myicon.png).

Gerador de EIT

EIT data from EPG Database can be generated in SPTS Stream. To do this, set EPG Source ID and select EPG Channel ID in the Stream settings. In this case, SDT will be generated anyway, even if it is not in the source. Set the correct SDT Data.

Se este Stream for usado em um multiplexador, o Service Name pode ser redefinido separadamente no ajuste output/muxer.

Servidor EPG (XMLTV)

Um servidor HTTP integrado separado do Perfect Streamer entrega o XMLTV completo para um dado conjunto de canais. O endpoint é destinado a middleware e players que mantêm o guia localmente e o atualizam com pouca frequência, como arquivo inteiro — normalmente uma ou duas vezes por dia.

O servidor e seus clientes são configurados em Configuration/EPG/EPG Server.

URL e autenticação

O serviço é atendido por um servidor HTTP separado epg-server (não o de /data/*). Por padrão, ele escuta nas portas 10444 (HTTP) e 10445 (HTTPS); portas e SSL são configurados em /config/epg-server.

Rotas:

URL

Content-Type

Comportamento

GET /xmltv

text/xml

Com Accept-Encoding: gzip a resposta é comprimida em tempo real (Content-Encoding: gzip); caso contrário, é entregue como XML sem compressão.

GET /xmltv.gz

application/octet-stream

Sempre retorna um fluxo gzip com Content-Disposition: inline; filename="xmltv.xml.gz" — prático para salvar como arquivo.

São suportados três métodos de autenticação:

  • HTTP Digest (preferencial) — conta em /config/epg-server/login.

  • Parâmetros na URL?l=<login>&p=<password> (sinônimos: login=…, password=…).

  • Loopback — uma solicitação de 127.0.0.1 é tratada anonimamente. Útil para scripts implantados na mesma máquina.

Aviso

Um login e senha na URL acabam nos access-logs do reverse-proxy e no histórico do navegador. Para distribuição pública do XMLTV, use HTTP Digest ou aceite solicitações apenas de endereços privados.

Acesso por channel-set

Cada conta epg-server/login está vinculada a um único channel-set em /config/epg-channel-set. O EPG retornado contém apenas os canais desse grupo. Isso permite que uma mesma instalação do PSS forneça XMLTV distintos para diferentes operadoras/middleware.

Configuração básica na IU:

  1. Em Configuration/EPG/EPG Channel Sets, crie um grupo de canais e atribua os canais desejados nas fontes EPG.

  2. Em Configuration/EPG/EPG Server Clients, crie uma conta e vincule o grupo criado a ela. Sem vínculo de channel-set, o cliente recebe um XMLTV vazio.

Restrições adicionais para um login:

  • ip-addr — se definido e não for curinga, uma solicitação de outro IP recebe 403 Forbidden.

  • limit-day — Unix epoch em s, após o qual a conta deixa de ser atendida (403 Forbidden). Útil para um modelo de assinatura.

  • pause — desativar temporariamente um login sem excluí-lo.

Formato da resposta

O corpo da resposta é um documento XMLTV com raiz <tv>. A estrutura segue o esquema XMLTV DTD habitual:

<?xml version="1.0" encoding="utf-8"?>
<tv source-info-name="..." source-info-url="...">
  <channel id="ru.first">
    <display-name lang="ru">Первый</display-name>
    <icon src="https://.../first.png"/>
  </channel>
  ...
  <programme start="20260504060000 +0300"
             stop ="20260504070000 +0300"
             channel="ru.first">
    <title lang="ru">Утренние новости</title>
    <desc  lang="ru">Обзор событий за сутки</desc>
    <rating system="RU"><value>12+</value></rating>
  </programme>
  ...
</tv>

Notas sobre os campos:

  • Os atributos source-info-name e source-info-url da raiz <tv> são preenchidos a partir dos campos EPG Source Name e EPG Source URL em Configuration/EPG/EPG Server.

  • Os atributos start e stop seguem o formato YYYYMMDDhhmmss ±zone (o fuso horário é obtido do campo time_zone do canal).

  • Um <programme> pode conter vários <title>/<desc> para idiomas diferentes. O atributo lang fica vazio quando o identificador de idioma dos dados EPG de origem não pôde ser mapeado no dicionário (a entrada ainda aparece na saída).

  • Canais com channel_id em conflito (quando o mesmo id chega de várias fontes) aparecem uma vez; as fontes restantes são ignoradas com um aviso no log do servidor.

  • Somente eventos com stop_time >= now entram na saída.

Cabeçalhos HTTP

O servidor sempre envia:

Cache-Control: no-cache, no-store, must-revalidate
Pragma:        no-cache
Expires:       0
Connection:    close

Para /xmltv, adicionalmente — Content-Encoding: gzip quando Accept-Encoding: gzip está presente na solicitação. Para /xmltv.gzContent-Disposition: inline; filename="xmltv.xml.gz".

A proibição do cache do lado do cliente é intencional: o XMLTV muda a cada importação EIT ou refresh de fontes XMLTV externas, e o player não deve manter dados desatualizados indefinidamente. Um cache edge (nginx), porém, é perfeitamente aceitável — veja a seção sobre desempenho abaixo.

Cache do servidor e sua limpeza

O XMLTV pronto é armazenado em cache na memória do processo PSS:

  • Uma entrada por channel-set; ambas as variantes do corpo (raw e gzip) são guardadas — solicitações repetidas com Accept-Encoding: gzip ou /xmltv.gz não recomprimem os dados.

  • Cada entrada é marcada com um contador update-time. Qualquer atualização de EPG (importação EIT, refresh de fonte XMLTV) incrementa o contador, e o cache é reconstruído na próxima solicitação.

Limpeza forçada do cache:

POST /xmltv/reset-cache

A rota é atendida pelo servidor admin (porta 43971/43981), não pelo epg-server. Corpo vazio; a resposta é 200 OK com um envelope JSON.

Códigos de resposta HTTP

Código

Condição

200 OK

Solicitação processada. O corpo é um documento XMLTV (possivelmente um <tv></tv> vazio em caso de falha transitória da BD).

401 Unauthorized

Nem Digest nem os parâmetros l/p passaram na verificação (para solicitações não loopback).

403 Forbidden

O login existe, mas a solicitação não vem de um IP permitido, ou limit-day expirou.

404 Not Found

Qualquer URL além de /xmltv e /xmltv.gz.

405 Method Not Allowed

Método diferente de GET.

O corpo do erro é um envelope JSON de formato fixo:

{"status": 401, "message": "Unauthorized"}

Desempenho e escalabilidade

Cache do servidor

O cache do servidor atende solicitações repetidas a um mesmo channel-set sem acessar o SQLite — copiando o corpo já pronto.

Construir o XMLTV «do zero» (cache miss) é mais caro: para cada canal é feito um SELECT separado em channel_name e, para cada evento, em event_text e event_rating. Tempos de construção aproximados:

Tamanho da saída

Cache hit

Cache miss (build)

100 canais / dia

dezenas de ms

~0,5–1 s

500 canais / dia

~50 ms

2–5 s

1000+ canais / semana

~100–300 ms

5–15 s

Para a maioria dos middleware é aceitável buscar o XMLTV a cada algumas horas ou uma vez por dia.

Quando é preciso um reverse-proxy externo (nginx)

Ao contrário de /data/epg/channel (respostas JSON curtas), o XMLTV é um único documento grande por channel-set, ideal para um cache edge:

  • Dezenas a centenas de clientes por channel-set — o cache interno do PSS costuma ser suficiente se eles consultam o XMLTV de hora em hora ou uma vez por dia.

  • Milhares de clientes simultâneos — recomenda-se um reverse-proxy com cache. Servir um arquivo XMLTV a centenas/milhares de solicitações é, antes de tudo, uma carga de rede (centenas de KB a alguns MB por resposta) que é melhor retirar do PSS.

  • Entrega geograficamente distribuída — um CDN/cache edge é indispensável independentemente do número de clientes.

O PSS devolve Cache-Control: no-cache, portanto é preciso dizer explicitamente ao nginx para ignorar o cabeçalho do upstream e manter o próprio TTL.

Exemplo de configuração nginx

# /etc/nginx/conf.d/pss-xmltv.conf

proxy_cache_path /var/cache/nginx/pss-xmltv
                 levels=1:2
                 keys_zone=pss_xmltv:8m
                 max_size=4g
                 inactive=2h
                 use_temp_path=off;

upstream pss_epg {
    server 127.0.0.1:10444;
    keepalive 16;
}

server {
    listen 80;
    # listen 443 ssl http2;     # SSL termination разумно держать здесь
    server_name epg-files.example.com;

    # Не включаем gzip on: /xmltv.gz уже сжат, /xmltv получит
    # gzip-encoding от PSS, повторное сжатие бесполезно.

    location ~ ^/xmltv(\.gz)?$ {
        proxy_pass http://pss_epg;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # PSS отдаёт no-cache; кешируем на edge принудительно.
        proxy_ignore_headers Cache-Control Expires Set-Cookie;
        proxy_hide_header   Cache-Control;
        proxy_hide_header   Pragma;
        proxy_hide_header   Expires;

        # Ключ кеша = весь URL включая query (login/password в /xmltv?l=...&p=...)
        # дают разные ключи для разных учёток с разным channel-set.
        proxy_cache_key     "$scheme$host$request_uri";

        proxy_cache         pss_xmltv;
        proxy_cache_valid   200      30m;       # XMLTV меняется не часто
        proxy_cache_valid   401 403  1m;
        proxy_cache_lock           on;          # коалесцируем cache miss
        proxy_cache_lock_timeout   60s;         # build XMLTV может занимать секунды
        proxy_cache_use_stale      error timeout updating
                                   http_500 http_502 http_503;

        # Большой буфер: XMLTV для крупного channel-set может
        # достигать нескольких мегабайт.
        proxy_buffering      on;
        proxy_buffers        16 256k;
        proxy_buffer_size    256k;
        proxy_busy_buffers_size 1m;

        # Клиенту разрешим закешировать на короткий срок.
        add_header Cache-Control "public, max-age=600";
        add_header X-Cache-Status $upstream_cache_status always;
    }
}

Explicações e recomendações

  • TTL ``proxy_cache_valid 200 30m`` — o XMLTV raramente muda com frequência maior que a cada meia hora. Se a sincronização com as fontes ocorre uma vez por hora ou menos, dá para elevar para 1 hora ou mais; se a frescura após POST /xmltv/reset-cache importa, reduza.

  • ``proxy_cache_lock_timeout 60s`` — aumentado em relação a /data/epg/channel (onde 5 segundos é o usual), porque construir o XMLTV de um channel-set grande leva mais tempo.

  • Uma ``keys_zone`` dedicada — mesmo em uma instalação grande, as chaves XMLTV únicas são poucas (número de contas × channel-set); 8 MB são suficientes. max_size é dimensionado pelo volume de XMLTV, não pela quantidade de chaves.

  • gzip do lado do nginx é desnecessário: para /xmltv.gz a resposta já vem comprimida, e para /xmltv o próprio PSS responde com gzip-encoded quando Accept-Encoding: gzip está presente.

  • Terminação HTTPS no nginx oferece melhor desempenho com muitos handshakes TLS simultâneos.

Endpoints relacionados

  • POST /xmltv/reset-cache — limpeza forçada do cache XMLTV do servidor (no servidor admin 43971/43981).

  • POST /data/epg/update?s=<src_id> — atualização forçada de uma fonte XMLTV externa; após sucesso, o cache XMLTV do servidor é limpo automaticamente.

  • GET /data/epg/channel?… — saída EPG em JSON para um canal por um dia; veja a seção separada.

A lista completa e a descrição detalhada da API HTTP estão em manual/http_data_api.txt.

EPG para middleware OTT

O servidor fornece os dados do guia de programação (EPG) para o dia selecionado e para um único canal no formato JSON. O endpoint é destinado aos back-ends de middleware OTT que agregam a programação do Perfect Streamer para montar o guia no cliente final.

URL e autenticação

O endpoint é servido pelo servidor admin integrado. Por padrão está disponível nas portas 43971 (HTTP) e 43981 (HTTPS); as portas são configuradas em Settings/Server Settings.

GET /data/epg/channel?src=<src_id>&ch=<channel_id>&lang=<lang>&t=<time>

A autenticação é HTTP Digest, como para o restante de /data/*. Para o middleware, basta uma conta com o papel viewer (somente leitura).

Nota

Solicitações do endereço loopback (127.0.0.1) são executadas sem verificação HTTP Digest — o servidor as trata como anônimas. É conveniente para scripts locais e health-checks de middleware implantado na mesma máquina que o Perfect Streamer; para acessos remotos as credenciais são obrigatórias.

Parâmetros da solicitação

Parâmetro

Tipo

Obrigatório

Padrão

Descrição

src

inteiro sem sinal

não

0

Fonte EPG. 0 — dados importados do EIT MPEG-TS dos fluxos de entrada. 1, 2, — identificador de entrada em /config/epg/epg-source (fonte XMLTV externa).

ch

cadeia

sim

Identificador do canal na base EPG: valor do campo channel_id da tabela channel. A lista de identificadores disponíveis pode ser obtida por uma consulta SQL via POST /data/epg/sql.

lang

inteiro ou ISO 639

não

idioma padrão do sistema

0 — idioma padrão do sistema; um inteiro > 0 — identificador interno de idioma (veja GET /schema/lang); uma cadeia — código ISO 639 de duas ou três letras, p. ex. eng, rus, fra.

t

inteiro sem sinal (Unix epoch, s)

não

hora atual do servidor

Qualquer ponto dentro do dia de interesse. O servidor retorna eventos do dia UTC ao qual t pertence: intervalo [t / 86400 · 86400, (t / 86400 + 1) · 86400). Para obter dados do «dia seguinte», basta somar 86400 ao horário atual.

Nota

O dia é tomado em UTC, não no fuso local. Se o middleware monta a programação pelo dia calendário local, o limite do dia UTC pode não coincidir com a meia-noite local; nesse caso é preciso fazer duas solicitações (para dias UTC adjacentes) e juntar os resultados pelo campo start.

Formato da resposta

  • Content-Type: application/json.

  • Os cabeçalhos HTTP proíbem o cache no lado do cliente e em proxies intermediários:

    Cache-Control: no-cache, no-store, must-revalidate
    Pragma: no-cache
    Expires: 0
    
  • O corpo da resposta é um JSON com a lista de eventos do dia:

{
  "event": [
    {"start": 1715000000, "end": 1715003400, "title": "Утренние новости", "desc": "Обзор событий за сутки"},
    {"start": 1715003400, "end": 1715007000, "title": "Прогноз погоды",   "desc": ""}
  ]
}

Campos do evento:

  • start, end — início e fim do programa em Unix epoch (s), UTC.

  • title — título do programa no idioma escolhido. Se o título no idioma solicitado não existir para o evento, o servidor recorre à entrada no idioma padrão do sistema e, depois, em qualquer outro disponível.

  • desc — descrição estendida. Pode ser uma cadeia vazia se a base não tiver descrição separada para o evento.

Particularidades da saída:

  • Eventos com título vazio e sem descrição, assim como aqueles com timestamps inválidos, são excluídos da saída.

  • Os duplicados por start são descartados: para o mesmo momento de início é retornada uma única entrada com a melhor prioridade de idioma (solicitado → padrão do sistema → demais).

  • A ordem dos eventos no array não é garantida — se necessário, o middleware ordena a lista pelo campo start por conta própria.

  • Se o canal não for encontrado, se a fonte não existir ou se não houver eventos para o dia escolhido, o servidor retorna 200 OK com o array vazio {"event":[]} ou, no caso raro de fonte ausente, com corpo vazio. O middleware deve tratar corretamente as duas variantes.

Cache no servidor

O JSON pronto é armazenado em cache pelo servidor sob a chave (channel_id, data UTC, idioma), de modo que solicitações repetidas para o mesmo dia e canal são atendidas sem acessar o banco de dados. O middleware não precisa gerenciar o cache.

O cache é limpo automaticamente:

  • quando chegam novos eventos do EIT MPEG-TS dos fluxos de entrada (src=0);

  • ao atualizar com sucesso uma fonte XMLTV externa (src > 0 — agendada ou forçada via POST /data/epg/update?s=<src_id>);

  • quando um dia sai da janela de retenção do EPG.

Um endpoint dedicado para a limpeza forçada do cache não está previsto nem é necessário.

Códigos de resposta HTTP

Código

Condição

200 OK

Solicitação processada. O corpo é um JSON com a lista de eventos (possivelmente vazia).

400 Bad Request

O parâmetro ch está ausente ou vazio; ou src, t não são analisáveis como inteiro sem sinal; ou um lang numérico aponta para um identificador de idioma inexistente.

401 Unauthorized

A autenticação HTTP Digest está ausente ou incorreta (para solicitações que não vêm de um endereço loopback).

Outras situações (src desconhecido, canal ausente, sem eventos no dia) não geram 4xx — o middleware recebe 200 OK com o array vazio {"event":[]}.

Em caso de erro, o corpo da resposta é um envelope JSON de formato fixo:

{"status": 400, "message": "Bad Request"}

O campo status duplica o código HTTP; o campo message traz a causa refinada do erro em inglês (ou o texto padrão do status HTTP, se não houver informação adicional). O Content-Type da resposta de erro é application/json.

Exemplo

curl -u middleware:secret --digest \
  'http://pss.example.com:43971/data/epg/channel?src=0&ch=12.0.1&lang=rus&t=1715000000'

Exemplo de resposta:

{
  "event": [
    {"start": 1715000000, "end": 1715003400, "title": "Утренние новости", "desc": "Обзор событий за сутки"},
    {"start": 1715003400, "end": 1715007000, "title": "Прогноз погоды",   "desc": ""}
  ]
}

Desempenho e escalabilidade

Cache do servidor Perfect Streamer

Dentro do processo PSS há um cache LRU de respostas em memória com chave (channel_id, data UTC, idioma) e teto rígido de 1024 entradas por fonte EPG. Sob carga típica (dezenas a centenas de canais × 1–3 idiomas × keep-day dias) todas as entradas atuais cabem inteiras no cache; solicitações repetidas são atendidas sem acessar o SQLite.

Ordem de grandeza (build de depuração, loopback local, sem HTTPS):

Cenário

Latência (solicitação única)

Vazão (P=8)

Cache hit

~0,3 ms

~1100 solicitações/s

Cache miss (SQL + JSON)

~1,0–1,5 ms

~1000 solicitações/s

Em um build de release e sem logging de depuração, os números ficam cerca de 2–3× melhores. Bandwidth — cerca de 14 KB por resposta para um canal-dia típico.

Quando é preciso um reverse-proxy externo (nginx)

O cache do servidor acelera solicitações repetidas para o mesmo (canal, dia, idioma), mas cada solicitação ainda passa pelo servidor HTTP integrado do PSS e consome um thread do seu pool. Com muitos clientes faz sentido mover o cache para o edge:

  • até ~1.000 clientes online — o cache interno costuma ser suficiente, reverse-proxy não é obrigatório.

  • dezenas de milhares ou mais — recomenda-se um reverse-proxy com cache (por exemplo, nginx). Um cache edge atende 99 % das solicitações sem o PSS, amortiza picos (start do middleware, refresh em massa do player) e permite mover a terminação SSL para um nó separado.

  • entrega geograficamente distribuída — um CDN/proxy externo é necessário antes mesmo de contar os clientes.

O PSS envia o próprio cabeçalho Cache-Control: no-cache, no-store, must-revalidate para que os clientes finais não armazenem o EPG por muito tempo. Já o reverse-proxy pode (e deve) cachear a resposta sozinho — abaixo mostra-se como informar explicitamente ao nginx que ignore o Cache-Control do upstream e mantenha o próprio TTL.

Exemplo de configuração nginx

Configuração mínima para um cache edge de EPG dimensionada para dezenas de milhares de clientes com intervalo de polling de 1–5 minutos:

# /etc/nginx/conf.d/pss-epg.conf

proxy_cache_path /var/cache/nginx/pss-epg
                 levels=1:2
                 keys_zone=pss_epg:32m
                 max_size=2g
                 inactive=30m
                 use_temp_path=off;

upstream pss_admin {
    server 127.0.0.1:43971;
    keepalive 64;
}

server {
    listen 80;
    # listen 443 ssl http2;  # рекомендовано: SSL termination здесь
    server_name epg.example.com;

    # gzip помогает: типовой EPG-JSON жмётся ~5–8x.
    gzip on;
    gzip_types application/json;
    gzip_min_length 512;
    gzip_proxied any;

    location = /data/epg/channel {
        proxy_pass http://pss_admin;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # PSS отдаёт no-cache; кешируем на edge принудительно.
        proxy_ignore_headers Cache-Control Expires Set-Cookie;
        proxy_hide_header   Cache-Control;
        proxy_hide_header   Pragma;
        proxy_hide_header   Expires;

        # Ключ кеша = весь URL с query string. Параметры src/ch/lang/t
        # уже определяют уникальность ответа.
        proxy_cache_key     "$scheme$host$request_uri";

        proxy_cache         pss_epg;
        proxy_cache_valid   200 60s;          # время устаревания
        proxy_cache_valid   400 404 10s;
        proxy_cache_lock           on;        # коалесцируем cache miss
        proxy_cache_lock_timeout   5s;
        proxy_cache_use_stale      error timeout updating
                                   http_500 http_502 http_503;

        # Отдадим клиенту результат в JSON, но с собственным TTL
        # (плеер пересмотрит EPG не раньше этого срока).
        add_header Cache-Control "public, max-age=60";
        add_header X-Cache-Status $upstream_cache_status always;
    }
}

Explicações e recomendações

  • TTL ``proxy_cache_valid 200 60s`` — compromisso entre frescura do EPG e carga no upstream. A programação não muda em tempo real, então 30–300 segundos são razoáveis. Após importar novos eventos, o PSS limpa o próprio cache imediatamente, e o cache edge alcança no próximo TTL.

  • ``proxy_cache_lock on`` é obrigatório com muitos clientes: em um cache miss, ele coalesce solicitações paralelas para a mesma chave em uma única solicitação upstream, protegendo o SQLite de picos de BUSY sob carga.

  • ``keys_zone`` e ``max_size`` são dimensionados pelo número de (canal × dia × idioma): 32 MB de keys_zone cobrem centenas de milhares de chaves; 2 GB de max_size cobrem um mês de histórico para centenas de canais com folga.

  • gzip reduz significativamente o tráfego: as respostas comprimem bem (chaves JSON repetidas, cirílico em UTF-8).

  • ``X-Cache-Status`` na resposta permite que o middleware veja HIT/MISS/EXPIRED e avalie a eficácia do cache.

  • Se nginx e PSS coabitam na mesma máquina, o servidor admin não exige HTTP Digest para loopback, portanto o bloco upstream pode ficar sem proxy_set_header Authorization . Para distribuir por redes diferentes, crie uma conta viewer dedicada e adicione autenticação Digest em proxy_pass.

  • HTTPS é melhor terminado no nginx: o PSS suporta HTTPS diretamente, mas um servidor edge costuma ser mais eficiente para lidar com handshakes TLS de milhares de clientes simultâneos.

Endpoints relacionados

  • POST /data/epg/sql?s=<src_id> — consulta SQL arbitrária ao banco EPG (em especial, para obter a lista de channel_id).

  • POST /data/epg/update?s=<src_id> — atualização forçada de uma fonte XMLTV externa.

A lista completa e a descrição detalhada da API HTTP estão em manual/http_data_api.txt.

Otimização do programa

Se com muitos stream houver problemas de alta carga de CPU ou falta de memória, é possível otimizar as configurações.

You can disable the MPEG-TS filtering and processing features if you don’t need to.By default, the stream has the Clean All Unnecessary Data function enabled, disable it if there is no unwanted data in the stream. Disabling these features completely will remove the Original Media Information section of the Report.

Desativar completamente ou alterar as configurações de Mosaic. A desativação completa pode ser feita nas configurações do servidor. É possível desativá-lo individualmente para cada stream ou alterar o intervalo de atualização pela configuração Check Interval.

Erros de queue overload para as bases DBStat e DBEPG

Ocorrem quando o desempenho dos bancos de dados é insuficiente — disco lento ou sistema sobrecarregado.

O local dos bancos de dados é definido pelo parâmetro data-dir no arquivo de configuração pss.properties

Possíveis soluções:

  1. Mover os arquivos de banco de dados para /tmp. Será utilizada a memória do sistema, o que requer estimativa de memória livre disponível e ajuste do tempo de armazenamento das estatísticas (ver configurações do servidor). Ao reiniciar o sistema, os dados serão perdidos.

  2. Reduzir o detalhamento das estatísticas — ver o parâmetro dbstat-detail. Por padrão 5 s; pode ser aumentado até 20.

  3. Colocar o banco de EPG em memória — definir dbepg-memory=true.

Transcodificadores

Os transcodificadores são implementados como binários executáveis separados, iniciados pelo pstreamer como processos independentes.

Suporta configurações 1toN: a partir de um decoder é possível gerar vários fluxos com configurações diferentes de encoder.

O fluxo de origem deve conter vídeo e áudio; variantes sem vídeo ou sem som não são suportadas.

Codecs implementados:

  • Video SW decoder: mpeg2, h.264, hevc (h.265)

  • Video NW decoder: mpeg2, h.264, hevc (h.265)

  • Video SW encoder: mpeg2, h.264, hevc (h.265)

  • Video NW encoder: h.264, hevc (h.265)

Fluxos entrelaçados são suportados na entrada e na saída.

Para os decoders H.264 e HEVC, há suporte ao interlace alternate (dois campos separados no fluxo); é convertido em interlace interleaved.

O decoder HEVC suporta o perfil Main10 com bt.709 (SDR) e bt.2020 (HDR). O encoder HEVC sempre usa o perfil Main com bt.709.

Para os decoders H.264 e HEVC há suporte ao VBR (Variable Frame Rate); ele é convertido para frame rate constante.

  • Audio decoder - mpeg (layer 1,2,3), aac, ac3

  • Audio encoder - mpeg (layer 2), aac

Existe o modo de transcodificação Video Passthrough — o vídeo não é transcodificado, apenas o áudio; é usado o transcodificador SW.

Nota

Para a transcodificação configure dois ou mais streams, com output (decoder) e input (encoder).

Para configurar uma instância do transcodificador é necessário:

  • Fonte — adicionar no stream output transcoder (decoder). Nas configurações escolha o tipo: SW, NV ou Video Passthrough.

  • Fluxo de saída — adicionar no stream input transcoder (encoder); nas configurações selecionar a fonte-decoder.

  • Repita se forem necessários vários fluxos de saída para um mesmo decoder.

Configurações do transcodificador de saída (decoder)

  • Convert colors to BT.709 — conversão dos formatos SD BT.470-2 (PAL) e SMPTE 170M (NTSC) para BT.709

  • Trace — ativar para diagnóstico o log detalhado do transcodificador.

Para o funcionamento correto do transcodificador, o fluxo de origem deve atender a determinados requisitos; em alguns casos isso pode ser corrigido. Estas configurações não convertem o fluxo — atuam como dicas para o funcionamento correto do transcodificador.

Para corrigir os dados do fluxo de entrada existem as configurações:

  • Fix PAR — corrigir o Pixel Aspect Ratio. É indicado como fração N/D; por exemplo, 16/9 para Wide SD.

  • Fix Framerate — especificar explicitamente o framerate. Em alguns fluxos o framerate pode estar ausente no SPS e o log do transcodificador apresentará o erro correspondente. Nesses casos é necessário indicar o framerate manualmente. É indicado como fração N/D.

Exemplos de valores de framerate:

  • PAL - 25/1

  • NTSC — 30/1 ou 30000/1001

  • Cinema — 24/1 ou 24000/1001

Configurações do transcodificador de entrada (encoder)

  • Encoder Type — codec de vídeo.

  • Align Total Bitrate — taxa de bits do stuffing do fluxo (preenchimento com pacotes null). É importante defini-la se o fluxo for usado para transmissão DVB. A taxa de bits deve ser garantidamente maior que a do vídeo e a de todas as trilhas de áudio.

  • Video Profile — para H.264 é possível escolher o perfil de codificação.

  • Video Bitrate — taxa de bits do fluxo de vídeo em kbps. A codificação é sempre CBR; a taxa total será maior por causa das trilhas de áudio.

  • Speed Preset — predefinições de codificação, valores de 1 a 7. Menor valor = maior qualidade e mais recursos. Padrão 4.

  • GOP Interval — intervalo em frames para o GOP (equivale ao Key Frame Interval). Padrão 25 (1 segundo a 25p); recomendado quando os players iniciam aleatoriamente.

  • BFrame — ativar para melhorar a qualidade. Valor recomendado: 3.

  • Lookahead — ativar para melhorar a qualidade. Valor recomendado: 20–50 frames.

  • Resize — redimensionamento da imagem.

  • Deinterlace — converte interlace em progressivo.

A inserção de crop (bordas vazias na imagem) não é suportada. Tamanhos de imagem arbitrários não são permitidos para não distorcer proporções.

Para resize estão disponíveis as opções:

  • Reduzir proporcionalmente o tamanho em 2 e 4.

  • Definir o formato Wide SD 16:9, será aplicada a Aspect Ratio adequada.

  • Upscale SD→HD. Aplica-se a fontes SD PAL/NTSC. O interlace não é suportado; aplique deinterlace antes se necessário.

  • Definir a largura. A altura será recalculada proporcionalmente.

  • Definir a altura. A largura será recalculada proporcionalmente.

Alguns parâmetros podem ser incompatíveis com o transcodificador escolhido; os erros aparecem nos logs dele.

Processamento de áudio

Por padrão todas as trilhas de áudio passam do input para o output sem processamento. Trilhas desnecessárias podem ser removidas com os filtros de PID do stream.

Para transcodificar áudio, configure regras separadas por codec. A opção skip — remover a trilha de áudio com esse codec.

Se no fluxo de saída não houver trilhas de áudio, ocorrerá um erro — consulte os logs do transcodificador.

Geração de PCR e TR 101 290.

O multiplexador MPEG-TS gera um novo PCR. Com Align Total Bitrate correto (maior que a soma dos bitrates de vídeo e áudio), o PCR deve passar na conformidade TR 101 290.

Status dos transcodificadores

Em caso de problemas no funcionamento do transcodificador (não há fluxo do encoder), consulte os logs na seção Transcoders — é exibida a lista de instâncias (cada linha é uma instância separada, decoder + N encoders); ao clicar na instância desejada, abre-se a janela de status dos logs. São exibidos o log atual e o log da execução anterior. Para log detalhado, ative trace nas configurações do output (decoder).