Como sinalizar metadados cronometrados com os Serviços de Mídia do Azure

Logotipo dos Serviços de Mídia v3


Aviso

Os Serviços de Mídia do Azure serão desativados em 30 de junho de 2024. Para obter mais informações, consulte o Guia de desativação do AMS.

Metadados cronometrados são dados personalizados inseridos em uma transmissão ao vivo. Os dados e seu carimbo de data/hora de inserção são preservados no próprio fluxo de mídia. Isso é para que os clientes que reproduzam o fluxo de vídeo possam obter os mesmos metadados personalizados exatamente ao mesmo tempo em relação ao fluxo de vídeo.

Observação

Os metadados cronometrados funcionam apenas para eventos ao vivo criados com ingestão RTMP e RTMPS.

Pré-requisitos

  • Uma conta dos Serviços de Mídia
  • Familiaridade com a transmissão ao vivo de um codificador local. Se você ainda não fez isso antes, experimente a transmissão ao vivo com o início rápido do OBS primeiro. Depois de ter essa configuração e execução, você deverá ser capaz de executar as etapas a seguir.
  • Uma ferramenta para testar postagens HTTP.

Exibir o exemplo

O exemplo a seguir mostra como um player de vídeo captura e exibe os metadados cronometrados do fluxo de vídeo. Ele usa o player Shaka e seu suporte interno para dados de Mensagem de Evento ('emsg') por meio do EmsgEvent.

Os Serviços de Mídia também dão suporte aos eventos Shaka player ID3 MetadataEvent, 'emsg' que usam o URI https://aomedia.org/emsg/ID3da ID do esquema .

Examinar o código no Stackblitz

Fornecemos um player Shaka de exemplo no Stackblitz para você trabalhar com ele. Use este botão para bifurcar o código de exemplo no Stackblitz.com.

Abrir Fork no StackBlitz

Examinar a página HTML

O documentoindex.html contém:

  • um elemento div em que a mensagem será exibida depois de enviada.
  • um elemento de vídeo HTML5 padrão. Observe que o elemento de vídeo está definido como autoplay e como start muted.
  • um campo de entrada para a URL do localizador de streaming. Há uma URL de espaço reservado no campo de entrada que você pode exibir, mas não é uma transmissão ao vivo. Você substituirá esse valor.
<script type="module" src="./index.js"></script>
<link href="./style.css" type="text/css" rel="stylesheet">

<div class="grid-container">

  <div id="header">
    <a href="https://github.com/Azure-Samples/media-services-v3-node-tutorials/tree/main/Player/examples/shaka">
      <span class="microsoft"><svg aria-hidden="true" role="presentation" viewBox="0 0 26 25"
          xmlns="http://www.w3.org/2000/svg">
          <path d="M12.5708 0.981934H0.907471V12.3682H12.5708V0.981934Z" fill="#F25022"></path>
          <path d="M25.4625 0.981934H13.7992V12.3682H25.4625V0.981934Z" fill="#7FBA00"></path>
          <path d="M12.5708 13.5649H0.907471V24.9512H12.5708V13.5649Z" fill="#00A4EF"></path>
          <path d="M25.4629 13.5649H13.7996V24.9512H25.4629V13.5649Z" fill="#FFB900"></path>
        </svg></span>
      <span class="title">Shaka Player LL-HLS with Timed Metadata Sample</span>
    </a>
  </div>
  <div id="videoArea">


    <div id="video-container" data-shaka-player-cast-receiver-id="07AEE832">
      <div id="metadata" class="metadata-hide"></div>
      <video autoplay muted playsinline id="video" style="width: 100%; height: 100%"></video>
    </div>
  </div>
  <div id="clock">
  </div>

  <div id="console">Waiting for timed metadata signals to arrive...</div>
  <div id="manifest">
    <label>Your Manifest (paste and hit enter):</label>
    <input id="manifestUrl" type="url" placeholder="place manifest URL here" size="80"
      value="//aka.ms/lowlatencydemo.m3u8" />
  </div>

  <div id="footer">
  <a href="http://media.azure">Azure Media Services</a>
  </div>
</div>

Examinar o JavaScript

O arquivo index.js cria e gerencia os eventos de jogador e jogador. A onEventMessage função é registrada para manipular o emsg evento do Shaka Player e exibir as mensagens recebidas do POST.

player.addEventListener('emsg', onEventMessage);

function onEventMessage(event) {         
    // In version 4.2.x of Shaka player, the event message from AMS will fire here.
    // In version 4.3.0 and higher of Shaka player, the message will only fire in the "metadata' event, since the Shaka player is looking for ID3 messages and filtering them out to that event.

    console.log('Timed Metadata Event Message');
    //console.log('emsg:', event)
    // emsg box information are in emsg.details
    const dataMsg = new TextDecoder().decode(event.detail.messageData);
    console.log('EMSG: Scheme = ' + event.detail.schemeIdUri);
    console.log('EMSG: StartTime = ' + event.detail.startTime);
    console.log(
        'video.currenttime=' + document.getElementById('video').currentTime
    );

    // The start time and the presentationTimeDelta are in seconds on the presentation timeline. Shaka player does this work for us. The value startTime-presentationTimeDelta will give you the exact time in the video player's timeline to display the event.
    console.log(
        'EMSG: startTime-presentationTimeDelta = ' +
        (event.detail.startTime - event.detail.presentationTimeDelta)
    );

    console.log(
        'EMSG: presentationTimeDelta = ' + event.detail.presentationTimeDelta
    );
    console.log('EMSG: endTime = ' + event.detail.endTime);
    console.log('EMSG: timescale = ' + event.detail.timescale);
    console.log('EMSG: duration = ' + event.detail.eventDuration);
    console.log('EMSG: message length = ' + event.detail.messageData.length);

    try {
        const frames = shaka.util.Id3Utils.getID3Frames(event.detail.messageData);

        if (frames.length > 0) {
            console.log('EMSG: message = ', frames[0]);
            console.log('EMSG: mimeType = ', frames[0].mimeType);

            if (frames[0].mimeType === 'application/json') {
                const jsonPayload = JSON.parse(frames[0].data);
                let message = jsonPayload.message;
                console.log('message=' + message);

                // Now do something with your custom JSON payload
                let metadataDiv = document.getElementById('metadata');
                metadataDiv.innerText = message;

                let logLine = document.createElement('p');
                logLine.innerText = 'onEmsg - timestamp:' + (event.detail.startTime - event.detail.presentationTimeDelta).toFixed(2) + ' ' + JSON.stringify(jsonPayload);
                document.getElementById('console').appendChild(logLine).scrollIntoView(false);

                metadataDiv.className = 'metadata-show';

                setTimeout(() => {
                    metadataDiv.className = 'metadata-hide';
                }, 5000); // clear the message

                console.log('JSON= ' + JSON.stringify(jsonPayload));
            }
        }
    } catch (err) {
        console.error(err.stack);
    }
}

Criar um evento ao vivo com um localizador de streaming

Se você ainda não fez isso com o início rápido do OBS mencionado anteriormente, crie um evento ao vivo com um localizador de streaming.

  1. Use o portal do Azure, REST ou seu SDK favorito para criar um evento ao vivo. Copie a URL de ingestão e cole-a em um editor de texto, pois você precisará editá-la para enviar uma mensagem ao player com uma solicitação HTTP PUT.
  2. Inicie o evento ao vivo e verifique se o ponto de extremidade de streaming associado também foi iniciado.

Transmitir o evento ao vivo

Copie e cole o localizador de streaming no campo de entrada no player em Stackblitz ou, opcionalmente, atualize o valor no elemento de entrada no arquivo index.html. Você deve ver o evento ao vivo transmitindo para o player.

Criar a URL POST

Edite a URL de ingestão:

  1. Alterar RTMPS para HTTPS.
  2. Remova o número da porta, incluindo os dois-pontos.
  3. Remova /live/ do caminho.
  4. Acrescente ingest.isml/eventdata ao caminho.

Exemplo:

rtmps://mylivestream.channel.media.azure-test.net:2935/live/0251458ba5df44b2b807ea02f40fed76

se torna

https://mylivestream.channel.media.azure-test.net/0251458ba5df44b2b807ea02f40fed76/ingest.isml/eventdata

Criar e enviar uma solicitação

Você pode usar qualquer ferramenta ou SDK que desejar para enviar um HTTP POST com os metadados no corpo para o player.

Cabeçalhos e corpo da solicitação

Lembrete: o cabeçalho HTTP Tipo de conteúdo DEVE ser definido como application/json. Em seguida, adicione as informações que você deseja exibir com a chave definida como "mensagem". Aqui está uma mensagem de exemplo simples:

POST https://mylivestream.channel.media.azure-test.net/0251458ba5df44b2b807ea02f40fed76/ingest.isml/eventdata
Content-Type: application/json

{

“message”: “Hello world!”

}

Ao enviar a solicitação, você deverá ver a mensagem na carga JSON aparecer no div flutuando sobre o elemento de vídeo.

Solicitações alternativas

Você pode enviar informações adicionais para uma sobreposição interativa. A configuração completa para esse cenário não é abordada aqui, mas aqui está como o corpo da solicitação poderia ser para um teste. Você pode iterar pelas respostas para cada "pergunta" (aqui substituindo "mensagem" como a chave) e fornecer um botão para o visualizador selecionar.

POST https://mylivestream.channel.media.azure-test.net/0251458ba5df44b2b807ea02f40fed76/ingest.isml/eventdata
Content-Type: application/json


{
    "question": "What is the airspeed velocity of an unladen swallow?",
     "answers" : [
        {"a1": "A shrubbery!"},
        {"a2": "I am not a witch!"},
        {"a3":  "An African or European swallow?"},
        {"a4": "It's just a flesh wound."},
    ]
}

Dica

Abra as Ferramentas de Desenvolvedor para o navegador e watch os eventos de vídeo que são acionados, bem como as mensagens recebidas do conteúdo JSON da solicitação.

Exemplo de POST usando cURL

Ao usar cURL, você deve definir o cabeçalho usando -H “Content-Type: application/json”. Use o -d sinalizador para definir os dados JSON na linha de comando (aspas de escape no corpo JSON com uma barra invertida ao usar a linha de comando). Opcionalmente, você pode apontar para um arquivo JSON usando -d \@\<path-to-json-file\>.

Um POST é implícito ao enviar dados, portanto, você não precisa usar o sinalizador -X POST.

Exemplo POST:

curl https://mylivestream.channel.media.azure.net/618377123f4c49b3937ade20204ca0b2/ingest.isml/eventdata -H "Content-Type: application/json" -d "{\\"message\\":\\"Hello from Seattle\\"}" -v

Limpar os recursos

Certifique-se de desligar o evento ao vivo e o ponto de extremidade de streaming e excluir os recursos que você não pretende continuar usando ou será cobrado.

Obter ajuda e suporte

Você pode entrar em contato com os Serviços de Mídia com dúvidas ou seguir nossas atualizações por um dos seguintes métodos: