Kit SDK de diffusion IVS : appareils mixtes - Amazon IVS

Kit SDK de diffusion IVS : appareils mixtes

Les appareils mixtes sont des appareils audio et vidéo qui acceptent plusieurs sources d’entrée et génèrent une seule sortie. Les appareils de mixage sont une fonctionnalité puissante qui vous permet de définir et de gérer plusieurs éléments à l’écran (vidéo) et pistes audio. Combinez de la vidéo et de l'audio provenant de sources multiples telles que des caméras, des microphones, des captures d'écran, ainsi que de l'audio et de la vidéo générés par votre application. Vous pouvez utiliser des transitions pour déplacer ces sources dans la vidéo que vous diffusez vers IVS, et ajouter ou supprimer des sources en cours de diffusion.

Les appareils mixtes se déclinent en versions image et audio. Pour créer un appareil d’image mixte, appelez :

DeviceDiscovery.createMixedImageDevice() sur Android

IVSDeviceDiscovery.createMixedImageDevice() sur iOS

L’appareil renvoyé peut être associé à un BroadcastSession (diffusion à faible latence) ou Stage (diffusion en temps réel), comme tout autre appareil.

Terminologie

Terminologie des appareils mixtes de diffusion IVS.
Terme Description

Appareil

Un composant matériel ou logiciel qui produit une entrée audio ou image. Les microphones, les caméras, les casques Bluetooth et les périphériques virtuels tels que les captures d'écran ou les entrées d'images personnalisées sont des exemples d'appareils.

Appareil mixte

Un Device qui peut être associé à un BroadcastSession comme n’importe quel autre Device, mais avec des API supplémentaires qui permettent d’ajouter des objets Source. Les appareils mixtes disposent de mixeurs internes qui composent l’audio ou les images, produisant un flux audio et image unique.

Les appareils mixtes sont disponibles en version audio ou image.

Configuration d’un appareil mixte

Un objet de configuration pour l’appareil mixte. Pour les appareils d’image mixtes, cela permet de configurer des propriétés telles que les dimensions et la fréquence d’images. Pour les appareils d’audio mixtes, cela permet de configurer le nombre de canaux.

Source

Un conteneur qui définit la position d'un élément visuel à l'écran et les propriétés d'une piste audio dans le mixage audio. Un appareil mixte peut être configuré avec zéro ou plusieurs sources. Les sources reçoivent une configuration qui affecte la manière dont les médias de la source sont utilisés. L’image ci-dessus montre quatre sources d’image :

  • En bas à gauche avec entrée caméra

  • En haut à droite avec entrée vidéo

  • En bas à droite avec le logo d'Amazon IVS

  • Une image plein écran d'arrière-plan

Configuration de la source

Un objet de configuration pour la source entrant dans un appareil mixte. Les objets de configuration complets sont décrits ci-dessous.

Transition

Pour déplacer un slot vers une nouvelle position ou modifier certaines de ses propriétés, utilisez MixedDevice.transitionToConfiguration(). Cette méthode nécessite :

  • Une nouvelle configuration de la source qui représente l’état suivant de la source.

  • Une durée qui spécifie le temps de l'animation par rapport à la chronologie de la vidéo. Si la durée est définie sur 0, la transition se produit sur la prochaine image qui est mélangée.

  • Une fonctionnalité de rappel facultatif qui vous informe lorsque l'animation est terminée. Le rappel peut être utile pour enchaîner les animations.

Appareil d’audio mixte

Configuration

MixedAudioDeviceConfiguration sur Android

IVSMixedAudioDeviceConfiguration sur iOS

Nom Type Description

channels

Entier

Nombre de canaux de sortie du mixage audio. Valeurs valides : 1, 2. 1 est un audio mono ; 2, un audio stéréo. Par défaut : 2.

Configuration de la source

MixedAudioDeviceSourceConfiguration sur Android

IVSMixedAudioDeviceSourceConfiguration sur iOS

Nom Type Description

gain

Float

Gain audio. Il s'agit d'un multiplicateur, donc toute valeur supérieure à 1 augmente le gain ; toute valeur inférieure à 1 le diminue. Valeurs valides : 0 à 2. Par défaut : 1.

Appareil d’image mixte

Configuration

MixedImageDeviceConfiguration sur Android

IVSMixedImageDeviceConfiguration sur iOS

Nom Type Description

size

Vec2

Taille du canevas de la vidéo.

targetFramerate

Entier

Nombre d’images cibles par seconde pour l’appareil mixte. En moyenne, cette valeur doit être respectée, mais le système peut sauter des images dans certaines circonstances (par exemple, en cas de charge élevée du processeur ou du processeur graphique).

transparencyEnabled

Booléen

Cela permet le mélange à l’aide de la propriété alpha sur les configurations de source d’image. Définir cette valeur sur true augmente la consommation de mémoire et de CPU. Par défaut: false.

Configuration de la source

MixedImageDeviceSourceConfiguration sur Android

IVSMixedImageDeviceSourceConfiguration sur iOS

Nom Type Description

alpha

Float

Alpha du slot. Il est multiplicative avec toutes les valeurs alpha de l'image. Valeurs valides : 0-1. 0 correspond à une transparence totale et 1 à une opacité totale. Par défaut : 1.

aspect

AspectMode

Mode de rapport d'aspect pour toute image rendue dans le slot. Valeurs valides :

  • Fill — Conservez le ratio hauteur/largeur de l'image mais remplissez le slot. L’image est recadrée si nécessaire.

  • Fit — Conservez le ratio hauteur/largeur de l'image mais remplissez l'image entière dans le slot. Le slot peut comporter une boîte aux lettres ou une messagerie si nécessaire. Le letter/pillarbox se trouve dans fillColor si cette valeur a été définie ; sinon, elle est transparente (ce qui peut apparaître en noir si la couleur du canevas derrière l’image est noire).

  • None — Ne conservez pas le rapport hauteur/largeur de l'image. L’image est ajustée pour correspondre aux dimensions du slot.

Par défaut : Fit

fillColor

Vec4

Couleur de remplissage à utiliser avec aspect Fit lorsque les rapports d’aspect du slot et de l’image ne correspondent pas. Le format est (rouge, vert, bleu, alpha). Valeur valide (pour chaque canal) : 0 à 1. Par défaut : (0, 0, 0, 0).

position

Vec2

Position du slot (en pixels) par rapport à l'angle supérieur gauche du canevas. L'origine du slot est également en haut à gauche.

size

Vec2

Taille du slot, en pixels. La définition de cette valeur définit également matchCanvasSize sur false. Par défaut : (0, 0) ; cependant, étant donné que matchCanvasSize la valeur par défaut est true, la taille rendue du slot correspond à la taille du canevas, et non (0, 0).

zIndex

Float

Ordre relatif des slots. Les slots avec des valeurs plus zIndex élevées sont dessinées au dessus des slots avec des valeurs zIndex inférieures.

Création et configuration d’un appareil d’image mixte

Configuration d'une séance de diffusion pour le mixage.

Ici, nous créons une scène similaire à celle du début de ce guide, avec trois éléments à l'écran :

  • Slot en bas à gauche pour une caméra.

  • Slot en bas à droite pour une superposition de logo.

  • Slot en haut à droite pour un film.

Notez que l'origine du canevas est le coin supérieur gauche et c'est la même chose pour les slots. Par conséquent, le positionnement d'un slot à (0, 0) le place dans le coin supérieur gauche avec l'ensemble du slot visible.

iOS

let deviceDiscovery = IVSDeviceDiscovery() let mixedImageConfig = IVSMixedImageDeviceConfiguration() mixedImageConfig.size = CGSize(width: 1280, height: 720) try mixedImageConfig.setTargetFramerate(60) mixedImageConfig.isTransparencyEnabled = true let mixedImageDevice = deviceDiscovery.createMixedImageDevice(with: mixedImageConfig) // Bottom Left let cameraConfig = IVSMixedImageDeviceSourceConfiguration() cameraConfig.size = CGSize(width: 320, height: 180) cameraConfig.position = CGPoint(x: 20, y: mixedImageConfig.size.height - cameraConfig.size.height - 20) cameraConfig.zIndex = 2 let camera = deviceDiscovery.listLocalDevices().first(where: { $0 is IVSCamera }) as? IVSCamera let cameraSource = IVSMixedImageDeviceSource(configuration: cameraConfig, device: camera) mixedImageDevice.add(cameraSource) // Top Right let streamConfig = IVSMixedImageDeviceSourceConfiguration() streamConfig.size = CGSize(width: 640, height: 320) streamConfig.position = CGPoint(x: mixedImageConfig.size.width - streamConfig.size.width - 20, y: 20) streamConfig.zIndex = 1 let streamDevice = deviceDiscovery.createImageSource(withName: "stream") let streamSource = IVSMixedImageDeviceSource(configuration: streamConfig, device: streamDevice) mixedImageDevice.add(streamSource) // Bottom Right let logoConfig = IVSMixedImageDeviceSourceConfiguration() logoConfig.size = CGSize(width: 320, height: 180) logoConfig.position = CGPoint(x: mixedImageConfig.size.width - logoConfig.size.width - 20, y: mixedImageConfig.size.height - logoConfig.size.height - 20) logoConfig.zIndex = 3 let logoDevice = deviceDiscovery.createImageSource(withName: "logo") let logoSource = IVSMixedImageDeviceSource(configuration: logoConfig, device: logoDevice) mixedImageDevice.add(logoSource)

Android

val deviceDiscovery = DeviceDiscovery(this /* context */) val mixedImageConfig = MixedImageDeviceConfiguration().apply { setSize(BroadcastConfiguration.Vec2(1280f, 720f)) setTargetFramerate(60) setEnableTransparency(true) } val mixedImageDevice = deviceDiscovery.createMixedImageDevice(mixedImageConfig) // Bottom Left val cameraConfig = MixedImageDeviceSourceConfiguration().apply { setSize(BroadcastConfiguration.Vec2(320f, 180f)) setPosition(BroadcastConfiguration.Vec2(20f, mixedImageConfig.size.y - size.y - 20)) setZIndex(2) } val camera = deviceDiscovery.listLocalDevices().firstNotNullOf { it as? CameraSource } val cameraSource = MixedImageDeviceSource(cameraConfig, camera) mixedImageDevice.addSource(cameraSource) // Top Right val streamConfig = MixedImageDeviceSourceConfiguration().apply { setSize(BroadcastConfiguration.Vec2(640f, 320f)) setPosition(BroadcastConfiguration.Vec2(mixedImageConfig.size.x - size.x - 20, 20f)) setZIndex(1) } val streamDevice = deviceDiscovery.createImageInputSource(streamConfig.size) val streamSource = MixedImageDeviceSource(streamConfig, streamDevice) mixedImageDevice.addSource(streamSource) // Bottom Right val logoConfig = MixedImageDeviceSourceConfiguration().apply { setSize(BroadcastConfiguration.Vec2(320f, 180f)) setPosition(BroadcastConfiguration.Vec2(mixedImageConfig.size.x - size.x - 20, mixedImageConfig.size.y - size.y - 20)) setZIndex(1) } val logoDevice = deviceDiscovery.createImageInputSource(logoConfig.size) val logoSource = MixedImageDeviceSource(logoConfig, logoDevice) mixedImageDevice.addSource(logoSource)

Suppression de sources

Pour supprimer une source, appelez MixedDevice.remove avec l’objet Source que vous voulez supprimer.

animations avec Transitions

La méthode de transition remplace la configuration d’une source par une nouvelle configuration. Ce remplacement peut être animé au fil du temps en définissant une durée supérieure à 0, en secondes.

Quelles propriétés peuvent être animées  ?

Toutes les propriétés de la structure du slot ne peuvent être animées. Toutes les propriétés basées sur des types Float peuvent être animées ; d’autres propriétés prennent effet au démarrage ou à la fin de l’animation.

Nom Peut-on l’animer ? Point d'impact

Audio.gain

Oui

Interpolé

Image.alpha

Oui

Interpolé

Image.aspect

Non

Fin

Image.fillColor

Oui

Interpolé

Image.position

Oui

Interpolé

Image.size

Oui

Interpolé

Image.zIndex

Remarque : Le zIndex déplace les plans 2D dans l'espace 3D, de sorte que la transition se produit lorsque les deux plans se croisent à un moment donné au milieu de l'animation. Cela peut être calculé, mais cela dépend du début et de la fin des valeurs zIndex. Pour une transition plus fluide, combinez cela avec alpha.

Oui

Je ne sais pas

Exemples simples

Vous trouverez ci-dessous des exemples de prise de contrôle de la caméra en plein écran à l’aide de la configuration définie ci-dessus dans Création et configuration d’un appareil d’image mixte. Il est animé pendant 0,5 seconde.

iOS

// Continuing the example from above, modifying the existing cameraConfig object. cameraConfig.size = CGSize(width: 1280, height: 720) cameraConfig.position = CGPoint.zero cameraSource.transition(to: cameraConfig, duration: 0.5) { completed in if completed { print("Animation completed") } else { print("Animation interrupted") } }

Android

// Continuing the example from above, modifying the existing cameraConfig object. cameraConfig.setSize(BroadcastConfiguration.Vec2(1280f, 720f)) cameraConfig.setPosition(BroadcastConfiguration.Vec2(0f, 0f)) cameraSource.transitionToConfiguration(cameraConfig, 500) { completed -> if (completed) { print("Animation completed") } else { print("Animation interrupted") } }

Mise en miroir de la diffusion

Pour mettre en miroir un périphérique d'image connecté lors de la diffusion dans cette direction... Utilisez une valeur négative pour …

Horizontalement

La largeur du slot

Verticalement

La hauteur du slot

Aussi bien horizontalement que verticalement

La largeur et la hauteur de la fente

La position devra être ajustée selon la même valeur, afin de placer la fente dans la bonne position lors de la mise en miroir.

Vous trouverez ci-dessous des exemples de mise en miroir de la diffusion horizontalement et verticalement.

iOS

Mise en miroir horizontale :

let cameraSource = IVSMixedImageDeviceSourceConfiguration() cameraSource.size = CGSize(width: -320, height: 720) // Add 320 to position x since our width is -320 cameraSource.position = CGPoint(x: 320, y: 0)

Mise en miroir horizontale verticale :

let cameraSource = IVSMixedImageDeviceSourceConfiguration() cameraSource.size = CGSize(width: 320, height: -720) // Add 720 to position y since our height is -720 cameraSource.position = CGPoint(x: 0, y: 720)

Android

Mise en miroir horizontale :

val cameraConfig = MixedImageDeviceSourceConfiguration().apply { setSize(BroadcastConfiguration.Vec2(-320f, 180f)) // Add 320f to position x since our width is -320f setPosition(BroadcastConfiguration.Vec2(320f, 0f)) }

Mise en miroir horizontale verticale :

val cameraConfig = MixedImageDeviceSourceConfiguration().apply { setSize(BroadcastConfiguration.Vec2(320f, -180f)) // Add 180f to position y since our height is -180f setPosition(BroadcastConfiguration.Vec2(0f, 180f)) }

Remarque : cette mise en miroir est différente de la méthode setMirrored utilisée sur ImagePreviewView (Android) et IVSImagePreviewView (iOS). Cette méthode n'affecte que la vue d'aperçu locale sur l'appareil et n'a aucun impact sur la diffusion.