×

📺 IPTV

B2C · Xtream · Reseller

Gerenciar Usuários IPTV

Camadas de Armazenamento de Arquivo

Sistema de arquivo em três camadas para 500+ clientes simultâneos. Configure em Config > Armazenamento > Camadas de Armazenamento. Cada camada tem ciclo de vida, cálculo de capacidade e comportamento de fallback independentes.

Codificador

Buffer de Escrita

Janela quente de 2h (NVMe ou tmpfs)

→ espelhar (contínuo)

HDD RAID 5

50 TB, retenção de 14 dias

→ pré-buscar sob demanda

Cache de Reprodução

1 TB de cache quente, 500+ clientes

Clientes

Espelhar, não mover

Segmentos mais antigos que mirror_min_age_minutes são COPIADOS para o RAID continuamente. O write_buffer mantém uma janela quente rolante de 2h para que a reprodução de retrocesso (rewind) recente permaneça no armazenamento rápido. Apenas após evict_age_minutes (e apenas quando verificado como espelhado) os segmentos são excluídos do write_buffer. O RAID sempre tem a cópia de cauda longa — sem transferências em rajada horária.

Camada

Finalidade

Configurações

Buffer de Gravação

Recebe segmentos 24/7, mantém uma janela quente de 2h para reprodução rápida de retrocesso recente, protege o RAID contra E/S aleatórias. O dispositivo pode ser uma partição NVMe física (produção) ou tmpfs (caixa de dev/teste sem NVMe físico — veja a seção tmpfs abaixo).

device_path (dispositivo de bloco ou 'tmpfs'), tmpfs_size_pct (10-50% de MemAvailable quando tmpfs), mirror_min_age_minutes, evict_age_minutes, flush_threshold_percent (gatilho de forçar flush)

Arquivo HDD RAID

Armazenamento de longo prazo para retenção completa (padrão 14 dias). Recebe um espelhamento contínuo e gradual do write_buffer — gravação sequencial, sem picos horários. Sobrevive a reinicializações. O RAID sobrevive à falha de um único disco.

retention_days, raid_device, nginx_location, min_free_percent

Cache de Reprodução (opcional)

Cache de leitura para arquivos populares com mais de 2h (ex.: catch-up de EPG). Preenchido a partir do archive sob demanda após o limite de popularidade (3 acessos / 5 min). O dispositivo pode ser NVMe ou tmpfs.

prefetch_hours, max_sessions, eviction_policy (session/lru/fifo)

Cálculo de capacidade

live writes × 2h = tamanho da janela quente do write_buffer. Exemplo: 50 streams × 8 Mbps × 2h ≈ 36 GB. Adicione ~30% de margem para backlog do trickle de espelhamento → ~50 GB de write_buffer são suficientes para 50 streams. RAID dimensionado para retenção completa: 50 × 8 Mbps × 14 dias ≈ 6 TB.

Leituras (busca consciente de camadas)

Stream.dvr_file_path/2 verifica write_buffer → playback_cache → archive na ordem. Um segmento na janela quente de 2h é servido do write_buffer em velocidades nativas, mesmo que também exista no RAID. O Nginx X-Accel-Redirect serve arquivos diretamente sem passar pelo Phoenix.

Disco Virtual tmpfs (dev/teste)

Cada camada pode usar um disco virtual tmpfs baseado em RAM em vez de um dispositivo de bloco físico. Útil para caixas de desenvolvimento sem NVMe sobressalente, ou para ambientes de teste efêmeros. A lista suspensa de dispositivos do cartão Storage Tier contém uma opção 'tmpfs (disco virtual da RAM)' que substitui o seletor de caminho do dispositivo por um controle deslizante de porcentagem.

Tamanho em % de RAM livre

A alocação é especificada como uma porcentagem do MemAvailable (de /proc/meminfo) — passo 10, valores válidos 10/20/30/40/50. Piso rígido de 10% (a validação rejeita valores abaixo). Teto rígido de 50%. Padrão 30%. Em um host com 100 GB de MemAvailable: 10% = 10 GB, 30% = 30 GB, 50% = 50 GB. O tamanho é recalculado e remontado em tempo real quando o controle deslizante é movido e salvo.

Proteção contra OOM

Se o alvo calculado exceder 60% do MemAvailable atual, a montagem é recusada e a camada permanece offline (Stream.archive_path passa para a próxima camada saudável). Impede que uma configuração agressiva derrube o BEAM via OOM. O guarda-execução é executado tanto na inicialização quanto em cada Salvamento na interface.

Persistência de reinicialização

O tmpfs vive na RAM — qualquer conteúdo de buffer em trânsito é PERDIDO quando o host reinicia. A entrada fstab escrita no momento do provisionamento monta novamente o tmpfs vazio automaticamente na próxima inicialização, mas os segmentos antigos não retornam. O espelhamento para o archive continua normalmente para tudo que já foi espelhado antes da reinicialização — apenas a última janela não espelhada (tipicamente < mirror_min_age_minutes) é perdida. Para produção, use um dispositivo NVMe físico; o tmpfs destina-se como substituto para dev/teste.

Quando usar tmpfs

Use tmpfs para write_buffer quando: (a) a caixa de dev/teste não tiver NVMe sobressalente, mas você ainda quiser o pipeline DVR completo em execução para testes de integração, (b) o operador quiser validar o comportamento de espelhamento + archive sem comprar NVMe antecipadamente, (c) testes efêmeros onde a perda na reinicialização é aceitável. NÃO use tmpfs em produção — a RAM é volátil e ordens de magnitude mais cara que NVMe por GB de retenção.

Flush mais rápido para tmpfs

Quando a camada de gravação é tmpfs, o StorageTierFlush usa padrões mais rigorosos — mirror_min_age 2 min, evict_age 15 min (vs 5 min / 120 min para NVMe físico). A RAM é mais cara que o disco, por isso a janela quente rolante é mantida menor. Substitua via variáveis de ambiente MIRROR_MIN_AGE_MINUTES / EVICT_AGE_MINUTES se necessário.

Provisionamento Automático de Camadas e Segurança

As camadas são configuradas uma vez via Config > Armazenamento > Camadas de Armazenamento e provisionadas automaticamente — sem edição manual de mkfs/mount/fstab no host. StorageTier.ensure_all_provisioned/0 é executado em cada inicialização a partir do SystemInitializer e é idempotente: camadas já montadas são ignoradas, dispositivos ausentes são ignorados, camadas tmpfs são remontadas limpas após a reinicialização.

Semente de inicialização padrão

Na primeira inicialização (sem camada de escrita no DB), o sistema cria automaticamente uma camada de escrita baseada em tmpfs com alocação de 30% do MemAvailable, ponto de montagem /mnt/nvme_write. Isso fornece um pipeline DVR funcional imediatamente em qualquer host com RAM suficiente. O operador pode posteriormente alterar o dispositivo para um NVMe físico via UI sem perder as configurações de outras camadas.

Saúde e failover

Stream.archive_path/1 retorna a primeira camada 'saudável' — write_buffer se montado+gravação+free_pct acima do piso de segurança, caso contrário, falha para o archive (modo degradado). Piso de segurança de 20% para tmpfs (RAM-estricto), 2% para dispositivos de bloco. O endpoint tier_health expõe por camada: mounted/gravação/free_pct para monitoramento.

Alteração de tamanho ao vivo

Alterar tmpfs_size_pct na UI aciona um desmonte + remonte com o novo tamanho ao salvar. As gravações DVR ativas são brevemente pausadas (transição de montagem < 1 s). Recomendação: altere o tamanho do tmpfs apenas quando a taxa de gravação do DVR for baixa e considere reiniciar os streams para garantir que eles peguem a nova montagem limpa.

URL Base — OSTV Player

Campos do Pacote

API de Pacotes

Política de Senha

API de Revendedor

Configurações

Campos do Usuário

Gerenciamento de Usuários

Gestão de Utilizadores IPTV

URL Base — Player OSTV

A aplicação OSTV Player permite aos utilizadores alterar o URL base do servidor (endereço de API). Esta funcionalidade está disponível apenas para utilizadores com provider definido como root.

Motivo: Alterar o URL base destina-se apenas a administradores/utilizadores root para que possam alternar entre servidores (ex. produção vs. teste). Os utilizadores regulares têm um URL base fixo.

Campos do Utilizador

API de Pacotes

Retorna uma lista de todos os pacotes ativos com preços e períodos de faturação.

Lista de utilizadores de gestão (revendedores / fornecedores).

Retorna o saldo de crédito para um utilizador de gestão específico.

Campos de Pacote

API de Revendedor

API para revendedores/fornecedores. Autorização: Authorization: Bearer mtk_... (token de Gerir Utilizadores). O revendedor vê apenas os seus próprios clientes (owner_id).

Política de Palavras-passe

A palavra-passe é obrigatória ao criar um subscritor. Regras:

Mínimo 8 caracteres

Pelo menos 1 letra maiúscula (A-Z)

Pelo menos 1 carácter especial (!@#$%^&* etc.)

Aplica-se à UI e à API. Na atualização, a palavra-passe é opcional, mas se fornecida deve cumprir as regras.

Definições

Auto-Provisionamento de Tier &amp; Segurança

Auto-deteção de capacidade + sistema de ficheiros: quando um NVMe livre é selecionado no dropdown, a capacidade (GB) é lida de lsblk -bn -o SIZE e o FS atual de blkid. O formulário mostra os valores em modo só leitura.

Mecanismo de Flush de Tier — Mirror Contínuo

O GenServer StorageTierFlush executa a cada 60s. Em vez de esperar que um diretório de hora envelheça e mover 5GB de uma vez, transfere segmentos continuamente para RAID mantendo uma janela quente de 2h em NVMe para reprodução rápida. As duas fases são desacopladas — cópia e eliminação são operações separadas e verificadas.

Por que o mirror contínuo é melhor que esperar 60min e mover em lote: (1) Carga RAID uniforme — sem picos de 5GB nos limites de hora; (2) A maioria dos dados quentes já está em RAID — recuperação de desastre perde apenas os últimos minutos; (3) A expulsão é verificada por ficheiro.

Segurança de segmento em progresso: o mirror apenas seleciona ficheiros mais antigos que MIRROR_MIN_AGE_MINUTES via find -mmin +5. Um ficheiro ainda a ser escrito pelo FFmpeg não aparecerá na lista.

Ajuste por Deployment (.env)

500–1000

Regra de dimensionamento:

Calendário de Pré-visualização DVR

O separador de Pré-visualização DVR mostra um calendário renderizado pelo servidor que destaca apenas os dias com gravações em disco. A verificação percorre todos os tiers para que um segmento recentemente transferido de NVMe para RAID fique visível sem demora.

Os dias com gravações são clicáveis (azul) — clicar pré-preenche o campo de data/hora com esse dia às 00:00. Os dias sem gravação estão acinzentados e inativos.

Implementado em Stream.available_dvr_days/1 via find -mindepth 4 -maxdepth 4 -type d em cada ponto de montagem de tier; desduplicado entre tiers.

API do Player B2C

Visão Geral

A API B2C (Business-to-Consumer) fornece autenticação e acesso ao stream para aplicativos de player de usuário final. Os usuários se autenticam com nome de usuário e senha e recebem um token de autenticação com tempo limitado para solicitações subsequentes.

Autenticação

Autenticar um usuário e obter um auth_token para chamadas subsequentes à API.

Método

Endpoint

Corpo da Solicitação

Parâmetro

Tipo

Obrigatório

Descrição

Sim

Nome de login do usuário

Senha do usuário

Exemplo de Solicitação

Campos da Resposta

Resposta de Sucesso (200)

Token de autenticação criptografado para chamadas subsequentes à API

Data/hora de expiração do token no formato ISO 8601

Exemplo de Resposta de Sucesso

Resposta de Erro (403)

Mensagem de descrição do erro

Código de status HTTP

Exemplo de Resposta de Erro

Informações do Usuário

Recupera informações sobre o usuário autenticado usando o token de autenticação.

Campos de Resposta

Nome de usuário do usuário autenticado

Mensagem do servidor (vazio se não houver)

Status de autenticação (1 = autenticado)

Status da conta: Ativo, Banido, Desativado, Teste

Data de expiração da conta (nulo se ilimitado)

Número de conexões ativas atuais

Data de criação da conta no formato ISO 8601

Número máximo de conexões simultâneas permitidas

Lista de formatos de stream de saída permitidos

Nome do provedor do proprietário/revendedor do usuário (nulo se não houver)

URL da imagem do logotipo do provedor (nulo se não houver)

URL da imagem do logotipo de colapso do provedor 208x208 (nulo se não houver)

Hora atual do servidor no formato ISO 8601

Exemplo de Solicitação

Categorias

Recuperar categorias filtradas por tipo. Tipos disponíveis: live (streams), vod (filmes), series (séries).

Tipo de categoria: live, vod ou series

ID da categoria como string

Nome de exibição da categoria

ID da categoria pai (0 se for raiz)

Hash MD5 do conteúdo para invalidação de cache

Exemplo de Solicitação

Detalhes do VOD

Recupera informações detalhadas sobre um item VOD específico, incluindo metadados e links de stream.

ID do stream VOD (UUID)

Campos do Objeto de Informações

URL da imagem de capa

Identificador TMDB

URL da imagem de fundo

String de gênero

Enredo / descrição

Elenco

Valor da classificação (0-10)

Nome do diretor

Data de lançamento

Duração em segundos

Duração como string formatada

Array de IDs de categoria

1 se for conteúdo adulto, 0 caso contrário

Campos do Objeto VOD

ID do stream VOD

Título do VOD

Data de adição (ISO 8601)

URLs de links de streaming

Metadados de codec de vídeo/áudio

Detalhes da Série

Recuperar informações da série com listagens completas de temporadas e episódios, agrupadas por número da temporada.

ID da Série (UUID)

Campos do Array de Temporadas

Número da temporada

Nome de exibição da temporada

Número de episódios na temporada

Data de estreia da temporada

Visão geral / descrição da temporada

URL da imagem de capa da temporada

Objeto de Episódios

Mapa com chave como string do número da temporada. Cada valor é um array de objetos de episódio.

Campos do Objeto de Episódio

ID do Episódio

ID do episódio no TMDB

Número do episódio dentro da temporada

Título do episódio

Data de adição (ISO 8601)

Número da temporada

Objeto de informações do episódio (mesma estrutura que as informações de VOD)

URLs dos links de stream

Metadados de codec de vídeo/áudio

Notas

A expiração do token depende do papel do usuário: admin = 365 dias, outros = 30 dias|Contas desabilitadas não podem autenticar (retorna 403)|Cada login bem-sucedido atualiza o timestamp last_login do usuário|Os tokens são criptografados e contêm user_id, username, role e expiration

Resposta de Sucesso (200)

Token de autenticação obtido do endpoint /auth