SDK de transmisión de IVS: guía del mezclador | Transmisión de baja latencia - Amazon IVS

SDK de transmisión de IVS: guía del mezclador | Transmisión de baja latencia

El mezclador es una unidad de procesamiento de audio y video que recibe varias fuentes de entrada y genera una única salida. Es una potente característica que le permite definir y administrar varios elementos en pantalla (video) y pistas de audio. Puede combinar video y audio de varias fuentes, como cámaras, micrófonos, grabadoras de pantalla y audio y video generados por su aplicación. Puede utilizar transiciones para mover estas fuentes al video que transmite a Amazon IVS y agregarlas y eliminarlas a mitad de la transmisión.

Para acceder al mezclador, llame a:

BroadcastSession.getMixer() en Android

IVSBroadcastSession.mixer en iOS

Terminología

Terminología del mezclador de transmisión de IVS.
Plazo Descripción

Tapa

Para asociar un dispositivo de entrada a una ranura, el dispositivo debe estar vinculado a la ranura del mezclador. Esto se realiza con el método Mixer.bind(). Una ranura puede tener una entrada de imagen y una de audio vinculadas a la vez. Puede desvincular un dispositivo de la ranura llamando a Mixer.unbind().

Canvas

El tamaño de visualización del video definido en su configuración BroadcastSession. El lienzo tiene el mismo tamaño que los ajustes de video y se ejecuta a la misma velocidad de fotogramas que se especifica en la configuración.

Dispositivo

Un componente de hardware o software que produce una entrada de audio o imagen en el BroadcastSession. Algunos ejemplos de dispositivos son micrófonos, cámaras, auriculares Bluetooth y dispositivos virtuales, como grabadoras de pantalla o entradas de imágenes personalizadas. A excepción de las entradas personalizadas, por lo general no es necesario mantener una referencia al objeto del dispositivo. En su lugar, puede conservar una copia del descriptor del dispositivo.

Descriptor del dispositivo

Estructura con información sobre un dispositivo de entrada, por ejemplo, su tipo, dirección del sistema, nombre “descriptivo” legible por humanos y posición física en el dispositivo móvil. Esta información le permite decidir si desea utilizar el dispositivo de referencia, y deja que Amazon IVS acceda a él.

Slot

Un contenedor que define la posición de un elemento visual en la pantalla y las propiedades de una pista de audio en la mezcla de audio. Un mezclador se puede configurar con cero ranuras o más. Las ranuras reciben un nombre que se puede utilizar para vincular dispositivos y ejecutar transiciones. La imagen de arriba muestra cuatro ranuras:

  • Abajo a la izquierda con entrada de cámara

  • Arriba a la derecha con entrada de video

  • Abajo a la derecha con el logotipo de Amazon IVS

  • Una imagen de fondo a pantalla completa

Después de configurar una sesión, puede agregar y quitar ranuras con los métodos addSlot y removeSlot del mezclador.

Transition

Para mover una ranura a una nueva posición o cambiar algunas de sus propiedades, utilice Mixer.transition(). Este método recibe:

  • Una nueva estructura de ranura que representa el siguiente estado de la ranura

  • Una duración que especifica cuánto tiempo debe durar la animación, en relación con la escala de tiempo del video. Si la duración se establece en 0, la transición se produce en el siguiente fotograma que se mezcla.

  • Una devolución de llamada opcional que le avisa cuando se ha completado la animación. La devolución de llamada puede ser útil para encadenar animaciones.

Propiedades del lienzo

Las propiedades del lienzo se establecen en función del BroadcastConfiguration que proporcione al crear el BroadcastSession. Varias propiedades en las estructuras Audio y Video afectan al lienzo:

Nombre Tipo Descripción

Audio.channels

Entero

Número de canales de salida del mezclador de audio. Valores válidos: 1, 2. 1 canal es audio mono; 2, audio estéreo. Valor predeterminado: 2.

Audio.sampleRate

Tasa de muestreo de audio

Número de muestras de audio por segundo del mezclador de audio. Este valor debe ser al menos el doble de la frecuencia más alta de la señal de audio. La gente puede escuchar hasta unos 20 kHz, por lo que en general bastan 44,1 kHz y 48 kHz. Valor predeterminado: 48 kHz.

Video.defaultAspectMode

Modo de aspecto

Modo de relación de aspecto predeterminado para las ranuras. Valores válidos:

  • Fill: mantiene la relación de aspecto de la imagen, pero rellena la ranura. La imagen se recortará si es necesario.

  • Fit: mantiene la relación de aspecto de la imagen, pero ajusta toda la imagen en la ranura. La ranura puede ser letterbox o pillarbox si es necesario. La letterbox o pillarbox será fillColor si se ha establecido ese valor, de lo contrario, será transparente (que puede ser negro si el color del lienzo detrás de la imagen es negro).

  • None: no mantiene la relación de aspecto de la imagen. La imagen se escalará para que coincida con las dimensiones de la ranura.

Video.size

Vec2

Tamaño del lienzo de video.

Video.targetFramerate

Entero

Número de fotogramas objetivo por segundo del lienzo. En promedio, este valor debe alcanzarse, pero el sistema puede perder fotogramas en determinadas circunstancias (por ejemplo, alta carga de CPU o congestión de la red).

Propiedades de las ranuras

Las ranuras tienen varias propiedades configurables que puede usar para personalizar sus escenas y animarlas. Cualquier valor que sea Float o Vector se anima mediante interpolación lineal para transiciones con una duración superior a 0 segundos.

Nombre Tipo Descripción

aspect

Modo de aspecto

Modo de relación de aspecto para cualquier imagen que se representa en la ranura. Valores válidos:

  • Fill: mantiene la relación de aspecto de la imagen, pero rellena la ranura. La imagen se recortará si es necesario.

  • Fit: mantiene la relación de aspecto de la imagen, pero ajusta toda la imagen en la ranura. La ranura puede ser letterbox o pillarbox si es necesario. La letterbox o pillarbox será fillColor si se ha establecido ese valor, de lo contrario, será transparente (que puede ser negro si el color del lienzo detrás de la imagen es negro).

  • None: no mantiene la relación de aspecto de la imagen. La imagen se escalará para que coincida con las dimensiones de la ranura.

Valor predeterminado: igual que el lienzo aspect si matchCanvasAspectMode es verdadero; en caso contrario, Fill. Establecer este valor también establece matchCanvasAspectMode como false.

fillColor

Vec4

Color de relleno que se utilizará con ajuste de aspecto cuando las relaciones de aspecto de la ranura y la imagen no coinciden. El formato es (rojo, verde, azul, alfa). Valor válido (para cada canal): 0-1. Valor predeterminado: (0, 0, 0, 0).

gain

Flotante

Ganancia de audio. Este es un multiplicador, por lo que cualquier valor superior a 1 aumenta la ganancia; cualquier valor inferior a 1, la disminuye. Valores válidos: 0-2. Valor predeterminado: 1.

matchCanvasAspectMode

Booleano

Si es verdadero, usa el valor Video.defaultAspectMode del lienzo. Esto se establece en false si configura la propiedad aspect de la ranura. Valor predeterminado: verdadero.

matchCanvasSize

Booleano

Si es verdadero, el tamaño de la ranura se ajusta para que sea igual al tamaño del lienzo y su posición se establece en (0, 0). Esto se establece en false si configura la propiedad size de la ranura. Valor predeterminado: verdadero.

name

Cadena

Nombre de la ranura. Esto se utiliza para referenciar a la ranura para enlaces y transiciones. Predeterminado: "default".

position

Vec2

Posición de la ranura (en píxeles), en relación con la esquina superior izquierda del lienzo. El origen de la ranura también está en la parte superior izquierda.

preferredAudioInput

DeviceType

Tipo de dispositivo de entrada de audio preferido. Si esta ranura no está enlazada y un dispositivo de audio del tipo especificado está adjunto a la sesión, el dispositivo se enlaza automáticamente a esta ranura. Valores válidos:

  • Micrófono: hardware de audio como micrófono integrado, auriculares enchufables o auriculares Bluetooth.

  • Audio del sistema: audio capturado desde el sistema operativo, normalmente acompañado de una grabación de pantalla.

  • Audio de usuario: entradas de audio personalizadas que crea.

  • Desconocido: no hay ningún dispositivo preferido; la ranura siempre se vinculará manualmente.

preferredVideoInput

DeviceType

Dispositivo de entrada de video preferido. Si esta ranura no está enlazada y un dispositivo de video del tipo especificado está adjunto a la sesión, el dispositivo se enlaza automáticamente a esta ranura. Valores válidos:

  • Cámara: dispositivos de cámara incorporados, como la cámara frontal, trasera o gran angular.

  • Pantalla: captura de pantalla desde el sistema operativo.

  • Imagen de usuario: entradas de imagen y video personalizadas que crea.

  • Desconocido: no hay ningún dispositivo preferido; la ranura siempre se vinculará manualmente.

size

Vec2

Tamaño de la ranura (en píxeles). Establecer este valor también establece matchCanvasSize como false. Valor predeterminado: (0, 0); sin embargo, dado que el valor predeterminado de matchCanvasSize es verdadero, el tamaño representado de la ranura es el tamaño del lienzo, y no (0, 0).

transparency

Flotante

Transparencia de la ranura. Esto es multiplicativo con cualquier valor alfa de la imagen. La opacidad es 1: transparency. Valores válidos: 0-1, donde 0 es totalmente opaco y 1 es totalmente transparente. Valor predeterminado: 0.

zIndex

Flotante

Ordenación relativa de ranuras. Las ranuras con mayor valor de zIndex se dibujan encima de las ranuras con menor valor de zIndex.

Configuración de una sesión de transmisión de mezcla

Configuración de una sesión de transmisión de mezcla.

Aquí creamos una escena similar a la del principio de esta guía, con tres elementos en pantalla:

  • Ranura inferior izquierda para una cámara.

  • Ranura inferior derecha para una superposición de logotipo.

  • Ranura superior derecha para una película.

Tenga en cuenta que el origen del lienzo es la esquina superior izquierda, que es la misma que para las ranuras. Por lo tanto, colocar una ranura en (0, 0) la coloca en la esquina superior izquierda con toda la ranura 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 }

Adición de ranuras

Una vez que haya creado un BroadcastSession con su configuración, puede agregar ranuras y quitar ranuras del mezclador. Aquí, agregamos al mezclador una ranura grande de fondo para una imagen.

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)

Eliminación de ranuras

Para quitar una ranura, llame a BroadcastSession.Mixer.removeSlot con el nombre de la ranura que desea quitar. Todos los dispositivos enlazados a esa ranura se desvinculan automáticamente, por lo que debe volver a vincularlos a diferentes ranuras si quiere seguir usándolos.

Animaciones con transiciones

El método de transición del mezclador reemplaza la configuración de una ranura por una nueva configuración. Este reemplazo se puede animar a lo largo del tiempo estableciendo una duración superior a 0 (en segundos).

¿Qué propiedades se pueden animar?

No se pueden animar todas las propiedades de la estructura de la ranura. Las propiedades basadas en tipos Float se pueden animar; otras propiedades se hacen efectivas al principio o al final de la animación.

Nombre ¿Se puede animar? Punto de impacto

aspect

No

Final

fillColor

Interpolado

gain

Interpolado

matchCanvasAspectMode

No

Inicio

matchCanvasSize

No

Inicio

name

Nota: No se puede cambiar el nombre de la ranura.

No

N/A

position

Interpolado

preferredAudioInput

No

Final

preferredVideoInput

No

Final

size

Interpolado

transparency

Interpolado

zIndex

Nota: El zIndex mueve planos 2D a través del espacio 3D, de modo que la transición se produce cuando los dos planos se cruzan en algún punto en el medio de la animación. Esto podría calcularse, pero depende de los valores iniciales y finales de zIndex. Para lograr una transición más fluida, combínela con transparency.

Desconocido

Ejemplos sencillos

A continuación se muestran ejemplos de una toma de cámara a pantalla completa utilizando la configuración definida anteriormente en Configuración de una sesión de transmisión de mezcla. Se anima durante 0,5 segundos.

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

Duplicar la transmisión

Para duplicar un dispositivo de imagen conectado a la transmisión en esta dirección… Utilice un valor negativo para el…

Horizontalmente

Ancho de la ranura

Verticalmente

Altura de la ranura

Tanto horizontal como verticalmente

Tanto el ancho como la altura de la ranura

Será necesario ajustar la posición con el mismo valor para colocar la ranura en la posición correcta cuando se duplique.

A continuación se muestran algunos ejemplos de cómo duplicar la transmisión horizontal y verticalmente.

iOS

Duplicación horizontal:

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)

Duplicación vertical:

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

Duplicación horizontal:

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 }

Duplicación vertical:

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: Este método de duplicación setMirrored es diferente en ImagePreviewView (Android) y IVSImagePreviewView (iOS). Este método solo afecta a la vista previa local del dispositivo y no afecta a la transmisión.