0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

記事3:Flutterで音声再生時に他アプリの音楽が止まる問題をどう解決したか

Last updated at Posted at 2025-11-20

ORPHE TRACKで発生していた問題

ORPHE TRACK で音声(効果音・TTS・動画音声など)を再生すると、

Spotify や Apple Music などの音楽アプリが停止してしまう問題がありました。

ランニングアプリでは

  • 音楽はそのまま
  • フィードバック音声だけ重ねて再生

という UX が求められるため、
この現象は実用上大きな課題でした。


最初のアプローチ:audio_session を使って競合を制御した

まずは audio_session を使って、

OS の「音声セッション」そのものを適切に設定しようとしました。

audio_session は

  • 音声ポリシー

  • 他アプリとの優先度

  • 再生の扱い

    などを一元的に設定できる便利なライブラリです。

しかし実際には……


問題:audioplayers だけ競合を解消できなかった

audio_session の設定を適用しても、
audioplayers のみ他アプリの音楽を止めてしまう挙動が残りました。


競合の流れ(問題状況)

+---------------------------+
| 他アプリ:音楽再生中      |
+-------------+-------------+
              |
              v
+---------------------------+
| ORPHE TRACK:音声再生      |
+-------------+-------------+
              |
              v
+---------------------------+
| audio_session 設定を適用  |
| → video_player はOK       |
| → flutter_tts もOK        |
| → audioplayers がNG       |
|   (音楽アプリが停止)     |
+---------------------------+


最終アプローチ:各ライブラリに用意された「競合設定」を直接使う方針へ

試行錯誤した結果、

“audio_session だけに依存せず、ライブラリごとの競合設定を直接調整する”

という方式が最も安定しました。

Flutter の音声関連ライブラリは

OSレベルの音声セッション制御を、それぞれ独自にラップしているため、

  • まとめて統一制御する

    よりも

  • 各ライブラリの公式 API で明示的に設定する

ほうが確実に動作します。


具体的に適用した設定

video_player(mixWithOthers)

VideoPlayerController.asset(
  theme.asset.videos.logo.path,
  videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
);

mixWithOthers: true

→ 他アプリの音声を止めず、自分の音声を重ねる


audioplayers(duckOthers)

await audioPlayer.play(
  AssetSource(theme.asset.sounds.countDownStart.path),
  volume: 1.0,
  ctx: AudioContext(
    iOS: AudioContextIOS(
      options: {AVAudioSessionOptions.duckOthers},
    ),
    android: AudioContextAndroid(
      audioFocus: AndroidAudioFocus.gainTransientMayDuck,
    ),
  ),
);

duckOthers

→ 他アプリの音楽の音量を一時的に下げる(ducking)

→ 完全停止はしない


flutter_tts(AudioSessionConfiguration.speech)

final session = await AudioSession.instance;
await session.configure(
  AudioSessionConfiguration.speech().copyWith(
    avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.duckOthers,
    androidAudioFocusGainType:
        AndroidAudioFocusGainType.gainTransientMayDuck,
    androidAudioAttributes: const AndroidAudioAttributes(
      contentType: AndroidAudioContentType.speech,
      usage: AndroidAudioUsage.assistanceAccessibility,
    ),
    androidWillPauseWhenDucked: false,
  ),
);

TTSは OS の音声セッション干渉が強いため、

speech() ベースで duckOthers に寄せるのが最も安定。


最終的な競合解消フロー

+-----------------------------------------+
|   ORPHE TRACK:音声再生要求             |
+-------------------------+---------------+
                          |
                          v
+-----------------------------------------+
| audio_session で基礎設定                |
| しかし一部ライブラリは制御しきれない    |
+-------------------------+---------------+
                          |
                          v
+-----------------------------------------+
| ライブラリごとに競合設定を適用          |
| - video_player: mixWithOthers           |
| - audioplayers: duckOthers              |
| - flutter_tts: speech() + duckOthers    |
+-------------------------+---------------+
                          |
                          v
+-----------------------------------------+
|   結果                                   |
| - 音楽アプリは停止しない                |
| - ORPHE TRACK の音声だけ重ねられる      |
+-----------------------------------------+


なぜこの構成に落ち着いたか

  • Flutterの音声ライブラリは “音声セッションの扱い” が個別に実装されている
  • そのため「完全統一」よりも、「ケースごとに最適化」のほうが安定
  • 特に audioplayers は OS の音声フォーカス処理の影響を受けやすい

結果として、

ライブラリ別に公式APIで競合設定を明示することで、

最も期待通りの挙動になりました。


記事3のまとめ

  • ORPHE TRACK では音声再生時に音楽アプリが止まる問題が発生した

  • 最初は audio_session による統合制御を試したが、

    audioplayers だけ期待通りに競合を解消できなかった

  • 最終的には、video_player / audioplayers / flutter_tts の

    各ライブラリが持つ公式競合設定を直接使用する方針を採用

  • 結果として、

    • 音楽アプリを止めず

    • ORPHE TRACK の音声だけを安全に重ねられる

      という動作が実現した

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?