【Flutter】AudioCache で BGM を再生するときに iPhone だとマナーモードを貫通してくる
AudioCache とは
AudioCache
とは Flutter 製のオーディオフレームワーク audioplayers
で音声再生を行うときに使うオブジェクトです。
詳しくはこちらの公式ページをご覧ください。
今回は普通に使う話はスルーさせて頂きます🙇♂️
iPhone だとマナーモードでも再生される
本題です。 AudioCahce
で BGM をそのまま再生するとマナーモード(サイレントスイッチをオン)にしても音楽が再生されてしまいます。
AudioCache _bgmCache = AudioCache(fixedPlayer: new AudioPlayer());
_bgmCache.loop(sound.filePath, volume: volume); // マナーモード貫通.
結論を先に書くと isNotification
を true にすればマナーモードではサイレントになります。
AudioCache _bgmCache = AudioCache(fixedPlayer: new AudioPlayer());
_bgmCache.loop(sound.filePath, volume: volume, isNotification: true);
めでたしめでたし(╹◡╹)
なんでなん?
そもそも iPhone でマナーモードはなぜ貫通するのかというと AVAudioSession.Category
で playback
が設定されているからです。
audioplayers
パッケージでは SwiftAudioplayersPlugin#configureAudioSession
で設定されているようです。
private func configureAudioSession(
category: AVAudioSession.Category? = nil,
options: AVAudioSession.CategoryOptions = [],
active: Bool? = nil
) {
do {
let session = AVAudioSession.sharedInstance()
if let category = category {
try session.setCategory(category, options: options)
}
if let active = active {
try session.setActive(active)
}
} catch {
log("Error configuring audio session: %@", error)
}
}
さらに configureAudioSession
は updateCategory
で呼ばれております。
func updateCategory(
recordingActive: Bool,
isNotification: Bool,
playingRoute: String,
duckAudio: Bool
) {
#if os(iOS)
// When using AVAudioSessionCategoryPlayback, by default, this implies that your app’s audio is nonmixable—activating your session
// will interrupt any other audio sessions which are also nonmixable. AVAudioSessionCategoryPlayback should not be used with
// AVAudioSessionCategoryOptionMixWithOthers option. If so, it prevents infoCenter from working correctly.
let category = (playingRoute == "earpiece" || recordingActive) ? AVAudioSession.Category.playAndRecord : (
isNotification ? AVAudioSession.Category.ambient : AVAudioSession.Category.playback
)
let options = isNotification || duckAudio ? AVAudioSession.CategoryOptions.mixWithOthers : []
configureAudioSession(category: category, options: options)
if isNotification {
UIApplication.shared.beginReceivingRemoteControlEvents()
}
#endif
}
以下の部分が非常に気になります。というか答えです。
let category = (playingRoute == "earpiece" || recordingActive) ? AVAudioSession.Category.playAndRecord : (
isNotification ? AVAudioSession.Category.ambient : AVAudioSession.Category.playback
)
AVAudioSession.Category.playback
を設定しているとバックグランドでも再生し続け、かつさサイレントモードでも再生されます。
参考:https://qiita.com/pandapanda/items/1c87fa0115a8bcba51a6#マナーモード下で音を鳴らす
なので、 isNotification
を true にして裏で ambient
を指定させる感じですね。
アプリの都合によっては soloAmbient
にするようにしてもいいかもしれません。
てか、普通デフォルトではマナーモード貫通して欲しくないでしょ・・・と思ったのは私だけでしょうか?w
皆さんのお役に立てると幸いです(╹◡╹)
Discussion