

# Kit SDK de diffusion IVS : Guide pour le Web \$1 Diffusion en temps réel
<a name="broadcast-web"></a>

Le SDK de diffusion Web par streaming en temps réel IVS fournit aux développeurs les outils nécessaires pour créer des expériences interactives en temps réel sur le Web. Ce kit SDK est destiné aux développeurs qui créent des applications web avec Amazon IVS.

Le SDK de diffusion Web permet aux participants d’envoyer et de recevoir des vidéos. Le SDK prend en charge les opérations suivantes :
+ Rejoindre une étape
+ Publier du contenu multimédia à l’intention des autres participants de l’étape
+ S’abonner à du contenu multimédia d’autres participants de l’étape
+ Gérer et surveiller la vidéo et le son publiés sur l’étape
+ Obtenir des statistiques WebRTC pour chaque connexion d’appairage
+ Toutes les opérations à partir du SDK de diffusion Web par streaming à faible latence

**Dernière version du kit SDK de diffusion Web :** 1.33.0 ([Notes de mise à jour](https://docs.aws.amazon.com/ivs/latest/RealTimeUserGuide/release-notes.html#mar12-26-broadcast-web-rt)) 

**Documentation de référence :** pour plus d’informations sur les méthodes les plus importantes disponibles dans le kit SDK de diffusion Web Amazon IVS, consultez la documentation de référence à l’adresse [https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference). Assurez-vous que la version la plus récente du kit SDK est sélectionnée.

**Exemple de code** : les exemples ci-dessous constituent un bon point de départ pour commencer à utiliser rapidement le kit SDK :
+ [Lecture simple](https://codepen.io/amazon-ivs/pen/RNwVBRK)
+ [Publication et abonnement simples](https://codepen.io/amazon-ivs/pen/ZEqgrpo)
+ [Démonstration complète de collaboration en temps réel avec React](https://github.com/aws-samples/amazon-ivs-real-time-collaboration-web-demo/tree/main)

**Exigences de la plateforme** : consultez le [SDK de diffusion Amazon IVS](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/broadcast.html) pour obtenir la liste des plateformes prises en charge

**Remarque :** la publication à partir d’un navigateur est pratique pour les utilisateurs finaux, car elle ne nécessite pas l’installation de logiciels supplémentaires. Cependant, la publication par navigateur est soumise aux contraintes et à la variabilité des environnements de navigateur. Si vous devez donner la priorité à la stabilité (par exemple, pour le streaming d’événements), nous vous recommandons généralement de publier à partir d’une source autre qu’un navigateur (par exemple, OBS Studio ou d’autres encodeurs dédiés), qui ont souvent un accès direct aux ressources du système et évitent les limitations du navigateur. Pour en savoir plus sur les options de publication hors navigateur, consultez la documentation [Ingestion de flux](rt-stream-ingest.md).

# Démarrez avec le SDK de diffusion Web IVS \$1 Streaming en temps réel
<a name="broadcast-web-getting-started"></a>

Ce document explique les étapes nécessaires pour le démarrage avec le SDK de diffusion Web IVS en temps réel.

## Importations
<a name="broadcast-web-getting-started-imports"></a>

Les composantes de base temps réel se trouvent dans un espace de noms différent de celui des modules de diffusion racine.

### Utilisation d’une balise de script
<a name="broadcast-web-getting-started-imports-script"></a>

Le kit SDK de diffusion Web est distribué sous forme de bibliothèque JavaScript et peut être consulté à l'adresse [https://web-broadcast.live-video.net/1.33.0/amazon-ivs-web-broadcast.js](https://web-broadcast.live-video.net/1.33.0/amazon-ivs-web-broadcast.js).

Les classes et les énumérations définies dans les exemples ci-dessous se trouvent sur l’objet global `IVSBroadcastClient` :

```
const { Stage, SubscribeType } = IVSBroadcastClient;
```

### Utilisation de npm
<a name="broadcast-web-getting-started-imports-npm"></a>

Pour installer le package `npm` : 

```
npm install amazon-ivs-web-broadcast
```

Les classes, les énumérations et les types peuvent également être importés depuis le module de package :

```
import { Stage, SubscribeType, LocalStageStream } from 'amazon-ivs-web-broadcast'
```

### Prise en charge du rendu côté serveur
<a name="broadcast-web-getting-started-imports-server-side-rendering"></a>

La bibliothèque de scènes du kit SDK de diffusion Web ne peut pas être chargée dans un contexte côté serveur, car elle référence des éléments de navigateur nécessaires à son fonctionnement lorsqu’elle est chargée. Pour contourner ce problème, chargez la bibliothèque dynamiquement, comme illustré dans la [démonstration de diffusion Web à l’aide de Next et React](https://github.com/aws-samples/amazon-ivs-broadcast-web-demo/blob/main/hooks/useBroadcastSDK.js#L26-L31).

## Demander des autorisations
<a name="broadcast-web-request-permissions"></a>

Votre application doit demander l’autorisation d’accéder à la caméra et au microphone de l’utilisateur, et cela doit être réalisé en utilisant HTTPS. (Ce n’est pas spécifique à Amazon IVS ; cette autorisation est requise pour toute application devant accéder aux caméras et aux microphones.)

Voici un exemple de fonction qui montre comment demander et capturer des autorisations pour les périphériques audio et vidéo :

```
async function handlePermissions() {
   let permissions = {
       audio: false,
       video: false,
   };
   try {
       const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
       for (const track of stream.getTracks()) {
           track.stop();
       }
       permissions = { video: true, audio: true };
   } catch (err) {
       permissions = { video: false, audio: false };
       console.error(err.message);
   }
   // If we still don't have permissions after requesting them display the error message
   if (!permissions.video) {
       console.error('Failed to get video permissions.');
   } else if (!permissions.audio) {
       console.error('Failed to get audio permissions.');
   }
}
```

Pour plus d’informations, consultez l’[API Permissions](https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API) et [MediaDevices.getUserMedia()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia).

## Répertorier les périphériques disponibles
<a name="broadcast-web-request-list-devices"></a>

Pour voir quels périphériques peuvent être capturés, interrogez la méthode [MediaDevices.enumerateDevices()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices) du navigateur :

```
const devices = await navigator.mediaDevices.enumerateDevices();
window.videoDevices = devices.filter((d) => d.kind === 'videoinput');
window.audioDevices = devices.filter((d) => d.kind === 'audioinput');
```

## Récupérer un MediaStream depuis un périphérique
<a name="broadcast-web-retrieve-mediastream"></a>

Après avoir acquis la liste des périphériques disponibles, vous pouvez récupérer un flux à partir d’un nombre quelconque de périphériques. Par exemple, vous pouvez utiliser la méthode `getUserMedia()` pour récupérer un flux d’une caméra.

Si vous souhaitez spécifier le périphérique à partir duquel vous souhaitez capturer le flux, vous pouvez définir explicitement le `deviceId` dans la section `audio` ou `video` des contraintes multimédias. Vous pouvez également omettre le `deviceId` et demander aux utilisateurs de sélectionner leurs périphériques à l’invite du navigateur.

Vous pouvez également spécifier une résolution de caméra idéale à l’aide des contraintes `width` et `height`. (Pour en savoir plus sur ces contraintes, [cliquez ici](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#properties_of_video_tracks).) Le kit SDK applique automatiquement des contraintes de largeur et de hauteur qui correspondent à votre résolution de diffusion maximale ; cependant, il est conseillé de les appliquer vous-même pour vous assurer que le rapport hauteur/largeur de la source n’est pas modifié une fois que vous avez ajouté la source au kit SDK.

Pour la diffusion en temps réel, assurez-vous que le contenu multimédia est limité à une résolution de 720p. Les valeurs de contrainte `getUserMedia` et `getDisplayMedia` pour la largeur et la hauteur ne doivent pas dépasser 921600 (1280×720) lorsqu’elles sont multipliées ensemble. 

```
const videoConfiguration = {
  maxWidth: 1280,
  maxHeight: 720,
  maxFramerate: 30,
}

window.cameraStream = await navigator.mediaDevices.getUserMedia({
   video: {
       deviceId: window.videoDevices[0].deviceId,
       width: {
           ideal: videoConfiguration.maxWidth,
       },
       height: {
           ideal:videoConfiguration.maxHeight,
       },
   },
});
window.microphoneStream = await navigator.mediaDevices.getUserMedia({
   audio: { deviceId: window.audioDevices[0].deviceId },
});
```

# Publication et abonnement avec le SDK de diffusion Web IVS \$1 Streaming en temps réel
<a name="web-publish-subscribe"></a>

Ce document explique les étapes nécessaires pour la publication et l'abonnement à une étape à l'aide du SDK de diffusion Web IVS en temps réel.

## Concepts
<a name="web-publish-subscribe-concepts"></a>

Trois concepts de base sous-tendent la fonctionnalité temps réel : [scène](#web-publish-subscribe-concepts-stage), [stratégie](#web-publish-subscribe-concepts-strategy) et [événements](#web-publish-subscribe-concepts-events). L’objectif de la conception consiste à minimiser la quantité de logique côté client nécessaire à la création d’un produit fonctionnel.

### Étape
<a name="web-publish-subscribe-concepts-stage"></a>

La classe `Stage` est le principal point d’interaction entre l’application hôte et le kit SDK. Il représente l’étape elle-même et est utilisé pour rejoindre et quitter l’étape. La création et la participation à une étape nécessitent une chaîne de jetons valide et non expirée provenant du plan de contrôle (représentée par `token`). Il est très facile de rejoindre une étape et de la quitter :

```
const stage = new Stage(token, strategy)

try {
   await stage.join();
} catch (error) {
   // handle join exception
}

stage.leave();
```

### Strategy
<a name="web-publish-subscribe-concepts-strategy"></a>

L’interface `StageStrategy` permet à l’application hôte de communiquer l’état de l’étape souhaité au kit SDK. Trois fonctions doivent être mises en œuvre : `shouldSubscribeToParticipant`, `shouldPublishParticipant` et `stageStreamsToPublish`. Elles sont toutes abordées ci-dessous.

Pour utiliser une stratégie définie, transmettez-la au constructeur `Stage`. Voici un exemple complet d’application utilisant une stratégie pour publier la webcam d’un participant sur l’étape et s’abonner à tous les participants. L’objectif de chaque fonction de stratégie requise est expliqué en détail dans les sections suivantes.

```
const devices = await navigator.mediaDevices.getUserMedia({ 
   audio: true,
   video: {
        width: { max: 1280 },
        height: { max: 720 },
    } 
});
const myAudioTrack = new LocalStageStream(devices.getAudioTracks()[0]);
const myVideoTrack = new LocalStageStream(devices.getVideoTracks()[0]);

// Define the stage strategy, implementing required functions
const strategy = {
   audioTrack: myAudioTrack,
   videoTrack: myVideoTrack,

   // optional
   updateTracks(newAudioTrack, newVideoTrack) {
      this.audioTrack = newAudioTrack;
      this.videoTrack = newVideoTrack;
   },

   // required
   stageStreamsToPublish() {
      return [this.audioTrack, this.videoTrack];
   },

   // required
   shouldPublishParticipant(participant) {
      return true;
   },

   // required
   shouldSubscribeToParticipant(participant) {
      return SubscribeType.AUDIO_VIDEO;
   }
};

// Initialize the stage and start publishing
const stage = new Stage(token, strategy);
await stage.join();


// To update later (e.g. in an onClick event handler)
strategy.updateTracks(myNewAudioTrack, myNewVideoTrack);
stage.refreshStrategy();
```

#### Abonnement aux participants
<a name="web-publish-subscribe-concepts-strategy-participants"></a>

```
shouldSubscribeToParticipant(participant: StageParticipantInfo): SubscribeType
```

Lorsqu’un participant distant rejoint l’étape, le kit SDK interroge l’application hôte sur l’état de l’abonnement souhaité pour ce participant. Les options sont `NONE`, `AUDIO_ONLY` et `AUDIO_VIDEO`. Lors d’un renvoi d’une valeur pour cette fonction, l’application hôte n’a pas à se soucier de l’état de publication, de l’état actuel de l’abonnement ou de l’état de la connexion de l’étape. Si `AUDIO_VIDEO` est renvoyé, le kit SDK attend que le participant distant effectue une publication avant de s’abonner, puis il met à jour l’application hôte en émettant des événements tout au long du processus.

Voici un exemple d’implémentation :

```
const strategy = {
   
   shouldSubscribeToParticipant: (participant) => {
      return SubscribeType.AUDIO_VIDEO;
   }

   // ... other strategy functions
}
```

Il s’agit de l’implémentation complète de cette fonction pour une application hôte qui souhaite toujours que tous les participants se voient mutuellement, comme une application de chat vidéo.

Des implémentations plus avancées sont également possibles. Par exemple, supposons que l’application fournisse un attribut `role` lors de la création du jeton avec CreateParticipantToken. L’application pourrait utiliser la propriété `attributes` sur `StageParticipantInfo` pour s’abonner de manière sélective à des participants en fonction des attributs fournis par le serveur :

```
const strategy = {
   
   shouldSubscribeToParticipant(participant) {
      switch (participant.attributes.role) {
         case 'moderator':
            return SubscribeType.NONE;
         case 'guest':
            return SubscribeType.AUDIO_VIDEO;
         default:
            return SubscribeType.NONE;
      }
   }
   // . . . other strategies properties
}
```

Elle peut servir à créer une scène où les modérateurs peuvent surveiller tous les invités sans être vus ou entendus. L’application hôte pourrait utiliser une logique métier supplémentaire pour permettre aux modérateurs de se voir mutuellement tout en restant invisible pour les invités.

#### Configuration d’abonnement aux participants
<a name="web-publish-subscribe-concepts-strategy-participants-config"></a>

```
subscribeConfiguration(participant: StageParticipantInfo): SubscribeConfiguration
```

[Lorsqu’un participant distant est abonné (voir Abonnement aux participants](#web-publish-subscribe-concepts-strategy-participants)), le kit SDK interroge l’application hôte sur une configuration d’abonnement personnalisée pour ce participant. Cette configuration est facultative et permet à l’application hôte de contrôler certains aspects du comportement de l’abonné. Pour plus d’informations sur les options de configuration, consultez [SubscribeConfiguration](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference/interfaces/SubscribeConfiguration) dans la documentation de référence du kit SDK.

Voici un exemple d’implémentation :

```
const strategy = {
   
   subscribeConfiguration: (participant) => {
      return {
         jitterBuffer: {
            minDelay: JitterBufferMinDelay.MEDIUM
         }  
      }

   // ... other strategy functions
}
```

Cette implémentation met à jour le délai minimum de la mémoire tampon pour tous les participants abonnés à un préréglage de `MEDIUM`.

Comme pour `shouldSubscribeToParticipant`, des implémentations plus avancées sont possibles. `ParticipantInfo` peut être utilisé pour mettre à jour de manière sélective la configuration d’abonnement pour des participants spécifiques.

Nous recommandons d’utiliser les comportements par défaut. Spécifiez une configuration personnalisée uniquement si vous souhaitez modifier un comportement particulier.

#### Publication
<a name="web-publish-subscribe-concepts-strategy-publishing"></a>

```
shouldPublishParticipant(participant: StageParticipantInfo): boolean
```

Une fois connecté à l’étape, le kit SDK interroge l’application hôte pour savoir si un participant en particulier doit effectuer une publication. Elle n’est invoquée que pour les participants locaux autorisés à publier sur la base du jeton fourni.

Voici un exemple d’implémentation :

```
const strategy = {
   
   shouldPublishParticipant: (participant) => {
      return true;
   }

   // . . . other strategies properties
}
```

Il s’agit d’une application de chat vidéo standard dans laquelle les utilisateurs souhaitent toujours publier. Ils peuvent désactiver et réactiver leur son et leur vidéo pour être instantanément masqués ou vus/entendus. (Ils peuvent également utiliser la fonction de publication/d’annulation de la publication, mais c’est beaucoup plus lent. Il est préférable de désactiver ou de réactiver le son dans les cas d’utilisation où il est souvent souhaitable de modifier la visibilité.)

#### Choix des flux à publier
<a name="web-publish-subscribe-concepts-strategy-streams"></a>

```
stageStreamsToPublish(): LocalStageStream[];
```

Lors de la publication, cette fonction est utilisée pour déterminer les flux audio et vidéo à publier. Ce point est abordé plus en détail dans la section [Publier un flux multimédia](#web-publish-subscribe-publish-stream).

#### Mise à jour de la stratégie
<a name="web-publish-subscribe-concepts-strategy-updates"></a>

La stratégie se veut dynamique : les valeurs renvoyées par n’importe laquelle des fonctions ci-dessus peuvent être modifiées à tout moment. Par exemple, si l’application hôte ne souhaite pas publier tant que l’utilisateur final n’a pas appuyé sur un bouton, vous pouvez renvoyer une variable depuis `shouldPublishParticipant` (quelque chose comme `hasUserTappedPublishButton`). Lorsque cette variable change en fonction d’une interaction de l’utilisateur final, appelez `stage.refreshStrategy()` pour signaler au kit SDK qu’il doit interroger la stratégie pour connaître les dernières valeurs, en appliquant uniquement les éléments qui ont changé. Si le kit SDK constate que la valeur `shouldPublishParticipant` a changé, il lance le processus de publication. Si les requêtes du kit SDK et toutes les fonctions renvoient la même valeur qu’auparavant, l’appel `refreshStrategy` ne modifie pas l’étape.

Si la valeur de retour de `shouldSubscribeToParticipant` passe de `AUDIO_VIDEO` à `AUDIO_ONLY`, le flux vidéo est supprimé pour tous les participants dont les valeurs renvoyées ont été modifiées, s’il existait déjà un flux vidéo.

En général, l’étape utilise la stratégie pour appliquer au mieux la différence entre les stratégies précédentes et actuelles, sans que l’application hôte n’ait à se soucier de tout l’état requis pour la gérer correctement. Pour cette raison, et pour réduire les frais, envisagez d’appeler `stage.refreshStrategy()`, car cela ne fait rien à moins que la stratégie ne change.

### Événements
<a name="web-publish-subscribe-concepts-events"></a>

Une instance `Stage` est un émetteur d’événements. En utilisant `stage.on()`, l’état de l’étape est communiqué à l’application hôte. Les mises à jour de l’interface utilisateur de l’application hôte peuvent généralement être entièrement prises en charge par les événements. Les événements sont les suivants :

```
stage.on(StageEvents.STAGE_CONNECTION_STATE_CHANGED, (state) => {})
stage.on(StageEvents.STAGE_PARTICIPANT_JOINED, (participant) => {})
stage.on(StageEvents.STAGE_PARTICIPANT_LEFT, (participant) => {})
stage.on(StageEvents.STAGE_PARTICIPANT_PUBLISH_STATE_CHANGED, (participant, state) => {})
stage.on(StageEvents.STAGE_PARTICIPANT_SUBSCRIBE_STATE_CHANGED, (participant, state) => {})
stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED, (participant, streams) => {})
stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_REMOVED, (participant, streams) => {})
stage.on(StageEvents.STAGE_STREAM_ADAPTION_CHANGED, (participant, stream, isAdapting) => ())
stage.on(StageEvents.STAGE_STREAM_LAYERS_CHANGED, (participant, stream, layers) => ())
stage.on(StageEvents.STAGE_STREAM_LAYER_SELECTED, (participant, stream, layer, reason) => ())
stage.on(StageEvents.STAGE_STREAM_MUTE_CHANGED, (participant, stream) => {})
stage.on(StageEvents.STAGE_STREAM_SEI_MESSAGE_RECEIVED, (participant, stream) => {})
```

Pour la plupart de ces événements, les `ParticipantInfo` correspondantes sont fournies.

Les informations fournies par les événements ne devraient pas avoir d’impact sur les valeurs de retour de la stratégie. Par exemple, la valeur de retour de `shouldSubscribeToParticipant` ne devrait pas changer lors de l’appel de `STAGE_PARTICIPANT_PUBLISH_STATE_CHANGED`. Si l’application hôte souhaite s’abonner à un participant en particulier, elle doit renvoyer le type d’abonnement souhaité, quel que soit l’état de publication de ce participant. Le kit SDK est chargé de s’assurer que l’état souhaité de la stratégie est appliqué au bon moment en fonction de l’état de l’étape.

## Publier un flux multimédia
<a name="web-publish-subscribe-publish-stream"></a>

Les appareils locaux tels que les microphones et les caméras sont récupérés en suivant les mêmes étapes que celles décrites ci-dessus dans [Récupérer un MediaStream depuis un périphérique](broadcast-web-getting-started.md#broadcast-web-retrieve-mediastream). Dans l’exemple, nous utilisons`MediaStream` pour créer une liste d’objets `LocalStageStream` utilisés à des fins de publication par le kit SDK :

```
try {
    // Get stream using steps outlined in document above
    const stream = await getMediaStreamFromDevice();

    let streamsToPublish = stream.getTracks().map(track => {
        new LocalStageStream(track)
    });

    // Create stage with strategy, or update existing strategy
    const strategy = {
        stageStreamsToPublish: () => streamsToPublish
    }
}
```

## Publier un partage d’écran
<a name="web-publish-subscribe-publish-screenshare"></a>

Les applications doivent souvent publier un partage d’écran en plus de la caméra Web de l’utilisateur. La publication d’un partage d’écran nécessite la création d’un jeton supplémentaire pour la scène, spécifiquement pour la publication du contenu multimédia du partage d’écran. Utilisez `getDisplayMedia` et limitez la résolution à un maximum de 720p. Ensuite, les étapes sont similaires à celles de la publication d’une caméra sur la scène.

```
// Invoke the following lines to get the screenshare's tracks
const media = await navigator.mediaDevices.getDisplayMedia({
   video: {
      width: {
         max: 1280,
      },
      height: {
         max: 720,
      }
   }
});
const screenshare = { videoStream: new LocalStageStream(media.getVideoTracks()[0]) };
const screenshareStrategy = {
   stageStreamsToPublish: () => {
      return [screenshare.videoStream];
   },
   shouldPublishParticipant: (participant) => {
      return true;
   },
   shouldSubscribeToParticipant: (participant) => {
      return SubscribeType.AUDIO_VIDEO;
   }
}
const screenshareStage = new Stage(screenshareToken, screenshareStrategy);
await screenshareStage.join();
```

## Afficher et supprimer des participants
<a name="web-publish-subscribe-participants"></a>

Une fois l’inscription terminée, vous recevez un tableau d’objets `StageStream` via l’événement `STAGE_PARTICIPANT_STREAMS_ADDED`. L’événement vous fournit également des informations sur les participants pour vous aider lors de l’affichage des flux de contenu multimédia :

```
stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED, (participant, streams) => {
    let streamsToDisplay = streams;

    if (participant.isLocal) {
        // Ensure to exclude local audio streams, otherwise echo will occur
        streamsToDisplay = streams.filter(stream => stream.streamType === StreamType.VIDEO)
    }

    // Create or find video element already available in your application
    const videoEl = getParticipantVideoElement(participant.id);

    // Attach the participants streams
    videoEl.srcObject = new MediaStream();
    streamsToDisplay.forEach(stream => videoEl.srcObject.addTrack(stream.mediaStreamTrack));
})
```

Lorsqu’un participant arrête de publier ou en cas de désabonnement d’un flux, la fonction `STAGE_PARTICIPANT_STREAMS_REMOVED` est appelée avec les flux qui ont été supprimés. Les applications hôte doivent utiliser ce signal pour supprimer le flux vidéo du participant du DOM.

`STAGE_PARTICIPANT_STREAMS_REMOVED` est invoqué pour tous les scénarios dans lesquels un flux peut être supprimé, notamment :
+ Le participant distant arrête de publier.
+ Un appareil local se désabonne ou modifie l’abonnement de `AUDIO_VIDEO` en `AUDIO_ONLY`.
+ Le participant distant quitte l’étape.
+ Le participant local quitte l’étape.

Comme `STAGE_PARTICIPANT_STREAMS_REMOVED` est invoqué pour tous les scénarios, aucune logique métier personnalisée n’est requise pour supprimer des participants de l’interface utilisateur lors des opérations de départ locales ou à distance.

## Désactiver et réactiver le son des flux de médias sociaux
<a name="web-publish-subscribe-mute-streams"></a>

Les objets `LocalStageStream` ont une fonction `setMuted` qui contrôle si le son du flux est désactivé. Cette fonction peut être appelée sur le flux avant ou après son renvoi par la fonction de stratégie `stageStreamsToPublish`.

**Important** : si une nouvelle instance d’objet `LocalStageStream` est renvoyée par `stageStreamsToPublish` après un appel à `refreshStrategy`, l’état muet du nouvel objet de flux est appliqué à l’étape. Lorsque vous créez des instances `LocalStageStream`, veillez à ce que l’état muet attendu soit conservé.

## Surveiller l’état muet du contenu multimédia des participants distants
<a name="web-publish-subscribe-mute-state"></a>

Lorsque les participants modifient l’état muet de leur vidéo ou audio, l’événement `STAGE_STREAM_MUTE_CHANGED` est déclenché avec une liste des flux qui ont changé. Utilisez la propriété `isMuted` sur `StageStream` pour mettre à jour votre interface utilisateur en conséquence :

```
stage.on(StageEvents.STAGE_STREAM_MUTE_CHANGED, (participant, stream) => {
   if (stream.streamType === 'video' && stream.isMuted) {
       // handle UI changes for video track getting muted
   }
})
```

Vous pouvez également consulter [StageParticipantInfo](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference#stageparticipantinfo) pour obtenir des informations sur l’état indiquant si le son ou la vidéo est désactivé :

```
stage.on(StageEvents.STAGE_STREAM_MUTE_CHANGED, (participant, stream) => {
   if (participant.videoStopped || participant.audioMuted) {
       // handle UI changes for either video or audio
   }
})
```

## Obtenir les statistiques WebRTC
<a name="web-publish-subscribe-webrtc-stats"></a>

La méthode `requestQualityStats()` permet d’accéder à des statistiques WebRTC détaillées pour les flux locaux et distants. Cette méthode est disponible à la fois sur les objets LocalStageStream et RemoteStageStream. Elle renvoie des métriques de qualité complètes, notamment la qualité du réseau, les statistiques sur les paquets, les informations sur le débit et les métriquess relatives au cadre.

Il s’agit d’une méthode asynchrone avec laquelle vous pouvez récupérer des statistiques soit via une attente, soit en enchaînant une promesse. Elle renvoie `undefined` lorsque les statistiques ne sont pas disponibles ; par exemple, le flux n’est pas actif ou les statistiques internes ne sont pas disponibles. Si des statistiques sont disponibles, et en fonction du flux (distant ou local, vidéo ou audio), la méthode renvoie un objet [LocalVideoStats](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference/interfaces/LocalVideoStats), [LocalAudioStats](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference/interfaces/LocalAudioStats), [RemoteVideoStats](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference/interfaces/RemoteVideoStats) ou [RemoteAudioStats](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference/interfaces/RemoteAudioStats).

Notez que pour les flux vidéo avec diffusion simultanée, le tableau contient plusieurs objets statistiques (un par couche).

**Bonnes pratiques**
+ Fréquence d’interrogation : appelez `requestQualityStats()` à intervalles raisonnables (1 à 5 secondes) pour éviter tout impact sur les performances
+ Gestion des erreurs : vérifiez toujours si la valeur renvoyée est bien `undefined` avant le traitement
+ Gestion de la mémoire : effacez les intervals/délais d’expiration des flux dont vous n’vez plus besoin
+ Qualité du réseau : utilisez `networkQuality` pour recueillir les commentaires des utilisateurs concernant les dégradations possibles causées par le réseau. Pour en svoir plus, consultez [NetworkQuality](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference/enumerations/NetworkQuality).

**Exemple d'utilisation**

```
// For local streams
const localStats = await localVideoStream.requestQualityStats();
const audioStats = await localAudioStream.requestQualityStats();

// For remote streams
const remoteVideoStats = await remoteVideoStream.requestQualityStats();
const remoteAudioStats = await remoteAudioStream.requestQualityStats();

// Example: Monitor stats every 10 seconds
const statsInterval = setInterval(async () => {
   const stats = await localVideoStream.requestQualityStats();
   if (stats) {
      // Note: If simulcast is enabled, you may receive multiple 
      // stats records for each layer
      stats.forEach(layer => {
         const rid = layer.rid || 'default';
         console.log(`Layer ${rid}:`, {
            active: layer.active,
            networkQuality: layer.networkQuality,
            packetsSent: layer.packetsSent,
            bytesSent: layer.bytesSent,
            resolution: `${layer.frameWidth}x${layer.frameHeight}`,
            fps: layer.framesPerSecond
         });
      });
   }
}, 10000);
```

## Optimisation de contenu multimédia
<a name="web-publish-subscribe-optimizing-media"></a>

Pour des performances optimales, il est recommandé de limiter les appels `getUserMedia` et `getDisplayMedia` aux contraintes suivantes :

```
const CONSTRAINTS = {
    video: {
        width: { ideal: 1280 }, // Note: flip width and height values if portrait is desired
        height: { ideal: 720 },
        framerate: { ideal: 30 },
    },
};
```

Vous pouvez restreindre davantage le contenu multimédia à l’aide d’options supplémentaires transmises au constructeur `LocalStageStream` :

```
const localStreamOptions = {
    minBitrate?: number;
    maxBitrate?: number;
    maxFramerate?: number;
    simulcast: {
        enabled: boolean
    }
}
const localStream = new LocalStageStream(track, localStreamOptions)
```

Dans le code ci-dessus :
+ `minBitrate` définit le débit minimum que le navigateur doit être censé utiliser. Toutefois, un flux vidéo de faible complexité peut pousser l’encodeur à descendre en dessous de ce débit.
+ `maxBitrate` définit un débit maximal que le navigateur ne doit pas dépasser pour ce flux.
+ `maxFramerate` définit une fréquence d’images maximale que le navigateur ne doit pas dépasser pour ce flux.
+ L’option `simulcast` n’est utilisable que sur les navigateurs basés sur Chromium. Elle permet d’envoyer trois couches de rendu du flux.
  + Cela permet au serveur de choisir le rendu à envoyer aux autres participants, en fonction des limites de leur réseau.
  + Lorsque `simulcast` est spécifié en même temps qu’une valeur `maxBitrate` et/ou `maxFramerate`, on s’attend à ce que la couche de rendu la plus élevée soit configurée en tenant compte de ces valeurs, à condition que `maxBitrate` ne descende pas en dessous de la valeur `maxBitrate` par défaut de 900 kbps de la deuxième couche la plus élevée du SDK interne.
  + Si `maxBitrate` est spécifié comme étant trop faible par rapport à la valeur par défaut de la deuxième couche la plus élevée, `simulcast` sera désactivé.
  + `simulcast` ne peut pas être activé et désactivé sans republier le média. Pour ce faire, il faut que `shouldPublishParticipant` renvoie la valeur `false`, que `refreshStrategy` soit appelé, que `shouldPublishParticipant` renvoie la valeur `true` et que `refreshStrategy` soit à nouveau appelé.

## Obtenir les attributs des participants
<a name="web-publish-subscribe-participant-attributes"></a>

Si vous spécifiez des attributs dans la demande de l’opération `CreateParticipantToken`, vous pouvez les voir dans les propriétés `StageParticipantInfo` :

```
stage.on(StageEvents.STAGE_PARTICIPANT_JOINED, (participant) => {
   console.log(`Participant ${participant.id} info:`, participant.attributes);
})
```

## Informations supplémentaires sur les améliorations (SEI)
<a name="web-publish-subscribe-sei-attributes"></a>

L’unité NAL d’informations supplémentaires sur les améliorations (SEI) est utilisée pour stocker des métadonnées alignées sur l’image à côté de la vidéo. Peuvent être utilisées lors de la publication et de l'abonnement à des flux vidéo H.264. Il n'est pas garanti que les données utiles SEI parviennent aux abonnés, en particulier en cas de mauvais état du réseau. Comme les données utiles SEI stockent les données directement dans la structure d’image H.264, cette fonctionnalité ne peut pas être exploitée pour les flux exclusivement audio.

### Insertion de données utiles SEI
<a name="sei-attributes-inserting-sei-payloads"></a>

Les clients de publication peuvent insérer des données utiles SEI dans un flux d'étape en cours de publication en configurant LocalStageStream de leur vidéo pour activer `inBandMessaging` puis en invoquant la méthode `insertSeiMessage`. Notez que l'activation de `inBandMessaging` augmente l'utilisation de la mémoire du SDK.

Les données utiles doivent être du type [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer). La taille des données utiles doit être supérieure à 0 Ko et inférieure à 1 Ko. Le nombre de messages SEI insérés par seconde ne doit pas dépasser 10 Ko par seconde.

```
const config = {
    inBandMessaging: { enabled: true }
};
const vidStream = new LocalStageStream(videoTrack, config);
const payload = new TextEncoder().encode('hello world').buffer;
vidStream.insertSeiMessage(payload);
```

#### Répétition de données utiles SEI
<a name="sei-attributes-repeating-sei-payloads"></a>

Fournissez éventuellement un `repeatCount` pour répéter l'insertion de données utiles SEI pour les N prochaines trames envoyées. Cela peut être utile pour atténuer les pertes inhérentes qui peuvent survenir en raison du protocole de transport UDP sous-jacent utilisé pour envoyer des vidéos. Notez que cette valeur doit être comprise entre 0 et 30. Les clients destinataires doivent disposer d'une logique permettant de dédupliquer le message.

```
vidStream.insertSeiMessage(payload, { repeatCount: 5 }); // Optional config, repeatCount must be between 0 and 30
```

### Lecture de données utiles du SEI
<a name="sei-attributes-reading-sei-payloads"></a>

Les clients abonnés peuvent lire les données utiles SEI d’un éditeur qui publie une vidéo H.264 si elle est présente en configurant le ou les abonnés `SubscribeConfiguration` pour activer `inBandMessaging` et en écoutant l’événement `StageEvents.STAGE_STREAM_SEI_MESSAGE_RECEIVED`, comme le montre l’exemple suivant :

```
const strategy = {
    subscribeConfiguration: (participant) => {
        return {
            inBandMessaging: {
                enabled: true
            }
        }
    }
    // ... other strategy functions
}

stage.on(StageEvents.STAGE_STREAM_SEI_MESSAGE_RECEIVED, (participant, seiMessage) => {
    console.log(seiMessage.payload, seiMessage.uuid);
});
```

## Encodage en couches avec Simulcast
<a name="web-publish-subscribe-layered-encoding-simulcast"></a>

L’encodage en couches avec diffusion simultanée est une fonctionnalité de diffusion en temps réel d’IVS qui permet aux diffuseurs d’envoyer plusieurs couches de vidéo de qualité différente et aux abonnés de modifier ces couches de manière dynamique ou manuelle. Cette fonctionnalité est décrite plus en détail dans le document [Optimisations de la diffusion](https://docs.aws.amazon.com//ivs/latest/RealTimeUserGuide/real-time-streaming-optimization.html).

### Configuration du codage en couches (diffuseur de publication)
<a name="web-layered-encoding-simulcast-configure-publisher"></a>

En tant que diffuseur de publication, pour activer l’encodage en couches avec la diffusion simultanée, ajoutez la configuration suivante à votre `LocalStageStream` lors de l’instanciation :

```
// Enable Simulcast
let cameraStream = new LocalStageStream(cameraDevice, {
   simulcast: { enabled: true }
})
```

En fonction de la résolution d’entrée de votre caméra, un certain nombre de couches seront encodées et envoyées comme défini dans la section [Couches, qualités et fréquences d’images par défaut](real-time-streaming-optimization.md#real-time-streaming-optimization-default-layers) de la section *Optimisations de la diffusion*.

Vous avez également la possibilité de configurer des couches individuelles depuis la configuration de diffusion simultanée :

```
import { SimulcastLayerPresets } from ‘amazon-ivs-web-broadcast’

// Enable Simulcast
let cameraStream = new LocalStageStream(cameraDevice, {
   simulcast: {
      enabled: true,
      layers: [
         SimulcastLayerPresets.DEFAULT_720,
          SimulcastLayerPresets.DEFAULT_360,
          SimulcastLayerPresets.DEFAULT_180, 
   }
})
```

Vous pouvez également créer vos propres configurations de couches personnalisées pour un maximum de trois couches. Si vous fournissez un tableau vide ou ne contenant aucune valeur, les valeurs par défaut décrites ci-dessus sont utilisées. Les couches sont décrites avec les propriétés requises suivantes :
+ `height: number;`
+ `width: number;`
+ `maxBitrateKbps: number;`
+ `maxFramerate: number;`

À partir des préréglages, vous pouvez remplacer des propriétés individuelles ou créer une toute nouvelle configuration :

```
import { SimulcastLayerPresets } from ‘amazon-ivs-web-broadcast’

const custom720pLayer = {
   ...SimulcastLayerPresets.DEFAULT_720,
   maxFramerate: 15,
}

const custom360pLayer = {
       maxBitrateKbps: 600,
       maxFramerate: 15,
       width: 640,
       height: 360,
}

// Enable Simulcast
let cameraStream = new LocalStageStream(cameraDevice, {
   simulcast: {
      enabled: true,
      layers: [
         custom720pLayer,
         custom360pLayer, 
   }
})
```

Pour connaître les valeurs maximales, les limites et les erreurs qui peuvent être déclenchées lors de la configuration de couches individuelles, consultez la documentation de référence du kit SDK.

### Configuration de l’encodage en couches (abonné)
<a name="web-layered-encoding-simulcast-configure-subscriber"></a>

En tant qu’abonné, il n’est pas nécessaire d’activer l’encodage en couches. Si un diffuseur de publication envoie des couches de diffusion simultanée, le serveur s’adapte dynamiquement entre les couches pour choisir la qualité optimale en fonction de l’appareil de l’abonné et des conditions du réseau.

Sinon, pour choisir les couches explicites que le diffuseur de publication envoie, il existe plusieurs options, décrites ci-dessous.

### Option 1 : préférence pour la qualité de la couche initiale
<a name="web-layered-encoding-simulcast-layer-quality-preference"></a>

En utilisant la stratégie `subscribeConfiguration`, il est possible de choisir la couche initiale que vous voulez recevoir en tant qu’abonné :

```
const strategy = {
    subscribeConfiguration: (participant) => {
        return {
            simulcast: {
                initialLayerPreference: InitialLayerPreference.LOWEST_QUALITY
            }
        }
    }
    // ... other strategy functions
}
```

Par défaut, les abonnés reçoivent toujours d’abord la couche de qualité la plus faible, puis la couche de qualité la plus élevée. Cela permet d’optimiser la consommation de bande passante de l’utilisateur final et d’offrir le meilleur temps d’accès à la vidéo, réduisant ainsi les blocages initiaux de la vidéo pour les utilisateurs sur des réseaux plus faibles.

Ces options sont disponibles pour `InitialLayerPreference` :
+ `LOWEST_QUALITY` : le serveur diffuse d’abord la couche de vidéo de qualité la plus faible. Cela permet d’optimiser la consommation de la bande passante ainsi que le temps d’accès au contenu multimédia. La qualité est définie comme la combinaison de la taille, du débit binaire et de la fréquence d’images de la vidéo. Par exemple, une vidéo 720p est de moins bonne qualité qu’une vidéo 1080p.
+ `HIGHEST_QUALITY` : le serveur délivre d’abord la couche de vidéo de la plus haute qualité. Cela permet d’optimiser la qualité, mais peut augmenter le temps d’accès au contenu multimédia. La qualité est définie comme la combinaison de la taille, du débit binaire et de la fréquence d’images de la vidéo. Par exemple, la vidéo 1080p est de meilleure qualité que la vidéo 720p.

**Remarque :** pour que les préférences de couche initiale (l’appel `initialLayerPreference`) prennent effet, un nouvel abonnement est nécessaire car ces mises à jour ne s’appliquent pas à l’abonnement actif.



### Option 2 : couche préférée pour le flux
<a name="web-layered-encoding-simulcast-preferred-layer"></a>

Une fois qu’un flux a démarré, vous pouvez utiliser la méthode de stratégie `preferredLayerForStream `. Cette méthode expose les informations relatives au participant et au flux.

La méthode de stratégie peut être renvoyée avec ce qui suit :
+ L’objet couche directement, en fonction de ce que renvoie `RemoteStageStream.getLayers` 
+ La chaîne d’étiquette de l’objet couche, basée sur `StageStreamLayer.label`
+ Undefined ou null, qui indique qu’aucune couche ne doit être sélectionnée et que l’adaptation dynamique est préférable

Par exemple, dans la stratégie suivante, les utilisateurs sélectionneront toujours la couche de vidéo de la plus basse qualité disponible :

```
const strategy = {
    preferredLayerForStream: (participant, stream) => {
        return stream.getLowestQualityLayer();
    }
    // ... other strategy functions
}
```

Pour réinitialiser la sélection des couches et revenir à l’adaptation dynamique, renvoyez null ou undefined dans la stratégie. Dans cet exemple, `appState` est une variable fictive qui représente l’état possible de l’application.

```
const strategy = {
    preferredLayerForStream: (participant, stream) => {
        if (appState.isAutoMode) {
            return null;
        } else {
            return appState.layerChoice
        }
    }
    // ... other strategy functions
}
```

### Option 3 : aides pour les couches de RemoteStageStream
<a name="web-layered-encoding-simulcast-remotestagestream-helpers"></a>

`RemoteStageStream` possède plusieurs aides qui peuvent être utilisées pour prendre des décisions concernant la sélection des couches et afficher les sélections correspondantes aux utilisateurs finaux :
+ **Événements relatifs aux couches** : tout comme `StageEvents`, l’objet `RemoteStageStream` lui-même possède des événements qui communiquent les modifications apportées aux couches et à l’adaptation de la diffusion simultanée :
  + `stream.on(RemoteStageStreamEvents.ADAPTION_CHANGED, (isAdapting) => {})`
  + `stream.on(RemoteStageStreamEvents.LAYERS_CHANGED, (layers) => {})`
  + `stream.on(RemoteStageStreamEvents.LAYER_SELECTED, (layer, reason) => {})`
+ **Méthodes relatives aux couches** : `RemoteStageStream` possède plusieurs méthodes d’aide qui peuvent être utilisées pour obtenir des informations sur le flux et les couches présentées. Ces méthodes sont disponibles sur le flux distant fourni dans la stratégie `preferredLayerForStream `, ainsi que sur les flux distants exposés via `StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED`.
  + `stream.getLayers`
  + `stream.getSelectedLayer`
  + `stream.getLowestQualityLayer`
  + `stream.getHighestQualityLayer`

Pour plus de détails, consultez la classe `RemoteStageStream` dans la [documentation de référence du kit SDK](https://aws.github.io/amazon-ivs-web-broadcast/docs/sdk-reference) (français non garanti). Pour la raison `LAYER_SELECTED`, si le message `UNAVAILABLE` est renvoyé, cela indique que la couche demandée n'a pas pu être sélectionnée. La meilleure sélection est faite à sa place, qui est généralement une couche de qualité inférieure pour maintenir la stabilité du flux.

## Gestion des problèmes de réseau
<a name="web-publish-subscribe-network-issues"></a>

En cas de perte de la connexion réseau de l’appareil local, le kit SDK essaie de se reconnecter en interne sans aucune action de l’utilisateur. Dans certains cas, le kit SDK échoue et une action de l’utilisateur est requise.

D’une manière générale, l’état de l’étape peut être géré via l’événement `STAGE_CONNECTION_STATE_CHANGED` :

```
stage.on(StageEvents.STAGE_CONNECTION_STATE_CHANGED, (state) => {
   switch (state) {
      case StageConnectionState.DISCONNECTED:
         // handle disconnected UI
         return;
      case StageConnectionState.CONNECTING:
         // handle establishing connection UI
         return;
      case StageConnectionState.CONNECTED:
         // SDK is connected to the Stage
         return;
      case StageConnectionState.ERRORED:
         // SDK encountered an error and lost its connection to the stage. Wait for CONNECTED.
         return;
    }
})
```

En général, vous pouvez ignorer un état d’erreur qui survient après avoir rejoint une scène avec succès, car le kit SDK tentera de se rétablir automatiquement. Si le kit SDK signale un état `ERRORED` et que la scène reste dans l’état `CONNECTING` pendant une période prolongée (par exemple, 30 secondes ou plus), cela peut indiquer une déconnexion du réseau.

## Diffuser la scène sur un canal IVS
<a name="web-publish-subscribe-broadcast-stage"></a>

Pour diffuser une étape, créez une session `IVSBroadcastClient` distincte, puis suivez les instructions habituelles de diffusion avec le kit SDK, décrites ci-dessus. La liste des `StageStream` exposés via `STAGE_PARTICIPANT_STREAMS_ADDED` peut être utilisée pour récupérer les flux de contenu multimédia des participants, qui peuvent être appliqués à la composition du flux de diffusion, comme suit :

```
// Setup client with preferred settings
const broadcastClient = getIvsBroadcastClient();

stage.on(StageEvents.STAGE_PARTICIPANT_STREAMS_ADDED, (participant, streams) => {
    streams.forEach(stream => {
        const inputStream = new MediaStream([stream.mediaStreamTrack]);
        switch (stream.streamType) {
            case StreamType.VIDEO:
                broadcastClient.addVideoInputDevice(inputStream, `video-${participant.id}`, {
                    index: DESIRED_LAYER,
                    width: MAX_WIDTH,
                    height: MAX_HEIGHT
                });
                break;
            case StreamType.AUDIO:
                broadcastClient.addAudioInputDevice(inputStream, `audio-${participant.id}`);
                break;
        }
    })
})
```

Vous pouvez éventuellement composer une scène et la diffuser sur un canal IVS à faible latence, afin de toucher un public plus large. Consultez la section [Activation d’hôtes multiples sur un flux Amazon IVS](https://docs.aws.amazon.com//ivs/latest/LowLatencyUserGuide/multiple-hosts.html) dans le guide de l’utilisateur du streaming à faible latence IVS.

# Problèmes connus et solutions de contournement dans le SDK de diffusion Web IVS \$1 Streaming en temps réel
<a name="broadcast-web-known-issues"></a>

Ce document contient les problèmes connus que vous pouvez rencontrer lors de l'utilisation du SDK de diffusion Web Amazon IVS en temps réel et suggère des solutions de contournement potentielles.
+ Lorsque vous fermez les onglets du navigateur ou quittez des navigateurs sans appeler `stage.leave()`, des utilisateurs peuvent toujours apparaître dans la session avec un cadre figé ou un écran noir pendant maximum 10 secondes.

  **Solution de contournement :** aucune.
+ Les sessions Safari apparaissent par intermittence avec un écran noir pour les utilisateurs qui rejoignent une session en cours.

  **Solution de contournement :** actualisez le navigateur et reconnectez la session.
+ Safari ne se rétablit pas correctement après un changement de réseau.

  **Solution de contournement :** actualisez le navigateur et reconnectez la session.
+ La console du développeur répète une erreur `Error: UnintentionalError at StageSocket.onClose`.

  **Solution de contournement :** il n’est possible de créer qu’une seule étape par jeton de participant. Cette erreur se produit lorsque plusieurs instances `Stage` sont créées avec le même jeton de participant, que l’instance se trouve sur un ou plusieurs appareils.
+ Il se peut que vous éprouviez des difficultés à maintenir un état `StageParticipantPublishState.PUBLISHED` et que vous receviez des états `StageParticipantPublishState.ATTEMPTING_PUBLISH` répétés lorsque vous écoutez l’événement `StageEvents.STAGE_PARTICIPANT_PUBLISH_STATE_CHANGED`.

  **Solution :** limitez la résolution vidéo à 720p lors de l’invocation de `getUserMedia` ou de `getDisplayMedia`. Les valeurs de contrainte `getUserMedia` et `getDisplayMedia` pour la largeur et la hauteur ne doivent pas dépasser 921600 (1280×720) lorsqu’elles sont multipliées ensemble.
+ Lorsque `stage.leave()` est invoqué ou qu'un participant distant quitte, une erreur 404 DELETE apparaît dans la console de débogage du navigateur.

  **Solution de contournement :** aucune. Il s'agit d'une erreur inoffensive.

## Limitations de Safari
<a name="broadcast-web-safari-limitations"></a>
+ Le refus d’une demande d’autorisation nécessite de réinitialiser l’autorisation dans les paramètres du site web Safari au niveau du système d’exploitation.
+ Safari ne détecte pas nativement tous les périphériques aussi efficacement que Firefox ou Chrome. Par exemple, la caméra virtuelle OBS n’est pas détectée.

## Limitations de Firefox
<a name="broadcast-web-firefox-limitations"></a>
+ Les autorisations système doivent être activées pour que Firefox puisse partager l’écran. Après les avoir activées, l’utilisateur doit redémarrer Firefox pour qu’il fonctionne correctement ; sinon, si les autorisations sont perçues comme bloquées, le navigateur renverra une exception [NotFoundError](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#exceptions).
+ La méthode `getCapabilities` est manquante. Cela signifie que les utilisateurs ne peuvent pas obtenir la résolution ou le rapport hauteur/largeur de la piste multimédia. Consultez ce [thread Bugzilla](https://bugzilla.mozilla.org/show_bug.cgi?id=1179084).
+ Plusieurs propriétés `AudioContext` sont manquantes, par exemple la latence et le nombre de canaux. Cela peut poser un problème aux utilisateurs expérimentés qui souhaitent manipuler les pistes audio.
+ Les flux de caméra provenant de `getUserMedia` sont limités au format 4:3 sur macOS. Consultez le [thread Bugzilla 1](https://bugzilla.mozilla.org/show_bug.cgi?id=1193640) et le [thread Bugzilla 2](https://bugzilla.mozilla.org/show_bug.cgi?id=1306034).
+ La capture audio n’est pas prise en charge avec `getDisplayMedia`. Consultez ce [thread Bugzilla](https://bugzilla.mozilla.org/show_bug.cgi?id=1541425).
+ La fréquence d’images lors de la capture d’écran n’est pas optimale (environ 15 images par seconde ?). Consultez ce [thread Bugzilla](https://bugzilla.mozilla.org/show_bug.cgi?id=1703522).

## Limites du Web mobile
<a name="broadcast-web-mobile-web-limitations"></a>
+ Le partage d’écran [GetDisplayMedia](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#browser_compatibility) n’est pas pris en charge sur les appareils mobiles.

  **Solution de contournement :** aucune.
+ Le participant met 15 à 30 secondes pour partir lorsqu’il ferme un navigateur sans appeler `leave()`.

  **Solution** : Ajoutez une interface utilisateur qui encourage les utilisateurs à se déconnecter correctement.
+ L’application d’arrière-plan entraîne l’arrêt de la diffusion de vidéos.

  **Solution** : Affichez une liste d’interfaces utilisateur lorsque le diffuseur de publication est suspendu.
+ La fréquence d’images vidéo chute pendant environ 5 secondes après avoir désactivé une caméra sur les appareils Android.

  **Solution de contournement :** aucune.
+ Le flux vidéo est étiré en rotation pour iOS 16.0.

  **Solution** : Affichez une interface utilisateur décrivant ce problème connu du système d’exploitation.
+ Commuter le périphérique d’entrée audio commute automatiquement le périphérique de sortie audio.

  **Solution de contournement :** aucune.
+ Mettre le navigateur en arrière-plan entraîne l’affichage en noir du flux de publication et diffuse uniquement de l’audio.

  **Solution de contournement :** aucune. C’est pour des raisons de sécurité.

# Gestion des erreurs dans le SDK de diffusion Web IVS \$1 Streaming en temps réel
<a name="broadcast-web-error-handling"></a>

Cette section donne un aperçu des conditions d’erreur, de la façon dont le kit SDK de diffusion Web les signale à l’application et des actions que l’application doit prendre lorsqu’elles se produisent. Les erreurs sont signalées par le kit SDK aux écouteurs de l’événement `StageEvents.ERROR` :

```
stage.on(StageEvents.ERROR, (error: StageError) => {
    // log or handle errors here
    console.log(`${error.code}, ${error.category}, ${error.message}`);
});
```

## Erreurs de scène
<a name="web-error-handling-stage-errors"></a>

Une erreur de scène (StageError) est signalée lorsque le kit SDK rencontre un problème qu’il ne peut pas résoudre seul et qui nécessite généralement une intervention de l’application et/ou une reconnexion au réseau pour se rétablir.

Chaque `StageError` signalé comporte un code (ou `StageErrorCode`), un message (chaîne de caractères) et une catégorie (`StageErrorCategory`). Chacune de ces erreurs est liée à une catégorie d’opération sous-jacente.

La catégorie d’opération de l’erreur est déterminée en fonction de la nature de l’erreur : si elle est liée à la connexion à la scène (`JOIN_ERROR`), à l’envoi de contenu multimédia vers la scène (`PUBLISH_ERROR`) ou à la réception d’un flux multimédia entrant depuis la scène (`SUBSCRIBE_ERROR`).

La propriété code d’un `StageError` indique le problème spécifique :


| Nom | Code | Action recommandée | 
| --- | --- | --- | 
| JETON\$1MALFORMÉ | 1 | Créez un jeton valide, puis réessayez l’instanciation de la scène. | 
| JETON\$1EXPIRÉ | 2 | Créez un jeton non expiré, puis réessayez l’instanciation de la scène. | 
| EXPIRATION | 3 | L’opération a expiré. Si la scène existe et que le jeton est valide, cet échec est probablement dû à un problème du réseau. Dans ce cas, attendez que la connexion de l’appareil se rétablisse. | 
| FAILED | 4 | Une situation fatale s’est produite lors d’une tentative d’opération. Vérifiez les détails de l’erreur. Si la scène existe et que le jeton est valide, cet échec est probablement dû à un problème du réseau. Dans ce cas, attendez que la connexion de l’appareil se rétablisse. Pour la plupart des échecs liés à la stabilité du réseau, le kit SDK effectuera une nouvelle tentative en interne pendant une période pouvant aller jusqu’à 30 secondes avant d’émettre une erreur FAILED.  | 
| ANNULÉE | 5 | Vérifiez le code de l’application et assurez-vous qu’il n’y a pas d’invocations `join`, `refreshStrategy`, ou `replaceStrategy` répétées qui pourraient provoquer le démarrage et l’annulation répétés des opérations avant leur fin. | 
| SCÈNE\$1À\$1CAPACITÉ\$1MAXIMALE | 6 | Cette erreur indique que la scène ou votre compte a atteint sa capacité maximale. Si la scène a atteint sa limite de participants, réessayez l’opération lorsque la scène n’est plus saturée, en actualisant la stratégie. Si votre compte a atteint son quota d’abonnements simultanés ou de diffuseurs de publication simultanés, réduisez l’utilisation ou demandez une augmentation du quota via la [console AWS Service Quotas](https://console.aws.amazon.com/servicequotas/).  | 
| INCOMPATIBILITÉ\$1DE\$1CODEC | 7 | Le codec n’est pas pris en charge par la scène. Vérifiez la compatibilité du codec avec le navigateur et la plateforme. Pour la diffusion en temps réel IVS, les navigateurs doivent prendre en charge le codec H.264 pour la vidéo et le codec Opus pour l’audio. | 
| JETON\$1NON\$1AUTORISÉ | 8 | Le jeton n’est pas autorisé à effectuer l’opération. Recréez le jeton avec les autorisations appropriées, puis réessayez. | 
| STAGE\$1DELETED | 9 | Aucune ; cette erreur se produit lorsque vous essayez de rejoindre une scène supprimée. | 
| PARTICIPANT\$1DISCONNECTED | 10 | Aucune ; cette erreur se produit lorsque vous essayez de rejoindre une étape avec un jeton d’un participant déconnecté. | 

### Exemple de gestion d’erreur de scène (StageError)
<a name="web-error-handling-stage-errors-example"></a>

Utilisez le code StageError pour déterminer si l’erreur est due à un jeton expiré :

```
stage.on(StageEvents.ERROR, (error: StageError) => {
    if (error.code === StageError.TOKEN_EXPIRED) {
        // recreate the token and stage instance and re-join
    }
});
```

### Erreurs réseau lorsque vous êtes déjà connecté
<a name="web-error-handling-stage-errors-network"></a>

En cas de perte de la connexion réseau de l’appareil, le kit SDK risque de perdre sa connexion aux serveurs de scène. Des erreurs peuvent s’afficher dans la console car le kit SDK ne peut plus accéder aux services backend. Les publications sur https://broadcast.stats.live-video.net échoueront.

Si vous publiez et/ou que vous vous abonnez, des erreurs liées à des tentatives de publication/d’abonnement apparaîtront dans la console.

En interne, le kit SDK tentera de se reconnecter avec une stratégie de backoff exponentiel.

**Action** : attendez que la connectivité de l’appareil soit rétablie.

## États d’erreur
<a name="web-error-handling-errored-states"></a>

Nous recommandons d’utiliser ces états pour consigner les erreurs dans l’application et afficher des messages aux utilisateurs pour les alerter des problèmes de connexion à la scène pour un participant particulier.

### Publication
<a name="errored-states-publish"></a>

Le kit SDK signale `ERRORED` lorsqu’une publication échoue.

```
stage.on(StageEvents.STAGE_PARTICIPANT_PUBLISH_STATE_CHANGED, (participantInfo, state) => {
  if (state === StageParticipantPublishState.ERRORED) {
      // Log and/or display message to user
  }
});
```

### S’abonner
<a name="errored-states-subscribe"></a>

Le kit SDK signale `ERRORED` lorsqu’un abonnement échoue. Cela peut se produire en raison des conditions du réseau ou si une étape est à pleine capacité pour les abonnés.

```
stage.on(StageEvents.STAGE_PARTICIPANT_SUBSCRIBE_STATE_CHANGED, (participantInfo, state) => {
  if (state === StageParticipantSubscribeState.ERRORED) {
    // Log and/or display message to user
  }
});
```