SDK di trasmissione IVS: guida al mixer | Streaming a bassa latenza - Amazon IVS

SDK di trasmissione IVS: guida al mixer | Streaming a bassa latenza

Il mixer è un'unità di elaborazione audio e video che prende più sorgenti di ingresso e genera una singola uscita. È 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. Puoi utilizzare le transizioni per spostare queste sorgenti nel video che trasmetti in streaming su Amazon IVS e aggiungerle e rimuoverle nel corso del flusso.

Per accedere al mixer, chiama:

BroadcastSession.getMixer() su Android

IVSBroadcastSession.mixer su iOS

Terminologia

Terminologia del mixer di trasmissione IVS.
Termine Descrizione

Rilegatura

Per associare un dispositivo di input a uno slot, il dispositivo deve essere collegato allo slot del mixer. Questo avviene con il metodo Mixer.bind(). Uno slot può avere un ingresso immagine e un ingresso audio collegati alla volta. È possibile scollegare un dispositivo dallo slot chiamando Mixer.unbind().

Canvas

L'estensione di visualizzazione del video definito nella tua configurazione BroadcastSession. La tela ha dimensioni uguali alle impostazioni video e viene eseguita alla stessa frequenza di fotogrammi specificata nella configurazione.

Dispositivo

Un componente hardware o software che produce input audio o immagine nel BroadcastSession. Esempi di dispositivi sono microfoni, fotocamere, cuffie Bluetooth e dispositivi virtuali come catture di schermo o ingressi di immagini personalizzate. Ad eccezione degli input personalizzati, in genere non è necessario mantenere un riferimento all'oggetto dispositivo, ma è possibile conservare una copia del descrittore del dispositivo.

Descrittore del dispositivo

Struttura con informazioni su un dispositivo di input, ad esempio tipo, indirizzo di sistema, nome intuitivo leggibile dall'uomo e posizione fisica sul dispositivo mobile. Queste informazioni ti consentono di decidere se utilizzare il dispositivo di riferimento e consentono ad Amazon IVS di accedervi.

Slot

Un container che definisce la posizione di un elemento visivo sullo schermo e le proprietà di una traccia audio nel mix audio. Un mixer può essere configurato con zero o più slot. Agli slot viene assegnato un nome stringa che può essere utilizzato per associare i dispositivi ed eseguire transizioni. L'immagine qui sopra mostra quattro slot:

  • 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

Dopo aver configurato una sessione, puoi aggiungere e rimuovere gli slot con i metodi del mixer addSlot e removeSlot.

Transition

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

  • Una nuova struttura di slot che rappresenta lo stato successivo per lo slot

  • 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.

Proprietà tela

Le proprietà della tela sono impostate in base al BroadcastConfigurationche fornisci quando crei il BroadcastSession. La tela è influenzata da diverse proprietà nelle strutture Audio e Video:

Nome Tipo Descrizione

Audio.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

Audio.sampleRate

Frequenza di campionatura audio

Il numero di campioni audio al secondo dal mixer audio. Questo valore deve essere almeno il doppio della frequenza più alta del segnale audio. Le persone possono sentire fino a circa 20 kHz, quindi in genere bastano 44,1 kHz e 48 kHz. Default: 48 kHz.

Video.defaultAspectMode

AspectMode

La modalità di proporzione di default per gli 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à dimensionata in modo che corrisponda alle dimensioni dello slot.

Video.size

Vec2

Dimensioni della tela video.

Video.targetFramerate

Numero intero

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

Proprietà dello slot

Gli slot hanno diverse proprietà configurabili che è possibile utilizzare per personalizzare le scene e le animazioni. Qualsiasi valore che sia Float o Vector viene animato utilizzando l'interpolazione lineare per transizioni con una durata superiore a 0 secondi.

Nome Tipo Descrizione

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à dimensionata in modo che corrisponda alle dimensioni dello slot.

Default: come la tela aspect se matchCanvasAspectMode è true (VERO), altrimenti Fill. L'impostazione di questo valore imposta anche matchCanvasAspectMode su false.

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).

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.

matchCanvasAspectMode

Booleano

Se true (VERO), usa il valore Video.defaultAspectMode della tela. Se si imposta la proprietà aspect dello slot, è false. Default: true (VERO).

matchCanvasSize

Booleano

Se true (VERO), la dimensione dello slot viene regolata in modo che sia uguale alla dimensione della tela e la sua posizione è impostata su (0, 0). Se si imposta la proprietà size dello slot, è false. Default: true (VERO).

name

Stringa

Nome dello slot. Viene utilizzato per fare riferimento allo slot per le associazioni e le transizioni. Default: "default".

position

Vec2

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

preferredAudioInput

DeviceType

Tipo di dispositivo di ingresso audio preferito. Se questo slot non è associato e un dispositivo audio del tipo specificato è collegato alla sessione, il dispositivo si associa automaticamente a questo slot. Valori validi:

  • Microfono: hardware audio come microfono integrato, cuffie collegabili o cuffie Bluetooth.

  • Audio di sistema: audio acquisito dal sistema operativo, solitamente accompagnato da una registrazione dello schermo.

  • Audio utente: input audio personalizzati creati dall'utente.

  • Sconosciuto: non esiste un dispositivo preferito; lo slot sarà sempre associato manualmente.

preferredVideoInput

DeviceType

Dispositivo di ingresso video preferito. Se questo slot non è associato e un dispositivo video del tipo specificato è collegato alla sessione, il dispositivo si associa automaticamente a questo slot. Valori validi:

  • Fotocamera: dispositivi integrati della fotocamera come la fotocamera frontale, posteriore o grandangolare.

  • Schermo: acquisizione dello schermo dal sistema operativo.

  • Immagine utente: input personalizzati per immagini e video creati dall'utente.

  • Sconosciuto: non esiste un dispositivo preferito; lo slot sarà sempre associato manualmente.

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 (VERO), la dimensione renderizzata dello slot è la dimensione della tela, non (0, 0).

transparency

Float

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

zIndex

Float

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

Configurazione di una sessione di trasmissione per il mixaggio

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

Aggiunta di slot

Una volta creato un BroadcastSession con la tua configurazione, potrai aggiungere e rimuovere gli slot dal mixer. Ora, aggiungiamo al mixer una grande slot in background per un'immagine.

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)

Rimozione degli slot

Per rimuovere uno slot, chiama BroadcastSession.Mixer.removeSlot con il nome dello slot da rimuovere. Tutti i dispositivi collegati a quello slot saranno automaticamente non associati, quindi se si desidera continuare a utilizzarli sarà necessario ricollegarli a slot diversi.

Animazioni con transizioni

Il metodo di transizione del mixer sostituisce la configurazione di uno slot 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

aspect

No

End

fillColor

Interpolato

gain

Interpolato

matchCanvasAspectMode

No

Start (Avvio)

matchCanvasSize

No

Start (Avvio)

name

Nota: non è possibile modificare il nome dello slot.

No

N/D

position

Interpolato

preferredAudioInput

No

End

preferredVideoInput

No

End

size

Interpolato

transparency

Interpolato

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 transparency.

Sconosciuto

Esempi semplici

Di seguito sono riportati esempi di acquisizione di una fotocamera a schermo intero utilizzando la configurazione definita in precedenza in Configurazione di una sessione di trasmissione per il mixaggio. Questo è animato per 0,5 secondi.

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

Mirroring della trasmissione

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

Orizzontalmente

Larghezza dello slot

Verticalmente

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:

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)

Mirroring 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

Mirroring orizzontale:

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 }

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

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.