

# Kit SDK de diffusion IVS : appareils mixtes
<a name="broadcast-mixed-devices"></a>

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
<a name="broadcast-mixed-devices-terminology"></a>

![\[Terminologie des appareils mixtes de diffusion IVS.\]](http://docs.aws.amazon.com/fr_fr/ivs/latest/LowLatencyUserGuide/images/Broadcast_SDK_Mixer_Glossary.png)



| 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 : [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html)  | 
| 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 : [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html) | 

## Appareil d’audio mixte
<a name="broadcast-mixed-audio-device"></a>

### Configuration
<a name="broadcast-mixed-audio-device-configuration"></a>

`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
<a name="broadcast-mixed-audio-device-source-configuration"></a>

`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
<a name="broadcast-mixed-image-device"></a>

### Configuration
<a name="broadcast-mixed-image-device-configuration"></a>

`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. Valeur par défaut : `false`. | 

### Configuration de la source
<a name="broadcast-mixed-image-device-source-configuration"></a>

`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 : [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html) Valeur 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
<a name="broadcast-mixed-image-device-creating-configuring"></a>

![\[Configuration d'une séance de diffusion pour le mixage.\]](http://docs.aws.amazon.com/fr_fr/ivs/latest/LowLatencyUserGuide/images/Broadcast_SDK_Mixer_Configuring.png)


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
<a name="broadcast-mixed-image-device-creating-configuring-ios"></a>

```
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
<a name="broadcast-mixed-image-device-creating-configuring-android"></a>

```
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
<a name="broadcast-mixed-devices-removing-sources"></a>

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

## animations avec Transitions
<a name="broadcast-mixed-devices-animations-transitions"></a>

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  ?
<a name="broadcast-mixed-devices-animations-properties"></a>

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
<a name="broadcast-mixed-devices-animations-examples"></a>

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](#broadcast-mixed-image-device-creating-configuring). Il est animé pendant 0,5 seconde.

#### iOS
<a name="broadcast-mixed-devices-animations-examples-ios"></a>

```
// 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
<a name="broadcast-mixed-devices-animations-examples-android"></a>

```
// 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
<a name="broadcast-mixed-devices-mirroring"></a>


| 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
<a name="broadcast-mixed-devices-mirroring-ios"></a>

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
<a name="broadcast-mixed-devices-mirroring-android"></a>

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.