

# IVS Broadcast SDK: 混合デバイス
<a name="broadcast-mixed-devices"></a>

混合デバイスは、複数の入力ソースを取得して単一の出力を生成するオーディオおよびビデオデバイスです。混合デバイスは、複数の画面上 (ビデオ) の要素およびオーディオトラックを定義および管理できる強力な機能です。カメラ、マイク、スクリーンキャプチャ、アプリで生成されたオーディオとビデオなど、複数のソースからのビデオとオーディオを組み合わせることができます。移行機能を使用して IVS にストリーミングするビデオ周辺にこれらのソースを移動させて、ストリーミングの途中でソースに追加およびソースを削除することができます。

混合デバイスは画像およびオーディオの形式で存在します。混合イメージデバイスを作成するには、次のものを呼び出します。

Android の`DeviceDiscovery.createMixedImageDevice()` 

iOS の `IVSDeviceDiscovery.createMixedImageDevice()`

返されたデバイスは、他のデバイスと同様に `BroadcastSession` (低レイテンシーストリーミング) または `Stage` (リアルタイムストリーミング) にアタッチできます。

## 用語
<a name="broadcast-mixed-devices-terminology"></a>

![\[IVS Broadcast 混合デバイスの用語。\]](http://docs.aws.amazon.com/ja_jp/ivs/latest/LowLatencyUserGuide/images/Broadcast_SDK_Mixer_Glossary.png)



| 言葉 | 説明 | 
| --- | --- | 
| デバイス | オーディオまたは画像入力を生成するハードウェアまたはソフトウェアコンポーネント。デバイスの例としては、マイク、カメラ、Bluetooth ヘッドセット、画面キャプチャやカスタム画像入力などの仮想デバイスがあります。 | 
| 混合デバイス | 他の `Device` と同様に、`Device` は `BroadcastSession` にアタッチできるますが、`Source` オブジェクトの追加を可能にする追加の API を使用します。混合デバイスにはオーディオまたは画像を複合する内部ミキサーがあり、単一の出力オーディオおよびイメージストリームを生成します。 混合デバイスはオーディオまたは画像のいずれかの形式で存在します。  | 
| 混合デバイスの設定 | 混合デバイスの設定オブジェクト。混合イメージデバイスの場合、寸法やフレームレートなどのプロパティが設定されます。混合オーディオデバイスの場合、チャンネル数が設定されます。 | 
|  ソース | 画面上のビジュアルエレメントの位置と、オーディオミックス内のオーディオトラックのプロパティを定義するコンテナです。混合デバイスは、ゼロ以上のソースで設定できます。ソースには、ソースのメディアの使用方法に影響する設定が与えられます。上のイメージには、4 つのイメージソースが示されています。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html)  | 
| ソース設定 |  混合デバイスに入るソースの設定オブジェクト。完全な設定オブジェクトは以下のように表記されています。  | 
| トランジション | スロットを新しい位置に移動したり、そのプロパティの一部を変更するには、`MixedDevice.transitionToConfiguration()` を使用します。このメソッドには次のものがあります。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html) | 

## 混合オーディオデバイス
<a name="broadcast-mixed-audio-device"></a>

### 設定
<a name="broadcast-mixed-audio-device-configuration"></a>

Android の`MixedAudioDeviceConfiguration` 

iOS の `IVSMixedAudioDeviceConfiguration`


| 名前 | 型 | 説明 | 
| --- | --- | --- | 
| `channels` | 整数 | オーディオミキサーからの出力チャネルの数。有効な値:1、2。1 はモノラルオーディオで、2 はステレオオーディオです。デフォルト: 2。 | 

### ソース設定
<a name="broadcast-mixed-audio-device-source-configuration"></a>

Android の`MixedAudioDeviceSourceConfiguration` 

iOS の `IVSMixedAudioDeviceSourceConfiguration`


| 名前 | 型 | 説明 | 
| --- | --- | --- | 
| `gain` | 浮動小数点数 | オーディオゲイン。これは乗数であるため、1 を超える値であればゲインが増加し、1 より小さい値であれば減少します。有効な値: 0 ～ 2。デフォルト: 1。 | 

## 混合イメージデバイス
<a name="broadcast-mixed-image-device"></a>

### 設定
<a name="broadcast-mixed-image-device-configuration"></a>

Android の`MixedImageDeviceConfiguration` 

iOS の `IVSMixedImageDeviceConfiguration`


| 名前 | 型 | 説明 | 
| --- | --- | --- | 
| `size` | Vec2 | ビデオキャンバスのサイズ。 | 
| `targetFramerate` | 整数 | 混合デバイスの 1 秒あたりのターゲットフレーム数。平均として、この値を満たす必要がありますが、特定の状況 (CPU や GPU の負荷の高さなど) でシステムのフレーム数が低下する場合があります。 | 
| `transparencyEnabled` | ブール値 | イメージソース設定で `alpha` プロパティを使用してブレンドできます。これを `true` に設定すると、メモリおよび CPU の消費量が増加します。デフォルト: `false`。 | 

### ソース設定
<a name="broadcast-mixed-image-device-source-configuration"></a>

Android の`MixedImageDeviceSourceConfiguration` 

iOS の `IVSMixedImageDeviceSourceConfiguration`


| 名前 | 型 | 説明 | 
| --- | --- | --- | 
| `alpha` | 浮動小数点数 | スロットのアルファ。これは、画像内のアルファ値との乗法です。有効な値: 0 〜 1。0 は完全に透明で、1 は完全に不透明です。デフォルト: 1。 | 
| `aspect` | AspectMode | スロットでレンダリングされたイメージのアスペクト比モード。有効な値: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/ivs/latest/LowLatencyUserGuide/broadcast-mixed-devices.html) デフォルト: `Fit`  | 
| `fillColor` | Vec4 | スロットおよび画像のアスペクト比が一致しない場合に `aspect Fit` と使用する塗りつぶしカラー。フォーマットは (赤、緑、青、アルファ) です。有効な値 (チャネルごとに): 0 〜 1。デフォルト: (0、0、0、0)。 | 
| `position` | Vec2 | キャンバスの左上隅からの相対で、スロット位置 (ピクセル) です。スロットの原点も左上です。 | 
| `size` | Vec2 | スロットのサイズ (ピクセル単位)。この値を設定すると、`matchCanvasSize` も `false` に設定されます。デフォルト: (0、0)。ただし、`matchCanvasSize` のデフォルトは `true` であるため、スロットのレンダリングサイズはキャンバスサイズであり、(0、0) ではありません。 | 
| `zIndex` | 浮動小数点数 | スロットの相対的な順序。`zIndex` 値が高いスロットは、`zIndex` 値が低いスロットの上に描画されます。 | 

## 混合イメージデバイスの作成と設定
<a name="broadcast-mixed-image-device-creating-configuring"></a>

![\[ミキシング用のブロードキャストセッションの設定。\]](http://docs.aws.amazon.com/ja_jp/ivs/latest/LowLatencyUserGuide/images/Broadcast_SDK_Mixer_Configuring.png)


ここでは、このガイドの冒頭にあるシーンに似たシーンを作成し、次の 3 つの画面上の要素を使用します。
+ カメラの左下のスロット。
+ ロゴオーバーレイ用の右下のスロット。
+ 映画の右上のスロット。

キャンバスの原点は左上隅で、これはスロットでも同じであることに注意してください。したがって、スロットを (0、0) に配置すると、スロット全体が見えるように左上隅に配置されます。

### 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)
```

## ソースの削除
<a name="broadcast-mixed-devices-removing-sources"></a>

ソースを削除するには、削除する `Source` オブジェクトで `MixedDevice.remove` を呼び出します。

## トランジションのあるアニメーション
<a name="broadcast-mixed-devices-animations-transitions"></a>

トランジション方法では、ソースの構成が新しい構成に置き換えられます。この置換は、デュレーションを 0 より高く秒単位で設定することで、時間の経過とともにアニメートできます。

### アニメーション化できるプロパティ
<a name="broadcast-mixed-devices-animations-properties"></a>

スロット構造のすべてのプロパティをアニメートできるわけではありません。Float タイプに基づくすべてのプロパティはアニメーション化できます。その他のプロパティは、アニメーションの開始時または終了時に有効になります。


| 名前 | アニメーション化の可否 | インパクトポイント | 
| --- | --- | --- | 
| `Audio.gain` | はい | Interpolated | 
| `Image.alpha` | はい | Interpolated | 
| `Image.aspect` | いいえ | 修了 | 
| `Image.fillColor` | はい | Interpolated | 
| `Image.position` | はい | Interpolated | 
| `Image.size` | はい | Interpolated | 
| `Image.zIndex` 注: `zIndex` は 2D 平面を 3D 空間内で移動するため、アニメーションの途中で 2 つの平面が交差したときにトランジションが発生します。これは計算できますが、開始A値と終了 `zIndex` 値によって異なります。トランジションをよりスムーズにするために、これを `alpha` と組み合わせます。  | はい | 不明 | 

### シンプルな例
<a name="broadcast-mixed-devices-animations-examples"></a>

以下では、上記の[混合イメージデバイスの作成と設定](#broadcast-mixed-image-device-creating-configuring)で定義された設定を使用したフルスクリーンのカメラテイクオーバーの例が示されます。これは 0.5 秒でアニメーション化されます。

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

## ブロードキャストのミラーリング
<a name="broadcast-mixed-devices-mirroring"></a>


| ブロードキャストでアタッチされた画像デバイスを以下の方向にミラーリングする場合 | 以下の条件には負の値を使用します | 
| --- | --- | 
| 水平方向 | スロットの幅 | 
| 垂直方向 | スロットの高さ | 
| 水平方向と垂直方向の両方 | スロットの幅と高さの両方 | 

ミラーリング時にスロットを正しい位置に配置するには、同じ値で位置を調整する必要があります。

以下は、ブロードキャストを水平方向と垂直方向にミラーリングする例です。

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

水平ミラーリング:

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

垂直ミラーリング:

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

水平ミラーリング:

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

垂直ミラーリング:

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

注: このミラーリングは `ImagePreviewView` (Android) や `IVSImagePreviewView` (iOS) の `setMirrored` 方法とは異なります。このメソッドはデバイス上のローカルプレビューにのみ影響し、ブロードキャストには影響しません。