Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Publication et abonnement
Concepts
Trois concepts de base sous-tendent la fonctionnalité temps réel : scène, stratégie et moteur de rendu. L’objectif de la conception consiste à minimiser la quantité de logique côté client nécessaire à la création d’un produit fonctionnel.
Étape
La classe IVSStage
est le principal point d’interaction entre l’application hôte et le kit SDK. La classe représente l’étape elle-même et est utilisée pour rejoindre et quitter l’étape. La création ou 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.
let stage = try IVSStage(token: token, strategy: self) try stage.join() stage.leave()
La classe IVSStage
est également l’endroit où vous pouvez joindre le IVSStageRenderer
et le IVSErrorDelegate
:
let stage = try IVSStage(token: token, strategy: self) stage.errorDelegate = self stage.addRenderer(self) // multiple renderers can be added
Strategy
Le protocole IVSStageStrategy
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 streamsToPublishForParticipant
. Elles sont toutes abordées ci-dessous.
Abonnement aux participants
func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType
Lorsqu’un participant distant rejoint une étape, le kit SDK interroge l’application hôte sur l’état de l’abonnement souhaité pour ce participant. Les options sont .none
, .audioOnly
et .audioVideo
. 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 .audioVideo
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 par le biais du moteur de rendu tout au long du processus.
Voici un exemple d’implémentation :
func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType { return .audioVideo }
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. Utilisez la propriété attributes
sur IVSParticipantInfo
pour vous abonner de manière sélective aux participants en fonction des attributs fournis par le serveur :
func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType { switch participant.attributes["role"] { case "moderator": return .none case "guest": return .audioVideo default: return .none } }
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.
Publication
func stage(_ stage: IVSStage, shouldPublishParticipant participant: IVSParticipantInfo) -> Bool
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 :
func stage(_ stage: IVSStage, shouldPublishParticipant participant: IVSParticipantInfo) -> Bool { return true }
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
func stage(_ stage: IVSStage, streamsToPublishForParticipant participant: IVSParticipantInfo) -> [IVSLocalStageStream]
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.
Mise à jour de la stratégie
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
n’apportera aucune modification à l’étape.
Si la valeur de retour de shouldSubscribeToParticipant
passe de .audioVideo
à .audioOnly
, le flux vidéo sera 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.
Moteur de rendu
Le protocole IVSStageRenderer
communique l’état de l’étape à l’application hôte. Les mises à jour de l’interface utilisateur de l’application hôte peuvent généralement être entièrement optimisées par les événements fournis par le moteur de rendu. Le moteur de rendu fournit les fonctions suivantes :
func stage(_ stage: IVSStage, participantDidJoin participant: IVSParticipantInfo) func stage(_ stage: IVSStage, participantDidLeave participant: IVSParticipantInfo) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChange publishState: IVSParticipantPublishState) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChange subscribeState: IVSParticipantSubscribeState) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didAdd streams: [IVSStageStream]) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didRemove streams: [IVSStageStream]) func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChangeMutedStreams streams: [IVSStageStream]) func stage(_ stage: IVSStage, didChange connectionState: IVSStageConnectionState, withError error: Error?)
Les informations fournies par le moteur de rendu 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 participant:didChangePublishState
. 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.
Notez que seuls les participants à la publication déclenchent participantDidJoin
et que chaque fois qu’un participant arrête de publier ou quitte la session de l’étape, participantDidLeave
est déclenché.
Publier un flux multimédia
Les appareils locaux tels que les microphones et les caméras intégrés sont découverts via IVSDeviceDiscovery
. Voici un exemple de sélection de la caméra frontale et du microphone par défaut, puis de leur renvoi en tant que IVSLocalStageStreams
à publier par le SDK :
let devices = IVSDeviceDiscovery.listLocalDevices() // Find the camera virtual device, choose the front source, and create a stream let camera = devices.compactMap({ $0 as? IVSCamera }).first! let frontSource = camera.listAvailableInputSources().first(where: { $0.position == .front })! camera.setPreferredInputSource(frontSource) let cameraStream = IVSLocalStageStream(device: camera) // Find the microphone virtual device, enable echo cancellation, and create a stream let microphone = devices.compactMap({ $0 as? IVSMicrophone }).first! microphone.isEchoCancellationEnabled = true let microphoneStream = IVSLocalStageStream(device: microphone) // This is a function on IVSStageStrategy func stage(_ stage: IVSStage, streamsToPublishForParticipant participant: IVSParticipantInfo) -> [IVSLocalStageStream] { return [cameraStream, microphoneStream] }
Afficher et supprimer des participants
Une fois l’abonnement effectué, vous recevrez un tableau d’objets IVSStageStream
via la fonction didAddStreams
du moteur de rendu. Pour avoir un aperçu ou recevoir des statistiques de niveau audio concernant ce participant, vous pouvez accéder à l’objet IVSDevice
sous-jacent depuis le flux :
if let imageDevice = stream.device as? IVSImageDevice { let preview = imageDevice.previewView() /* attach this UIView subclass to your view */ } else if let audioDevice = stream.device as? IVSAudioDevice { audioDevice.setStatsCallback( { stats in /* process stats.peak and stats.rms */ }) }
Lorsqu’un participant arrête de publier ou en cas de désabonnement, la fonction didRemoveStreams
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 de la hiérarchie des vues.
didRemoveStreams
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
.audioVideo
en.audioOnly
. -
Le participant distant quitte l’étape.
-
Le participant local quitte l’étape.
Comme didRemoveStreams
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
Les objets IVSLocalStageStream
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 streamsToPublishForParticipant
.
Important : si une nouvelle instance d’objet IVSLocalStageStream
est renvoyée par streamsToPublishForParticipant
après un appel à refreshStrategy
, l’état muet du nouvel objet de flux est appliqué à l’étape. Lorsque vous créez des instances IVSLocalStageStream
, veillez à ce que l’état muet attendu soit conservé.
Surveiller l’état muet du contenu multimédia des participants distants
Lorsqu’un participant modifie l’état muet de son flux vidéo ou audio, la fonction didChangeMutedStreams
du moteur de rendu est invoquée avec un tableau des flux qui ont changé. Utilisez la propriété isMuted
sur IVSStageStream
pour mettre à jour votre interface utilisateur en conséquence :
func stage(_ stage: IVSStage, participant: IVSParticipantInfo, didChangeMutedStreams streams: [IVSStageStream]) { streams.forEach { stream in /* stream.isMuted */ } }
Création d’une configuration d’étape
Pour personnaliser les valeurs de la configuration vidéo d’une étape, utilisez IVSLocalStageStreamVideoConfiguration
:
let config = IVSLocalStageStreamVideoConfiguration() try config.setMaxBitrate(900_000) try config.setMinBitrate(100_000) try config.setTargetFramerate(30) try config.setSize(CGSize(width: 360, height: 640)) config.degradationPreference = .balanced
Obtenir les statistiques WebRTC
Pour obtenir les dernières statistiques WebRTC relatives à un flux de publication ou d’abonnement, utilisez requestRTCStats
sur IVSStageStream
. Lorsqu’une collecte est réalisée, vous recevez des statistiques via le IVSStageStreamDelegate
que vous pouvez définir sur IVSStageStream
. Pour collecter en permanence des statistiques WebRTC, appelez cette fonction sur un Timer
.
func stream(_ stream: IVSStageStream, didGenerateRTCStats stats: [String : [String : String]]) { for stat in stats { for member in stat.value { print("stat \(stat.key) has member \(member.key) with value \(member.value)") } } }
Obtenir les attributs des participants
Si vous spécifiez des attributs dans la demande de point de terminaison CreateParticipantToken
, vous pouvez les voir dans les propriétés IVSParticipantInfo
:
func stage(_ stage: IVSStage, participantDidJoin participant: IVSParticipantInfo) { print("ID: \(participant.participantId)") for attribute in participant.attributes { print("attribute: \(attribute.key)=\(attribute.value)") } }
Poursuivre la session en arrière-plan
Lorsque l’application passe en arrière-plan, vous pouvez rester dans l’étape tout en écoutant le son distant, mais il n’est pas possible de continuer à envoyer vos propres images et sons. Vous devrez mettre à jour votre implémentation IVSStrategy
pour arrêter la publication et vous abonner à .audioOnly
(ou .none
, le cas échéant) :
func stage(_ stage: IVSStage, shouldPublishParticipant participant: IVSParticipantInfo) -> Bool { return false } func stage(_ stage: IVSStage, shouldSubscribeToParticipant participant: IVSParticipantInfo) -> IVSStageSubscribeType { return .audioOnly }
Passez ensuite un appel à stage.refreshStrategy()
.
Activer/désactiver le codage en couches avec Simulcast
Lors de la publication d’un flux multimédia, le SDK transmet des flux vidéo de haute et de faible qualité, afin que les participants distants puissent s’abonner au flux même s’ils disposent d’une bande passante descendante limitée. L’encodage en couches avec simulcast est activé par défaut. Vous pouvez le désactiver avec IVSSimulcastConfiguration
:
// Disable Simulcast let config = IVSLocalStageStreamVideoConfiguration() config.simulcast.enabled = false let cameraStream = IVSLocalStageStream(device: camera, configuration: config) // Other Stage implementation code
Diffuser la scène sur un canal IVS
Pour diffuser une étape, créez une IVSBroadcastSession
distincte, puis suivez les instructions habituelles de diffusion avec le kit SDK, décrites ci-dessus. La propriété device
sur IVSStageStream
sera soit un IVSImageDevice
soit un IVSAudioDevice
comme indiqué dans l’extrait ci-dessus. Ils peuvent être connectés au IVSBroadcastSession.mixer
pour diffuser l’intégralité de l’étape dans une disposition personnalisable.
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 dans le guide de l’utilisateur du streaming à faible latence IVS.