S'abonner à des flux — Web

Une fois que vous avez connecté à une session, vous pouvez vous abonner aux flux de la session. Lorsque vous vous abonnez à un flux, son flux vidéo s'affiche sur la page du client et son audio est lu.

Cette rubrique comprend les sections suivantes :

Détecter la création de flux au cours d'une session

L'objet Session envoie un streamCreated lorsqu'un nouveau flux (autre que le vôtre) est créé dans une session. Un flux est créé lorsqu'un client publie un flux vers la session. Les streamCreated est également déclenché pour chaque flux existant dans la session lors de la première connexion. Cet événement est défini par l'événement StreamEvent, qui possède un élément stream représentant le flux qui a été créé :

session.on("streamCreated", function (event) {
   console.log("New stream in the session: " + event.stream.streamId);
});
// Replace with a valid token:
session.connect(token);

Vous pouvez vous abonner à n'importe quel flux. Voir la section suivante.

S'abonner à un flux

Pour s'abonner à un flux, il suffit de passer l'objet Stream dans la fonction subscribe de l'objet Session :

session.subscribe(stream, replacementElementId);

Les subscribe() prend les paramètres suivants :

  • stream-L'objet Stream.

  • targetElement- (Facultatif) Définit l'élément DOM que la vidéo d'abonné remplace.

  • properties— (Facultatif) Un ensemble de propriétés permettant de personnaliser l'apparence de la vue « Abonné » dans la page HTML (voir Personnaliser l'interface utilisateur) et choisissez si vous souhaitez vous abonner aux flux audio et vidéo (voir Réglage de l'audio et de la vidéo).

  • completionHandler- (Facultatif) Une fonction qui est appelée de manière asynchrone lorsque l'appel à la fonction subscribe() se termine avec succès ou échoue. Si l'appel à la méthode subscribe() échoue, un objet d'erreur est transmis au gestionnaire d'achèvement. Cet objet a une valeur code et message qui décrivent l'erreur.

Le code suivant s'abonne à tous les flux, autres que ceux publiés par votre client :

session.on("streamCreated", function(event) {
    session.subscribe(event.stream);
});

// Replace with your API key and token:
session.connect(token, function (error) {
    if(error) {
        // failed to connect
    }
});

Les insertMode de la propriété properties du paramètre Session.subscribe() spécifie comment l'objet Publisher sera inséré dans le DOM HTML, par rapport à l'objet targetElement paramètre. Ce paramètre peut prendre l'une des valeurs suivantes :

  • "replace" - L'objet Subscriber remplace le contenu de l'élément targetElement. Il s'agit de la valeur par défaut.
  • "after" - L'objet Subscriber est un nouvel élément inséré après le targetElement dans le DOM HTML. (L'abonné et l'élément cible ont tous deux le même élément parent).
  • "before" - L'objet Subscriber est un nouvel élément inséré avant le targetElement dans le DOM HTML. (L'abonné et l'élément cible ont tous deux le même élément parent).
  • "append" - L'objet Subscriber est un nouvel élément ajouté en tant qu'enfant de l'élément cible. S'il existe d'autres éléments enfants, le Publisher est ajouté en tant que dernier élément enfant du targetElement.

Par exemple, le code suivant ajoute un nouvel objet Abonné en tant qu'enfant d'un objet subscriberContainer Élément DOM :

session.on('streamCreated', function(event) {
  var subscriberProperties = {insertMode: 'append'};
  var subscriber = session.subscribe(event.stream,
    'subscriberContainer',
    subscriberProperties,
    function (error) {
      if (error) {
        console.log(error);
      } else {
        console.log('Subscriber added.');
      }
  });
});

L'objet Abonné possède une fonction element qui correspond à l'élément HTML DOM qui le contient.

Si vous ne souhaitez pas utiliser l'interface utilisateur par défaut, vous pouvez accéder à la Video élément pour l'abonné (voir ce sujet). Vous pouvez également utiliser votre propre Video élément pour afficher la vidéo de l'abonné, et utiliser l'objet MediaStream de l'abonné comme source multimédia pour cette Video élément (voir ce sujet).

Se désabonner d'un flux

Pour interrompre la lecture d'un flux auquel vous êtes abonné, transmettez l'objet Subscriber à la méthode unsubscribe() de l'objet Session :

session.unsubscribe(subscriber);

L'objet Subscriber est détruit et l'affichage du flux est supprimé du DOM HTML.

Détecter quand les flux quittent une session

Lorsqu'un flux, autre que le vôtre, quitte une session, l'objet Session envoie un message de type streamDestroyed événement :

session.on("streamDestroyed", function (event) {
  console.log("Stream stopped. Reason: " + event.reason);
});

Lorsqu'un flux que vous publiez quitte une session, l'objet Publisher envoie une commande streamDestroyed événement :

var publisher = OT.initPublisher();
publisher.on("streamDestroyed", function (event) {
  console.log("Stream stopped. Reason: " + event.reason);
});

Les streamDestroyed est défini par la classe StreamEvent. L'événement comprend un reason qui explique pourquoi le flux s'est terminé. Ces raisons comprennent "clientDisconnected", "forceDisconnected", "forceUnpublished"ou "networkDisconnected". Pour plus de détails, voir Événement de flux.

Par défaut, lorsqu'un streamDestroyed est déclenché pour un flux auquel vous êtes abonné, les objets Subscriber correspondants (il peut y en avoir plusieurs) sont détruits et supprimés du DOM HTML. Vous pouvez empêcher ce comportement par défaut en appelant la fonction preventDefault() de l'objet StreamEvent :

session.on("streamDestroyed", function (event) {
  event.preventDefault();
  var subscribers = session.getSubscribersForStream(event.stream);
  // Now you can adjust the DOM elements around each
  // subscriber to the stream, and then delete it yourself.
});

Il convient de noter que le getSubscribersForStream() d'un objet Session renvoie tous les objets Subscriber d'un flux.

Il se peut que vous souhaitiez empêcher le comportement par défaut et conserver l'Abonné, si vous voulez ajuster les éléments DOM connexes avant de supprimer l'Abonné vous-même. Vous pouvez alors supprimer l'objet Abonné (et son élément DOM) en appelant la fonction destroy() de l'objet Abonné.

Un objet Abonné envoie un destroyed lorsque l'objet a été supprimé du DOM HTML. En réponse à cet événement, vous pouvez choisir d'ajuster (ou de supprimer) les éléments du DOM liés à l'abonné qui a été supprimé.

Reconnexion automatique

Si un client perd la connexion à un flux auquel il est abonné (par exemple, en raison d'une interruption de la connexion réseau chez l'un ou l'autre des clients), il tentera de se reconnecter automatiquement au flux. Lorsque la connexion au flux est interrompue et que le client tente de se reconnecter, l'objet `Subscriber` déclenche un disconnected événement. Lorsque le flux est rétabli, l'objet Abonné envoie un événement connected . Si le client ne peut pas restaurer le flux, l'objet Abonné envoie un événement destroyed événement.

En réponse à ces événements, votre application peut (éventuellement) afficher des notifications d'interface utilisateur indiquant les états de déconnexion temporaire, de reconnexion et de destruction :

subscriber.on(
  disconnected: function() {
    // Display a user interface notification.
  },
  connected: function() {
    // Adjust user interface.
  },
  destroyed: function() {
    // Adjust user interface.
  }
);

Limitation de la fréquence d'images d'un flux souscrit

Vous pouvez également limiter la fréquence d'images du flux vidéo d'un abonné. Pour limiter la fréquence d'images d'un abonné, appelez la fonction restrictFrameRate() méthode de l'objet Subscriber, en lui transmettant true:

subscriber.restrictFrameRate(true);

Entrer false et la fréquence d'images du flux vidéo n'est pas limitée :

subscriber.restrictFrameRate(false);

Lorsque la fréquence d'images est limitée, l'image vidéo de l'abonné est actualisée une fois ou moins par seconde.

Cette fonctionnalité n'est disponible que dans les sessions utilisant OpenTok Media Router (sessions avec le mode média (réglé sur « routed »), et non dans les sessions où le mode multimédia est réglé sur « relayed ». Dans les sessions de type « relayed », l'appel de cette méthode n'a aucun effet.

La limitation de la fréquence d'images de l'abonné présente les avantages suivants :

  • Il réduit l'utilisation de l'unité centrale.
  • Il réduit la largeur de bande du réseau consommée par l'application.
  • Il vous permet de vous abonner à plusieurs flux simultanément.

La réduction de la fréquence d'images d'un abonné n'a aucun effet sur la fréquence d'images de la vidéo dans les autres clients.

Détection du blocage ou du déblocage de l'audio d'un abonné

Certains navigateurs bloquent automatiquement la lecture des fichiers audio, ce qui oblige à utiliser un logiciel de lecture. click avant que la lecture audio ne commence pour les abonnés. Les navigateurs concernés sont Safari, Firefox 66+ et Chrome 71+.

L'objet « Subscriber » affiche un bouton de lecture audio si la lecture audio est bloquée. Vous pouvez désactiver le bouton de lecture audio par défaut du « Subscriber » et afficher votre propre élément d'interface utilisateur sur lequel l'utilisateur cliquera pour lancer la lecture audio. Voir Affichage d'un élément d'interface utilisateur personnalisé lorsque l'audio de l'abonné est bloqué.

Lorsque le son de l'abonné est bloqué, l'objet « Subscriber » déclenche un audioBlocked événement, et il déclenche un audioUnblocked événement déclenché lorsque le son est réactivé :

subscriber.on({
  audioBlocked: function(event) {
   console.log("Subscriber audio is blocked.")
  },
  audioUnblocked: function(event) {
   console.log("Subscriber audio is unblocked.")
  }
});

Par ailleurs, l'abonné inclut un isAudioBlocked() qui renvoie true si le son est coupé ou false si ce n'est pas le cas.

L'audio de l'abonné est débloqué lorsque l'une des situations suivantes se produit :

  • L'utilisateur clique sur l'icône de lecture audio par défaut de l'abonné.
  • Les OT.unblockAudio() La méthode est appelée en réponse à l'émission d'un événement par un élément HTML. click événement (si vous avez désactivé l'icône de lecture audio par défaut)
  • Le client local obtient l'accès à la caméra ou au microphone (par exemple, à la suite d'un appel réussi vers OT.initPublisher()).

Pour plus d'informations, voir cet article de Mozilla sur l'autoplay dans Firefox et cet article de Google sur la lecture automatique dans Chrome.

Détection de la désactivation de la vidéo d'un abonné

Lorsque la vidéo de l'abonné est désactivée, l'objet « Subscriber » déclenche un videoDisabled événement :

subscriber.on("videoDisabled", function(event) {
  // You may want to hide the subscriber video element:
  domElement = document.getElementById(subscriber.id);
  domElement.style["visibility"] = "hidden";

  // You may want to add or adjust other UI.
});

Lorsque le routeur multimédia OpenTok, ou un éditeur prenant en charge la fonction de repli, désactive la vidéo d'un abonné, vous pouvez souhaiter adapter l'interface utilisateur associée à cet abonné.

Les reason de la propriété videoDisabled définit la raison pour laquelle la vidéo a été désactivée. Il peut prendre l'une des valeurs suivantes :

  • "publishVideo" — L'éditeur a cessé de publier des vidéos en appelant publishVideo(false).

  • "quality" — Le routeur multimédia OpenTok, ou le client de publication si repli audio de l'éditeur est activée, l'envoi de la vidéo à l'abonné est interrompu en fonction des changements de qualité du flux. Cette fonctionnalité de l'OpenTok Media Router fait en sorte que l'abonné interrompe la réception du flux vidéo lorsque la connexion se détériore. (L'abonné continue de recevoir le flux audio, s'il y en a un.) La fonctionnalité de repli audio de l'éditeur fait en sorte que l'éditeur cesse de diffuser le flux vidéo lorsque sa connectivité se détériore, ce qui entraîne la coupure du flux vidéo par l'abonné.

    Avant d'envoyer cet événement, lorsque la qualité du flux de l'abonné se détériore, ou lorsque celle d'un éditeur ayant activé la fonction de repli se détériore, à un niveau suffisamment bas pour que le flux vidéo risque d'être désactivé, l'abonné envoie un videoDisableWarning événement.

    Si la connexion s'améliore et permet à nouveau la diffusion de vidéos, l'objet « Subscriber » déclenche un videoEnabled événement, et l'abonné recommence à recevoir la vidéo.

    Par défaut, l'abonnant affiche un indicateur signalant que la vidéo est désactivée lorsqu'un videoDisabled Un événement associé à ce motif est déclenché et supprime l'indicateur lorsque le videoDisabled Un événement associé à ce motif est déclenché. Vous pouvez contrôler l'affichage de cette icône en appelant la fonction setStyle() méthode de l'abonné, en définissant le videoDisabledDisplayMode propriété ; ou vous pouvez définir le style lors de l'appel de la méthode Session.subscribe() méthode, en définissant le style de la propriété properties paramètre.

    Cette fonctionnalité n'est disponible que dans les sessions utilisant OpenTok Media Router (sessions avec le mode média (configuré sur « routed »), ou dans des sessions avec un éditeur pour lequel la fonction de repli est activée. Voir la section « Activation de la fonction de repli pour l'éditeur » documents.

    Lorsque vous publiez un flux, vous pouvez éviter que sa vidéo soit désactivée en raison de la qualité du flux. Définir audioFallbackEnabled à false dans le properties passé dans l'objet OT.initPublisher() méthode (cette fonctionnalité sera obsolète), ou définir subscriber à false dans le audioFallback objet transmis en tant que properties du paramètre OT.initPublisher() méthode.

  • "subscribeToVideo" — L'abonné a souscrit ou résilié son abonnement à un service vidéo en appelant le subscribeToVideo(false).

  • "codecNotSupported" - L'abonné a cessé de s'abonner à la vidéo en raison d'un codec incompatible (voir la section Codecs vidéo guide du développeur).

L'abonné envoie un videoEnabled lorsque la vidéo reprend :

subscriber.on("videoEnabled", function(event) {
  // You may want to display the subscriber video element,
  // if it was hidden:
  domElement = document.getElementById(subscriber.id);
  domElement.style["visibility"] = "visible";

  // You may want to add or adjust other UI.
});

Les reason de la propriété videoEnabled L'objet « event » définit la raison pour laquelle la vidéo a été activée. Il peut prendre l'une des valeurs suivantes :

  • "publishVideo" — L'éditeur s'est lancé dans la diffusion de vidéos en appelant publishVideo(true).

  • "quality" — Le routeur multimédia OpenTok, ou « éditeur avec fonctionnalité de repli », a repris l’envoi de la vidéo à l’abonné en fonction des variations de qualité du flux. Cette fonctionnalité du routeur multimédia OpenTok permet à l’abonné d’interrompre la diffusion du flux vidéo lorsque la connexion se détériore, puis de la reprendre si la qualité du flux s’améliore. La fonctionnalité de basculement audio de l’éditeur fait en sorte que l’éditeur cesse de diffuser le flux vidéo lorsque sa connectivité se détériore, ce qui entraîne la coupure du flux vidéo par l’abonné.

    Cette fonctionnalité n'est disponible que dans les sessions utilisant OpenTok Media Router (sessions avec le mode média (configuré sur « routed »), ou dans les sessions avec un éditeur pour lequel la fonction de repli est activée.

  • "subscribeToVideo" — L'abonné a souscrit ou résilié son abonnement à un service vidéo en appelant le subscribeToVideo(false).

  • "codecChanged" - La vidéo d'abonné a été activée après un changement de codec à partir d'un codec incompatible (voir la section Codecs vidéo guide du développeur).

Détecter les changements de dimensions de la vidéo diffusée par un abonné

Les dimensions du flux vidéo d'un abonné peuvent changer si un flux publié depuis un appareil mobile est redimensionné, en raison d'un changement d'orientation de l'appareil. Cela peut également se produire si la source vidéo est une fenêtre de partage d'écran et que l'utilisateur qui publie le flux redimensionne la fenêtre servant de source au flux. Lorsque les dimensions de la vidéo changent, l'objet « Subscriber » déclenche un videoDimensionsChanged événement.

Le code suivant redimensionne un abonné lorsque les dimensions de la vidéo du flux changent :

subscriber.on('videoDimensionsChanged', function(event) {
  subscriber.element.style.width = event.newValue.width + 'px';
  subscriber.element.style.height = event.newValue.height + 'px';
  // You may want to adjust other UI.
});

Obtenir des informations sur un flux

L'objet Stream possède les propriétés suivantes qui définissent le flux :

  • connection— L'objet `Connection` correspondant à la connexion qui publie le flux. Vous pouvez le comparer à l'objet connection propriété de l'objet Session permettant de vérifier si le flux est publié par la page Web locale.
  • creationTime—L'horodatage (un nombre) correspondant à la création du flux. Cette valeur est exprimée en millisecondes. Vous pouvez convertir cette valeur en objet Date en appelant new Date(stream.creationTime).
  • hasAudio—(Booléen) Indique si le flux contient du son. Cette propriété peut changer si l'éditeur active ou désactive le son (en appelant Publisher.publishAudio()). Lorsque cela se produit, le Session envoie un streamPropertyChanged événement.
  • hasVideo-(booléen) Indique si le flux contient de la vidéo.
  • initials—(Booléen) Les initiales du flux (si des initiales ont été définies lors de la création de l'éditeur du flux) a été initialisé).
  • name—(Chaîne) Nom du flux. Par défaut, ce nom s'affiche lorsque l'utilisateur passe la souris sur l'abonné dans le DOM HTML. Vous pouvez toutefois personnaliser l'interface utilisateur pour masquer ce nom ou l'afficher sans avoir à passer la souris dessus.
  • videoDimensions—Cet objet possède deux propriétés : width et height. Les deux sont des nombres. Les deux sont des nombres. width est la largeur du flux encodé ; la propriété height est la hauteur du flux encodé. (Ces propriétés sont indépendantes de la largeur réelle des objets Publisher et Subscriber correspondant au flux). Cette propriété peut changer si un flux publié à partir d'un appareil iOS est redimensionné, en fonction d'un changement d'orientation de l'appareil.
  • videoType—Le type de vidéo : « camera », « screen », « custom » ou non défini. Une vidéo de type « screen » utilise le partage d'écran sur le serveur de publication comme source vidéo ; une vidéo de type « custom » utilise un élément VideoTrack comme source vidéo sur le serveur de publication. Le videoType est undefined lorsqu'un flux est uniquement vocal (voir la rubrique Guide vocal). Cette propriété peut changer si un flux publié à partir d'un appareil mobile passe d'un type de caméra à un type de vidéo de partage d'écran. Pour plus d'informations, voir Partage d'écran - Web.

Les hasAudio, hasVideo, videoDimensionset videoType certaines propriétés peuvent changer (par exemple, lorsque l'éditeur active ou désactive la vidéo). Lorsque cela se produit, le Session envoie un streamPropertyChanged événement (voir StreamPropertyChangedEvent.)

Les getStats() La méthode d'un objet `Subscriber` vous fournit des informations sur le flux de l'abonné. Pour obtenir des statistiques de bas niveau sur la connexion entre pairs, utilisez la méthode Subscriber.getRtcStatsReport() . Elle renvoie une promesse qui, en cas de succès, est résolue avec un numéro d'identification. Elle renvoie une promesse qui, en cas de succès, se résout avec un RtcStatsReport objet correspondant au flux auquel l'utilisateur est abonné.

Se référer à le guide du développeur de l'observabilité du client pour obtenir des informations détaillées.

Réglage de la fréquence d'images et de la résolution

Lors de l'abonnement à un flux qui utilise le fonctionnalité vidéo adaptative, vous avez la possibilité de configurer preferredResolution à "auto" pour gérer automatiquement la résolution vidéo des abonnés en fonction de la taille de rendu, afin d'optimiser l'utilisation du réseau et du processeur. Les utilisateurs avancés peuvent également définir manuellement la fréquence d'images et la résolution souhaitées pour le flux que le client abonné reçoit depuis le routeur multimédia OpenTok. Vous pouvez définir ces paramètres comme suit : preferredFrameRate et preferredResolution les propriétés de la options vous entrez dans le [`Session.subscribe()`](/video/sdk-reference/js/Session.html#subscribe) méthode. Nous vous recommandons de définir preferredResolution à "auto". Avec le "auto" Avec ce paramètre, OpenTok.js sélectionne la résolution optimale en fonction des dimensions de la vidéo de l'abonné dans le navigateur. Vous pouvez également définir la fréquence d'images et la résolution souhaitées après vous être abonné à un flux (voir [`Subscriber.setPreferredFrameRate()`](/opentok/sdks/js/reference/Subscriber.html#setPreferredFrameRate) et Subscriber.setPreferredResolution()).

Remarque : Les "auto" Le paramètre de résolution ne s'applique que lorsque vous utilisez l'élément « Subscriber Video » par défaut créé par le SDK. Il ne fonctionne pas si vous créez votre propre élément « Video » en réponse à la videoElementCreated événement (voir ce sujet).

Remarque : Ces préférences supposent que l'éditeur utilise la disposition par défaut de la couche d'évolutivité. Si l'éditeur a défini un mode d'évolutivité cible différent de celui par défaut (voir Configuration du mode d'évolutivité cible), il se peut que la sélection de couche du routeur multimédia ne corresponde pas à la résolution ou à la fréquence d'images demandée. Voir Interaction avec la résolution et la fréquence d'images préférées de l'abonné pour plus de détails.

Appliquer des filtres et des effets aux fichiers audio et vidéo auxquels vous êtes abonné

Vous pouvez appliquer des filtres et des effets aux pistes audio ou vidéo d'un flux auquel vous êtes abonné — voir ce sujet.

Détection des variations de qualité audio et vidéo

Si un client subit des périodes de dégradation de la connectivité réseau, cela peut se répercuter sur la qualité des appels de l'abonné. L'objet « Abonné » envoie un qualityScoreChanged événement survenant lorsque les scores MOS audio et vidéo calculés changent. Ces scores sont exprimés sous forme de nombres entiers compris entre 1 (le pire) et 5 (le meilleur), correspondant respectivement à « mauvais », « médiocre », « passable », « bon » et « excellent ». Pour plus de détails, consultez la section « Abonné » qualityScoreChanged événement.

Un objet « Subscriber » déclenche cet événement uniquement lorsqu'un des scores de qualité a changé. Chaque « Subscribe » déclenche des événements avec ses propres scores de qualité audio et vidéo, selon qu'il s'abonne à l'audio, à la vidéo ou aux deux.

En réponse à ces événements, votre application peut (si vous le souhaitez) signaler au client les conditions réseau entraînant une dégradation de la qualité de l'appel :

subscriber.on('qualityScoreChanged', ({qualityScore}) => {
  if (qualityScore.audioQualityScore <= 3){
    // Alert the user that the remote party is experiencing degraded service
  }
  if (qualityScore.videoQualityScore <= 3){
    // Alert the user that the remote party is experiencing degraded service
  }
});

Dépannage

Suivez les conseils fournis dans cette section pour éviter tout problème de connexion lors de votre abonnement. Pour obtenir des informations générales sur le dépannage, consultez Débogage — Web.

Traitement des erreurs

La gestion des erreurs lors de l'abonnement est un peu plus simple que lors de la publication. Il n'existe qu'une seule façon de s'abonner : avec le Session.subscribe() — et pratiquement toutes les erreurs qui surviennent lors de l'abonnement sont dues à un problème de réseau. Cela peut se produire si, par exemple, l'utilisateur se trouve sur une connexion réseau très restrictive qui n'autorise pas les connexions WebRTC (alors que la connexion WebSocket a fonctionné). Si l’abonné ne parvient pas à se connecter, il affichera simplement son propre message d’erreur à l’intérieur de l’abonné. Ce message n’est pas particulièrement esthétique et n’apporte pas beaucoup d’informations à l’utilisateur final. Nous vous recommandons de gérer ce cas vous-même et d’afficher un message à l’utilisateur indiquant que l’abonnement a échoué et qu’il doit vérifier sa connexion réseau. La gestion de ces erreurs se présente comme suit :

session.subscribe(event.stream, 'subscriber', {insertMode: 'append'}, function (err) {
  if (err) {
    showMessage('Streaming connection failed. This could be due to a restrictive firewall.');
  }
});

Perte de connectivité

Votre abonné peut également perdre sa connexion après s'être connecté avec succès. Le plus souvent, cela entraîne également la perte de connexion de la session, mais ce n'est pas toujours le cas. Il se peut également que ce soit l'éditeur de l'autre côté qui ait perdu la connexion, plutôt qu'une perte de connexion locale. Vous pouvez gérer la déconnexion de l'abonné en surveillant l'événement streamDestroyed événement sur la session avec un reason propriété définie sur « networkDisconnected », comme ceci :

session.on({
  streamDestroyed: function (event) {
    if (event.reason === 'networkDisconnected') {
      event.preventDefault();
      var subscribers = session.getSubscribersForStream(event.stream);
      if (subscribers.length > 0) {
        var subscriber = document.getElementById(subscribers[0].id);
        // Display error message inside the Subscriber
        subscriber.innerHTML = 'Lost connection. This could be due to your internet connection '
          + 'or because the other party lost their connection.';
        event.preventDefault();   // Prevent the Subscriber from being removed
      }
    }
  }
});

Mise en œuvre des tentatives de réabonnement à une session

Des problèmes temporaires d'abonnement peuvent survenir lorsque session.subscribe() est appelée et que la connexion WebRTC sous-jacente ne peut pas être établie à temps, ou lorsqu’un incident réseau interrompt la négociation ICE. Lorsque session.subscribe() En cas d'échec, le SDK renvoie une erreur via la fonction de rappel de son gestionnaire de fin d'exécution. Il est recommandé de mettre en place une logique de nouvelle tentative au niveau de l'application, en prévoyant un délai entre chaque tentative.

Remarque : Prise en charge intégrée des tentatives de reconnexion pour session.subscribe() Cela figure dans la feuille de route du SDK. En attendant sa sortie, vous devrez l'implémenter vous-même.

Pourquoi les échecs d'abonnement se produisent-ils ?

Les causes principales les plus courantes des échecs temporaires d'abonnement sont les suivantes :

  • OT_TIMEOUT (code 1501) : L'abonnement n'a pas pu être effectué dans le délai imparti (30 secondes). Il s'agit de l'équivalent, du côté de l'abonné, du délai d'expiration de publication ; c'est l'erreur la plus courante pouvant faire l'objet d'une nouvelle tentative.
  • Échecs des négociations avec l'ICE (OT_ICE_WORKFLOW_FAILED) : La connexion entre pairs WebRTC n'a pas pu être établie, généralement en raison d'un réseau trop restrictif ou d'un problème de connectivité temporaire.
  • Échecs lors de la création de connexions entre pairs (OT_CREATE_PEER_CONNECTION_FAILED) : La création de l'objet de connexion entre pairs WebRTC a échoué ; cela est souvent dû à un problème temporaire lié à la plateforme ou au réseau.
  • Problèmes de réseau pendant le processus d'abonnement : Une brève interruption du réseau pendant la négociation ICE ou l'établissement de la liaison média peut entraîner l'expiration de l'abonnement sans qu'une erreur grave ne se produise.

Erreurs récupérables et non récupérables

Pas tous session.subscribe() Toutes les erreurs ne se valent pas. Il est essentiel de bien identifier la nature des erreurs avant de tenter une nouvelle opération : réessayer en cas d’erreur irrémédiable fait perdre du temps et peut masquer de véritables défaillances.

Remarque : Utilisez toujours le error.name propriété permettant d'identifier les erreurs par programmation. La valeur numérique error.code Cette propriété est obsolète.

Erreurs irrémédiables — Ne pas réessayer

Ces erreurs correspondent à des contraintes strictes, à un contexte d'appel non valide ou à des états de flux de terminal. Une nouvelle tentative ne permettra pas de les résoudre.

error.name Description Action recommandée
OT_NOT_CONNECTED session.subscribe() a été appelée avant que la session ne soit établie. Garantir session.connect() a été menée à bien avant l'inscription.
OT_DISCONNECTED L'opération a échoué car le client n'est pas connecté à la session. Attendez que la session se reconnecte avant de réessayer.
OT_INVALID_PARAMETER Un ou plusieurs paramètres transmis à session.subscribe() étaient invalides (par exemple, flux nul ou élément cible). Corrigez la logique de l'application. Ne réessayez pas.
OT_STREAM_DESTROYED Le flux a été supprimé avant que l'on ait pu s'y abonner. Ne réessayez pas : le flux n'existe plus. Supprimez tout état d'abonnement en attente pour ce flux.
OT_STREAM_NOT_FOUND Le flux n'a pas pu être trouvé dans la session. Ne réessayez pas : le flux n'est plus disponible.
OT_STREAM_LIMIT_EXCEEDED La session a dépassé la limite du nombre de flux simultanés. Informer l'utilisateur. Ne pas réessayer tant qu'un emplacement de flux n'est pas disponible.
OT_UNABLE_TO_SUBSCRIBE L'utilisateur a tenté de s'abonner au cours d'une session activant le chiffrement de bout en bout (E2EE) sans spécifier de clé de chiffrement ; ou une erreur inattendue a empêché l'abonnement. Pour les sessions E2EE, assurez-vous qu'un secret de chiffrement est défini via session.setEncryptionSecret() avant de s'abonner. Dans le cas général, consignez l'erreur et informez l'utilisateur.

Erreurs récupérables — On peut réessayer en toute sécurité

Ces erreurs sont généralement dues à des perturbations passagères du réseau, à des délais d'attente de signalisation ou à une indisponibilité temporaire de la plateforme.

error.name Description Action recommandée
OT_TIMEOUT (code 1501) L'abonnement n'a pas pu être finalisé dans un délai raisonnable. Il s'agit de l'erreur d'abonnement la plus courante pouvant faire l'objet d'une nouvelle tentative. Se désabonner, puis réessayer en respectant un délai d'attente (jusqu'à 3 tentatives).
OT_ICE_WORKFLOW_FAILED Échec de la négociation ICE : la connexion entre pairs n'a pas pu être établie. Ce phénomène est fréquent sur les réseaux restrictifs. Désabonnez-vous, puis réessayez. Si le problème persiste malgré toutes ces tentatives, informez l'utilisateur d'un éventuel problème lié au réseau ou au pare-feu.
OT_CREATE_PEER_CONNECTION_FAILED La connexion entre pairs WebRTC n'a pas pu être établie. Cela peut être dû à un pare-feu trop restrictif ou à un problème temporaire lié à la plateforme. Désabonnez-vous, puis réessayez. Si le problème persiste, conseillez à l'utilisateur de vérifier sa connexion réseau.
OT_SET_REMOTE_DESCRIPTION_FAILED La connexion WebRTC a échoué pendant setRemoteDescription. Il s'agit généralement d'un problème de signalisation temporaire. Se désabonner, puis réessayer en respectant un délai d'attente.
OT_MEDIA_ERR_ABORTED / OT_MEDIA_ERR_NETWORK L'acquisition du fichier multimédia a été annulée ou interrompue en raison d'une erreur réseau. Désabonnez-vous, puis réessayez après un court délai.
OT_MEDIA_ERR_DECODE Une erreur de décodage s'est produite lors de la lecture du flux dans l'élément vidéo. Désabonnez-vous, puis réessayez après un court délai. Si le problème persiste, le format multimédia est peut-être incompatible.
OT_MEDIA_ERR_SRC_NOT_SUPPORTED Le flux a été identifié comme non compatible avec la lecture. Désabonnez-vous, puis réessayez une fois. Si le problème persiste, vérifiez la configuration de l'élément vidéo de l'abonné.

Important : veillez à toujours vous désabonner avant de réessayer

Contrairement à session.publish(), où l'instance de l'éditeur peut souvent être réutilisée directement, session.subscribe() vous oblige à appeler session.unsubscribe() et supprimer l'objet abonné avant de réessayer. Tenter de réutiliser une instance d'abonné ayant échoué ne fonctionnera pas.

async function subscribeWithRetry(session, stream, targetElement, options, attempt = 1) {
  const MAX_RETRIES = 3;
  const RETRY_DELAY_MS = 3000;

  let subscriber = session.subscribe(stream, targetElement, options);

  const error = await new Promise((resolve) => {
    subscriber.on('subscribeComplete', (err) => resolve(err));
  });

  if (!error) {
    console.log('Subscribed successfully.');
    return subscriber;
  }

  // Always clean up the failed subscriber before retrying
  try { session.unsubscribe(subscriber); } catch (e) { /* ignore */ }

  // Non-recoverable: do not retry
  const nonRetryable = [
    'OT_NOT_CONNECTED',
    'OT_DISCONNECTED',
    'OT_INVALID_PARAMETER',
    'OT_STREAM_DESTROYED',
    'OT_STREAM_NOT_FOUND',
    'OT_STREAM_LIMIT_EXCEEDED',
    'OT_UNABLE_TO_SUBSCRIBE',
  ];

  if (nonRetryable.includes(error.name)) {
    console.error('Non-retryable subscribe error:', error.name);
    handleNonRecoverableError(error);
    return null;
  }

  // Recoverable: retry with backoff
  if (attempt < MAX_RETRIES) {
    console.warn(`Subscribe attempt ${attempt} failed (${error.name}), retrying...`);
    await delay(RETRY_DELAY_MS * attempt);
    return subscribeWithRetry(session, stream, targetElement, options, attempt + 1);
  }

  console.error('All subscribe attempts failed.');
  handleSubscribeFailure(session, stream);
  return null;
}

function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

function handleNonRecoverableError(error) {
  // Surface a meaningful message to the user based on error.name
}

function handleSubscribeFailure(session, stream) {
  // Inform the user that the stream could not be loaded
}

Utilisation :

session.on('streamCreated', (event) => {
  subscribeWithRetry(session, event.stream, document.getElementById('subscriber'), {});
});

Scénarios où le temps est un facteur déterminant

Le flux prend fin lors d'une tentative de réessai

Si le flux est détruit alors qu'une nouvelle tentative est en cours, le streamDestroyed L'événement de session se déclenchera. Vous devez annuler toute nouvelle tentative en attente pour ce flux afin d'éviter de vous abonner à un flux qui n'existe plus.

const pendingRetries = new Map(); // stream.id → timeout handle

session.on('streamDestroyed', (event) => {
  const pending = pendingRetries.get(event.stream.id);
  if (pending) {
    clearTimeout(pending);
    pendingRetries.delete(event.stream.id);
    console.log(`Cancelled pending retry for destroyed stream: ${event.stream.id}`);
  }
});

Reconnexion à la session lors d'une nouvelle tentative d'abonnement

Si la session est en cours de reconnexion (par exemple, après une interruption de connexion), reportez la nouvelle tentative jusqu'à ce que la session soit rétablie. Toute tentative d'abonnement pendant la reconnexion de la session échouera immédiatement.

let isSessionReconnecting = false;

session.on('sessionReconnecting', () => { isSessionReconnecting = true; });
session.on('sessionReconnected', () => {
  isSessionReconnecting = false;
  // Re-trigger any deferred subscriptions here
});

// In your retry logic, check before retrying:
if (isSessionReconnecting) {
  // Defer — wait for sessionReconnected before retrying
  return;
}

Ce qu'il ne faut PAS faire

  • Faire pas réutiliser une instance d'abonné ayant échoué — toujours appeler session.unsubscribe() et créer un nouvel abonnement lors de la nouvelle tentative.
  • Faire pas réessayer le OT_STREAM_DESTROYED ou OT_STREAM_NOT_FOUND — le flux a disparu et toute nouvelle tentative échouera systématiquement.
  • Faire pas réessayer le OT_STREAM_LIMIT_EXCEEDED — Il s'agit d'une contrainte de capacité au niveau de la session, et non d'une erreur temporaire.
  • Faire pas réessayer indéfiniment — limiter à 3 tentatives et avertir l'utilisateur si toutes échouent.
  • Faire pas réessayer pendant que la session se reconnecte — reporter jusqu’à ce que sessionReconnected incendies.

Résumé des paramètres recommandés

Paramètres Valeur recommandée Notes
Nombre maximal de tentatives 3 Conformément à session.publish() instructions de nouvelle tentative
Délai avant nouvelle tentative 3 s × essai (3 s, 6 s, 9 s) Légèrement plus long que les tentatives de publication — le délai d'expiration de l'abonnement est de 30 s
En cas d'échec de toutes les tentatives de réessai Informer l'utilisateur Évitez de fermer le flux sans avertissement
Erreurs ne pouvant pas faire l'objet d'une nouvelle tentative OT_STREAM_DESTROYED, OT_STREAM_NOT_FOUND, OT_STREAM_LIMIT_EXCEEDED Échouez rapidement sur ces points
Nettoyage de la liste des abonnés Toujours session.unsubscribe() avant de réessayer Obligatoire — contrairement aux éditeurs, les instances d'abonnés ne peuvent pas être réutilisées