Flutterの音声ファイル再生パッケージ、audioplayersは軽量で使い勝手が良いパッケージです。
音楽再生に特化したアプリに使うには機能不足かもしれませんが、簡単なBGMや効果音の再生を行う場合には設定の手間が少なく便利に扱えます。
開発中、効果音を高速に連続再生したい場面があり、通常の使い方では遅延が気になったため行った対策を紹介します。
確認環境
- Flutter 3.22.3
- audioplayers 6.0.0
setPlayerMode()の設定
playerを低遅延モードに設定することができます。
final _audioPlayer = AudioPlayer();
_audioPlayer.setPlayerMode(PlayerMode.lowLatency);
setSource()とresume()でファイルを事前読み込みする
通常利用する分には、以下のようにplay()メソッドにファイルへのパスを指定すればOKです。ただplay()メソッドを呼ぶ時にソースが決定されるため、再生までに若干の遅延が生じます。
final _audioPlayer = AudioPlayer();
_audioPlayer.play(AssetSource('ファイルへのパス'));
それを避けるためには事前にファイルを読み込むようにします。
final _audioPlayer = AudioPlayer();
// initState()等で以下の事前読み込みを行っておく
_audioPlayer.setSource(AssetSource('ファイルへのパス'));
// 再生が必要な箇所でresume()を行うことで低遅延で再生できる
_audioPlayer.resume();
setSource()メソッドによりファイルを事前に読み込むことができます。このコードはあくまで例なので連続して書いてしまっていますが、実際にはファイルが固定であれば事前読み込みはinitState()等で行うのが良いでしょう。
動的に再生するファイルが変化する場合は読み込みのタイミングが難しいこともあるかもしれません。使う音声ファイル数が少ない場合は、ファイル数分playerインスタンスを作りそれぞれにファイルをセットして、1ファイル1インスタンスとして用意する方法も考えられます。
setSource()で読み込んだあとはresume()メソッドで再生できます。
必要な箇所でstop()メソッドを呼ぶ
効果音を連続して鳴らすなどの場合、前の再生が終わらないうちに次の再生を行おうとすると音が途切れてしまう場合があるため、再生中であれば停止してから再生する処理を入れます。
void _play() async {
if (_audioPlayer.state == PlayerState.playing) {
await _audioPlayer.stop(); // stop()が完了する前にresume()が呼ばれないようawaitする
}
_audioPlayer.resume();
}
audioplayersのメソッドのほとんどが戻り値がFuture型の非同期処理となっているため、このようにstop()→resume()など連続で処理する場合には、適切にawaitを使わないと意図通り動かない場合があるので注意してください。
コメント