FlutterでもBGMや効果音を再生したいなと思い、
いろいろ調べてみたときの備忘録(*´ω`*)
参考サイトを見てみると、いろいろ違いがありそうだけど、
公式のCasual Games Toolkitで紹介されていたaudioplayersを試してみる。
インストール
公式ドキュメントはGitHubのmdファイルっぽいので、
このあたりを見ながら、進める感じ。
- bluefireteam/audioplayers: A Flutter package to play multiple audio files simultaneously (Android/iOS/web/Linux/Windows/macOS)
- Getting Started · bluefireteam/audioplayers
- サンプル
$ fvm flutter pub add audioplayers
基本的な使い方
// ** playerを作成 final player = AudioPlayer(); // ** 音声ファイルの設定 await player.setSource(AssetSource('sounds/coin.wav')); await player.setSourceUrl(url); await player.play(DeviceFileSource(localFile)); // ** 再生などの操作 await player.resume(); await player.seek(Duration(milliseconds: 1200)); await player.pause(); await player.stop(); await player.dispose(); // ** 音量などの設定 // 音量 await player.setVolume(1.0); // 0.0〜1.0 // 左右のバランス await player.setBalance(0.0); // -1.0〜1.0 // 再生速度 await player.setPlaybackRate(1.0); // プレイバック時の動作 await player.setReleaseMode(ReleaseMode.stop); // 停止 await player.setReleaseMode(ReleaseMode.release); // リソースの開放 await player.setReleaseMode(ReleaseMode.loop); // ループ再生 // ** PlayerMode // BGMなど長いメディアやストリーム再生向け(default) await player.setPlayerMode(PlayerMode.mediaPlayer); // 効果音など短い音声ファイル向け。UIの描画への影響が軽減されるらしい await player.setPlayerMode(PlayerMode.lowLatency);
stop()
とpause()
の違いは、
- stopの場合は、最初から再生される
- pauseの場合は、途中から再生される
Tips
小ネタいろいろ
複数の音を同時に再生する
1playerで1音声なので、同時に再生したい数だけ
playerインスタンスを用意すればOK
// BGM用 final bgmPlayer = AudioPlayer(playerId: "bgm"); // 効果音用(sound effects / SE) final sfxPlayer = AudioPlayer(playerId: "sfx");
Super Dashだと、BGMで1つ、効果音は種類ごとにplayerを作成してる。
マナーモードでは音がならないようにする
デフォルトだと、マナーモードでも音がなるので、
マナーモードだと無音になるようにするための設定が必要。
// AudioContextConfigでマナーモードの尊重をする設定に const audioContext = AudioContextConfig(respectSilence: true).build(); // or 個別で指定する const audioContext = AudioContext( iOS: AudioContextIOS( category: AVAudioSessionCategory.ambient, // .palybackから変更 ), android: AudioContextAndroid(), // Androidでは該当する設定なし ); // 反映 await AudioPlayer.global.setAudioContext(audioContext);
画面を閉じたら停止する
アプリを終了せずに、アプリを閉じると、
バックグラウンドで動作し続けるため、
音声だけ流れる状態が起きる。
AppLifecycleState
を参照してコントロールが必要
final AppLifecycleState state = // ... switch (_lifecycleNotifier!.value) { // アプリを閉じる場合 case AppLifecycleState.paused: case AppLifecycleState.detached: // TODO: すべての音声を停止する // アプリを表示する場合 case AppLifecycleState.resumed: // TODO: 音声を開始/再開する // 閉じる途中の状態は、何もしない case AppLifecycleState.inactive: case AppLifecycleState.hidden: break; }
事前読み込み/キャッシュに保存
効果音など、すぐに使いたい音声の場合、
事前に読み込んでおくことができる。
await AudioCache.instance.loadAll([ "sound/xxx.mp3", "sound/yyy.wav", ]);
連打時の効果音
再生中に再度play
を実行しても、同じ音声だと再生されない。
なので、再生中かどうかを見て、処理を分けるとよい
if (player.state == PlayerState.playing) { // 再生中なら最初の位置に戻す await player.seek(Duration.zero); } else { // それ以外の場合は、再生する await player.play(AssetSource("xxx.mp3")); }
以上!! これでなんかいろいろできそう(*´ω`*)
参考にしたサイト様
- Flutterのオーディオファイルのループ再生を比較してみた ※2023/10/24更新 #iOS - Qiita
audioplayersのドキュメントを読むと、ループ再生で途切れることがあるのでjust_audioやocarinaもあるよ的なことが書かれていた
- Flutterメディア再生のすすめ | レコチョクのエンジニアブログ
- Flutterで音再生 効果音再生
- (1) Xユーザーのグウジさん: 「Flutterの音声再生パッケージについて。 audioplayers: 一番人気だが最近はフリーズの原因となる不具合あり? assets_audio_player: iOS版で音がしっかり鳴らないことがよくある。 just_audio: 音声再生に問題はないが、iOS版ではInfo.plistにマイクに関する設定をしないと配信できない。」 / X
- [Flutter]audioplayersやjust_audioでマナーモードにしても音楽がなってしまう #Flutter - Qiita
- 【Flutter】AudioPlayersでiPhoneサイレントモード時に音声停止