Kit SDK de diffusion IVS : Guide de mixage | Diffusion à faible latence
Le mixage est une unité de traitement audio et vidéo qui prend sources multiples d'entrée et génère une seule sortie. Il s'agit d'une fonction puissante qui vous permet de définir et de gérer plusieurs éléments (vidéo) et des pistes audio à l'écran. 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 sur Amazon IVS et les ajouter et les supprimer en cours de diffusion.
Pour accéder au mixage, appelez :
BroadcastSession.getMixer()
sur Android
IVSBroadcastSession.mixer
sur iOS
Terminologie
Terme | Description |
---|---|
Binding |
Pour associer un périphérique d'entrée à un slot, le périphérique doit être lié au slot de mixage. Cette opération est exécutée avec la méthode |
Canvas |
La taille d'affichage de la vidéo définie dans votre configuration |
Appareil |
Un composant matériel ou logiciel qui produit une entrée audio ou une image pour le |
Description du périphérique |
Une structure contenant des informations sur un périphérique d'entrée, par exemple son type, son adresse système, son nom « adapté » à la lecture humaine et à sa position physique sur l'appareil mobile. Ces informations vous permettent de décider si vous souhaitez utiliser l'appareil référencé et permettent à Amazon IVS d'y accéder. |
Slot |
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 mixage peut être configuré avec zéro ou plusieurs slots. Les Slots reçoivent un nom de chaîne qui peut être utilisé pour lier des périphériques et exécuter des transitions. L'image ci-dessus montre quatre slots :
Après avoir configuré une séance, vous pouvez ajouter et supprimer des slots avec le |
Transition |
Pour déplacer un slot vers une nouvelle position ou modifier certaines de ses propriétés, utilisez
|
Propriétés du canevas
Les propriétés du canevas sont définies sur la base de BroadcastConfiguration
que vous fournissez lors de la création du BroadcastSession
. Plusieurs propriétés dans les Audio
et Video
structures affectent le canevas :
Nom | Type | Description |
---|---|---|
|
Entier |
Nombre de canaux de sortie du mixage audio. Valeurs valides : 1, 2. 1 canal est un audio mono ; 2, un audio stéréo. Par défaut : 2. |
|
AudioSampleRate |
Nombre d'échantillons audio par seconde provenant du mixage audio. Cette valeur doit être au moins deux fois supérieur à la fréquence la plus élevée de votre signal audio. Les gens peuvent entendre jusqu'à environ 20 kHz, donc 44,1 kHz et 48 kHz suffisent en principe. Valeur par défaut : 48 kHz. |
|
AspectMode |
Mode ratio d'aspect par défaut pour les slots. Valeurs valides :
|
|
Vec2 |
Taille du canevas de la vidéo. |
|
Entier |
Nombre d'images cibles par seconde pour le canevas. 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 CPU ou un réseau surchargé). |
Propriétés du Slot
Les slots possèdent plusieurs propriétés configurables que vous pouvez utiliser pour personnaliser et animer vos scènes. Toute valeur de type Float ou Vector est animée à l'aide d'une interpolation linéaire pour les transitions dont la durée est supérieure à 0 seconde.
Nom | Type | Description |
---|---|---|
|
AspectMode |
Mode de rapport d'aspect pour toute image rendue dans le slot. Valeurs valides :
Par défaut : identique au Canvas |
|
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). |
|
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. |
|
Booléen |
Si la valeur est vraie, utilisez la valeur du canevas |
|
Booléen |
Si la valeur est vraie, la taille du slot est ajustée pour être égale à la taille du canevas et sa position est définie sur (0, 0). Cette option est « fausse » si vous définissez la propriété du |
|
Chaîne |
Nom du slot. Ceci est utilisé pour référencer le slot pour les liaisons et les transitions. Par défaut: |
|
Vec2 |
Position du slot (en pixels) par rapport à l'angle supérieur gauche du canevas. L'origine du slot est également en haut à gauche. |
|
DeviceType |
Type de périphérique d'entrée audio préféré. Si ce slot n'est pas lié et qu'un périphérique audio du type spécifié est connecté à la séance, le périphérique se lie automatiquement à ce slot. Valeurs valides :
|
|
DeviceType |
Périphérique d'entrée vidéo préféré. Si ce slot n'est pas lié et qu'un périphérique vidéo du type spécifié est connecté à la séance, le périphérique se lie automatiquement à ce slot. Valeurs valides :
|
|
Vec2 |
Taille du slot, en pixels. Si vous définissez cette valeur elle devient également |
|
Float |
Transparence du slot. Il est multiplicative avec toutes les valeurs alpha de l'image. L'opacité est de 1 - |
|
Float |
Ordre relatif des slots. Les slots avec des valeurs plus |
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 config = IVSBroadcastConfiguration() try config.video.setSize(CGSize(width: 1280, height: 720)) try config.video.setTargetFramerate(60) config.video.enableTransparency = true // Bottom Left var cameraSlot = IVSMixerSlotConfiguration() cameraSlot.size = CGSize(width: 320, height: 180) cameraSlot.position = CGPoint(x: 20, y: 1280 - 200) cameraSlot.preferredVideoInput = .camera cameraSlot.preferredAudioInput = .microphone cameraSlot.matchCanvasAspectMode = false cameraSlot.zIndex = 2 try cameraSlot.setName("camera") // Top Right var streamSlot = IVSMixerSlotConfiguration() streamSlot.size = CGSize(width: 640, height: 320) streamSlot.position = CGPoint(x: 1280 - 660, y: 20) streamSlot.preferredVideoInput = .userImage streamSlot.preferredAudioInput = .userAudio streamSlot.matchCanvasAspectMode = false streamSlot.zIndex = 1 try streamSlot.setName("stream") // Bottom Right var logoSlot = IVSMixerSlotConfiguration() logoSlot.size = CGSize(width: 320, height: 180) logoSlot.position = CGPoint(x: 1280 - 340, y: 720 - 200) logoSlot.preferredVideoInput = .userImage logoSlot.preferredAudioInput = .unknown logoSlot.matchCanvasAspectMode = false logoSlot.zIndex = 3 try logoSlot.setTransparency(0.7) try logoSlot.setName("logo") config.mixer.slots = [ cameraSlot, streamSlot, logoSlot ]
Android
// Bottom Left val cameraSlot = BroadcastConfiguration.Mixer.Slot.with { s -> s.setSize(320, 180) s.position = BroadcastConfiguration.Vec2(20, 1280 - 200) s.preferredVideoInput = Device.Descriptor.DeviceType.CAMERA s.preferredAudioInput = Device.Descriptor.DeviceType.MICROPHONE s.matchCanvasAspectMode = false s.zIndex = 2 s.name = "camera" s } // Top Right val streamSlot = BroadcastConfiguration.Mixer.Slot.with { s -> s.setSize(640, 320) s.position = BroadcastConfiguration.Vec2(1280 - 660, 20) s.preferredVideoInput = Device.Descriptor.DeviceType.USER_IMAGE s.preferredAudioInput = Device.Descriptor.DeviceType.USER_AUDIO s.matchCanvasAspectMode = false s.zIndex = 1 s.name = "stream" s } // Bottom Right val logoSlot = BroadcastConfiguration.Mixer.Slot.with { s -> s.setSize(320, 180) s.position = BroadcastConfiguration.Vec2(1280 - 340, 720 - 200) s.preferredVideoInput = Device.Descriptor.DeviceType.USER_IMAGE s.preferredAudioInput = Device.Descriptor.DeviceType.UNKNOWN s.matchCanvasAspectMode = false s.zIndex = 3 s.name = "logo" s.transparency = 0.7 s } val config = BroadcastConfiguration.with { c -> c.mixer.slots = listOf(cameraSlot, streamSlot, logoSlot) c.video.targetFramerate = 60 c.video.setSize(1280, 720) c }
Ajout d'options
Une fois que vous avez créé un BroadcastSession
avec votre configuration, vous pouvez ajouter ou supprimer des slots au mixage. Ici, nous ajoutons au mixage un large slot arrière-plan pour une image.
iOS
// Background. We will use most of the defaults for this slot. var backgroundSlot = IVSMixerSlotConfiguration() backgroundSlot.preferredVideoInput = .userImage backgroundSlot.preferredAudioInput = .unknown backgroundSlot.matchCanvasAspectMode = false try backgroundSlot.setName("background") session.mixer.addSlot(backgroundSlot)
Android
// Background. We will use most of the defaults for this slot. val backgroundSlot = BroadcastConfiguration.Mixer.Slot.with { s -> s.preferredVideoInput = Device.Descriptor.DeviceType.USER_IMAGE s.preferredAudioInput = Device.Descriptor.DeviceType.UNKNOWN s.matchCanvasAspectMode = false s.name = "background" s } session.mixer.addSlot(backgroundSlot)
Suppression de Slots
Pour supprimer un slot, appelez BroadcastSession.Mixer.removeSlot
en indiquant le nom du slot que vous souhaitez supprimer. Tous les appareils associés à ce slot sont automatiquement dissociés. Vous devez donc les relier à différents slots si vous souhaitez continuer à les utiliser.
animations avec Transitions
La méthode de transition du mixage remplace la configuration d'un slot 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 |
---|---|---|
|
Non |
Fin |
|
Oui |
Interpolé |
|
Oui |
Interpolé |
|
Non |
Démarrer |
|
Non |
Démarrer |
Remarque : Vous ne pouvez pas modifier le nom du slot. |
Non |
N/A |
|
Oui |
Interpolé |
|
Non |
Fin |
|
Non |
Fin |
|
Oui |
Interpolé |
|
Oui |
Interpolé |
Remarque : Le |
Oui |
Je ne sais pas |
Exemples simples
Vous trouverez ci-dessous des exemples de reprise d'une caméra plein écran utilisant la configuration définie ci-dessus dans Configuring a Broadcast Session for Mixing (Configuration d'une séance de diffusion pour le mixage). Il est animé pendant 0,5 seconde.
iOS
// Bottom Left var bigCameraSlot = cameraSlot bigCameraSlot.size = CGSize(width: 1280, height: 720) bigCameraSlot.position = CGPoint(x: 0, y: 0) session.mixer.transition("camera", bigCameraSlot, 0.5) { println("animation completed!") }
Android
// Bottom Left val bigCameraSlot = cameraSlot.changing { s -> s.setSize(1280, 720) s.position = BroadcastConfiguration.Vec2(0, 0) s } session.mixer.transition("camera", bigCameraSlot, 0.5) { print("animation completed!") }
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 |
Largeur de la fente |
Verticalement |
Hauteur de la fente |
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 :
var cameraSlot = IVSMixerSlotConfiguration cameraSlot.size = CGSize(width: -320, height: 720) // Add 320 to position x since our width is -320 cameraSlot.position = CGPoint(x: 320, y: 0)
Mise en miroir horizontale verticale :
var cameraSlot = IVSMixerSlotConfiguration cameraSlot.size = CGSize(width: 320, height: -720) // Add 720 to position y since our height is -720 cameraSlot.position = CGPoint(x: 0, y: 720)
Android
Mise en miroir horizontale :
cameraSlot = BroadcastConfiguration.Mixer.Slot.with { it.size = BroadcastConfiguration.Vec2(-320f, 180f) // Add 320f to position x since our width is -320f it.position = BroadcastConfiguration.Vec2(320f, 0f) return@with it }
Mise en miroir horizontale verticale :
cameraSlot = BroadcastConfiguration.Mixer.Slot.with { it.size = BroadcastConfiguration.Vec2(320f, -180f) // Add 180f to position y since our height is -180f it.position = BroadcastConfiguration.Vec2(0f, 180f) return@with it }
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.