

# SDK de transmissão do IVS: dispositivos de mixagem
<a name="broadcast-mixed-devices"></a>

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
<a name="broadcast-mixed-devices-terminology"></a>

![\[Terminologia dos dispositivos de mixagem de transmissão do IVS.\]](http://docs.aws.amazon.com/pt_br/ivs/latest/LowLatencyUserGuide/images/Broadcast_SDK_Mixer_Glossary.png)



| 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: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html)  | 
| 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: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html) | 

## Dispositivo de áudio de mixagem
<a name="broadcast-mixed-audio-device"></a>

### Configuração
<a name="broadcast-mixed-audio-device-configuration"></a>

`MixedAudioDeviceConfiguration` no Android

`IVSMixedAudioDeviceConfiguration` no iOS


| Nome | 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
<a name="broadcast-mixed-audio-device-source-configuration"></a>

`MixedAudioDeviceSourceConfiguration` no Android

`IVSMixedAudioDeviceSourceConfiguration` no iOS


| Nome | 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
<a name="broadcast-mixed-image-device"></a>

### Configuração
<a name="broadcast-mixed-image-device-configuration"></a>

`MixedImageDeviceConfiguration` no Android

`IVSMixedImageDeviceConfiguration` no iOS


| Nome | 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
<a name="broadcast-mixed-image-device-source-configuration"></a>

`MixedImageDeviceSourceConfiguration` no Android

`IVSMixedImageDeviceSourceConfiguration` no iOS


| Nome | 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: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html) 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
<a name="broadcast-mixed-image-device-creating-configuring"></a>

![\[Configuração de uma sessão de transmissão para mixagem.\]](http://docs.aws.amazon.com/pt_br/ivs/latest/LowLatencyUserGuide/images/Broadcast_SDK_Mixer_Configuring.png)


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
<a name="broadcast-mixed-image-device-creating-configuring-ios"></a>

```
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
<a name="broadcast-mixed-image-device-creating-configuring-android"></a>

```
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
<a name="broadcast-mixed-devices-removing-sources"></a>

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

## Animações com transições
<a name="broadcast-mixed-devices-animations-transitions"></a>

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?
<a name="broadcast-mixed-devices-animations-properties"></a>

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.


| Nome | Pode ser animado? | Ponto de impacto | 
| --- | --- | --- | 
| `Audio.gain` | Sim | Interpolado(a) | 
| `Image.alpha` | Sim | Interpolado(a) | 
| `Image.aspect` | Não | Final | 
| `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
<a name="broadcast-mixed-devices-animations-examples"></a>

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](#broadcast-mixed-image-device-creating-configuring). Isso fica animado por 0,5 segundo.

#### iOS
<a name="broadcast-mixed-devices-animations-examples-ios"></a>

```
// 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
<a name="broadcast-mixed-devices-animations-examples-android"></a>

```
// 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
<a name="broadcast-mixed-devices-mirroring"></a>


| 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
<a name="broadcast-mixed-devices-mirroring-ios"></a>

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
<a name="broadcast-mixed-devices-mirroring-android"></a>

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.