📱

【Expo / AdMob】インタースティシャル広告の後に音が出なくなる iOS バグの原因と解決策

に公開

はじめに

React Native + Expo で構成した語学学習アプリのクイズ終了後に、react-native-google-mobile-ads を使ったインタースティシャル広告を実装しました。

基本的なインタースティシャル広告の実装は割愛しますが、iOS動画広告後にアプリ内の音声が完全に無音になるバグに遭遇しました。本記事ではその原因と対処法をまとめます!

技術スタック

  • Expo SDK(Bare Workflow)
  • react-native-google-mobile-ads
  • TypeScript

症状

動画広告を閉じた後、アプリ内のリスニング音声・単語読み上げ音声が完全に無音になります。

原因

動画広告は iOS の AVAudioSession を占有します。広告終了後にアプリ側でセッションを再アクティブ化しないと、音声再生ができなくなります。

動画広告とUXの考慮

インタースティシャル広告には動画フォーマットが配信されることがあります。動画広告は収益性が高い一方、学習中に突然広告の音声が流れることでユーザーが驚いてアプリを離脱するリスクがあります...

学習アプリとしてのUXを優先したいため、今回は AdMob の管理画面で動画広告フォーマットを無効化する設定を入れています。

もともと動画広告はONの状態で運用していましたが、UXへの影響を考慮して後からOFFに変更しました。しかし設定の反映には数時間〜数日のラグがあり、その間も動画広告が配信され続けていました。実際にこのラグが原因で音声バグを踏んだため、管理画面の設定に関わらずコード側でも音声セッションの復元処理を常時入れておくことを推奨します。

対処法

AdEventType.CLOSED のハンドラ内で expo-audiosetAudioModeAsync を呼び出してセッションを復元します。

const unsubClose = interstitial.addAdEventListener(AdEventType.CLOSED, async () => {
  // iOS: 動画広告が占有した AVAudioSession をアプリ側に戻す。
  // これがないと広告終了後にリスニング・単語音声が再生されなくなる。
  // AdMob で動画広告を無効化していても念のため残す
  //(設定反映ラグ・配信ロジックの考慮)。
  if (Platform.OS === 'ios') {
    const { setAudioModeAsync } = require('expo-audio')
    await setAudioModeAsync({ playsInSilentMode: true })
  }
  isLoadedRef.current = false
  onClosedRef.current?.()
  onClosedRef.current = null
})

まとめ

ポイント 対応
iOS動画広告後の無音バグ CLOSED イベントで setAudioModeAsync を呼び出し
AdMob設定OFFでも油断しない 設定反映ラグを考慮してコード側でも常時対処

音声系の機能を持つアプリで動画広告を使う場合は、iOS の AVAudioSession の挙動に注意が必要です。
同じ問題で詰まっている方の参考になれば幸いです!

Discussion