

# IVS Broadcast SDK: モバイルオーディオモード \| リアルタイムストリーミング
<a name="broadcast-mobile-audio-modes"></a>

オーディオ品質はリアルチームのメディアエクスペリエンスにとって重要な部分であり、あらゆるユースケースに最適な万能のオーディオ構成はありません。IVS リアルタイムストリームを聴くときにユーザーが最高の体験を得られるように、モバイル SDK には複数のプリセットオーディオ構成が用意されているほか、必要に応じてさらに強力なカスタマイズも可能です。

## 序章
<a name="broadcast-mobile-audio-modes-introduction"></a>

IVS モバイル Broadcast SDK には `StageAudioManager` クラスが用意されています。このクラスは、2 つのプラットフォームの基盤オーディオモードを一元的に制御できるように設計されています。Android では、オーディオモード、オーディオソース、コンテンツタイプ、使用方法、通信デバイスなど、[AudioManager](https://developer.android.com/reference/android/media/AudioManager) を制御します。iOS では、アプリケーションの [AVAudioSession](https://developer.apple.com/documentation/avfaudio/avaudiosession) を制御し、[voiceProcessing](https://developer.apple.com/documentation/avfaudio/avaudioionode/3152101-voiceprocessingenabled?language=objc) を有効にするかどうかも制御します。

**重要**: IVS リアルタイム Broadcast SDK がアクティブな間は、`AVAudioSession` や `AudioManager` を直接操作しないでください。これを行うと、オーディオが失われたり、間違ったデバイスから録音されたり、間違ったデバイスで再生されたりする可能性があります。

最初の `DeviceDiscovery` オブジェクトまたは `Stage` オブジェクトを作成する前に、`StageAudioManager` クラスを設定する必要があります。

------
#### [ Android (Kotlin) ]

```
StageAudioManager.getInstance(context).setPreset(StageAudioManager.UseCasePreset.VIDEO_CHAT) // The default value

val deviceDiscovery = DeviceDiscovery(context)
val stage = Stage(context, token, this)

// Other Stage implementation code
```

------
#### [ iOS (Swift) ]

```
IVSStageAudioManager.sharedInstance().setPreset(.videoChat) // The default value

let deviceDiscovery = IVSDeviceDiscovery()
let stage = try? IVSStage(token: token, strategy: self)

// Other Stage implementation code
```

------

`DeviceDiscovery` インスタンスや `Stage` インスタンスの初期化前に `StageAudioManager` に何も設定されていない場合、`VideoChat` プリセットが自動的に適用されます。

## オーディオユースケースのプリセット
<a name="broadcast-mobile-audio-modes-presets"></a>

リアルタイム Broadcast SDK には 3 つのプリセットがあり、以下で説明するように、それぞれ一般的なユースケースに合わせて調整されています。各プリセットについて、プリセットを互いに区別する 5 つの主要カテゴリについて説明します。

**Volume Rocker** カテゴリは、デバイスの物理ボリュームロッカーを介して使用または変更されたボリュームのタイプ (メディアボリュームまたはコールボリューム) を指します。これは、オーディオモードを切り替えるときにボリュームに影響することに注意してください。例えば、Video Chat プリセットの使用中にデバイスボリュームが最大値に設定されているとします。Subscribe Only プリセットに切り替えると、オペレーティングシステムとは異なるボリュームレベルになり、デバイスで大幅なボリューム変更が発生する可能性があります。

### ビデオチャット
<a name="audio-modes-presets-video-chat"></a>

これはデフォルトのプリセットで、ローカルデバイスが他の参加者とリアルタイムで会話する場合に適しています。

**iOS の既知の問題**: このプリセットを使用してマイクをアタッチしないと、デバイススピーカーではなくイヤホンでオーディオが再生されます。このプリセットは、マイクと組み合わせてのみ使用してください。


| Category | Android | iOS | 
| --- | --- | --- | 
| エコーキャンセレーション | 有効 | 有効 | 
| ノイズ抑制 | 有効 | 有効 | 
| Volume Rocker | 通話ボリューム | 通話ボリューム | 
| マイク選択 | OS によって制限されます。USB マイクを使用できない場合があります。 | OS によって制限されます。USB マイクと Bluetooth マイクを使用できない場合があります。<br />AirPods のように、入力と出力の両方を同時に処理する Bluetooth ヘッドセットは動作するはずです。 | 
| オーディオ出力 | どの出力デバイスでも動作するはずです。 | OS によって制限されます。有線ヘッドセットを使用できない場合があります。 | 
| オーディオ品質 | 中/低 メディア再生とは違い、電話のように聞こえます。 | 中/低 メディア再生とは違い、電話のように聞こえます。 | 

### サブスクライブのみ
<a name="audio-modes-presets-subscribe-only"></a>

このプリセットは、公開している他の参加者をサブスクライブする予定があっても自分では公開しない場合向けに設計されています。オーディオの品質に重点を置き、利用可能なすべての出力デバイスをサポートしています。


| Category | Android | iOS | 
| --- | --- | --- | 
| エコーキャンセレーション | Disabled | Disabled | 
| ノイズ抑制 | Disabled | Disabled | 
| Volume Rocker | メディアボリューム | メディアボリューム | 
| マイク選択 | 非該当。このプリセットは公開用ではありません。 | 非該当。このプリセットは公開用ではありません。 | 
| オーディオ出力 | どの出力デバイスでも動作するはずです。 | どの出力デバイスでも動作するはずです。 | 
| オーディオ品質 | 高 音楽を含め、どんな種類のメディアでもクリアに聞こえるはずです。 | 高 音楽を含め、どんな種類のメディアでもクリアに聞こえるはずです。 | 

### Studio
<a name="audio-modes-presets-studio"></a>

このプリセットは、公開機能を維持したまま、質の高いサブスクライブができるように設計されています。エコーキャンセレーション機能付きの録音再生ハードウェアが必要です。この場合のユースケースは、USB マイクと有線ヘッドセットの使用です。エコーの原因とならないようにデバイスの物理的な分離を確保しながら、SDK は最高品質のオーディオを維持します。


| Category | Android | iOS | 
| --- | --- | --- | 
| エコーキャンセレーション | Disabled | Disabled | 
| ノイズ抑制 | Disabled | Disabled | 
| Volume Rocker | ほとんどの場合、メディアボリューム。Bluetooth マイクが接続されている場合は、通話ボリューム。 | メディアボリューム | 
| マイク選択 | どのマイクでも動作するはずです。 | どのマイクでも動作するはずです。 | 
| オーディオ出力 | どの出力デバイスでも動作するはずです。 | どの出力デバイスでも動作するはずです。 | 
| オーディオ品質 | 高 双方が音楽を送信でき、反対側でもクリアに聞こえるはずです。<br />Bluetooth ヘッドセットが接続されている場合、Bluetooth SCO モードが有効になっているため、音質が低下します。 | 高 双方が音楽を送信でき、反対側でもクリアに聞こえるはずです。<br />Bluetooth ヘッドセットが接続されている場合、ヘッドセットによっては Bluetooth SCO モードが有効になっているため、音質が低下する場合があります。 | 

## 高度なユースケース
<a name="broadcast-mobile-audio-modes-advanced-use-cases"></a>

プリセット以外にも、iOS と Android のリアルタイムストリーミング Broadcast SDK では、基盤となるプラットフォームのオーディオモードを次のように設定できます。
+ Android では、[AudioSource](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource)、[Usage](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ALARM)、[ContentType](https://developer.android.com/reference/android/media/AudioAttributes#CONTENT_TYPE_MOVIE) を設定します。
+ iOS では、[AVAudioSession.Category](https://developer.apple.com/documentation/avfaudio/avaudiosession/category)、[AVAudioSession.CategoryOptions](https://developer.apple.com/documentation/avfaudio/avaudiosession/categoryoptions)、[AVAudioSession.Mode](https://developer.apple.com/documentation/avfaudio/avaudiosession/mode)、および公開中に[音声処理](https://developer.apple.com/documentation/avfaudio/avaudioionode/3152101-voiceprocessingenabled?language=objc)を有効にするかどうかを切り替える機能を使用します。

注: これらのオーディオ SDK メソッドを使用する場合、基盤となるオーディオセッションを誤って設定する可能性があります。例えば、iOS で `.allowBluetooth` オプションを `.playback` カテゴリと組み合わせて使用すると、無効なオーディオ設定が作成され、SDK はオーディオを録音または再生できません。これらのメソッドは、アプリケーションに特定のオーディオセッション要件が検証されている場合にのみ使用されるように設計されています。

------
#### [ Android (Kotlin) ]

```
// This would act similar to the Subscribe Only preset, but it uses a different ContentType.
StageAudioManager.getInstance(context)
    .setConfiguration(StageAudioManager.Source.GENERIC,
                      StageAudioManager.ContentType.MOVIE,
                      StageAudioManager.Usage.MEDIA);

val stage = Stage(context, token, this)

// Other Stage implementation code
```

------
#### [ iOS (Swift) ]

```
// This would act similar to the Subscribe Only preset, but it uses a different mode and options.
IVSStageAudioManager.sharedInstance()
    .setCategory(.playback,
                 options: [.duckOthers, .mixWithOthers],
                 mode: .default)

let stage = try? IVSStage(token: token, strategy: self)

// Other Stage implementation code
```

------

### iOS エコーキャンセレーション
<a name="advanced-use-cases-ios_echo_cancellation"></a>

iOS でのエコーキャンセレーションは、`echoCancellationEnabled` メソッドを使用して `IVSStageAudioManager` を介して個別に制御することもできます。このメソッドは、SDK が使用し、基盤となっている `AVAudioEngine` の入出力ノードで[音声処理](https://developer.apple.com/documentation/avfaudio/avaudioionode/3152101-voiceprocessingenabled?language=objc)が有効になっているかどうかを制御します。このプロパティを手動で変更した場合の以下の影響を理解することは重要です。
+ `AVAudioEngine` プロパティは、SDK のマイクがアクティブな場合にのみ使用されます。これは、入力ノードと出力ノードの両方で音声処理を同時に有効にするという iOS の要件のために必要です。通常、これは、`IVSDeviceDiscovery` から返されたマイクを使用して行われ、公開用に `IVSLocalStageStream` が作成されます。または、マイク自体に `IVSAudioDeviceStatsCallback` をアタッチすることで、公開に使用することなくマイクを有効にすることもできます。この代替アプローチは、IVS SDK のマイクの代わりにカスタムオーディオソースベースのマイクを使用しているときにエコーキャンセレーションが必要な場合に役立ちます。
+ `AVAudioEngine` プロパティを有効にするには、`.videoChat` または `.voiceChat` のモードが必要です。別のモードをリクエストすると、iOS の基盤となるオーディオフレームワークが SDK と戦い、オーディオが失われます。
+ `AVAudioEngine` を自動的に有効にすると、`.allowBluetooth ` オプションが有効になります。

デバイスと iOS のバージョンによって動作が異なる場合があります。

### iOS カスタムオーディオソース
<a name="advanced-use-cases-ios_custom_audio_sources"></a>

カスタムオーディオソースは、`IVSDeviceDiscovery.createAudioSource` を使用して SDK で使用できます。ステージに接続する場合、IVS Real-Time Streaming Broadcast SDK は、SDK のマイクが使用されていなくても、音声再生用の内部 `AVAudioEngine` インスタンスを管理します。そのため、`IVSStageAudioManager` に提供される値は、カスタムオーディオソースによって提供されるオーディオと互換性がある必要があります。

公開に使用されるカスタムオーディオソースがマイクからの録音でホストアプリケーションで管理されている場合、上記のエコーキャンセレーション SDK は、SDK 管理のマイクがアクティブ化されない限り機能しません。この要件を回避する方法については、[「iOS エコーキャンセレーション](#advanced-use-cases-ios_echo_cancellation)」を参照してください。

### Android で Bluetooth を使用して公開する
<a name="advanced-use-cases-bluetooth-android"></a>

以下の条件が満たされると、SDK は Android の `VIDEO_CHAT` プリセットに自動的に戻ります。
+ 割り当てられた設定には、`VOICE_COMMUNICATION` 使用状況の値は使用されていない。
+ Bluetooth マイクがデバイスに接続されている。
+ ローカル参加者がステージに公開している。

これは Bluetooth ヘッドセットを使用してオーディオを録音する方法に関する Android オペレーティングシステムの制限です。

## 他の SDK との統合
<a name="broadcast-mobile-audio-modes-integrating-other-sdks"></a>

iOS と Android はどちらもアプリケーションごとにアクティブなオーディオモードを 1 つしかサポートしていないため、オーディオモードの制御を必要とする複数の SDK をアプリケーションで使用していると、競合が発生することがよくあります。このような競合が発生した場合は、以下で説明する一般的な解決方法をいくつか試してみてください。

### オーディオモードの値に合わせる
<a name="integrating-other-sdks-match-values"></a>

IVS SDK の高度なオーディオ設定オプションまたは他の SDK の機能を使用して、2 つの SDK を基本となる値に合わせます。

### Agora
<a name="integrating-other-sdks-agora"></a>

#### iOS
<a name="integrating-other-sdks-agora-ios"></a>

iOS では、Agora SDK に `AVAudioSession` をアクティブのままにしておくように指示すると、IVS Real-Time Streaming Broadcast SDK が使用している間は非アクティブ化されなくなります。

```
myRtcEngine.SetParameters("{\"che.audio.keep.audiosession\":true}");
```

#### Android
<a name="integrating-other-sdks-agora-android"></a>

IVS Real-Time Streaming Broadcast SDK で公開中に `RtcEngine` で `setEnableSpeakerphone` を呼び出すことや `enableLocalAudio(false)` を呼び出すことは避けてください。IVS SDK で公開していないときに再度 `enableLocalAudio(true)` を呼び出す機会があります。