Как сообщить о временных метаданных с помощью Служб мультимедиа Azure
Предупреждение
Поддержка Служб мультимедиа Azure будет прекращена 30 июня 2024 г. Дополнительные сведения см. в руководстве по прекращению поддержки AMS.
Метаданные по времени — это пользовательские данные, которые вставляются в динамический поток. Данные и метка времени вставки сохраняются в самом потоке мультимедиа. Это необходимо, чтобы клиенты, воспроизводимые видеопоток, могли получать одни и те же пользовательские метаданные в одно и то же время по отношению к видеопотоку.
Примечание
Метаданные по времени работают только для трансляций, созданных с помощью приема RTMP и RTMPS.
Предварительные требования
- Учетная запись Служб мультимедиа
- Знакомство с потоковой трансляцией из локального кодировщика. Если вы еще не делали этого, сначала попробуйте потоковую трансляцию с помощью краткого руководства по OBS . После установки и запуска вы сможете выполнить следующие действия.
- Средство для проверки записей HTTP.
Просмотр примера
В приведенном ниже примере показано, как видеопроигрыватель перехватывает и отображает метаданные видеопотока по времени. Он использует проигрыватель Shaka и встроенную поддержку данных сообщения о событиях (emsg) через EmsgEvent.
Службы мультимедиа также поддерживают события MetadataEvent проигрывателя Shaka ID3, emsg, использующие URI https://aomedia.org/emsg/ID3
идентификатора схемы .
Проверка кода на Stackblitz
Мы предоставили пример игрока Shaka на Stackblitz, с которым вы можете работать. Используйте эту кнопку, чтобы создать вилку примера кода на Stackblitz.com.
Просмотр HTML-страницы
Документ index.html содержит:
- элемент div, в котором сообщение будет отображаться после отправки.
- стандартный элемент видео HTML5. Обратите внимание, что элементу video присвоено значение
autoplay
, а — .start muted
- поле ввода для URL-адреса указателя потоковой передачи. В поле ввода есть URL-адрес заполнителя, который можно просмотреть, но он не является трансляцией. Это значение будет заменено.
<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>
Проверка JavaScript
Файл index.js создает и управляет событиями проигрывателя и проигрывателя. Функция onEventMessage
регистрируется для обработки emsg
события из проигрывателя Shaka и отображения сообщений, полученных от 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);
}
}
Создание трансляции с помощью указателя потоковой передачи
Если вы еще не сделали этого с помощью краткого руководства по OBS , упомянутого ранее, создайте трансляцию с указателем потоковой передачи.
- Используйте портал Azure, REST или избранный пакет SDK для создания трансляции. Скопируйте URL-адрес приема и вставьте его в текстовый редактор, так как вам потребуется изменить его, чтобы отправить сообщение проигрывателю с HTTP-запросом PUT.
- Запустите трансляцию и убедитесь, что связанная конечная точка потоковой передачи также запущена.
Потоковая передача трансляции
Скопируйте и вставьте указатель потоковой передачи в поле ввода в проигрывателе на Stackblitz или при необходимости обновите значение входного элемента в файле index.html. Вы должны увидеть потоковую передачу трансляции в проигрыватель.
Создание URL-адреса POST
Измените URL-адрес приема:
- Измените
RTMPS
наHTTPS
. - Удалите номер порта, включая двоеточие.
- Удалить
/live/
из пути. - Добавьте
ingest.isml/eventdata
в путь.
Пример
rtmps://mylivestream.channel.media.azure-test.net:2935/live/0251458ba5df44b2b807ea02f40fed76
becomes
https://mylivestream.channel.media.azure-test.net/0251458ba5df44b2b807ea02f40fed76/ingest.isml/eventdata
Создание и отправка запроса
Вы можете использовать любое средство или пакет SDK для отправки HTTP POST с метаданными в тексте проигрывателю.
Заголовки и текст запроса
Напоминание. Для заголовка Content-type HTTP необходимо задать значение application/json. Затем добавьте сведения, которые вы хотите отобразить, с помощью ключа, заданного как "message". Вот простой пример сообщения:
POST https://mylivestream.channel.media.azure-test.net/0251458ba5df44b2b807ea02f40fed76/ingest.isml/eventdata
Content-Type: application/json
{
“message”: “Hello world!”
}
При отправке запроса вы увидите сообщение в полезных данных JSON, которое отображается в div, плавающем над элементом video.
Альтернативные запросы
Вы можете отправить дополнительные сведения для интерактивного наложения. Полная настройка для этого сценария не рассматривается здесь, но вот как может выглядеть текст запроса для теста. Вы можете выполнить итерацию по ответам на каждый "вопрос" (здесь вместо "сообщение" в качестве ключа) и предоставить кнопку для выбора зрителя.
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."},
]
}
Совет
Откройте средства разработчика для браузера и watch видеосодержимы, которые активируются, а также сообщения, полученные из полезных данных JSON запроса.
Пример post с использованием cURL
При использовании cURL необходимо задать заголовок с помощью -H “Content-Type: application/json”
. Используйте флаг , -d
чтобы задать данные JSON в командной строке (экранирование кавычек в тексте JSON с обратной косой чертой при использовании командной строки). При необходимости можно указать json-файл с помощью -d \@\<path-to-json-file\>
.
Post является неявным при отправке данных, поэтому вам не нужно использовать флаг -X POST.
Пример POST:
curl https://mylivestream.channel.media.azure.net/618377123f4c49b3937ade20204ca0b2/ingest.isml/eventdata -H "Content-Type: application/json" -d "{\\"message\\":\\"Hello from Seattle\\"}" -v
Очистка ресурсов
Убедитесь, что вы завершили трансляцию и конечную точку потоковой передачи и удалили ресурсы, которые вы не планируете использовать, или вам будет выставлен счет.
Справка и поддержка
Вы можете обратиться к Службам мультимедиа с вопросами или следить за нашими обновлениями одним из следующих способов:
- ВОПРОСЫ И ОТВЕТЫ
-
Stack Overflow. Пометьте вопросы с помощью
azure-media-services
. - @MSFTAzureMedia или используйте @AzureSupport для запроса на поддержку.
- Отправьте запрос в службу поддержки через портал Azure.