如何使用 Azure 媒體服務發出計時元數據的訊號

媒體服務標誌 v3


警告

Azure 媒體服務將於 2024 年 6 月 30 日淘汰。 如需詳細資訊,請參閱 AMS淘汰指南

計時元數據是插入至實時數據流的自定義數據。 數據及其插入時間戳都會保留在媒體數據流本身中。 如此一來,播放視訊串流的用戶端可以取得與視訊串流完全相同的相同自定義元數據。

注意

計時元數據僅適用於使用 RTMP 和 RTMPS 擷取建立的即時活動。

必要條件

  • 媒體服務帳戶
  • 熟悉來自內部部署編碼器的即時串流。 如果您之前尚未這麼做,請先嘗試使用 OBS 快速入門 進行即時串流。 設定並執行之後,您應該能夠執行下列步驟。
  • 測試 HTTP 文章的工具。

檢視範例

下列範例顯示影片播放程式如何攔截並顯示影片串流的計時元數據。 它會透過 EmsgEvent,使用「事件訊息」數據 (『emsg』) 的內建支援。

媒體服務也支援使用配置標識碼 URI https://aomedia.org/emsg/ID3的「系統標識碼」3 MetadataEvent、'emsg' 事件。

檢閱 Stackblitz 上的程式碼

我們已在 Stackblitz 上提供一個範例的一位 Surveya 球員,供您使用。 使用此按鈕來分叉 Stackblitz.com 上的範例程序代碼。

在 StackBlitz 中開啟分支

檢閱 HTML 頁面

index.html 檔包含:

  • 訊息傳送後會顯示的 div 元素。
  • 標準 HTML5 視訊專案。 請注意,視訊項目設定為 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 來自 Surveya Player 的事件,並顯示從 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 快速入門 來完成此動作,請使用串流定位器建立即時活動。

  1. 使用 Azure 入口網站、REST 或您最愛的 SDK 來建立即時活動。 複製 擷取 URL ,並將其貼到文本編輯器中,因為您必須編輯它,才能使用 HTTP PUT 要求將訊息傳送給播放程式。
  2. 啟動即時活動,並確定也已啟動相關聯的串流端點。

串流即時活動

將串流定位器複製並貼到 Stackblitz 上播放器的輸入欄位中,或選擇性地更新 index.html 檔案中輸入元素的值。 您應該會看到即時活動串流至播放程式。

建立 POST URL

編輯內嵌網址:

  1. RTMPS 變更為 HTTPS
  2. 拿掉埠號碼,包括冒號。
  3. 從路徑中移除 /live/
  4. 附加 ingest.isml/eventdata 至路徑。

範例:

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

變成

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

建立並傳送要求

您可以使用任何您想要的工具或 SDK,將 HTTP POST 與本文中的元資料傳送給播放程式。

標頭和要求本文

提醒:HTTP 內容類型標頭 必須 設定為 application/json。 然後,新增您想要顯示的資訊,並將密鑰集設定為 「message」。 以下是簡單的範例訊息:

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

{

“message”: “Hello world!”

}

當您傳送要求時,應該會在影片元素上浮動的 div 中看到 JSON 承載中的訊息。

替代要求

您可以傳送互動式重疊的其他資訊。 此處未涵蓋該案例的完整設定,但以下是要求本文對測驗的外觀。 您可以在這裡逐一查看每個「問題」的解答, (取代 「message」 作為索引鍵) 並提供按鈕供查看器選取。

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 承載收到的訊息。

使用 cURL 的 POST 範例

使用 cURL 時,您必須使用 -H “Content-Type: application/json”來設定標頭。 -d使用旗標在命令行上設定 JSON 數據, (使用命令行) 時,以反斜杠逸出 JSON 主體中的引號。 您可以選擇性地使用 -d \@\<path-to-json-file\>指向 JSON 檔案。

傳送數據時,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

清除資源

請務必關閉即時事件和串流端點,並刪除您不打算繼續使用的資源,或向您收取費用。

取得說明及支援

您可以連絡媒體服務並提出問題,或遵循下列其中一種方法來追蹤我們的更新: