AVAudioSessionは、iOSアプリが「自分は音をどう使うつもりか」をOSに宣言するための仕組みです。音を鳴らす処理そのものはAVAudioPlayerやAVAudioEngineが担当しますが、サイレントスイッチで消音されるか、他のアプリの音楽を止めるか、マイクを使えるかといった振る舞いは、AVAudioSessionの設定が起点になります(画面ロック後も鳴らし続けるには、これに加えてInfo.plistの設定が要ります)。再生コードが正しいのに音が出ないときは、まずここを確認すると早く切り分けられます。
この記事では、カテゴリ・モード・カテゴリオプションの3つの設定軸を表で一覧にし、そのうえでSwiftの実装例を示します。掲載するコードはiOS向けの実装断片で、プレイヤーの生成やUI側の処理は省いています。あわせて、2026年9月20日時点のApple公式ドキュメントで確認した変更点も反映しています。録音許可の取得APIはiOS 17でAVAudioSessionからAVAudioApplicationへ移り、カテゴリオプションのallowBluetoothは公式ドキュメント上allowBluetoothHFPへの改称が記録されています。日本語で読める解説記事の多くはこれらより前に書かれたものなので、コードをそのまま写すと非推奨APIを踏むことになります。
まとめ:AVAudioSessionの設定順と押さえどころ
結論から言うと、決める順番は「カテゴリ→モード→オプション→有効化」です。音楽・動画の再生アプリならplayback、通話や録音を伴うならplayAndRecordを選び、モードは通話ならvoiceChat、それ以外はdefaultのままにします。オプションは、他アプリの音と共存させたいときだけmixWithOthersかduckOthersを足します。カテゴリとモードの決定は一度で済みますが、有効化と無効化は再生の開始・終了や割り込みに合わせて繰り返し行うことになります。
そのうえで押さえるべき点が4つあります。第1に、画面ロック後やホーム画面に戻った後も音を鳴らし続けるには、カテゴリの設定だけでは足りず、Info.plistのUIBackgroundModesにaudioを追加する必要があります。第2に、録音許可の取得はiOS 17以降AVAudioApplicationの担当で、AVAudioSession側の同名APIは非推奨です。第3に、電話やSiriによる割り込みとイヤホンの抜き差しには対応が要ります。AVPlayerを使っている場合はAVPlayer自身がセッションを監視して自動で一時停止しますが、AVAudioPlayerやAVAudioEngineを直接動かす実装では、interruptionNotificationとrouteChangeNotificationを自分で購読しないと「電話の後に音が戻らない」「イヤホンを抜いたのに鳴り続ける」という挙動になります。第4に、再生を終えてセッションを閉じるときは、setActive(false)にnotifyOthersOnDeactivationを付けます。これがないと、自分が中断させた音楽アプリがアクティブ状態へ戻れません。
| やりたいこと | カテゴリ | モード | 追加で必要なもの |
|---|---|---|---|
| 音楽・動画の再生(サイレント時も鳴らす) | playback | default / moviePlayback | UIBackgroundModes に audio |
| ゲームの効果音(BGMアプリを止めない) | ambient | default | なし(既定でミックス) |
| VoIP通話・ボイスチャット | playAndRecord | voiceChat | NSMicrophoneUsageDescription |
| ボイスメモ・録音アプリ | playAndRecord | default | 録音許可の取得 |
| 読み上げ・音声ガイド | playback | spokenAudio / voicePrompt | なし |
| 他アプリの音量を下げて割り込む | playback | default | オプション duckOthers |
AVAudioSessionの役割とデフォルト動作
AVAudioSessionはAVFAudioフレームワークのクラスで、Apple公式ドキュメントは「アプリが音声をどう使うつもりかをシステムに伝えるオブジェクト」と定義しています。公式ドキュメントに載っている対応プラットフォームは、iOS 3.0・iPadOS 3.0・Mac Catalyst 13.1・tvOS 9.0・visionOS 1.0・watchOS 2.0です。macOSは入っていないため、Mac Catalystを使わないmacOSアプリでは出てきません。
実体はシングルトンで、AVAudioSession.sharedInstance()で取得します。アプリごとにインスタンスを作るものではなく、アプリ全体で1つの状態を共有します。したがってライブラリの内部と画面側の両方でカテゴリを書き換えると、後から呼んだほうが勝って想定外の挙動になります。設定を触る場所はアプリ内で1か所に寄せるのが安全です。
何も設定しない場合の既定はsoloAmbientカテゴリです。この状態では、録音はできず、サイレントスイッチをオンにすると音が消え、画面をロックすると音が止まり、他アプリのバックグラウンド再生は自分のセッションを有効化した時点で中断されます。多くのアプリではこの既定で問題ありませんが、音楽プレイヤー・動画プレイヤー・通話アプリ・録音アプリはいずれもこの既定と要件が合わないため、明示的な設定が必要になります。
カテゴリ7種の選び方
カテゴリは、アプリの音の使い方を大づかみに宣言する設定です。AVAudioSession.Category型で、公式ドキュメントが挙げるのは次の7つですが、audioProcessingは「もはや不要」としてiOS 10で非推奨になっており、新規に選ぶことはありません。実質的には6択です。
| カテゴリ | 再生 | 録音 | サイレント時 | 既定のミックス | 主な用途 |
|---|---|---|---|---|---|
| soloAmbient(既定) | 可 | 不可 | 消音 | しない | 指定しなかったときの既定 |
| ambient | 可 | 不可 | 消音 | する | 効果音・UI音 |
| playback | 可 | 不可 | 鳴る | しない | 音楽・動画・読み上げ |
| record | 不可 | 可 | 該当なし | しない | 出力を完全に止めたい録音 |
| playAndRecord | 可 | 可 | 鳴る | しない | 通話・録音アプリ全般 |
| multiRoute | 可 | 可 | 鳴る | しない | 複数の入出力を同時に使う |
| audioProcessing | 不可 | 不可 | 該当なし | しない | iOS 10で非推奨。選ぶ必要はない |
迷いやすいのはrecordとplayAndRecordの使い分けです。公式ドキュメントはrecordについて「セッションが有効な間、システム上のほぼすべての出力を無音にする効果がある。予期しない音の再生を防ぐ必要がないかぎり、playAndRecordを使うこと」と書いています。録音中に操作音やプレビュー再生を鳴らしたいなら、recordではなくplayAndRecordが正解です。
もう1点、recordは出力を黙らせますが、電話・アラーム・その他のミックス不可なセッションからの割り込みまでは防げません。これも公式ドキュメントに注記があります。割り込まれない前提でコードを書かないでください。
モード11種とiOS 26系での追加分
モードは、選んだカテゴリの中で用途をさらに細かく指定する設定です。AVAudioSession.Mode型で、設定するとシステムが音の傾向や使える経路を用途に合わせて調整します。たとえばvoiceChatでは、公式ドキュメントによれば音声向けに音色が最適化され、使える経路がボイスチャットに適したものだけに絞られ、さらにallowBluetoothHFPオプションが自動で適用されます。公式ドキュメントが挙げるのは次の11種類です。
| モード | 公式の説明 | 追加 |
|---|---|---|
| default | 既定のモード | iOS 5.0 |
| voiceChat | VoIPなど双方向の音声通話を行うとき | iOS 5.0 |
| videoChat | オンラインのビデオ会議を行うとき | iOS 7.0 |
| gameChat | GameKitのボイスチャット利用時にGameKitが設定する | iOS 5.0 |
| videoRecording | 動画を録画するとき | iOS 5.0 |
| measurement | 音声入出力の測定を行うとき | iOS 5.0 |
| moviePlayback | 映像コンテンツを再生するとき | iOS 6.0 |
| spokenAudio | 連続した音声コンテンツ。他アプリの短い音声プロンプト時に一時停止する | iOS 9.0 |
| voicePrompt | 音声合成で音声を再生するとき | iOS 12.0 |
| shortFormVideo | 短尺動画コンテンツを再生するアプリ向け | iOS 26.0 |
| dualRoute | 内蔵マイク・スピーカーと、入出力に対応した副デバイスを同時に使う | iOS 26.2 |
spokenAudioとvoicePromptは名前が似ていますが役割が逆です。公式ドキュメントはspokenAudioについて「ポッドキャストやオーディオブックのように連続した音声を再生するアプリに適している。このモードを設定すると、他のアプリが音声プロンプトを再生したときに、ダッキングではなく一時停止すべきであることを示す」と説明しています。voicePromptはその短い案内を出す側で、公式が挙げている例もターンバイターンのナビゲーションアプリです。同種のアプリはduckOthersとinterruptSpokenAudioAndMixWithOthersを併せて設定するのが通例だとも書かれています。つまりカーナビの案内音声がvoicePrompt、オーディオブック再生がspokenAudioです。
新しい2つのモードには、カテゴリ側の制約があります。shortFormVideoはplaybackカテゴリでのみ有効です。dualRouteはさらに限定的で、公式ドキュメントは「このモードはmultiRouteカテゴリでのみ使用できる。加えてallowBluetoothHFPオプションの設定が必要になる」としています。playAndRecordに付けても効きません。
shortFormVideoとdualRouteはどちらもiOS 26系での追加なので、対応範囲を広く取るアプリではavailableによる分岐が必要です。特にdualRouteはiOS 26.2追加と新しく、かつ後述のとおりカテゴリ側の条件も付きます。
カテゴリオプション11種とallowBluetoothの改称
カテゴリオプションは、カテゴリの既定の振る舞いを部分的に上書きする設定です。AVAudioSession.CategoryOptions型のOptionSetで、複数を同時に指定できます。ただしカテゴリによって使えるオプションが決まっており、対応しない組み合わせを渡すとsetCategoryがエラーを投げます。
| オプション | 効果 | 備考 |
|---|---|---|
| mixWithOthers | 他アプリの音を止めずに自分の音を重ねる | 明示指定は playAndRecord / playback / multiRoute のみ |
| duckOthers | セッションが有効な間、他アプリの音量を下げる | 同上。指定すると mixWithOthers も立つ |
| interruptSpokenAudioAndMixWithOthers | spokenAudioモードのセッションだけ止め、それ以外とはミックスする | iOS 9.0。spokenAudioモード側と対になる |
| allowBluetoothHFP | Bluetoothハンズフリー機器を音声入力に使えるようにする | playAndRecord / record と、dualRouteモードのmultiRoute |
| allowBluetooth | 同上 | 公式がallowBluetoothHFPへの改称を記録 |
| allowBluetoothA2DP | A2DP対応のBluetooth機器へ出力できるようにする | iOS 10.0。高音質の出力専用 |
| allowAirPlay | AirPlay機器へ出力できるようにする | iOS 10.0。明示指定は playAndRecord のみ |
| defaultToSpeaker | 受話口ではなく内蔵スピーカーを既定の出力にする | playAndRecordのみ |
| overrideMutedMicrophoneInterruption | 内蔵マイクがミュートされたときにセッションを割り込ませない | iOS 14.5。iPadのカバーを閉じたときなど |
| bluetoothHighQualityRecording | 対応機器でフル帯域の音声を有効にする | iOS 26.0。defaultモード限定。EUでは非対応、入力遅延が増える場合あり |
| farFieldInput | 利用可能なときに遠距離集音の入力を優先する | iOS 26.2。allowBluetoothHFP必須(無いとエラー) |
ここで注意が要るのがallowBluetoothです。Apple公式ドキュメントのこのシンボルには、allowBluetoothHFPへ改称された旨の記録が入っています。値の意味は同じで既存コードがすぐ壊れるわけではありませんが、正式名として掲載されているのはallowBluetoothHFPなので、新しく書くコードではこちらを使います。
もうひとつ、allowBluetoothHFPとallowBluetoothA2DPは別物です。HFPは通話用プロファイルで双方向(マイクも使える)ですが音質は電話品質に落ちます。A2DPは出力専用で音質は高いままです。つまり「Bluetoothヘッドセットで通話したい」ならHFP、「Bluetoothスピーカーで音楽を流したい」ならA2DPです。録音アプリでBluetoothマイクを使うと音質が落ちて聞こえるのは、HFPに切り替わっているためで、不具合ではありません。iOS 26のbluetoothHighQualityRecordingは、この制約を緩めるために追加されたオプションです。ただし適用条件が細かく、公式ドキュメントは「Bluetooth経路が対応している場合(一部のAirPodsなど)にフル帯域の音声を有効にする」「高音質録音を要求できるのはdefaultモードを使っているときだけ」としています。対応可否は入力ポートのbluetoothMicrophoneExtensionからhighQualityRecording機能を調べて判定します。加えて「現時点でEUではサポートされていない」「入力遅延が増える可能性があり、リアルタイム通信用途には推奨しない」という2つの注記が付いています。
Swift実装:設定・有効化・割り込み・ルート変更
カテゴリ設定とセッションの有効化
設定はsetCategory(_:mode:options:)で1回にまとめ、そのあとsetActive(true)で有効化します。公式ドキュメントは「通常、セッションを有効化する前にカテゴリとモードを設定する。有効化した状態で変更することもできるが、その場合は即座に反映される」としています。
注意したいのは、カテゴリ設定と有効化を同じタイミングで行うとは限らない点です。playbackは既定でミックス不可なので、セッションを有効化した瞬間に他アプリの再生が止まります。再生ボタンを持つアプリなら、カテゴリ設定はあらかじめ済ませておき、有効化はユーザーが再生を始めるところまで待つほうがユーザー体験に沿います。下の例は、その再生開始時に呼ぶ想定の関数です。
import AVFAudio
func configureForPlayback() {
let session = AVAudioSession.sharedInstance()
do {
try session.setCategory(.playback, mode: .default, options: [])
try session.setActive(true)
} catch {
print("audio session setup failed: \(error)")
}
}
setCategoryもsetActiveもthrowsなので、do-catchかtry?で必ず受けます。有効化に失敗する典型は、電話などミックス不可の上位セッションが先に動いているケースです。公式ドキュメントは「自分より優先度の高いセッション(通話など)があり、どちらもミックスを許していない場合、有効化は失敗する」と明記しています。失敗したまま再生処理へ進むと無音になるため、catch側で再生を中止するか、再試行する設計が必要です。
終了時のnotifyOthersOnDeactivation指定
再生を終えてセッションを閉じるときは、オプションを付けます。
try? AVAudioSession.sharedInstance()
.setActive(false, options: [.notifyOthersOnDeactivation])
公式ドキュメントはこのオプションを「自分のセッションが無効化されたとき、自分のセッションに中断されていた他のオーディオセッションがアクティブ状態へ戻れることを示す」と説明しています。実際に再生を再開するかどうかは相手のアプリ次第ですが、付け忘れると戻る余地そのものが無くなります。無効化のときだけ使うオプションで、setActive(true)に渡しても意味はありません。
割り込み(電話・Siri・アラーム)のハンドリング
電話の着信やSiriの起動で音が止まるのはシステムの仕様で、避けられません。代わりにAVAudioSession.interruptionNotificationが飛んでくるので、開始時は状態を保存して停止し、終了時にshouldResumeが立っていれば再開します。公式ドキュメントによれば、この通知はメインスレッドに投げられます。
NotificationCenter.default.addObserver(
forName: AVAudioSession.interruptionNotification,
object: AVAudioSession.sharedInstance(),
queue: .main
) { note in
guard let raw = note.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt,
let type = AVAudioSession.InterruptionType(rawValue: raw) else { return }
switch type {
case .began:
wasPlayingBeforeInterruption = player.isPlaying
player.pause() // セッションはすでに無効化されている
case .ended:
guard let optRaw = note.userInfo?[AVAudioSessionInterruptionOptionKey] as? UInt
else { return }
let options = AVAudioSession.InterruptionOptions(rawValue: optRaw)
guard options.contains(.shouldResume), wasPlayingBeforeInterruption else { return }
do {
try AVAudioSession.sharedInstance().setActive(true)
player.play()
} catch {
print("failed to reactivate session: \(error)") // 再生は始めない
}
@unknown default:
break
}
}
再開の条件をshouldResumeだけにしないでください。割り込み中にユーザーが停止操作をしたり、そもそも再生していなかったりする場合があるため、上の例のように割り込み開始時点の再生状態を保存し(wasPlayingBeforeInterruptionは所有クラスのプロパティとして持ちます)、両方が立っているときだけ再開します。なお、addObserverが返すトークンは所有クラスのプロパティに保持し、監視をやめるときにremoveObserverへ渡してください。画面表示のたびに登録すると観測が重複します。
ここで見落とされがちな挙動が1つあります。公式ドキュメントは「iOS 10以降、システムはアプリのプロセスをサスペンドする際にオーディオセッションを無効化する。アプリが再び動き出したとき、セッションが無効化されたという割り込み通知を受け取る」と説明しています。この通知は時間的にずれて届くので、再生していないタイミングで突然beganが来ることがあります。判別にはAVAudioSessionInterruptionWasSuspendedKeyがtrueかどうかを見ます。
同じ節に対策も書かれていて、「ミックス不可に設定している場合(playback、playAndRecord、soloAmbient、multiRouteの既定動作)、バックグラウンドへ移るときに音声を積極的に使っていないならセッションを無効化しておくこと。そうすれば、システムに無効化されてこの紛らわしい通知を受け取ることを避けられる」とされています。再生が止まっているならセッションも閉じる、というのが公式の推奨です。
ルート変更(イヤホンの抜き差し)のハンドリング
イヤホンを抜いたら再生を止める、という挙動はユーザーの期待です。公式ドキュメントも「ヘッドホンを外したとき、ユーザーは聴いている内容を周囲に共有したいわけではない。アプリはこの暗黙のプライバシー要求を尊重し、自動的に再生を一時停止すべきである」としています。AVPlayerを使っている場合、この対応はAVPlayer自身が行うため自前の実装は不要です(rateプロパティをKVOで監視すればUIを追随させられます)。AVAudioPlayerやAVAudioEngineを直接動かす実装では、AVAudioSession.routeChangeNotificationのreasonがoldDeviceUnavailableのときに自分で停止します。この通知は割り込み通知と違い、公式ドキュメントによればセカンダリスレッドに投げられます。UIを触るならメインスレッドへ戻してください。
NotificationCenter.default.addObserver(
forName: AVAudioSession.routeChangeNotification,
object: nil,
queue: nil // セカンダリスレッドで届く
) { note in
guard let raw = note.userInfo?[AVAudioSessionRouteChangeReasonKey] as? UInt,
let reason = AVAudioSession.RouteChangeReason(rawValue: raw) else { return }
if reason == .oldDeviceUnavailable {
DispatchQueue.main.async { player.pause() } // イヤホンが抜かれた
}
}
reasonには他にnewDeviceAvailable(イヤホンを挿した等)、categoryChange、override、wakeFromSleep、noSuitableRouteForCategory、routeConfigurationChange、unknownがあります。直前の経路を知りたい場合はAVAudioSessionRouteChangePreviousRouteKeyから取得できます。
入力デバイスと出力先の指定
マイクを選ぶにはsetPreferredInput(_:)、スピーカーへ一時的に切り替えるにはoverrideOutputAudioPort(_:)を使います。setPreferredInput(_:)に渡す候補は、録音に対応するカテゴリを設定してセッションを有効化したうえで、availableInputsから取得します。カテゴリを設定する前に読んでも候補は揃いません。ただし公式ドキュメントは、overrideOutputAudioPortについて「この効果は現在の経路が変わるか、noneを指定して再度呼ぶまでしか続かない。恒久的に有効にしたいなら、代わりにカテゴリオプションのdefaultToSpeakerを設定すること」と明記しています。通話画面のスピーカーボタンのような一時的な切り替えがoverrideOutputAudioPort、アプリ全体で常にスピーカーから出したいならdefaultToSpeakerです。
また、allowBluetoothHFPの説明には連動仕様が書かれています。setPreferredInput(_:)でBluetooth HFPの入力を選ぶと出力も自動的に対応するHFP出力へ変わり、逆に経路選択UIからHFP出力を選ぶと入力もHFPへ変わります。入力だけ、出力だけを個別に選ぶことはできません。
バックグラウンド再生とマイク権限
バックグラウンド再生に必要なUIBackgroundModesのaudio値
カテゴリをplaybackにすればサイレントスイッチと画面ロックを無視して鳴りますが、それだけでは足りません。公式ドキュメントはplayback・playAndRecord・recordの各カテゴリの説明で、いずれも同じ条件を挙げています。「アプリがバックグラウンドへ移行したとき(たとえば画面がロックされたとき)に再生を続けるには、情報プロパティリストのUIBackgroundModesキーにaudioの値を追加すること」です。
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
Xcodeでは、ターゲットのSigning & CapabilitiesからBackground Modesを追加し、Audio, AirPlay, and Picture in Pictureにチェックを入れると同じ内容が書き込まれます。この設定は録音にも同様に必要で、バックグラウンドで録音を続ける場合も同じaudio値を使います。宣言した用途に実際に使うことが前提なので、バックグラウンドで音声を扱わないアプリでは外しておきます。
iOS 17以降の録音許可とAVAudioApplication
録音許可の取得APIは移行済みです。長くAVAudioSession.sharedInstance().requestRecordPermission(_:)が使われてきましたが、公式ドキュメントはこのメソッドとrecordPermissionプロパティの両方について、iOS 17で非推奨となりAVAudioApplicationの同等APIを使うよう案内しています。iOS 17で追加されたAVAudioApplicationは、アプリに属する1つ以上のオーディオセッションを束ねて管理するクラスで、録音許可の取得と状態確認、入力ミュートの管理を担当します。
import AVFAudio
switch AVAudioApplication.shared.recordPermission {
case .granted:
startRecording()
case .denied:
showSettingsGuidance() // ダイアログは再表示されない
case .undetermined:
AVAudioApplication.requestRecordPermission { granted in
DispatchQueue.main.async {
granted ? startRecording() : showSettingsGuidance()
}
}
@unknown default:
break
}
許可を求める前提として、Info.plistにNSMicrophoneUsageDescriptionで利用目的を書いておく必要があります。Appleはこのキーについて「デバイスのマイクにアクセスするAPIを使う場合、このキーは必須」と明記しており、未設定のままマイクへアクセスするとアプリが実行時に停止します。また、許可の状態はアプリごとに保存され、一度deniedになると同じアプリでは再びダイアログが出ません。この場合は再要求ではなく、設定アプリへの導線を出すのが正しい対応です。
AVAudioApplicationには他にも、通話に音声を差し込む権限を扱うrequestMicrophoneInjectionPermission(completionHandler:)と、アプリ単位の入力ミュートを扱うisInputMuted・setInputMuted(_:)・inputMuteStateChangeNotificationがあります。会議アプリのミュートボタンをアプリ全体へ反映したい場合は、AVAudioSessionではなくこちらを使います。
音が出ない・録音できないときの切り分け
症状ごとに、最初に疑う設定をまとめます。
| 症状 | 確認する順番 | 対処 |
|---|---|---|
| まったく音が出ない | カテゴリがrecordになっていないか | playbackかplayAndRecordへ変更 |
| サイレント時だけ出ない | カテゴリがambient / soloAmbientか | playbackへ変更 |
| 端末を耳に当てないと聞こえない | playAndRecord + voiceChatで受話口へ出ている | defaultToSpeakerかoverrideOutputAudioPort(.speaker) |
| ロックすると止まる | UIBackgroundModesにaudioがあるか | Info.plistへ追加 |
| 録音ファイルが無音 | カテゴリが再生専用、または許可がdenied | playAndRecordへ変更、設定アプリへ誘導 |
| Bluetoothマイクが選べない | allowBluetoothHFPを付けているか | playAndRecord / recordで指定 |
| 電話の後に再生が戻らない | interruptionNotificationを受けているか | ended時にshouldResumeで再開 |
| 他アプリの音楽が再開しない | setActive(false)にオプションがあるか | notifyOthersOnDeactivationを付ける |
「音が出ない」で見落としやすいのは、setActive(true)が実際には失敗しているケースです。try?で握りつぶしていると気づけないので、切り分け中は一度do-catchに変えてエラーを表示してください。通話中に有効化を試みた場合など、正当に失敗する状況があります。
録音側では、通話中にサードパーティアプリがマイクを使えない点と、Bluetooth機器が接続されていると内蔵マイクが選ばれない点が定番の原因です。どのマイクが使われているかは、セッションのcurrentRouteから現在の入力ポートを確認すると判別できます。
なお、システムのアラート音でセッションを中断されたくない場合は、iOS 14.5で追加されたprefersNoInterruptionsFromSystemAlertsで意向を伝えられます。あくまで「希望」であり、優先度の高い割り込みまで止められるわけではありません。
よくある質問
AVAudioSessionの設定はいつ行えばよいですか?
再生や録音を始める前であれば、アプリ起動時でも画面表示時でも構いません。公式ドキュメントは「通常はセッションを有効化する前にカテゴリとモードを設定する」としており、有効化後の変更も可能ですが即座に反映されるため、経路が切り替わって音が途切れる可能性があります。シングルトンなのでアプリ内の複数箇所から設定すると後勝ちになります。設定箇所は1か所に集約してください。
playbackとplayAndRecordはどちらを選ぶべきですか?
マイクを使わないならplaybackです。要件が再生だけなのにplayAndRecordを選ぶ理由はなく、入力経路を使う段になればマイクの許可が必要になります。また、playAndRecordは既定で受話口から音が出るので、スピーカーで鳴らすにはdefaultToSpeakerの指定が追加で必要になります。
requestRecordPermissionはもう使えないのですか?
コンパイルは通りますが、AVAudioSession側のrequestRecordPermission(_:)とrecordPermissionはiOS 17で非推奨になり、公式ドキュメントはAVAudioApplicationの同等APIを使うよう案内しています。新規実装ではAVAudioApplication.requestRecordPermission(completionHandler:)とAVAudioApplication.shared.recordPermissionを使ってください。
allowBluetoothとallowBluetoothHFPはどちらを書けばよいですか?
新しく書くコードではallowBluetoothHFPです。Apple公式ドキュメントのallowBluetoothにはallowBluetoothHFPへの改称が記録されており、正式名として掲載されているのは後者です。指定できるのは入力を扱うカテゴリで、playAndRecordとrecord、それにdualRouteモードと組み合わせたmultiRouteです。
mixWithOthersとduckOthersの違いは何ですか?
mixWithOthersは他アプリの音をそのまま流したまま自分の音を重ねます。duckOthersは他アプリの音量を下げますが、公式ドキュメントによればその期間は「セッションを有効化したときに始まり、無効化したときに終わる」で、自分が音を出している区間とは一致しません。案内を流すあいだだけ下げたいなら、その都度セッションを有効化・無効化します。カーナビの案内音声のように「BGMを消さずに案内だけ聞かせたい」場面がduckOthers、ゲームの効果音のように「BGMと対等に混ぜたい」場面がmixWithOthersです。
サイレントスイッチを無視して音を鳴らすにはどうしますか?
カテゴリをplayback、playAndRecord、multiRouteのいずれかにします。公式ドキュメントはplaybackについて「このカテゴリを使うと、サイレントスイッチがサイレントに設定されていても、画面がロックされても、アプリの音声は継続する」と説明しています。逆にambientとsoloAmbientでは消音されるため、通知音やアラーム用途には使えません。