SDK di trasmissione IVS: Dispositivi misti - Amazon IVS

SDK di trasmissione IVS: Dispositivi misti

I dispositivi misti sono dispositivi audio e video che prendono più sorgenti di ingresso e generano una singola uscita. I dispositivi di mixaggio sono una potente funzionalità che consente di definire e gestire più elementi sullo schermo (video) e tracce audio. È possibile combinare video e audio da più sorgenti come fotocamere, microfoni, catture dello schermo e audio e video generati dall'app. È possibile utilizzare le transizioni per spostare queste sorgenti nel video trasmesso in streaming su IVS, nonché aggiungere e rimuovere sorgenti durante lo streaming.

I dispositivi misti sono disponibili nelle versioni audio e immagine. Per creare un dispositivo con immagini misto, chiamare:

DeviceDiscovery.createMixedImageDevice() su Android

IVSDeviceDiscovery.createMixedImageDevice() su iOS

Il dispositivo restituito può essere collegato a una BroadcastSession (streaming a bassa latenza) o Stage (streaming in tempo reale), come qualsiasi altro dispositivo.

Terminologia

Terminologia per i dispositivi misti per la trasmissione IVS.
Termine Descrizione

Dispositivo

Un componente hardware o software che produce input audio o immagine. Esempi di dispositivi sono microfoni, fotocamere, cuffie Bluetooth e dispositivi virtuali come catture di schermo o ingressi di immagini personalizzate.

Dispositivi misti

Un Device che può essere collegato a una BroadcastSession come qualsiasi altro Device, ma con API aggiuntive che consentono di aggiungere oggetti Source. I dispositivi misti dispongono di mixer interni che combinano audio o immagini, producendo un unico flusso di audio e immagini in uscita.

I dispositivi misti sono disponibili nelle versioni audio e immagine.

Configurazione del dispositivo misto

Un oggetto di configurazione per il dispositivo misto. Per i dispositivi con immagini miste, questa opzione configura proprietà quali dimensioni e framerate. Per i dispositivi audio misti, configura il numero di canali.

Origine

Un container che definisce la posizione di un elemento visivo sullo schermo e le proprietà di una traccia audio nel mix audio. Un dispositivo misto può essere configurato con zero o più sorgenti. Alle origini viene assegnata una configurazione che influisce sul modo in cui vengono utilizzati i contenuti multimediali della sorgente. L'immagine qui sopra mostra quattro sorgenti di immagini:

  • In basso a sinistra con ingresso telecamera

  • In alto a destra con ingresso filmato

  • In basso a destra con il logo Amazon IVS

  • Un'immagine di sfondo a schermo intero

Configurazione della sorgente

Un oggetto di configurazione per la sorgente che entra in un dispositivo misto. Gli oggetti di configurazione completi sono descritti di seguito.

Transition

Per spostare uno slot in una nuova posizione o modificarne alcune proprietà, utilizza MixedDevice.transitionToConfiguration(). Questo metodo richiede:

  • Una nuova configurazione della sorgente che rappresenta lo stato successivo per l'origine.

  • Una durata che specifichi la durata dell'animazione rispetto alla timeline del video. Se la durata è impostata su 0, la transizione avviene sul fotogramma successivo che è misto.

  • Un callback facoltativo che informa quando l'animazione è completata. Il callback può essere utile per concatenare animazioni.

Dispositivo audio misto

Configurazione

MixedAudioDeviceConfiguration su Android

IVSMixedAudioDeviceConfiguration su iOS

Nome Tipo Descrizione

channels

Numero intero

Numero di canali di output dal mixer audio. Valori validi: 1, 2. Il canale 1 è audio mono mentre il canale 2 è audio stereo. Default: 2

Configurazione della sorgente

MixedAudioDeviceSourceConfiguration su Android

IVSMixedAudioDeviceSourceConfiguration su iOS

Nome Tipo Descrizione

gain

Float

Guadagno audio. Questo è un moltiplicatore, quindi qualsiasi valore maggiore di 1 aumenta il guadagno e qualsiasi valore minore di 1 lo diminuisce. Valori validi: 0-2. Default: 1.

Dispositivo di immagine

Configurazione

MixedImageDeviceConfiguration su Android

IVSMixedImageDeviceConfiguration su iOS

Nome Tipo Descrizione

size

Vec2

Dimensioni della tela video.

targetFramerate

Numero intero

Il numero di frame di destinazione al secondo per il dispositivo misto. In media questo valore dovrebbe essere raggiunto, ma il sistema potrebbe perdere frame in determinate circostanze (ad esempio, con carico elevato della CPU o della GPU).

transparencyEnabled

Booleano

Ciò consente la fusione utilizzando la proprietà alpha sulle configurazioni delle sorgenti delle immagini. L'impostazione di questa opzione su true aumenta il consumo di memoria e CPU. Default: false.

Configurazione della sorgente

MixedImageDeviceSourceConfiguration su Android

IVSMixedImageDeviceSourceConfiguration su iOS

Nome Tipo Descrizione

alpha

Float

L'alfa dello slot. Questo è un fattore moltiplicativo con qualsiasi valore alfa nell'immagine. Valori validi: 0-1, dove 0 è completamente trasparente e 1 è completamente opaco. Default: 1.

aspect

AspectMode

La modalità proporzioni per qualsiasi immagine renderizzata nello slot. Valori validi:

  • Fill - Mantieni le proporzioni dell'immagine ma riempi lo slot. Se necessario, l'immagine verrà ritagliata.

  • Fit - Mantieni le proporzioni dell'immagine ma inserisci l'intera immagine nello slot. Lo slot potrebbe avere un formato letterbox o pillarbox se necessario. Il formato letterbox/pilarbox sarà fillColor se tale valore è stato impostato, altrimenti trasparente (che potrebbe apparire nero se il colore della tela dietro l'immagine è nero).

  • None - Non mantenere le proporzioni dell'immagine. L'immagine verrà scalata in modo che corrisponda alle dimensioni dello slot.

Impostazione predefinita: Fit

fillColor

Vec 4

Il colore di riempimento da utilizzare con aspect Fit quando le proporzioni dello slot e dell'immagine non corrispondono. Il formato è (rosso, verde, blu, alfa). Valore valido (per ciascun canale): 0 - 1. Default: (0, 0, 0, 0).

position

Vec2

Posizione dello slot (in pixel) rispetto all'angolo superiore sinistro della tela. Anche l'origine dello slot è in alto a sinistra.

size

Vec2

Dimensioni dello slot, in pixel. L'impostazione di questo valore imposta anche matchCanvasSize su false. Default: (0, 0); tuttavia, perché matchCanvasSize di default è true, la dimensione renderizzata dello slot è la dimensione della tela, non (0, 0).

zIndex

Float

Ordinamento relativo degli slot. Gli slot con valori zIndex più elevati sono disegnati sopra gli slot con valori zIndex minori.

Creazione e configurazione di un dispositivo di immagini misto

Configurazione di una sessione di tramissione per il mixaggio.

Qui creiamo una scena simile a quella all'inizio di questa guida, con tre elementi sullo schermo:

  • Slot in basso a sinistra per una fotocamera.

  • Slot in basso a destra per una sovrapposizione del logo.

  • Slot in alto a destra per un filmato.

Nota che l'origine della tela è l'angolo in alto a sinistra e questa è la stessa per gli slot. Quindi, posizionando uno slot in (0, 0) sarà posizionato nell'angolo in alto a sinistra con l'intero slot visibile.

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)

Rimozione delle sorgenti

Per rimuovere una sorgente, chiamare MixedDevice.remove con l'oggetto di Source che desideri rimuovere.

Animazioni con transizioni

Il metodo di transizione sostituisce la configurazione di una sorgente con una nuova configurazione. Questa sostituzione può essere animata nel tempo impostando una durata superiore a 0, in secondi.

Quali proprietà possono essere animate?

Non tutte le proprietà nella struttura dello slot possono essere animate. Qualsiasi proprietà basata su tipi Float può essere animata; altre proprietà hanno effetto all'inizio o alla fine dell'animazione.

Nome Può essere animato? Punto d'impatto

Audio.gain

Interpolato

Image.alpha

Interpolato

Image.aspect

No

End

Image.fillColor

Interpolato

Image.position

Interpolato

Image.size

Interpolato

Image.zIndex

Nota: zIndex sposta i piani 2D attraverso lo spazio 3D, quindi la transizione avviene quando i due piani si incrociano in un certo punto al centro dell'animazione. Questo potrebbe essere calcolato, ma dipende dai valori di zIndex di inizio e di fine. Per una transizione più fluida, combinalo con alpha.

Sconosciuto

Esempi semplici

Di seguito sono riportati esempi di acquisizione di una fotocamera a schermo intero utilizzando la configurazione definita in alto in Creazione e configurazione di un dispositivo di immagini misto. Questo è animato per 0,5 secondi.

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") } }

Mirroring della trasmissione

Per eseguire il mirroring di un dispositivo immagine collegato nella trasmissione in questa direzione... Usa un valore negativo per...

Orizzontalmente

La larghezza dello slot

Verticalmente

L’altezza dello slot

Sia orizzontalmente che verticalmente

Larghezza e altezza dello slot

La posizione dovrà essere regolata dello stesso valore per mettere lo slot nella posizione corretta quando viene eseguito il mirroring.

Di seguito sono riportati alcuni esempi di mirroring della trasmissione in orizzontale e in verticale.

iOS

Mirroring orizzontale:

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)

Mirroring 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

Mirroring orizzontale:

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

Mirroring 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)) }

Nota: questo mirroring è diverso dal metodo setMirrored su ImagePreviewView (Android) e IVSImagePreviewView (iOS). Questo metodo influisce solo sulla visualizzazione dell'anteprima locale sul dispositivo e non ha alcun impatto sulla trasmissione.