Diffusion de flux — Web

Une fois que vous avez connecté à une sessionvous pouvez publier un flux que les autres clients connectés à la session peuvent visualiser.

Cette rubrique comprend les sections suivantes :

Vérifier si un client dispose de capacités de publication

Une fois que vous êtes connecté à une session, vous pouvez vérifier si le client est en mesure de publier. Vérifiez la valeur du capabilities.publish de la propriété Session objet. S'il vaut 1, le client peut publier :

if (session.capabilities.publish == 1) {
    // The client can publish. See the next section.
} else {
    // The client cannot publish.
    // You may want to notify the user.
}

Pour publier, le client doit se connecter à la session à l'aide d'un jeton auquel est attribué un rôle qui prend en charge la publication. Une caméra et un microphone doivent être connectés. L'environnement du client doit également prendre en charge la publication (voir Prise en charge des navigateurs).

En outre, la publication n'est possible que sur les pages HTTPS.

Initialisation d'un éditeur

Les OT.initPublisher() initialise et renvoie un objet éditeur. L'objet Publisher représente la vue d'une vidéo que vous publiez :

var publisher;
var targetElement = 'publisherContainer';

publisher = OT.initPublisher(targetElement, null, function(error) {
  if (error) {
    // The client cannot publish.
    // You may want to notify the user.
  } else {
    console.log('Publisher initialized.');
  }
});

Les OT.initPublisher() prend trois paramètres :

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

  • properties- (Facultatif) Un ensemble de propriétés qui personnalisent l'éditeur. Les propriétés properties Ce paramètre comprend également des options permettant de spécifier un périphérique d'entrée audio et vidéo utilisé par l'éditeur (voir Configuration de la caméra et du microphone utilisés par l'éditeur). Les properties Ce paramètre comprend également des options permettant de personnaliser l'apparence de la vue dans la page HTML (voir Personnaliser l'interface utilisateur) et choisir de publier ou non des fichiers audio et vidéo (voir Publication d'audio ou de vidéo uniquement). Pour découvrir d'autres options d'édition, consultez la documentation de la properties du paramètre OT.initPublisher() méthode.

  • completionHandler- (Facultatif) Un gestionnaire d'achèvement qui spécifie si l'éditeur a été instancié avec succès ou avec une erreur.

Vous pouvez transmettre cet objet Publisher à la fonction Session.publish() méthode permettant de publier un flux vers une session. Voir Publication d'un flux.

Avant d'appeler Session.publish()Vous pouvez utiliser cet objet Publisher pour tester le microphone et la caméra attachés au Publisher.

Les insertMode de la propriété properties du paramètre OT.initPublisher() 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 Publisher remplace le contenu de l'élément targetElement. Il s'agit de la valeur par défaut.
  • "after" - L'objet Publisher est un nouvel élément inséré après l'élément cible dans le DOM HTML. (Le Publisher et le targetElement ont tous deux le même élément parent).
  • "before" - L'objet Publisher est un nouvel élément inséré avant l'élément cible dans le DOM HTML. (Le Publisher et le targetElement ont tous deux le même élément parent).
  • "append" - L'objet Publisher est un nouvel élément ajouté en tant qu'enfant de l'élément cible. S'il existe d'autres éléments enfants, l'objet Publisher est ajouté en tant que dernier élément enfant de l'élément cible.

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

// Try setting insertMode to other values: "replace", "after", or "before":
var publisherProperties = {insertMode: "append"};
var publisher = OT.initPublisher('publisherContainer', publisherProperties, function (error) {
  if (error) {
    console.log(error);
  } else {
    console.log("Publisher initialized.");
  }
});

Détecter quand un client a autorisé l'accès à la caméra et au microphone

Avant qu'un objet Publisher puisse accéder à la caméra et au microphone du client, l'utilisateur doit lui accorder l'accès. L'objet Publisher déclenche des événements lorsque l'utilisateur autorise ou refuse l'accès à la caméra et au microphone :

publisher.on({
  accessAllowed: function (event) {
    // The user has granted access to the camera and mic.
  },
  accessDenied: function accessDeniedHandler(event) {
    // The user has denied access to the camera and mic.
  }
});

De plus, un objet Publisher déclenche des événements lorsque l'utilisateur est invité à autoriser ou à refuser l'accès à la caméra et au microphone :

publisher.on({
  accessDialogOpened: function (event) {
    // The Allow/Deny dialog box is opened.
  },
  accessDialogClosed, function (event) {
    // The Allow/Deny dialog box is closed.
  }
});

L'éditeur dispose d'un accessAllowed propriété qui indique si un client dispose (true) ou n'a pas (false) a autorisé l'accès à la caméra et au microphone.

Configuration de la caméra et du microphone utilisés par l'éditeur

Vous pouvez (en option) spécifier un périphérique d'entrée audio et vidéo à utiliser par l'éditeur. Lorsque vous appelez la fonction OT.initPublisher() vous pouvez (facultativement) définir la méthode audioSource et videoSource les propriétés de la properties passé dans l'objet OT.initPublisher() méthode.

Tout d'abord, utilisez l'outil OT.getDevices() pour énumérer les appareils disponibles. Le tableau d'appareils est transmis en tant que paramètre devices du paramètre callback passée dans la fonction OT.getDevices() méthode. Par exemple, le code suivant permet d'obtenir une liste de périphériques d'entrée audio et vidéo :

var audioInputDevices;
var videoInputDevices;
OT.getDevices(function(error, devices) {
  audioInputDevices = devices.filter(function(element) {
    return element.kind == "audioInput";
  });
  videoInputDevices = devices.filter(function(element) {
    return element.kind == "videoInput";
  });
  for (var i = 0; i < audioInputDevices.length; i++) {
    console.log("audio input device: ", audioInputDevices[i].deviceId);
  }
  for (i = 0; i < videoInputDevices.length; i++) {
    console.log("video input device: ", videoInputDevices[i].deviceId);
  }
});

Chaque dispositif répertorié par OT.getDevices() possède un identifiant unique, défini comme l'identifiant deviceId propriété. Vous pouvez utiliser ces valeurs d'identification de l'appareil comme audioSource et videoSource les propriétés de la properties passé dans l'objet OT.initPublisher():

var pubOptions =
  {
    audioSource: audioInputDevices[0].deviceId,
    videoSource: videoInputDevices[0].deviceId
  };
var publisher = OT.initPublisher(null, pubOptions, function(error) {
  console.log("OT.initPublisher error: ", error);
});

Régler le videoSource à la propriété null ou false dans une session vocale uniquement (voir Publier dans une session vocale).

Les Composant de configuration matérielle OpenTok fournit une interface utilisateur permettant aux clients de sélectionner la caméra et le microphone à utiliser. Il est construit à l'aide du logiciel OT.getDevices() méthode.

Notez que vous pouvez également publier un flux de partage d'écran, dans lequel la source est l'écran du client et non une caméra. Pour plus d'informations, voir Partage d'écran.

Vous pouvez également changer l'appareil photo utilisé par l'éditeur, ou le configurer pour qu'il utilise le caméra avant ou arrière (lorsque cette option est disponible).

Vous pouvez également changer la source audio utilisée par l'éditeur.

Utilisation de la caméra avant ou arrière

Lorsque vous initialisez un éditeur, vous pouvez définir le facingMode propriété de l'objet « options » que vous transmettez à la fonction OT.initPublisher(). Par exemple, vous pouvez définir la propriété sur "user" (caméra avant) ou "environment" (caméra arrière), lorsque cette option est disponible sur le système du client. (En général, ces options ne sont disponibles que sur les appareils mobiles.)

Si vous réglez le facingMode option, faire pas fixer le videoSource propriété.

Mémorisation du choix de la caméra et du microphone

Pour des raisons de sécurité, lorsque les pages sont chargées via HTTP, tous les navigateurs demandent systématiquement à l'utilisateur de sélectionner la caméra et le microphone utilisés pour diffuser un flux.

Dans les pages chargées via HTTPS dans Chrome, les préférences de l'utilisateur concernant la caméra et le microphone sont mémorisées et réutilisées lors des visites suivantes sur une page chargée à partir du même domaine HTTPS.

Dans les pages chargées via HTTPS dans Firefox, l'utilisateur a la possibilité de choisir de mémoriser l'accès à la caméra et au microphone (lors de ses prochaines visites sur une page chargée à partir du même domaine HTTPS) lorsqu'il sélectionne ces périphériques.

Dans les pages chargées via HTTPS dans Internet Explorer, vous pouvez utiliser les paramètres de caméra et de microphone précédemment sélectionnés par l'utilisateur lors d'une utilisation antérieure sur le même domaine HTTPS (le cas échéant), en définissant le paramètre usePreviousDeviceSelection à la propriété true dans les options que vous passez dans le OT.initPublisher() méthode :

var pubOptions = {usePreviousDeviceSelection: true};
var publisher = OT.initPublisher(null, pubOptions, function(error) {
  console.log("OT.initPublisher error: ", error);
});

Pour inviter l'utilisateur à sélectionner la caméra et le microphone à utiliser dans IE (et ignorer les sélections précédentes), procédez comme suit : pas fixer le usePreviousDevices dans les options que vous passez dans le OT.initPublisher() (ou lui attribuer la valeur false(par défaut).

Désactivation de la gestion des périphériques d'entrée audio par défaut

Par défaut, le SDK gère automatiquement le changement de périphérique d'entrée audio lorsqu'un nouveau périphérique est branché. Ce comportement peut ne pas convenir à certains utilisateurs finaux qui souhaitent conserver leur microphone actuel.

En tant qu'utilisateur avancé du SDK, vous pouvez désactiver la gestion automatique des périphériques d'entrée audio. Pour ce faire, configurez le disableAudioInputDeviceManagement aux options passées dans la fonction OT.initPublisher() méthode :

var pubOptions = {disableAudioInputDeviceManagement: true};
var publisher = OT.initPublisher(null, pubOptions, function(error) {
  console.log("Publishing a stream");
});

Remarque : Il s'agit d'une fonctionnalité avancée. Si vous l'activez, le périphérique d'entrée audio utilisé par le SDK ne sera pas être mis à jour lorsque l'utilisateur final change de microphone.

Publication d'un flux

Une fois que vous avez créé un objet Publisher (voir Initialisation d'un éditeur), vous pouvez le transmettre à la publish() d'un objet Session pour publier un flux dans la session :

    publisher = OT.initPublisher('replacementElementId');
    session.publish(publisher, function(error) {
      if (error) {
        console.log(error);
      } else {
        console.log('Publishing a stream.');
      }
    });

Le second paramètre est une fonction de gestion de l'achèvement à laquelle est transmis un objet d'erreur si la publication échoue. Dans le cas contraire, la fonction de gestion de l'achèvement est appelée sans qu'aucune erreur ne soit transmise.

Ce code suppose que session est un objet Session et que le client s'est connecté à la session. Pour plus d'informations, voir Rejoindre une session.

L'objet Publish envoie un streamCreated lorsqu'il commence à diffuser des informations dans la session :

var publisher = OT.initPublisher();
session.publish(publisher, function(error) {
  if (error) {
    console.log(error);
  } else {
    console.log('Publishing a stream.');
  }
});
publisher.on('streamCreated', function (event) {
    console.log('The publisher started streaming.');
});

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

Empêcher un éditeur de diffuser en continu vers une session

Vous pouvez empêcher l'éditeur de diffuser en continu vers la session en appelant la méthode unpublish() de l'objet Session :

    session.unpublish(publisher);

Notez que vous pouvez interrompre séparément la diffusion de la vidéo ou de l'audio (tout en continuant à diffuser). Pour plus d'informations, consultez Réglage de l'audio et de la vidéo.

Détection de la sortie d'une session d'un flux publié

L'objet Publisher envoie un streamDestroyed lorsqu'il cesse d'alimenter la session :

var publisher = OT.initPublisher();
session.publish(publisher);
publisher.on("streamDestroyed", function (event) {
  console.log("The publisher stopped streaming. 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 éditeur envoie la commande streamDestroyed l'éditeur est détruit et supprimé du DOM HTML. Vous pouvez empêcher ce comportement par défaut en appelant la fonction preventDefault() de l'objet StreamEvent :

publisher.on("streamDestroyed", function (event) {
    event.preventDefault();
    console.log("The publisher stopped streaming.");
});

Il se peut que vous souhaitiez empêcher le comportement par défaut et conserver l'objet Publisher si vous souhaitez réutiliser l'objet Publisher pour publier à nouveau dans la session.

L'éditeur envoie également 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'éditeur qui a été supprimé.

Réglage de la résolution vidéo d'un flux

Pour définir une résolution vidéo recommandée pour un flux publié, définissez le paramètre resolution de la propriété properties que vous passez dans le paramètre OT.initPublisher() méthode :

var publisherProperties = {resolution: '1280x720'};
var publisher = OT.initPublisher(targetElement,
                                 publisherProperties);
publisher.on('streamCreated', function(event) {
   console.log('Stream resolution: ' +
     event.stream.videoDimensions.width +
     'x' + event.stream.videoDimensions.height);
});

Le présent resolution est une chaîne de caractères définissant la résolution souhaitée pour la vidéo. Le format de la chaîne est le suivant "_width_x_height_"où la largeur et la hauteur sont représentées en pixels. Les valeurs valables sont "1920x1080", "1280x720", "640x480"et "320x240".

La résolution demandée pour un flux vidéo est définie comme suit : videoDimensions.width et videoDimensions.height propriétés de l'objet Stream.

La résolution par défaut d'un flux (si vous ne spécifiez pas de résolution) est de 640x480 pixels. Si le système client ne peut pas prendre en charge la résolution que vous avez demandée, le flux utilisera le paramètre suivant le plus élevé.

Les videoHeight() et videoWidth() renvoient la résolution configurée de l'objet éditeur. La résolution réelle d'un flux vidéo d'abonné est renvoyée par la méthode videoWidth() et videoHeight() de l'objet Abonné. Ces valeurs peuvent être différentes de celles de l'objet resolution propriété transmise en tant que properties de la propriété OT.initPublisher() méthode, si le navigateur de publication ne prend pas en charge la résolution demandée.

Remarque : Voir le Guide du développeur 1080p pour les considérations relatives à l'utilisation de la résolution 1080p.

Réglage de la fréquence d'images d'un flux

Pour définir une fréquence d'images recommandée pour un flux publié, définissez le paramètre frameRate de la propriété properties que vous passez dans le paramètre OT.initPublisher() méthode :

var publisherProperties = {frameRate: 7};
var publisher = OT.initPublisher(targetElement,
                                 publisherProperties);
publisher.on('streamCreated', function(event) {
   console.log('Frame rate: ' + event.stream.frameRate);
});

Définissez la valeur correspondant à la fréquence d'images souhaitée, en images par seconde, pour la vidéo. Les valeurs valides sont 30, 15, 7 et 1.

Si l'éditeur spécifie une fréquence d'images, la fréquence d'images réelle du flux vidéo est définie comme la fréquence d'images de l'éditeur. frameRate de l'objet Stream, bien que la fréquence d'images réelle varie en fonction des conditions changeantes du réseau et du système. Si vous ne spécifiez pas de fréquence d'images lorsque vous appelez OT.initPublishercette propriété n'est pas définie.

Pour les sessions qui utilisent OpenTok Media Router (sessions avec le mode média (réglé sur « routed »), la réduction de la fréquence d'images diminue proportionnellement la bande passante maximale que le flux peut utiliser. Cependant, lors d'une session avec le mode média est réglé sur relayed, la réduction de la fréquence d'images ne réduit pas la bande passante du flux.

Vous pouvez également limiter la fréquence d'images du flux vidéo d'un abonné. Pour plus d'informations, consultez Limitation de la fréquence d'images d'un flux souscrit.

Définition du débit maximal d'un flux

Vous pouvez définir le débit binaire maximal d'un flux publié. La définition d'un débit binaire maximal peut contribuer à réduire la consommation de bande passante lorsqu'un utilisateur se connecte via une connexion à volume limité. Voir cette documentation.

Supprimer un éditeur

Vous pouvez supprimer un éditeur en appelant son destroy() méthode :

    publisher.destroy();

Appeler le destroy() Cette méthode supprime l'objet Publisher et le retire du DOM HTML.

Obtenir des statistiques sur le flux d'un éditeur

Les Publisher.getStats() Cette méthode vous fournit un tableau d'objets définissant les statistiques audio-vidéo actuelles de l'éditeur. Pour un éditeur participant à une session acheminée (c'est-à-dire une session qui utilise le Routeur multimédia OpenTok), ce tableau contient un seul objet, qui définit les statistiques relatives au flux audio-vidéo unique envoyé au routeur multimédia OpenTok. Dans le cadre d'une session relayée, le tableau contient un objet pour chaque abonné au flux publié.

Pour obtenir des statistiques détaillées de bas niveau sur les connexions entre pairs, utilisez la commande Publisher.getRtcStatsReport() méthode. Elle renvoie une promesse qui, en cas de réussite, se résout en un tableau de RtcStatsReport objets.

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

Tester le flux d'un éditeur

Vous pouvez publier un flux de test et vérifier ses statistiques audio et vidéo afin de déterminer le type de flux (haute résolution ou audio uniquement) pris en charge par votre connexion.

Pour obtenir les statistiques relatives à un flux publié par le client local, vous devez utiliser une session qui exploite OpenTok Media Router (les sessions avec le mode média (réglé sur « routed »), et vous devez définir le testNetwork à la propriété true dans le options que vous passez dans l'objet Session.subscribe() méthode. Vous pouvez alors utiliser la méthode getStats() méthode de l'objet `Subscriber` permettant d'obtenir les statistiques audio et vidéo du flux que vous publiez. Voir ce sujet pour plus d'informations.

Les test-du-réseau-opentok comprend un exemple de code montrant comment utiliser les statistiques d'un flux de test avant de le publier dans une session.

Diffusion d'une vidéo provenant d'une source autre qu'une caméra ou un écran

Vous pouvez définir la source vidéo d'un Publisher sur une vidéo MediaStreamTrack objet. Cela vous permet d'effectuer les opérations suivantes :

  • Publier une vidéo en utilisant un élément HTML « Canvas » comme source vidéo. Vous pouvez appeler le captureStream() de la méthode HTMLCanvasElement objet et appeler la méthode getVideoTracks() méthode de la fonction résultante CanvasCaptureMediaStream objet permettant d'obtenir un objet MediaStreamTrack de type vidéo. Pour un exemple simple, consultez l'exemple « Publish-Canvas ». repo opentok-web-samples sur GitHub.

  • Publier une vidéo à partir d'un élément « Vidéo ». Appelez le captureStream() méthode d'un HTMLVideoElement objet permettant d'obtenir un objet MediaStream. Le getVideoTracks() La méthode de l'objet MediaStream renvoie un tableau d'objets MediaStreamTrack audio (généralement un seul). Vous pouvez ensuite utiliser l'objet MediaStreamTrack comme audioSource de la propriété options que vous passez dans l'objet OT.initPublisher() méthode. Pour un exemple simple, consultez l'exemple « Publish-Video » repo opentok-web-samples sur GitHub.

Vous pouvez utiliser un objet MediaStreamTrack vidéo en tant qu'objet videoSource de la propriété options que vous passez dans l'objet OT.initPublisher() (méthode de publication). La vidéo représentée par l'objet MediaStreamTrack devient alors la source vidéo du flux publié.

Diffusion d'un flux audio provenant d'une source autre qu'un microphone

Vous pouvez définir la source audio d'un Publisher sur un fichier audio MediaStreamTrack objet. Cela vous permet d'effectuer les opérations suivantes :

  • Publier le contenu audio d'un élément « Audio » ou « Vidéo ». Appelez le captureStream() méthode d'un HTMLAudioElement objet ou un HTMLVideoElement objet permettant d'obtenir un objet MediaStream. Le getAudioTracks() La méthode de l'objet MediaStream renvoie un tableau d'objets MediaStreamTrack audio (généralement un seul). Vous pouvez ensuite utiliser l'objet MediaStreamTrack comme audioSource de la propriété options que vous passez dans l'objet OT.initPublisher() méthode.
  • Publier le flux audio à partir d'un objet MediaStreamTrack de type audio. Par exemple, vous pouvez utiliser le AudioContext objet et le API audio Web pour générer du son de manière dynamique. Vous pouvez ensuite appeler createMediaStreamDestination().stream.getAudioTracks()[0] sur l'objet AudioContext pour obtenir l'objet MediaStreamTrack audio à utiliser en tant qu'objet audioSource de la propriété options que vous passez dans l'objet OT.initPublisher() méthode. Pour un exemple simple, consultez l'exemple « Stereo-Audio » repo opentok-web-samples sur GitHub.

Appliquer des filtres et des effets aux fichiers audio et vidéo publiés

Vous pouvez appliquer des filtres et des effets, tels que le remplacement ou le flou de l'arrière-plan, à l'audio ou à la vidéo provenant d'un microphone ou d'une caméra utilisés comme source audio ou vidéo pour un flux publié — voir ce sujet.

Définition de conseils sur le contenu vidéo pour améliorer les performances de la vidéo dans certaines situations

Vous pouvez définir un indice de contenu vidéo afin d'améliorer la qualité et les performances d'une vidéo publiée. Cela peut s'avérer utile dans certaines situations :

  • Lors de la publication d'une vidéo de partage d'écran, celle-ci contiendra principalement du texte ou du contenu vidéo.
  • Lorsque vous utilisez une source vidéo provenant d'une caméra, si vous préférez réduire la fréquence d'images tout en conservant la résolution, vous pouvez définir l'indicateur de contenu sur « texte » ou « détail ». Dans une session acheminée, si l'éditeur prend en charge l'utilisation de vidéo évolutive, il enverra un flux en pleine résolution à faible fréquence d'images et — si les conditions du réseau le permettent — un flux en pleine résolution à fréquence d'images normale. Le routeur multimédia OpenTok transmettra l'un de ces flux aux abonnés.

Cela indique au navigateur d'utiliser des méthodes d'encodage ou de traitement plus appropriées au type de contenu que vous spécifiez.

Définir l'indice de contenu vidéo initial pour un flux en définissant le paramètre videoContentHint des options que vous passez dans la fonction OT.initPublisher() méthode :

var publisherOptions = {
  videoContentHint: "text",
  // other options, such as videoSource: "screen"
};
var publisher = OT.initPublisher(targetElement, publisherOptions, callbackFunction);

Vous pouvez modifier l'indice de contenu vidéo de manière dynamique en appelant la fonction setVideoContentHint() d'un objet Publisher :

publisher.setVideoContentHint("motion");

Vous pouvez définir l'indice de contenu vidéo sur l'une des valeurs suivantes :

  • "" - Aucune indication n'est fournie (par défaut). Le client de publication fera une estimation de la manière dont le contenu vidéo doit être traité.
  • "motion" - La piste doit être traitée comme si elle contenait de la vidéo lorsque le mouvement est important. Par exemple, vous pouvez utiliser ce paramètre pour un flux vidéo de partage d'écran qui contient de la vidéo.
  • "detail" - La piste doit être traitée comme si les détails de la vidéo étaient très importants. Par exemple, vous pouvez utiliser ce paramètre pour un flux vidéo de partage d'écran contenant du texte, des peintures ou des dessins au trait.
  • "text" - La piste doit être traitée comme si les détails du texte étaient très importants. Par exemple, vous pouvez utiliser ce paramètre pour un flux vidéo de partage d'écran contenant du texte.

Pour les indices de contenu "texte" et "détaillé", le navigateur tente de maintenir une résolution élevée, même s'il doit réduire la fréquence d'images vidéo. Pour l'indication de contenu "motion", le navigateur réduit la résolution pour éviter que la fréquence d'images ne s'arrête.

Pour en savoir plus sur ces options, consultez le Projet de travail du W3C.

Chrome 60 et versions ultérieures, Safari 12.1 et versions ultérieures, Edge 79 et versions ultérieures, Opera 47 et versions ultérieures, les versions récentes de Samsung Internet, WebView sous Android 70 et versions ultérieures, ainsi que WebView sous iOS 12.2 et versions ultérieures prennent en charge les indications relatives au contenu vidéo. Ce paramètre est ignoré dans les autres navigateurs.

Si vous pouvez vous accommoder d'une fréquence d'images réduite, vous pouvez également envisager limiter la fréquence d'images des flux auxquels on est abonné pour améliorer la qualité.

Solution de secours pour l'éditeur audio

Consultez le guide du développeur pour repli audio . La fonctionnalité de solution de secours audio de l'éditeur offre un suivi amélioré de la bande passante et de la qualité afin d'optimiser les communications.

Autres options audio et vidéo

Consultez le guide du développeur pour Réglage de l'audio et de la vidéo.

Bonnes pratiques de publication

Cette section contient des conseils pour publier des flux avec succès.

Autoriser l'accès aux appareils

Il est recommandé d'informer vos utilisateurs qu'ils seront invités à autoriser l'accès à leur caméra et à leur microphone. Nous constatons que la grande majorité des échecs de publication sont dus au fait que les utilisateurs cliquent sur le bouton « Refuser » ou n'appuient tout simplement pas sur le bouton « Autoriser ». Nous mettons à votre disposition tous les événements dont vous avez besoin pour guider vos utilisateurs tout au long de ce processus :

publisher.on({
  accessDialogOpened: function (event) {
    // Show allow camera message
    pleaseAllowCamera.style.display = 'block';
  },
  accessDialogClosed: function (event) {
    // Hide allow camera message
    pleaseAllowCamera.style.display = 'none';
  }
});

C'est également une bonne idée d'utiliser le protocole SSL pour votre site web. En effet, Chrome ne demande aux utilisateurs de cliquer sur l'autorisation d'accès aux appareils qu'une seule fois par domaine si ce dernier est desservi par SSL. Cela signifie que vos utilisateurs (s'ils utilisent Chrome) n'ont pas à faire face à cette boîte de dialogue d'autorisation ou de refus à chaque fois qu'ils chargent la page.

Séparer OT.initPublisher() et Session.publish()

Nous recommandons également de diviser le OT.initPublisher() et Session.publish() étapes. Cela accélère le temps de connexion initial car vous vous connectez à la session en attendant que l'utilisateur clique sur le bouton d'autorisation. Ainsi, au lieu de :

session.connect(token, function (err) {
{... your error handling code ...}
if (!err) {
    var publisher = OT.initPublisher();
    session.publish(publisher);
  }
});

Déplacer le OT.initPublisher() avant de vous connecter, comme dans l'exemple suivant :

var publisher = OT.initPublisher();
session.connect(token, function (err) {
{... your error handling code ...}
  if (!err) {
    session.publish(publisher);
  }
});

Résolution et fréquence d'images

Vous pouvez définir la résolution et la fréquence d'images de l'éditeur lorsque vous l'initialisez :

OT.initPublisher(divId, {
  resolution: '320x240',
  frameRate: 15
});

Par défaut, la résolution d'un éditeur est de 640x480, mais vous pouvez également la régler sur 1920x1080, 1280x720 ou 320x240. Il est préférable d'essayer de faire correspondre la résolution à la taille d'affichage de la vidéo. Si vous n'affichez la vidéo qu'à 320x240 pixels, il est inutile de la diffuser à 1280x720 ou 1920x1080. La réduction de la résolution permet d'économiser de la bande passante et de réduire les encombrements et les interruptions de connexion.

Par défaut, la fréquence d'images de la vidéo est de 30 images par seconde, mais vous pouvez également la régler sur 15, 7 ou 1. La réduction de la fréquence d'images permet de réduire la bande passante requise. Les vidéos à faible résolution peuvent avoir une fréquence d'images plus faible sans que l'utilisateur perçoive une différence notable. Par conséquent, si vous utilisez une faible résolution, vous pouvez également envisager d'utiliser une faible fréquence d'images.

Pour plus d'informations, consultez la documentation relative à OT.initPublisher().

Dépannage

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

Traitement des erreurs

Il existe des méthodes de rappel pour les deux Session.publish() et OT.initPublisher(). Nous recommandons de gérer les réponses d'erreur à ces deux méthodes. Comme nous l'avons déjà mentionné, il est préférable de séparer ces étapes et d'appeler OT.initPublisher() avant d'avoir commencé à vous connecter à votre session. Il est également plus facile de gérer les erreurs si vous n'appelez pas ces deux méthodes en même temps. En effet, les deux gestionnaires d'erreurs se déclenchent en cas de publication d'une erreur. Il est préférable d'attendre que OT.initPublisher() à compléter et Session.connect() et appeler ensuite Session.publish(). De cette façon, vous pouvez traiter tous les problèmes liés au matériel dans l'espace de travail. OT.initPublisher() et tous les problèmes liés au réseau dans le Session.publish() rappel.

var connected = false,
  publisherInitialized = false;

var publisher = OT.initPublisher(function(err) {
  if (err) {
    // handle error
  } else {
    publisherInitialized = true;
    publish();
  }
});

var publish = function() {
  if (connected && publisherInitialized) {
    session.publish(publisher);
  }
};

session.connect(token, function(err) {
  if (err) {
    // handle error
  } else {
    connected = true;
    publish();
  }
});

Accès refusé

Le plus grand nombre d'échecs de OT.initPublisher() sont dues au fait que l'utilisateur final refuse l'accès à la caméra et au microphone. Il est possible d'y remédier en écoutant le message accessDenied ou en écoutant une réponse d'erreur à la méthode OT.initPublisher() avec une valeur de code fixée à 1500 et un message avec la valeur "Publisher Access Denied :". Nous vous recommandons de traiter ce cas et d'envoyer un message à l'utilisateur pour lui indiquer qu'il doit réessayer de publier et autoriser l'accès à la caméra.

publisher.on({
  'accessDenied': function() {
    showMessage('Please allow access to the Camera and Microphone and try publishing again.');
  }
});

Accès au dispositif

Une autre raison pour OT.initPublisher() L'échec d'OpenTok est dû au fait qu'il ne peut pas accéder à une caméra ou à un microphone. Cela peut se produire s'il n'y a pas de caméra ou de microphone attaché à la machine, s'il y a un problème avec le pilote de la caméra ou du microphone, ou si une autre application utilise la caméra ou le microphone (cela ne se produit que sous Windows). Vous pouvez essayer de minimiser l'occurrence de ces problèmes en utilisant notre composant de configuration du matériel ou en appelant la fonction OT.getDevices() directement. Cependant, vous devez également gérer toute erreur lors de l'appel de la méthode OT.initPublisher() car un problème peut toujours survenir. Par exemple, l'utilisateur peut avoir refusé l'accès à la caméra ou au microphone. Dans ce cas, le error.name est fixée à "OT_USER_MEDIA_ACCESS_DENIED":

publisher = OT.initPublisher('publisher', {}, function (err) {
  if (err) {
    if (err.name === 'OT_USER_MEDIA_ACCESS_DENIED') {
      // Access denied can also be handled by the accessDenied event
      showMessage('Please allow access to the Camera and Microphone and try publishing again.');
    } else {
      showMessage('Failed to get access to your camera or microphone. Please check that your webcam'
        + ' is connected and not being used by another application and try again.');
    }
    publisher.destroy();
    publisher = null;
  }
});

Erreurs de réseau

Les autres raisons des échecs de publication sont généralement dues à une défaillance du réseau. Nous les gérons dans le rappel à Session.publish(). Si l'utilisateur n'est pas connecté au réseau, la fonction de rappel reçoit un objet d'erreur avec la valeur name est définie comme étant la propriété "OT_NOT_CONNECTED". Si l'utilisateur se trouve sur un réseau très restrictif qui n'autorise pas les connexions WebRTC, le Publisher ne parvient pas à se connecter et l'élément Publisher affiche simplement une roue qui tourne. Cette erreur est associée à un name est définie comme étant la propriété "OT_CREATE_PEER_CONNECTION_FAILED". Dans ce cas, nous vous recommandons d'envoyer un message à l'utilisateur pour lui indiquer qu'il n'a pas réussi à publier et qu'il doit vérifier sa connexion réseau. La gestion de ces erreurs se fait de la manière suivante :

session.publish(publisher, function(err) {
  if (err) {
    switch (err.name) {
      case "OT_NOT_CONNECTED":
        showMessage("Publishing your video failed. You are not connected to the internet.");
        break;
      case "OT_CREATE_PEER_CONNECTION_FAILED":
        showMessage("Publishing your video failed. This could be due to a restrictive firewall.");
        break;
      default:
        showMessage("An unknown error occurred while trying to publish your video. Please try again later.");
    }
    publisher.destroy();
    publisher = null;
  }
});

Perte de connectivité

Votre éditeur peut également perdre sa connexion après avoir réussi à se connecter. Le plus souvent, la Session perd également sa connexion, mais ce n'est pas toujours le cas. Vous pouvez gérer la déconnexion de l'éditeur en écoutant la commande streamDestroyed avec un reason à "networkDisconnected" comme suit :

publisher.on({
  streamDestroyed: function (event) {
    if (event.reason === 'networkDisconnected') {
      showMessage('Your publisher lost its connection. Please check your internet connection and try publishing again.');
    }
  }
});

La mise en place de l'ensemble

Le code suivant crée un éditeur, se connecte à une session (voir Notions de base sur les sessions), publie un flux dans la session lorsque le client se connecte à la session, et détecte quand l'éditeur démarre et arrête le flux :

var session;
var publisher;

// Replace with the replacement element ID:
publisher = OT.initPublisher(replacementElementId);
publisher.on({
  streamCreated: function (event) {
    console.log("Publisher started streaming.");
  },
  streamDestroyed: function (event) {
    console.log("Publisher stopped streaming. Reason: "
      + event.reason);
  }
});

// Replace apiKey and sessionID with your own values:
session = OT.initSession(apiKey, sessionID);
// Replace token with your own value:
session.connect(token, function (error) {
  if (session.capabilities.publish == 1) {
    session.publish(publisher);
  } else {
    console.log("You cannot publish an audio-video stream.");
  }
});

Mise en œuvre des tentatives de publication de session

Les échecs temporaires de publication constituent un phénomène connu et récurrent dans le SDK JS de la Video API, en particulier sur les navigateurs mobiles. Lorsque session.publish() 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.publish() Cela figure dans la feuille de route du SDK. En attendant sa sortie, vous devrez l'implémenter vous-même.

Comment session.publish() Œuvres

session.publish() peut être appelée de deux façons :

  • Avec un éditeur pré-initialisé : session.publish(publisher, callback) — tu appelles OT.initPublisher() Tout d'abord, transmettez ensuite l'instance d'éditeur obtenue à session.publish(). Il s'agit du approche recommandée car cela permet de dissocier l'acquisition des médias de la création du flux, ce qui rend la gestion des erreurs plus claire.
  • Sans instance d'éditeur : session.publish(targetElement, options, callback) — le SDK appelle en interne OT.initPublisher() pour vous. Dans ce cas, les erreurs d’acquisition de médias et les erreurs de création de flux apparaissent toutes deux via le même session.publish() rappel.

Bonnes pratiques : Split OT.initPublisher() et session.publish() en étapes distinctes. Cela vous permet de gérer les erreurs matérielles ou liées aux supports dans le OT.initPublisher() erreurs de rappel et d' réseau/de signalisation dans le session.publish() callback — ce qui simplifie considérablement la logique de réessai et la rend plus ciblée.

// Recommended: split initialization from publishing
let publisherReady = false;
let sessionConnected = false;

const publisher = OT.initPublisher('publisher-container', publisherOptions, (err) => {
  if (err) {
    handleInitPublisherError(err); // hardware/media errors — see OT.initPublisher() errors below
    return;
  }
  publisherReady = true;
  maybePublish();
});

session.connect(token, (err) => {
  if (err) { /* handle connection error */ return; }
  sessionConnected = true;
  maybePublish();
});

function maybePublish() {
  if (sessionConnected && publisherReady) {
    publishWithRetry(session, publisher);
  }
}

Pourquoi les échecs de publication se produisent-ils ?

Les causes principales les plus courantes des échecs de publication temporaires sont les suivantes :

  • Dépassement du délai d'attente de StreamCreateRequest (erreur 1500) : L'éditeur n'a pas réussi à finaliser la création du flux dans un délai raisonnable — ce qui est généralement dû à des retards réseau lors de la négociation ICE/SDP.
  • mediaStopped événements survenant au cours du processus de publication, où l'accès aux périphériques multimédias peut être interrompu.
  • Réutilisation d'un objet « Publisher » sans nettoyage approprié — réutiliser une instance d'éditeur initialisée avec des contraintes différentes sans appeler unpublish et la réinitialisation.
  • OT_NOT_CONNECTED — tentative de publication avant que la session ne soit entièrement établie.
  • OT_PERMISSION_DENIED — Le jeton ne dispose pas du rôle « publish » (erreur irréversible).

Erreurs provenant de OT.initPublisher()

Lorsque vous pré-initialisez un éditeur avec OT.initPublisher(), toutes les erreurs matérielles et d'acquisition de données multimédia sont transmises à son gestionnaire de fin d'exécution — avant session.publish() est appelée. Traitez-les dans cette fonction de rappel à l'aide des actions spécifiques à chaque type d'erreur décrites ci-dessous : certaines nécessitent une intervention de l'utilisateur ou une correction du code, tandis que les erreurs temporaires liées aux médias peuvent être résolues en réinitialisant l'éditeur.

Remarque : Si vous appelez session.publish() Sans éditeur pré-initialisé, ces mêmes erreurs apparaîtront via le session.publish() utiliser plutôt une fonction de rappel.

error.name Description Action recommandée
OT_HARDWARE_UNAVAILABLE Le matériel existe, mais n'a pas pu être accédé (par exemple, car il est utilisé par une autre application). Demander à l'utilisateur de fermer les autres applications en cours d'exécution sur l'appareil, puis appeler OT.initPublisher() encore une fois.
OT_INVALID_PARAMETER Un ou plusieurs paramètres transmis à OT.initPublisher() étaient invalides. Corriger l'objet « options » transmis à OT.initPublisher().
OT_MEDIA_ENDED Les ended événement déclenché sur l'élément vidéo lors de l'initialisation. Réinitialisez l'éditeur.
OT_MEDIA_ERR_ABORTED La récupération du flux pour l'élément vidéo a été interrompue. Réinitialisez l'éditeur 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. Réinitialisez l'éditeur après un court délai.
OT_MEDIA_ERR_NETWORK Une erreur réseau a entraîné l'interruption du téléchargement du flux. Réinitialisez l'éditeur après un court délai.
OT_MEDIA_ERR_SRC_NOT_SUPPORTED Le flux a été identifié comme non compatible avec la lecture. Vérifiez la configuration de la source vidéo/audio du diffuseur, puis réinitialisez-la.
OT_NOT_SUPPORTED Un élément de la requête multimédia de l'utilisateur n'est pas pris en charge par le navigateur. Informer l'utilisateur et ne pas réessayer.
OT_NO_DEVICES_FOUND Aucun périphérique d'entrée audio ou vidéo n'a été détecté. Demander à l'utilisateur de connecter un périphérique avant de réessayer.
OT_NO_VALID_CONSTRAINTS La vidéo et l'audio étaient tous deux désactivés — l'un des deux doit être activé. Garantir publishAudio ou publishVideo est true dans les options de l'éditeur.
OT_PROXY_URL_ALREADY_SET_ERROR Les proxyUrl a déjà été défini. Le redéfinir n'aura aucun effet. Définissez l'URL du proxy une seule fois, avant d'initialiser tout objet Session ou Publisher.
OT_REQUESTED_DEVICE_PERMISSION_DENIED Le périphérique audio demandé ne dispose pas des autorisations nécessaires pour être utilisé. Demander à l'utilisateur d'accorder les autorisations nécessaires à l'appareil.
OT_USER_MEDIA_ACCESS_DENIED L'utilisateur a refusé l'accès à la caméra, au microphone ou à l'écran. Demander à l'utilisateur d'autoriser l'accès dans les paramètres du navigateur ; ne pas réessayer automatiquement.
OT_SCREEN_SHARING_NOT_SUPPORTED Le partage d'écran n'est pas pris en charge par le navigateur utilisé actuellement. Informer l'utilisateur et ne pas réessayer.
OT_UNABLE_TO_CAPTURE_SCREEN Le partage d'écran a été demandé, mais cette fonctionnalité n'est pas prise en charge (par exemple : videoSource fixé à "screen", "application"ou "window"). Appeler OT.checkScreenSharingCapability() avant d'initialiser un éditeur de partage d'écran.
OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED Le partage d'écran nécessite une extension de navigateur, mais aucune n'a été enregistrée. Enregistrez l'extension avant de passer l'appel OT.initPublisher().
OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED Le partage d'écran nécessite une extension de navigateur, mais celle-ci n'est pas installée. Invitez l'utilisateur à installer l'extension requise.
const publisher = OT.initPublisher('publisher-container', publisherOptions, (err) => {
  if (!err) {
    publisherReady = true;
    maybePublish();
    return;
  }

  // Hardware/media errors — handle before session.publish() is called
  switch (err.name) {
    case 'OT_REQUESTED_DEVICE_PERMISSION_DENIED':
      showMessage('Please allow access to your camera and microphone and try again.');
      break;
    case 'OT_HARDWARE_UNAVAILABLE':
    case 'OT_NO_DEVICES_FOUND':
      showMessage('Could not access your camera or microphone. Please check your devices.');
      break;
    case 'OT_SCREEN_SHARING_NOT_SUPPORTED':
    case 'OT_UNABLE_TO_CAPTURE_SCREEN':
    case 'OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED':
    case 'OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED':
      showMessage('Screen sharing is not available. Please check your browser settings.');
      break;
    default:
      showMessage('Could not initialize the publisher. Please try again.');
  }

  publisher.destroy();
});

Erreurs récupérables et non récupérables provenant de session.publish()

Pas tous session.publish() les erreurs ne se valent pas toutes. Avant de mettre en place une logique de réessai, il est essentiel de classer correctement les erreurs : tenter un réessai en cas d’erreur irrémédiable fait perdre du temps, nuit à l’expérience utilisateur et peut masquer de véritables défaillances qui nécessitent une réponse différente.

Remarque : Code d'erreur 1500 est obsolète en tant que mécanisme de classification. Utilisez toujours le error.name propriété permettant d'identifier les erreurs par programmation, car elle correspond à un scénario d'échec spécifique.

Remarque : Quand session.publish() s'appelle sans un éditeur pré-initialisé, des erreurs d'acquisition de médias provenant de OT.initPublisher() (énumérés ci-dessus) peuvent également se manifester par le biais de la session.publish() rappel. Dans ce cas, considérez-les comme ne pouvant faire l'objet d'aucune nouvelle tentative et appliquez la même procédure que celle décrite ci-dessus.

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

Ces erreurs sont dues à des erreurs de programmation, à des contraintes strictes en matière d'autorisations ou à un contexte d'appel non valide. Une nouvelle tentative ne permettra pas de les résoudre. Il convient plutôt d'afficher un message clair à l'utilisateur ou de corriger la logique de l'application.

error.name Description Action recommandée
OT_NOT_CONNECTED session.publish() a été appelée avant que la session ne soit établie. Garantir session.connect() a été menée à bien avant la publication.
OT_PERMISSION_DENIED Le rôle de ce jeton ne permet pas la publication (il doit être publisher ou moderator). Indiquez à l'utilisateur qu'il ne dispose pas des autorisations de publication. Ne réessayez pas : générez un jeton avec le rôle approprié.
OT_INVALID_PARAMETER L'éditeur fourni n'est pas valide, a déjà été publié ou est déjà associé à une autre session. Corrigez la logique de l'application : appelez session.unpublish(publisher) avant de republier, ou de créer un nouvel éditeur.
OT_USER_MEDIA_ACCESS_DENIED L'utilisateur a refusé l'accès à la caméra ou au microphone (ou à l'écran, dans le cas des diffusions avec partage d'écran). Demandez à l'utilisateur d'autoriser l'accès à l'appareil dans les paramètres de son navigateur, puis réessayez. Ne réessayez pas automatiquement.
OT_CHROME_MICROPHONE_ACQUISITION_ERROR Le navigateur n'a pas pu accéder au microphone en raison d'un bug connu. L'utilisateur doit redémarrer le navigateur et recharger la page pour résoudre ce problème. Informer l'utilisateur et ne pas réessayer.
OT_SCREEN_SHARING_NOT_SUPPORTED Le partage d'écran n'est pas pris en charge par le navigateur utilisé actuellement. Informer l'utilisateur et ne pas réessayer.
OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED Le partage d'écran nécessite une extension de navigateur, mais aucune n'a été enregistrée. Enregistrez l'extension avant de tenter de publier un flux de partage d'écran.
OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED Le partage d'écran nécessite une extension de navigateur, mais celle-ci n'est pas installée. Invitez l'utilisateur à installer l'extension requise.
OT_CONSTRAINTS_NOT_SATISFIED Le navigateur n'a pas pu respecter les contraintes multimédias demandées (résolution, fréquence d'images, appareil). Modifiez les contraintes de l'éditeur et réinitialisez-le.
OT_NO_VALID_CONSTRAINTS La vidéo et l'audio étaient tous deux désactivés — l'un des deux doit être activé. Garantir publishAudio ou publishVideo est true avant d'appeler session.publish().
OT_NOT_SUPPORTED Un élément de la requête multimédia de l'utilisateur n'est pas pris en charge par le navigateur. Informer l'utilisateur et ne pas réessayer.
OT_STREAM_CREATE_FAILED L'utilisateur a tenté de publier dans une session avec chiffrement de bout en bout (E2EE) activé sans spécifier de clé de chiffrement ; ou bien le flux n'a pas pu être créé dans le modèle serveur. Pour les sessions E2EE, assurez-vous qu'un secret de chiffrement est défini via session.setEncryptionSecret() avant la publication.
OT_INVALID_AUDIO_OUTPUT_SOURCE L'identifiant du périphérique de sortie audio fourni n'est pas valide. Verify que l'identifiant du périphérique correspond bien à un périphérique de sortie audio valide avant de réessayer.
OT_UNABLE_TO_CAPTURE_MEDIA Impossible de capturer le contenu multimédia — une erreur inconnue s'est produite. Informer l'utilisateur et lui demander de vérifier la disponibilité de l'appareil.

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. Elles constituent la cible principale de la logique de réessai.

error.name Description Action recommandée
OT_TIMEOUT (code 1500) session.publish() délai d'attente écoulé — le StreamCreateRequest n'a pas été achevée à temps. Cela est le plus souvent dû à des retards dans la négociation ICE/SDP ou mediaStopped événements. Réessayer avec un délai d'attente exponentiel (jusqu'à 3 tentatives). Réutiliser la même instance d'éditeur si celle-ci n'a pas été détruite.
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. 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. Réessayez. Si le problème persiste, affichez un message invitant l'utilisateur à vérifier sa connexion réseau.
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. 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. Réessayez après un court délai. Si le problème persiste, il se peut que le format du support ne soit pas compatible.
OT_MEDIA_ERR_SRC_NOT_SUPPORTED Le flux a été identifié comme non compatible avec la lecture. Réessayez une fois. Si le problème persiste, vérifiez la configuration des sources vidéo/audio de l'éditeur.
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. Réessayez en respectant un délai d'attente. Si le problème persiste après toutes les tentatives, informez l'utilisateur d'un éventuel problème de réseau.
OT_UNEXPECTED_SERVER_RESPONSE Une erreur inattendue s'est produite côté serveur. Réessayez une fois après un court délai. Si le problème persiste, consignez l'erreur et informez l'utilisateur.

Erreurs nécessitant une action différente (autre qu'une simple nouvelle tentative)

Certaines erreurs ne peuvent être ni simplement réessayées ni définitivement interrompues : elles nécessitent une action corrective spécifique avant toute nouvelle tentative.

error.name Description Action recommandée
OT_HARDWARE_UNAVAILABLE La caméra ou le microphone n'est pas disponible (par exemple, il est utilisé par une autre application ou n'est pas connecté). Demandez à l'utilisateur de fermer les autres applications en cours d'exécution sur l'appareil, puis réinitialisez l'éditeur à l'aide de OT.initPublisher() avant de réessayer.
OT_NO_DEVICES_FOUND Aucun périphérique d'entrée audio ou vidéo n'a été détecté. Demander à l'utilisateur de connecter un appareil. Ne pas réessayer tant que l'utilisateur n'a pas confirmé qu'un appareil est disponible.

Synthèse : modèle de nouvelle tentative recommandé avec classification des erreurs

async function publishWithRetry(session, publisher, attempt = 1) {
  const MAX_RETRIES = 3;
  const RETRY_DELAY_MS = 2000;

  const error = await new Promise((resolve) => {
    session.publish(publisher, resolve);
  });

  if (!error) {
    console.log('Publishing started successfully.');
    return;
  }

  // Non-recoverable: programmer error or hard permission constraint
  const nonRetryable = [
    'OT_NOT_CONNECTED',
    'OT_PERMISSION_DENIED',
    'OT_INVALID_PARAMETER',
    'OT_USER_MEDIA_ACCESS_DENIED',
    'OT_CHROME_MICROPHONE_ACQUISITION_ERROR',
    'OT_SCREEN_SHARING_NOT_SUPPORTED',
    'OT_SCREEN_SHARING_EXTENSION_NOT_REGISTERED',
    'OT_SCREEN_SHARING_EXTENSION_NOT_INSTALLED',
    'OT_CONSTRAINTS_NOT_SATISFIED',
    'OT_NO_VALID_CONSTRAINTS',
    'OT_NOT_SUPPORTED',
    'OT_STREAM_CREATE_FAILED',
    'OT_INVALID_AUDIO_OUTPUT_SOURCE',
    'OT_UNABLE_TO_CAPTURE_MEDIA',
  ];

  // Requires corrective action before retrying
  const requiresAction = [
    'OT_HARDWARE_UNAVAILABLE',
    'OT_NO_DEVICES_FOUND',
  ];

  if (nonRetryable.includes(error.name)) {
    console.error('Non-retryable error — user action or code fix required:', error.name);
    handleNonRecoverableError(error);
    return;
  }

  if (requiresAction.includes(error.name)) {
    console.warn('Device error — prompting user before retrying:', error.name);
    handleDeviceError(error);
    return;
  }

  // Recoverable: retry with backoff
  if (attempt < MAX_RETRIES) {
    console.warn(`Publish attempt ${attempt} failed (${error.name}), retrying...`);
    await delay(RETRY_DELAY_MS * attempt);
    await publishWithRetry(session, publisher, attempt + 1);
  } else {
    console.error('All publish attempts failed. Disconnecting user.');
    handlePublishFailure(session);
  }
}

function handleNonRecoverableError(error) {
  // Surface a meaningful message to the user based on error.name
  // e.g. for OT_USER_MEDIA_ACCESS_DENIED: "Please allow camera/mic access"
}

function handleDeviceError(error) {
  // Prompt the user to check their device, then allow them to retry manually
}

function handlePublishFailure(session) {
  session.disconnect();
}

Utilisation :

const publisher = OT.initPublisher('publisher-container', publisherOptions);

// Wait for session to be connected before publishing
session.connect(token, (err) => {
  if (err) { /* handle connection error */ return; }
  publishWithRetry(session, publisher);
});

Important : nettoyage de l'éditeur avant de réessayer

Dans la plupart des scénarios de défaillance — notamment OT_TIMEOUT / OT_ICE_WORKFLOW_FAILED — l'instance de l'éditeur peut être réutilisé directement pour le prochain session.publish() appel. Vous n'avez pas besoin de le réinitialiser.

Lorsqu'une tentative de publication échoue, le SDK interrompt le flux qu'il tentait de créer et génère un streamDestroyed événement sur l'éditeur avec reason: "reset". Il s'agit d'un nettoyage prévu qui pas vous obligent à réinitialiser l'éditeur — vous pouvez réessayer avec la même instance. Notez que "reset" Il s'agit d'un motif général indiquant que « le flux de l'éditeur a été interrompu » (il est également généré lorsque vous appelez publisher.destroy()), considérez-le donc comme un signal de nettoyage plutôt que comme un indicateur spécifique d'échec de publication ; utilisez la error.name de la session.publish() fonction de rappel permettant de décider s'il faut réessayer.

Le SDK permet de pas réessayer automatiquement session.publish() en votre nom — la logique de nouvelle tentative doit être mise en œuvre au niveau de l'application, comme indiqué ci-dessus.

Le seul cas où vous devez réinitialiser l'éditeur avec OT.initPublisher() Avant de réessayer, c'est lorsque l'éditeur lui-même destroyed L'événement se déclenche. Cet événement est définitif et indique que l'objet émetteur lui-même n'est plus utilisable.

publisher.on('destroyed', () => {
  // Publisher object is no longer usable — reinitialize before retrying
  publisher = OT.initPublisher('publisher-container', publisherOptions);
});

// A streamDestroyed event with reason 'reset' is emitted by the SDK when it tears
// down the stream (during a failed publish attempt, or when you call publisher.destroy()).
// A 'reset' during a failed publish does NOT require reinitializing the publisher.
publisher.on('streamDestroyed', (event) => {
  if (event.reason === 'reset') {
    // Expected cleanup — reuse the same publisher instance
    return;
  }
  // Handle other streamDestroyed reasons as appropriate for your application
});

Ce qu'il ne faut PAS faire

  • Faire pas appel OT.initPublisher() deux fois sur le même objet « publisher » avec des contraintes différentes sans avoir effectué de nettoyage au préalable (session.unpublish() → attendre streamDestroyed → puis réinitialiser).
  • Faire pas réessayer le OT_PERMISSION_DENIED (l'utilisateur a refusé l'accès à la caméra/au micro) — cela nécessite une intervention de l'utilisateur, et non une nouvelle tentative.
  • Faire pas réessayer le OT_NOT_CONNECTED — assurez-vous que la session est bien connectée avant de publier.
  • Faire pas réessayer indéfiniment — limiter à 3 tentatives et gérer l'échec de manière appropriée.

Gestion de la mediaStopped Événement

La lecture du fichier multimédia peut être interrompue en cours de publication. Surveillez cet événement et considérez-le comme un déclencheur pour relancer la publication :

publisher.on('mediaStopped', async () => {
  console.warn('Media stopped during publish — retrying...');
  // Unpublish if already publishing, then retry
  try { session.unpublish(publisher); } catch (e) { /* ignore */ }
  await delay(2000);
  publishWithRetry(session, publisher);
});

Résumé des paramètres recommandés

Paramètres Valeur recommandée Notes
Nombre maximal de tentatives 3 Trouve le juste équilibre entre la résilience et le temps d'attente des utilisateurs
Délai avant nouvelle tentative 2 s × essai (2 s, 4 s, 6 s) Cela laisse à la plateforme le temps de se rétablir
En cas d'échec de toutes les tentatives de réessai Déconnecter l'utilisateur Évite l'état de « participant fantôme »
Erreurs ne pouvant pas faire l'objet d'une nouvelle tentative OT_NOT_CONNECTED, OT_PERMISSION_DENIED Échouez rapidement sur ces points

Résolution des problèmes liés à la capture audio : audioAcquisitionProblem et audioAcquisitionProblemResolved

Au-delà des tentatives de publication, il existe une autre catégorie de problèmes audio pouvant affecter un éditeur actif : le périphérique audio du client peut ne pas parvenir à transmettre les données audio, même après une publication réussie. Le SDK JS de la Video API propose deux événements spécialement conçus pour ce cas de figure.

Causes courantes

Les audioAcquisitionProblem Cet événement est déclenché lorsque le SDK détecte — via les statistiques de l'éditeur — que la piste audio a cessé d'envoyer des octets à la connexion entre pairs, même si getUserMedia L'opération a abouti et l'éditeur semble actif. Les causes principales les plus courantes sont les suivantes :

  • Appareil audio Bluetooth connecté ou déconnecté en cours de session : Lorsqu'un utilisateur branche ou débranche des écouteurs, ou connecte un casque Bluetooth (par exemple, des AirPods) au cours d'une session active, le système d'exploitation peut changer de périphérique audio par défaut. Il peut arriver que le pipeline audio du navigateur ne parvienne pas à reconnecter le microphone sur le nouveau périphérique, ce qui entraîne l'absence totale d'envoi d'octets audio.
  • Changement de périphérique audio au démarrage de la session : Le fait de changer d'entrée audio très tôt dans la session — dans les 1 à 2 premières secondes suivant la publication — est particulièrement susceptible de déclencher ce problème.
  • Piste audio interrompue par le navigateur ou le système d'exploitation (trackEndedEvent) : Le navigateur peut interrompre la piste audio sous-jacente indépendamment de toute action de l'utilisateur. Le SDK détecte cela via un track.ended événement et soulève audioAcquisitionProblem avec method: trackEndedEvent.
  • Détection basée sur les statistiques (absence de flux d'octets audio) : Une fois que la connexion entre pairs est établie, le SDK interroge les statistiques de l'éditeur toutes les quelques secondes environ. Si la piste audio sortante bytesSent n'augmente pas d'un sondage à l'autre, audioAcquisitionProblem est soulevée (avec method: getStats). Lorsque bytesSent commence à augmenter à nouveau, audioAcquisitionProblemResolved est soulevée.

Remarque : Cet événement ne signifie pas toujours une défaillance irrémédiable. Dans certaines sessions, le son revient tout seul (et audioAcquisitionProblemResolved est déclenché) ; dans d'autres cas, le flux audio ne se rétablit jamais et les abonnés en aval peuvent finir par dépasser le délai d'attente.

Les événements

Ces événements sont émis sur l'instance de l'éditeur :

  • audioAcquisitionProblem — déclenché lorsque le SDK détecte que l'éditeur a cessé d'envoyer du contenu audio (d'après les statistiques de l'éditeur), ou lorsque la piste audio sous-jacente déclenche un ended événement. Cela ne signifie pas nécessairement que la diffusion va échouer, mais cela indique que la capture audio a été interrompue.
  • audioAcquisitionProblemResolved — déclenché lorsque la transmission audio est rétablie après une audioAcquisitionProblem. Si cet événement se produit, aucune mesure corrective n'est nécessaire.

Remarque : Ces événements ont actuellement lieu ne fait pas partie de l'API publique documentée/définie par écrit (ils ne sont pas déclarés dans les définitions TypeScript du SDK). Considérez-les comme des signaux fournis « au mieux » susceptibles de changer d’une version à l’autre, et vérifiez leur disponibilité par rapport à la version de votre SDK avant de vous y fier en production. Lorsqu’ils sont émis par l’éditeur, ils incluent un method propriété indiquant comment le problème a été détecté ('getStats' ou 'trackEndedEvent').

Remarque : Les vérifications d'acquisition audio s'appuient sur les statistiques fournies par les éditeurs ; il peut donc y avoir un léger décalage entre le moment où l'audio est effectivement interrompu et celui où l'événement est déclenché.

Modèle de récupération recommandé

Lancer un minuteur court dès la réception audioAcquisitionProblem. Si audioAcquisitionProblemResolved Si le problème disparaît avant la fin du délai, cela signifie que le son s'est rétabli de lui-même et qu'aucune intervention n'est nécessaire. Si le délai expire sans que le problème ne soit résolu, changez de source audio pour rétablir le son.

publisher.on('audioAcquisitionProblem', () => {
  // Start a 3-second timer
  const timeout = setTimeout(() => {
    // Problem not resolved — attempt recovery by switching audio source
    publisher.setAudioSource(newDeviceId);
  }, 3000);

  publisher.on('audioAcquisitionProblemResolved', () => {
    // Audio recovered — clear the timer, no action needed
    clearTimeout(timeout);
  });
});

Éléments clés à prendre en compte

  • Ce n'est pas un indicateur d'échec certain : audioAcquisitionProblem Cela n'entraîne pas systématiquement l'échec de l'abonnement. Considérez-le comme un signal précoce permettant de surveiller la situation et, le cas échéant, d'intervenir, et non comme un échec définitif.
  • Suivre les statistiques audio de l'éditeur : Après avoir reçu audioAcquisitionProblem, vous pouvez également suivre les statistiques audio de l'éditeur (par exemple, via publisher.getStats()) afin de vérifier si la transmission audio a bien cessé avant d'intervenir.
  • Mesures de rétablissement : Appel publisher.setAudioSource(newDeviceId) Il s'agit du principal mécanisme de récupération. Cela permet de changer de périphérique d'entrée audio sans avoir à passer par un cycle complet de désactivation puis de réactivation.
  • Lien avec les délais d'expiration des abonnements : Si le flux audio n'est pas rétabli et que l'éditeur continue de ne pas envoyer de paquets audio, les abonnés risquent à terme de se retrouver face à OT_TIMEOUT (1501). Gestion proactive de audioAcquisitionProblem peut permettre d’éviter cette défaillance en aval.