SDK de transmissão do IVS: dispositivos de mixagem - Amazon IVS

SDK de transmissão do IVS: dispositivos de mixagem

Dispositivos de mixagem são dispositivos de áudio e vídeo que recebem de várias fontes de entrada e geram uma única saída. Dispositivos de mixagem são um atributo sofisticado que permite definir e gerenciar vários elementos e faixas de áudio na tela (vídeo). Você pode combinar vídeo e áudio de várias fontes, como câmeras, microfones, capturas de tela e áudio e vídeo gerados pela sua aplicação. Você pode usar transições para mover essas fontes pelo vídeo que você transmite para o IVS, e adicionar e remover fontes durante o fluxo.

Os dispositivos de mixagem vêm nas versões de imagem e áudio. Para criar um dispositivo de imagem de mixagem, chame:

DeviceDiscovery.createMixedImageDevice() no Android

IVSDeviceDiscovery.createMixedImageDevice() no iOS

O dispositivo retornado pode ser anexado a uma BroadcastSession (streaming de baixa latência) ou Stage (streaming em tempo real), como qualquer outro dispositivo.

Terminologia

Terminologia dos dispositivos de mixagem de transmissão do IVS.
Prazo Descrição

Dispositivo

Um componente de hardware ou software que produz entrada de áudio ou imagem. Alguns exemplos de dispositivos são microfones, câmeras, fones de ouvido de Bluetooth e dispositivos virtuais, como capturas de tela ou entradas de imagens personalizadas.

Dispositivo de mixagem

Um Device que pode ser anexado a uma BroadcastSession como qualquer outro Device, mas com APIs adicionais que permitem a adição de objetos Source. Os dispositivos de mixagem têm mixadores internos que combinam áudio ou imagens, produzindo um único fluxo de áudio e imagem de saída.

Dispositivos de mixagem vêm nas versões de áudio ou imagem.

Configuração de dispositivo de mixagem

Um objeto de configuração para o dispositivo de mixagem. Para dispositivos de imagem de mixagem, isso configura propriedades como dimensões e taxa de quadros. Para dispositivos de áudio de mixagem, isso configura a quantidade de canais.

Origem

Um contêiner que define a posição de um elemento visual na tela e as propriedades de uma faixa de áudio na mixagem de áudio. Um dispositivo de mixagem pode ser configurado com zero ou mais fontes. É dada às fontes uma configuração que afeta como a mídia da fonte é usada. A imagem acima mostra quatro fontes de imagens:

  • Inferior esquerdo com entrada de câmera

  • Superior direito com entrada de filme

  • Inferior direito com o logo do Amazon IVS

  • Uma imagem de plano de fundo em tela cheia

Configuração de fonte

Um objeto de configuração para a fonte que entra em dispositivo de mixagem. Os objetos de configuração completos são descritos abaixo.

Transição

Para mover um slot para uma nova posição ou alterar algumas de suas propriedades, use MixedDevice.transitionToConfiguration(). Esse método aceita:

  • Uma nova configuração de fonte que representa o próximo estado da fonte.

  • Uma duração que especifica quanto tempo a animação deve demorar em relação à linha do tempo do vídeo. Se a duração for definida como 0, a transição acontecerá no próximo quadro mixado.

  • Um retorno de chamada opcional que informa quando a animação é concluída. O retorno de chamada pode ser útil para encadear animações.

Dispositivo de áudio de mixagem

Configuração

MixedAudioDeviceConfiguration no Android

IVSMixedAudioDeviceConfiguration no iOS

Name Tipo Descrição

channels

Inteiro

Número de canais de saída do mixer de áudio. Valores válidos: 1, 2. 1 é áudio mono; em 2 é áudio estéreo. Padrão: 2.

Configuração de fonte

MixedAudioDeviceSourceConfiguration no Android

IVSMixedAudioDeviceSourceConfiguration no iOS

Name Tipo Descrição

gain

Float

Ganho de áudio. Este é um multiplicador. Assim, qualquer valor acima de 1 aumenta o ganho e qualquer valor abaixo de 1, diminui. Valores válidos: 0 - 2. Padrão: 1.

Dispositivo de imagem de mixagem

Configuração

MixedImageDeviceConfiguration no Android

IVSMixedImageDeviceConfiguration no iOS

Name Tipo Descrição

size

Vec2

Tamanho da tela de vídeo.

targetFramerate

Inteiro

Número de quadros por segundo do destino para o dispositivo de mixagem. Em média, esse valor deve ser alcançado, mas o sistema pode abandonar quadros em determinadas circunstâncias (por exemplo, alta carga de CPU ou GPU).

transparencyEnabled

Booleano

Isso permite a mistura usando a propriedade alpha nas configurações da fonte de imagens. Definir isso como true aumenta o consumo de memória e CPU. Padrão: false.

Configuração de fonte

MixedImageDeviceSourceConfiguration no Android

IVSMixedImageDeviceSourceConfiguration no iOS

Name Tipo Descrição

alpha

Float

Alfa do slot. É um valor multiplicativo com quaisquer valores alfa na imagem. Valores válidos: 0 - 1. 0 é completamente transparente e 1 é completamente opaco. Padrão: 1.

aspect

AspectMode

Modo de taxa de proporção para qualquer imagem renderizada no slot. Valores válidos:

  • Fill: mantenha a taxa de proporção da imagem, mas preencha o slot. A imagem será recortada, se necessário.

  • Fit: mantenha a taxa de proporção da imagem, mas enquadre a imagem inteira no slot. O slot pode ter um letterbox ou pillarbox, se necessário. O efeito letter/pillarbox será na fillColor se esse valor tiver sido definido; caso contrário, será transparente (o que poderá parecer preto se a tela atrás da imagem for da cor preta).

  • None: não mantém a taxa de proporção da imagem. A imagem é escalada para coincidir com as dimensões do slot.

Padrão: Fit

fillColor

Vec4

A cor de preenchimento a ser usada com aspect Fit quando as proporções do slot e da imagem não coincidem. O formato é (vermelho, verde, azul, alfa). Valor válido (para cada canal): 0 e 1. Padrão: (0, 0, 0, 0).

position

Vec2

Posição do slot (em pixels) em relação ao canto superior esquerdo da tela. A origem do slot também está no canto superior esquerdo.

size

Vec2

Tamanho do slot, em pixels. Definir esse valor também define matchCanvasSize como false. Padrão: (0, 0); porém, como matchCanvasSize assume o padrão true, o tamanho renderizado do slot é o tamanho da tela, não (0, 0).

zIndex

Float

Ordenação relativa de slots. Slots com valores mais altos de zIndex são desenhados por cima dos slots com valores menores de zIndex.

Criar e configurar um dispositivo de imagem de mixagem

Configuração de uma sessão de transmissão para mixagem.

Aqui, criamos uma cena semelhante à do início deste guia, com três elementos na tela:

  • Slot inferior esquerdo para uma câmera.

  • Slot inferior direito para uma sobreposição de logo.

  • Slot superior direito para um filme.

Observe que a origem da tela é o canto superior esquerdo, e é o mesmo para os slots. Assim, posicionar um slot em (0, 0) o coloca no canto superior esquerdo com todo o slot visível.

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)

Removendo fontes

Para remover uma fonte, chame MixedDevice.remove com o objeto Source que você deseja remover.

Animações com transições

O método de transição substitui a configuração de uma fonte por uma nova configuração. Essa substituição pode ser animada ao longo do tempo, definindo uma duração superior a 0, em segundos.

Quais propriedades podem ser animadas?

Nem todas as propriedades na estrutura do slot podem ser animadas. Todas as propriedades baseadas em tipos Flutuantes podem ser animadas; outras propriedades produzem efeito no início ou no fim da animação.

Name Pode ser animado? Ponto de impacto

Audio.gain

Sim

Interpolado(a)

Image.alpha

Sim

Interpolado(a)

Image.aspect

Não

Fim

Image.fillColor

Sim

Interpolado(a)

Image.position

Sim

Interpolado(a)

Image.size

Sim

Interpolado(a)

Image.zIndex

Observações: o zIndex move planos 2D através do espaço 3D. Assim, a transição acontece quando os dois planos se cruzam em algum ponto no meio da animação. Isso pode ser calculado, mas depende dos valores de início e fim do zIndex. Para obter uma transição mais suave, combine ele com a alpha.

Sim

Desconhecido

Exemplos simples

Os exemplos abaixo são do controle da câmera em tela cheia usando a configuração definida acima em Criar e configurar um dispositivo de imagem de mixagem. Isso fica animado por 0,5 segundo.

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

Espelhamento da transmissão

Para espelhar um dispositivo de imagem conectado na transmissão nessa direção... Use um valor negativo para …

Horizontalmente

A largura do slot

Verticalmente

A altura do slot

Horizontalmento e verticalmente

Tanto a largura quanto a altura do slot

A posição precisará ser ajustada com base no mesmo valor para colocar o slot na posição correta quando espelhado.

Abaixo estão alguns exemplos para espelhar a transmissão horizontalmente e verticalmente.

iOS

Espelhamento horizontal:

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)

Espelhamento vertical:

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

Espelhamento horizontal:

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

Espelhamento vertical:

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

Observação: esse espelhamento é diferente do método setMirrored em ImagePreviewView (Android) e IVSImagePreviewView (iOS). Esse método afeta somente a visualização local no dispositivo e não afeta a transmissão.