Partilhar via


Como sinalizar metadados temporizados com os Serviços de Multimédia do Azure

Logótipo dos Serviços de Multimédia v3


Aviso

Os Serviços de Multimédia do Azure serão descontinuados a 30 de junho de 2024. Para obter mais informações, veja o Guia de Extinção do AMS.

Os metadados temporizados são dados personalizados que são inseridos numa transmissão em direto. Os dados e o carimbo de data/hora de inserção são preservados no próprio fluxo de multimédia. Isto é para que os clientes que reproduzem a transmissão em fluxo de vídeo possam obter os mesmos metadados personalizados exatamente ao mesmo tempo em relação à transmissão em fluxo de vídeo.

Nota

Os metadados temporizados só funcionam para eventos em direto criados com ingestão RTMP e RTMPS.

Pré-requisitos

  • Uma conta dos Serviços de Multimédia
  • Estar familiarizado com a transmissão em fluxo em direto de um codificador no local. Se ainda não o fez, experimente primeiro a transmissão em fluxo em direto com o início rápido do OBS . Assim que tiver a configuração e a execução, deverá conseguir executar os seguintes passos.
  • Uma ferramenta para testar mensagens HTTP.

Ver o exemplo

O exemplo abaixo mostra como um leitor de vídeo captura e apresenta os metadados temporizados da transmissão em fluxo de vídeo. Utiliza o leitor Shaka e o suporte incorporado para dados de Mensagens de Evento ('emsg') através do EmsgEvent.

Os Serviços de Multimédia também suportam o ID3 MetadataEvent do leitor Shaka, eventos "emsg" que utilizam o URI https://aomedia.org/emsg/ID3do ID do esquema.

Rever o código no Stackblitz

Fornecemos um exemplo de jogador do Shaka no Stackblitz para que possa trabalhar. Utilize este botão para bifurcar o código de exemplo no Stackblitz.com.

Abrir Fork no StackBlitz

Rever a página HTML

O documento index.html contém:

  • um elemento div onde a mensagem será apresentada assim que for enviada.
  • um elemento de vídeo HTML5 padrão. Repare que o elemento de vídeo está definido como autoplay e como start muted.
  • um campo de entrada para o URL do localizador de transmissão em fluxo. Existe um URL de marcador de posição no campo de entrada que pode ver, mas não é uma transmissão em direto. Irá substituir este 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>

Rever o JavaScript

O ficheiro index.js cria e gere os eventos do leitor e do leitor. A onEventMessage função está registada para processar o emsg evento do Shaka Player e apresentar 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 em direto com um localizador de transmissão em fluxo

Se ainda não o tiver feito com o início rápido do OBS mencionado anteriormente, crie um evento em direto com um localizador de transmissão em fluxo.

  1. Utilize o portal do Azure, REST ou o seu SDK favorito para criar um evento em direto. Copie o URL de ingestão e cole-o num editor de texto, uma vez que terá de editá-lo para enviar uma mensagem ao leitor com um pedido HTTP PUT.
  2. Inicie o evento em direto e certifique-se de que o ponto final de transmissão em fluxo associado também foi iniciado.

Transmitir em fluxo o evento em direto

Copie e cole o localizador de transmissão em fluxo no campo de entrada no leitor no Stackblitz ou, opcionalmente, atualize o valor no elemento de entrada no ficheiro index.html. Deverá ver a transmissão em fluxo do evento em direto para o leitor.

Criar o URL POST

Edite o URL de ingestão:

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

Exemplo:

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

torna-se

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

Criar e enviar um pedido

Pode utilizar qualquer ferramenta ou SDK que pretenda para enviar um HTTP POST com os metadados no corpo para o leitor.

Cabeçalhos e corpo do pedido

Lembrete: o cabeçalho tipo conteúdo HTTP TEM de ser definido como aplicação/json. Em seguida, adicione as informações que pretende apresentar com a chave definida como "mensagem". Eis uma simples mensagem de exemplo:

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

{

“message”: “Hello world!”

}

Quando enviar o pedido, deverá ver a mensagem no payload JSON a aparecer no div a flutuar sobre o elemento de vídeo.

Pedidos alternativos

Pode enviar informações adicionais para uma sobreposição interativa. A configuração completa para esse cenário não é abordada aqui, mas eis o aspeto que o corpo do pedido pode ter para um questionário. Pode iterar as 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 Programador para o browser e watch os eventos de vídeo que são acionados, bem como as mensagens recebidas do payload JSON do pedido.

Post de exemplo com cURL

Ao utilizar cURL, tem de definir o cabeçalho com -H “Content-Type: application/json”. Utilize o -d sinalizador para definir os dados JSON na linha de comandos (aspas de escape no corpo JSON com uma barra invertida ao utilizar a linha de comandos). Opcionalmente, pode apontar para um ficheiro JSON com -d \@\<path-to-json-file\>.

Um POST é implícito ao enviar dados, pelo que não precisa de utilizar o sinalizador -X POST.

POST de exemplo:

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 que encerra o evento em direto e o ponto final de transmissão em fluxo e elimina os recursos que não pretende continuar a utilizar ou que lhe será faturado.

Obter ajuda e suporte

Pode contactar os Serviços de Multimédia com perguntas ou seguir as nossas atualizações através de um dos seguintes métodos: