Como sinalizar metadados cronometrados com os Serviços de Mídia do Azure
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/ID3
da 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.
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 comostart 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.
- 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.
- 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:
- Alterar
RTMPS
paraHTTPS
. - Remova o número da porta, incluindo os dois-pontos.
- Remova
/live/
do caminho. - 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:
- P & R
-
Stack Overflow. Marque perguntas com
azure-media-services
. - @MSFTAzureMedia ou use @AzureSupport para solicitar suporte.
- Abra um tíquete de suporte por meio do portal do Azure.