Guide pratique pour signaler des métadonnées chrono timed avec Azure Media Services

Logo de Media Services v3


Avertissement

Azure Media Services sera mis hors service le 30 juin 2024. Pour plus d’informations, consultez le Guide de mise hors service AMS.

Les métadonnées chronométriques sont des données personnalisées qui sont insérées dans un flux en direct. Les données et leur horodatage d’insertion sont conservés dans le flux multimédia lui-même. Cela permet aux clients qui luent le flux vidéo d’obtenir les mêmes métadonnées personnalisées exactement en même temps par rapport au flux vidéo.

Notes

Les métadonnées chronométriques fonctionnent uniquement pour les événements en direct créés avec l’ingestion RTMP et RTMPS.

Prérequis

  • Un compte Media Services
  • Familiarité avec la diffusion en direct à partir d’un encodeur local. Si vous ne l’avez pas déjà fait, essayez d’abord la diffusion en continu en direct avec le démarrage rapide OBS . Une fois que vous avez configuré et exécuté, vous devez être en mesure d’effectuer les étapes suivantes.
  • Outil pour tester les publications HTTP.

Afficher l’exemple

L’exemple ci-dessous montre comment un lecteur vidéo intercepte et affiche les métadonnées chronotés du flux vidéo. Il utilise le lecteur Shaka et sa prise en charge intégrée des données de message d’événement (« emsg ») via EmsgEvent.

Media Services prend également en charge les événements « emsg » du lecteur Shaka ID3 MetadataEvent qui utilisent l’URI https://aomedia.org/emsg/ID3d’ID de schéma .

Passer en revue le code sur Stackblitz

Nous avons fourni un exemple de joueur Shaka sur Stackblitz avec lequel vous pouvez travailler. Utilisez ce bouton pour fork l’exemple de code sur Stackblitz.com.

Ouvrir la fourche dans StackBlitz

Passer en revue la page HTML

Le documentindex.html contient :

  • un élément div dans lequel le message s’affiche une fois qu’il est envoyé.
  • élément vidéo HTML5 standard. Notez que l’élément vidéo est défini sur autoplay et sur start muted.
  • champ d’entrée pour l’URL du localisateur de streaming. Il existe une URL d’espace réservé dans le champ d’entrée que vous pouvez afficher, mais il ne s’agit pas d’un flux en direct. Vous allez remplacer cette valeur.
<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>

Passer en revue le Code JavaScript

Le fichier index.js crée et gère les événements du lecteur et du lecteur. La onEventMessage fonction est inscrite pour gérer l’événement emsg à partir du lecteur Shaka et afficher les messages reçus de la 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);
    }
}

Créer un événement en direct avec un localisateur de streaming

Si vous ne l’avez pas déjà fait avec le démarrage rapide OBS mentionné précédemment, créez un événement en direct avec un localisateur de streaming.

  1. Utilisez le Portail Azure, REST ou votre KIT de développement logiciel (SDK) favori pour créer un événement en direct. Copiez l’URL d’ingestion et collez-la dans un éditeur de texte, car vous devez la modifier pour envoyer un message au lecteur avec une requête HTTP PUT.
  2. Démarrez l’événement en direct et vérifiez que le point de terminaison de streaming associé est également démarré.

Diffuser l’événement en direct

Copiez et collez le localisateur de diffusion en continu dans le champ d’entrée du lecteur sur Stackblitz ou mettez éventuellement à jour la valeur de l’élément d’entrée dans le fichier index.html. Vous devez voir le streaming d’événements en direct sur le lecteur.

Créer l’URL POST

Modifiez l’URL d’ingestion :

  1. Remplacez RTMPS par HTTPS.
  2. Supprimez le numéro de port, y compris les deux-points.
  3. Supprimer /live/ du chemin d’accès.
  4. Ajoutez ingest.isml/eventdata au chemin d’accès.

Exemple :

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

devient

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

Créer et envoyer une demande

Vous pouvez utiliser n’importe quel outil ou KIT de développement logiciel (SDK) de votre choix pour envoyer un message HTTP POST avec les métadonnées dans le corps au lecteur.

En-têtes et corps de la requête

Rappel : L’en-tête de type content HTTP DOIT être défini sur application/json. Ensuite, ajoutez les informations que vous souhaitez afficher avec la touche définie comme « message ». Voici un exemple de message simple :

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

{

“message”: “Hello world!”

}

Lorsque vous envoyez la demande, vous devez voir le message dans la charge utile JSON s’afficher dans le div flottant sur l’élément vidéo.

Autres demandes

Vous pouvez envoyer des informations supplémentaires pour une superposition interactive. La configuration complète de ce scénario n’est pas abordée ici, mais voici à quoi le corps de la demande peut ressembler pour un questionnaire. Vous pouvez itérer à travers les réponses pour chaque « question » (en remplaçant ici « message » comme clé) et fournir un bouton que la visionneuse peut sélectionner.

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."},
    ]
}

Conseil

Ouvrez les outils de développement du navigateur et watch les événements vidéo déclenchés, ainsi que les messages reçus à partir de la charge utile JSON de la requête.

Exemple POST utilisant cURL

Lorsque vous utilisez cURL, vous devez définir l’en-tête à l’aide de -H “Content-Type: application/json”. Utilisez l’indicateur -d pour définir les données JSON sur la ligne de commande (guillemets d’échappement dans le corps JSON avec une barre oblique inverse lors de l’utilisation de la ligne de commande). Si vous le souhaitez, vous pouvez pointer vers un fichier JSON à l’aide de -d \@\<path-to-json-file\>.

Un POST est implicite lors de l’envoi de données. Vous n’avez donc pas besoin d’utiliser l’indicateur POST -X.

Exemple POST :

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

Nettoyer les ressources

Veillez à arrêter l’événement en direct et le point de terminaison de streaming et à supprimer les ressources que vous n’avez pas l’intention de continuer à utiliser, sinon vous serez facturé.

Obtenir de l’aide et du support

Vous pouvez contacter Media Services pour vous poser des questions ou suivre nos mises à jour en suivant l’une des méthodes suivantes :