Skip to content

Perfis de dispositivo

Nem todo dispositivo do espectador reproduz todas as faixas de um stream. Um set-top box não dá conta de 720p60, uma TV não reproduz HEVC, um player de webOS falha com legendas. Um perfil de dispositivo esconde desse dispositivo as faixas excedentes e não afeta os demais espectadores.

Um perfil é um registro com nome e três partes:

  • como reconhecer o dispositivo — por User-Agent, por um cabeçalho da requisição ou por um parâmetro da URL;
  • onde o perfil se aplica — modos de entrega e streams;
  • quais faixas manter — limites de vídeo, áudio e legendas.

Há um único conjunto de perfis para todo o cluster. O central o guarda e o entrega a cada streamer junto com o restante da configuração; a decisão é tomada pelo streamer ao qual o espectador chegou, sem consultar o central.

Um perfil só restringe: remove faixas e nunca adiciona. Não é controle de acesso — um espectador que falsifica um cabeçalho recebe o conjunto que corresponde a esse cabeçalho, e «4K só para premium» é tarefa da política de acesso.

Do que um perfil é feito

A seção Perfis de dispositivo do console mostra os perfis na ordem em que o streamer os testa. Clique em um perfil para abrir a ficha dele.

A seção de perfis: ordem de teste, um perfil somente pela URL e um perfil que um streamer não aplicou

No cabeçalho da ficha aparecem:

  • o nome do perfil e a URL p/<nome>/ dele;
  • a prioridade, por exemplo prioridade 10, ou a marca somente pela URL em um perfil sem condições;
  • a marca alterado se o perfil tiver alterações não salvas.

Para criar um perfil, clique em Adicionar perfil, informe o nome no diálogo Novo perfil e clique em Adicionar perfil. O nome do perfil é formado por letras latinas minúsculas, dígitos e os caracteres ., _, -, tem no máximo 64 caracteres e começa com letra ou dígito. O nome faz parte da URL p/<nome>/ (veja URLs sob perfil). Pode haver no máximo 64 perfis: com 64, Adicionar perfil fica indisponível. Um perfil novo, como qualquer alteração, só vale depois de Salvar (veja edição).

Como reconhecer o dispositivo

O perfil é escolhido se pelo menos uma condição coincidir:

  • User-Agent contém — uma substring do cabeçalho User-Agent, sem diferenciar maiúsculas: Roku coincide com Roku/DVP-14.5.
  • Cabeçalhos da requisição — o nome de um cabeçalho e uma substring do valor, sem diferenciar maiúsculas em nenhum dos dois. É assim que se reconhece um dispositivo por um cabeçalho que o seu middleware coloca (X-CDN-DEV-MODEL: 4800X) ou por uma classe de dispositivo que a CDN já fornece (CloudFront-Is-SmartTV-Viewer: true, X-UA-Device). O streamer não tem base de dispositivos embutida.
  • Parâmetros da URL — o nome de um parâmetro e uma lista de valores separados por vírgula. O parâmetro coincide se o valor inteiro for igual a um dos valores, diferenciando maiúsculas: ?device_profile=arris coincide com o valor arris, mas não com arris-4205 nem com Arris. Os valores são escritos decodificados: + na URL é um espaço, então ?p=S10+ coincide com o valor S10 (com espaço), e o valor S10+ só coincide com ?p=S10%2B.

Uma requisição sem User-Agent não coincide com uma condição por User-Agent.

Um perfil sem nenhuma condição recebe a marca somente pela URL: o streamer o escolhe só quando a própria URL nomeia o perfil (veja URLs sob perfil).

Onde se aplica

  • Prioridade — obrigatória e única nos perfis com condições: o streamer os testa em ordem crescente e pega o primeiro que se encaixa. Em um perfil sem condições não tem efeito.
  • Modos de entrega — a quais requisições o perfil se aplica. Por padrão, os três modos.
  • Etiquetas de streams e Nomes de streams — a quais streams o perfil se aplica: um stream entra se tiver pelo menos uma das etiquetas ou se estiver nomeado. Vazio significa todos os streams. Somando todos os perfis, é possível nomear no máximo 1000 streams; para muitos streams use uma etiqueta.

Modos de entrega:

  • Ao vivo — requisição do stream ao vivo;
  • Arquivo — requisição com from;
  • Retrocesso — URL rewind/<segundos>/.

As Etiquetas de streams são informadas uma de cada vez: digite a etiqueta e pressione Enter. Uma etiqueta é formada por letras latinas, dígitos e os caracteres _, ., - e tem no máximo 40 caracteres. O console verifica a etiqueta na hora: uma etiqueta de outra forma não é adicionada, e um erro aparece sob o campo. Uma etiqueta que já está na lista não é adicionada de novo.

Quais faixas manter

Os limites são agrupados por tipo de faixa, e cada grupo julga só as faixas do seu tipo:

  • Vídeo — Codecs ou Todos os codecs exceto, Largura, Altura, Quadros por segundo.
  • Áudio — Codecs ou Todos os codecs exceto, Idiomas ou Todos os idiomas exceto, o interruptor Não entregar áudio.
  • Legendas — Idiomas ou Todos os idiomas exceto, o interruptor Não entregar legendas.

Os campos de uma mesma seção dependem uns dos outros:

  • o campo Codecs preenchido desativa Todos os codecs exceto, e vice-versa: o central não aceita as duas listas na mesma seção;
  • da mesma forma, o campo Idiomas preenchido desativa Todos os idiomas exceto, e vice-versa;
  • o interruptor Não entregar áudio ou Não entregar legendas, ligado, remove todas as faixas desse tipo e esconde os demais campos da seção.

A faixa é mantida se passar em todos os limites do seu grupo; dentro de um mesmo limite basta coincidir com qualquer valor. Largura, altura e quadros por segundo são escritos separados por vírgula, como valores exatos e intervalos; um intervalo pode deixar uma das pontas aberta:

1080, 720          exatamente 1080 ou exatamente 720
..720              no máximo 720
720..              no mínimo 720
480..1080          de 480 a 1080, inclusive
..30               no máximo 30 quadros por segundo
25, 29.97          taxa como inteiro ou como decimal com ponto
30000/1001         taxa como fração

Um limite não remove uma faixa cuja propriedade limitada é desconhecida (sem taxa de quadros, sem idioma): não há o que julgar. Os idiomas são comparados pela tag padrão: eng na descrição da faixa e en no perfil são o mesmo idioma; und («indeterminado») conta como faixa sem idioma.

Um perfil sem nenhum limite é escolhido, mas não remove nada.

A ficha de um perfil: condições, alcance e limites de faixas

Como o perfil é escolhido

O streamer escolhe o perfil em cada requisição de master playlist HLS (fMP4 e MPEG-TS, com e sem LL-HLS) e de manifesto DASH, em todos os modos de entrega:

  • Ao vivo;
  • Arquivo;
  • Retrocesso.

A escolha segue estes passos:

  1. Se a URL contém um segmento de perfil p/<nome>/, o perfil nomeado é escolhido e as condições não são verificadas.
  2. Caso contrário, o streamer testa os perfis com condições por prioridade crescente e pega o primeiro cuja condição coincidiu e cujo alcance cobre o modo de entrega e o stream.

A cada requisição se aplica exatamente um perfil: os limites de perfis diferentes não se somam. Se nenhum perfil é escolhido, o espectador recebe o conjunto completo de faixas — exatamente o playlist entregue sem perfis.

A faixa removida some do master junto com a sua variante ou rendition; um grupo de áudio ou de legendas que fica vazio some por inteiro. Se o perfil removeu a faixa de áudio padrão, a primeira faixa que sobrou no mesmo grupo passa a ser a padrão: um grupo são as faixas de um mesmo codec (veja áudio em codecs diferentes).

Áudio em codecs diferentes no HLS

O master HLS agrupa as faixas de áudio por codec. Em um stream com AAC e AC-3, o master dá ao player dois grupos de áudio, aac e ac3, e combina cada qualidade de vídeo com cada um deles. Um player sem decodificador AC-3 ignora as variantes do grupo ac3 e toca AAC, em vez de perder o stream inteiro.

Um perfil cuja seção Áudio tem só aac em Codecs remove o AC-3 por inteiro: no master não ficam nem o grupo ac3 nem as variantes dele.

O player oferece ao espectador os idiomas do grupo que está tocando. Um idioma que só existe em AC-3 não aparece para um player sem decodificador AC-3.

URLs sob perfil

A decisão é tomada uma vez, no master playlist, e depois segue na URL. Um master cujo perfil foi escolhido por condições leva o player aos playlists filhos sob o segmento do perfil:

/playback/v/<stream>/index.m3u8                     requisição do player
/playback/v/<stream>/p/<perfil>/variant/v2/...      para onde o master aponta

Playlists, partes e segmentos sob p/<perfil>/ não olham cabeçalhos nem parâmetros da requisição e são iguais para qualquer espectador dessa URL. O playlist de uma faixa que o perfil removeu responde 404 sob p/. Sem o segmento de perfil, o playlist de uma faixa é entregue a qualquer espectador: as condições só são verificadas no master.

A URL com segmento de perfil também pode ser dada diretamente ao player — é assim que uma vitrine ou um middleware que já conhece o dispositivo escolhe o perfil:

/playback/v/<stream>/p/<perfil>/index.m3u8
/playback/v/<stream>/p/<perfil>/Manifest.mpd
/playback/v/<stream>/p/<perfil>/ts/index.m3u8
/playback/v/<stream>/p/<perfil>/rewind/600/index.m3u8

Um perfil que o streamer não conhece (excluído, renomeado ou o streamer ainda não aplicou a alteração), ou cujo alcance não cobre a requisição, não remove nada: a URL sob ele entrega o conjunto completo, sem erro.

Cabeçalhos do intermediário e redirecionamento. Quando o central faz proxy da requisição, ele repassa ao streamer os cabeçalhos do player. Quando o central responde com um redirecionamento para o endereço público do streamer, o cabeçalho colocado por um intermediário à frente do central (CDN, middleware) não chega ao streamer: o player não o repete. Nesse esquema, escolha o perfil pela URL p/<perfil>/.

URLs do Flussonic

Uma URL de master no formato antigo (/<stream>/index.m3u8?device_profile=arris) redireciona para o master /streaming/v/<stream>/index.m3u8 com os mesmos parâmetros, e o perfil é escolhido normalmente. Uma URL de faixa única (/<stream>/tracks-v1/index.m3u8) leva direto ao playlist dessa faixa, sem perfil.

O Catena não executa a seleção de faixas por número do Flussonic — o parâmetro filter.tracks e URLs com um conjunto de faixas como tracks-v1a1/index.m3u8 —: os números de faixa dele são outros, e o espectador recebe o conjunto completo. Crie um perfil para esse dispositivo; o contador device_profile_track_numbers_total (veja o diagnóstico) mostra quantas dessas requisições nenhum perfil cobre.

DASH

No DASH a decisão também é tomada no manifesto: o perfil remove os Representation com faixas que não se encaixam, e um AdaptationSet que fica sem nenhum Representation some por inteiro. Um manifesto escolhido por condições mantém as URLs dos segmentos na raiz do stream; um manifesto sob p/<perfil>/ aponta para os segmentos sob o mesmo segmento de perfil.

O player relê o manifesto DASH ao vivo, e cada releitura escolhe o perfil de novo, pela versão vigente dos perfis. Editar um perfil durante a reprodução pode remover o Representation que o player está tocando, e muitos players param aí. Faça mudanças radicais com um perfil novo (veja edição).

O DASH não tem retrocesso: um perfil que só se aplica em Retrocesso não afeta o manifesto.

Resultado vazio

Se depois da filtragem não sobra nenhuma faixa do tipo principal — vídeo, ou áudio em um stream sem vídeo —, o streamer responde ao master com 400 e o código device_profile_empty e grava um aviso no log. O espectador não recebe o conjunto completo: é exatamente o que o perfil escondia do dispositivo. Também não é entregue só o áudio de um stream com vídeo: o player do dispositivo não aceitaria esse master como vídeo.

A URL p/<perfil>/ responde da mesma forma: a vitrine que colocou essa URL vai ver. Um resultado vazio se corrige pelo alcance do perfil (etiquetas, modos) ou com limites mais brandos.

Edição, exclusão e renomeação

O botão Excluir da ficha exclui o perfil, e Renomear o renomeia. Um perfil novo, uma exclusão e uma renomeação, como as alterações de campos, só valem depois de Salvar: até lá existem apenas no formulário. O botão Cancelar descarta todas as alterações não salvas, inclusive os campos incompletos.

O botão Salvar envia só os campos alterados. Se os perfis foram editados em paralelo, o formulário mostra um conflito; suas alterações continuam no formulário — Mostrar o atual recarrega o documento sem as suas alterações, Levar minhas alterações as aplica à versão atual. O resultado fica no formulário sem salvar: confira — por exemplo, um perfil que outro operador excluiu enquanto você o editava volta só com os seus campos — e salve. Enquanto o formulário tiver um campo incompleto (um valor de largura, altura ou quadros por segundo que não foi interpretado, uma condição sem nome ou sem valor, um nome repetido), Salvar fica indisponível.

Uma alteração chega aos streamers sem reinício e sem recalcular a alocação. Um player HLS lê o master raramente, então uma alteração que esconde a faixa que ele está tocando leva a um 404 no playlist dessa faixa, e o player muda para outra. No DASH o manifesto ao vivo é relido, e a alteração vale na hora. Por isso:

  • alteração pequena (estreitar um intervalo, adicionar um codec a Todos os codecs exceto) — edite o perfil;
  • alteração radical (remover uma qualidade inteira, trocar o codec) — crie um perfil com outro nome e passe para ele as condições ou as URLs da vitrine.

Renomear equivale a excluir e criar. Os players que abriram o stream com o nome anterior recebem o conjunto completo de faixas até relerem o master. Excluir funciona do mesmo jeito: a URL sob um perfil excluído entrega tudo.

Quando um perfil não se aplica

Um streamer pode não aplicar um perfil se o central gravou um valor que a versão do streamer não conhece. Os demais perfis e o restante da configuração do streamer são aplicados mesmo assim. Onde isso aparece:

  • na seção Perfis de dispositivo — a marca Não aplicado nos streamers no cabeçalho da ficha, com os nomes dos streamers, o motivo entre parênteses e o caminho até o campo, por exemplo e1 (parse) video.codecs[1]; o nome leva à página do streamer. A ficha aberta mostra os textos de recusa que os streamers enviaram;
  • na página do streamer — um bloco ao lado do erro de aplicação da configuração: nome do perfil, motivo, caminho até o campo e mensagem;
  • na API — o campo rejected_profiles em GET /central/api-v4/nodes/stats;
  • nas métricas do streamer — device_profile_rejected{reason}.

Motivos:

  • parse — um campo não foi interpretado: valor ou tipo desconhecido;
  • invalid — o perfil foi interpretado, mas não passou na validação;
  • limit — o perfil passa de 64.

Um streamer cuja versão não conhece perfis de forma alguma entrega todas as faixas a qualquer espectador, e o central responde com sucesso à edição de um perfil. O console avisa sobre isso em dois lugares:

  • na seção Perfis de dispositivo — um aviso comum acima da lista, «Os perfis não têm efeito nos streamers cuja versão não os suporta…», com links para esses streamers;
  • na página do streamer — a nota «Os perfis não têm efeito neste streamer: a versão dele não os suporta…».

O aviso aparece só quando o documento de perfis tem pelo menos um perfil. Ele não é mostrado para streamers revogados nem para um streamer que ainda não aplicou a configuração desde que iniciou.

A página do streamer: um perfil que o streamer não aplicou, com o motivo e o caminho até o campo

Atualização e reversão

  • Crie os perfis depois de atualizar todos os streamers. Um streamer da versão anterior não conhece as URLs p/ e responde 404 a elas quando o master veio de um streamer atualizado e o playlist filho de um antigo.
  • Reverter o central para uma versão sem perfis os desativa em todo o cluster até o retorno: os streamers recebem a configuração sem perfis. O documento de perfis fica no banco de dados, e ao voltar o central o entrega sem edição.
  • Reverter o central uma versão não quebra a entrega: os streamers recebem os perfis como estão. Um campo que só a versão nova conhece atrapalha apenas a edição que contém esse campo: essa edição responde 422. Um valor desconhecido (por exemplo, um codec novo) faz qualquer edição do documento responder 422 até que esse valor seja excluído.
  • Depois de reverter o central, salve a config de cada streamer com qualquer alteração: caso contrário, um streamer que estava offline durante a reversão pode ficar com a configuração anterior.

Limitações

  • Quadros por segundo não limitam o arquivo: a descrição da gravação não os inclui, e uma propriedade desconhecida não remove a faixa. Ao vivo e em retrocesso o limite funciona; altura, largura e codec funcionam também no arquivo.
  • No máximo 64 perfis e 1000 nomes de streams nos alcances de todos os perfis.
  • O perfil se aplica só a HLS (incluindo LL-HLS e MPEG-TS) e a DASH; não afeta a entrega listada abaixo.
  • Não existe o formato 720p60 do Flussonic: altura e taxa são limites independentes, e «remover 720p60, manter 1080p60» não se expressa com um único perfil.

Entrega à qual o perfil não se aplica:

  • MSE;
  • MPEG-TS por HTTP;
  • stream fMP4;
  • MSS;
  • VOD.

Diagnóstico

Contadores do streamer (Prometheus) por perfil:

Contador O que conta
device_profile_checks_total{profile} masters e manifestos em que o streamer verificou as condições do perfil
device_profile_input_absent_total{profile} desses, requisições sem nenhum cabeçalho ou parâmetro citado nas condições
device_profile_selected_total{profile, by} o perfil foi escolhido: by="match" por condições, by="path" pela URL
device_profile_noop_total{profile} escolhido, mas não removeu nada
device_profile_empty_total{profile} respostas 400 de resultado vazio
device_profile_undescribed_total{profile} playlists de arquivo sob o perfil em que a gravação não tem descrição de faixas e a filtragem não ocorreu
device_profile_unknown_total requisições sob um perfil que o streamer não conhece
device_profile_track_numbers_total{covered} requisições com seleção de faixas por número do Flussonic; covered="false" — nenhum perfil as cobriu

Como ler:

  • checks e input_absent crescem juntos, selected não. O cabeçalho ou o parâmetro não chega ao streamer: uma CDN, um proxy ou um redirecionamento o corta. Escolha o perfil pela URL p/<perfil>/.
  • checks não cresce. O perfil nunca é alcançado: outro perfil é escolhido antes, ou a requisição fica fora dos modos e streams dele.
  • selected cresce junto com noop. O perfil é escolhido, mas o stream não tem faixas às quais os limites se apliquem.

Perfis pela API

O documento de perfis é GET e PATCH (JSON Merge Patch) em /central/api-v4/device_profiles. O PATCH altera só os perfis nomeados, e null sob um nome exclui o perfil; envie If-Match com o ETag da leitura para que uma edição paralela volte como 412 em vez de ser sobrescrita:

curl -X PATCH http://<endereço do central>/central/api-v4/device_profiles \
  -H 'Content-Type: application/merge-patch+json' -H 'If-Match: "<etag>"' \
  -d '{
    "roku-4800x": {
      "priority": 10,
      "match": {"headers": {"x-cdn-dev-model": "4800x"}},
      "video": {"fps": [{"max": 30}]}
    },
    "arris": {
      "priority": 20,
      "match": {"query": {"device_profile": ["arris", "arris-4205"]}},
      "video": {"codecs": ["h264"]}
    },
    "webos": {
      "priority": 30,
      "match": {"user_agent": "Web0S"},
      "text": {"exclude_all": true}
    }
  }'

Um erro no documento volta como 422 com o caminho até o campo — o mesmo que o console destaca. Um streamer entrega os perfis que aplicou em GET /streamer/api-v4/device_profiles.