PR

【Flutter】audioplayersで低遅延で再生する方法

Flutter audioplayersを低遅延で再生 ソフトウェア

Flutterの音声ファイル再生パッケージ、audioplayersは軽量で使い勝手が良いパッケージです。

音楽再生に特化したアプリに使うには機能不足かもしれませんが、簡単なBGMや効果音の再生を行う場合には設定の手間が少なく便利に扱えます。

audioplayers | Flutter package
A Flutter plugin to play multiple audio files simultaneously

開発中、効果音を高速に連続再生したい場面があり、通常の使い方では遅延が気になったため行った対策を紹介します。

確認環境

  • Flutter 3.22.3
  • audioplayers 6.0.0

setPlayerMode()の設定

playerを低遅延モードに設定することができます。

Dart
final _audioPlayer = AudioPlayer();
_audioPlayer.setPlayerMode(PlayerMode.lowLatency);

setSource()とresume()でファイルを事前読み込みする

基本的な再生方法としては以下のようにplay()メソッドにファイルへのパスを指定すればOKです。ただしこの方法はplay()メソッドを呼ぶ時にソースが決定されるため、再生までに若干の遅延が生じます。

Dart
final _audioPlayer = AudioPlayer();
_audioPlayer.play(AssetSource('ファイルへのパス'));  // この時点でソースが決定し、読み込みが開始される

それを避けるためには事前にファイルを読み込むようにします。

Dart
final _audioPlayer = AudioPlayer();

// initState()内等で以下の事前読み込みを行っておく
_audioPlayer.setSource(AssetSource('ファイルへのパス'));

// 再生が必要な箇所でresume()を呼ぶことで低遅延で再生できる
_audioPlayer.resume();

setSource()メソッドによりファイルを事前に読み込むことができます。このコードはあくまで例なので連続して書いていますが、実際にはファイルが固定であれば事前読み込みはinitState()等で行うのが良いでしょう。

setSource()で読み込んだあとはresume()メソッドで再生できます。

動的に再生するファイルが変化する場合は事前読み込みのタイミングが難しいこともあるかもしれません。使う音声ファイル数が少ない場合、以下のようにファイル数分playerインスタンスを作りそれぞれにファイルをセットして、1ファイル1インスタンスとして用意する方法も考えられます。

Dart
// 音声ファイル毎にインスタンスを作成する
final _audioPlayer1 = AudioPlayer();
final _audioPlayer2 = AudioPlayer();

_audioPlayer1.setSource(AssetSource('ファイルへのパス'));
_audioPlayer2.setSource(AssetSource('ファイルへのパス'));

極端にインスタンスを多く作ることは避けるべきでしょうが、リソースが足りていれば検討できる実装です。

必要な箇所でstop()メソッドを呼ぶ

効果音を連続して鳴らすなどの場合、前の再生が終わらないうちに次の再生を行おうとすると音が途切れてしまう場合があるため、再生中であれば停止してから再生する処理を入れます。

Dart
void _play() async {
  if (_audioPlayer.state == PlayerState.playing) {
    await _audioPlayer.stop();  // stop()が完了する前にresume()が呼ばれないようawaitする
  }
    _audioPlayer.resume();
}

audioplayersのメソッドのほとんどが戻り値がFuture型の非同期処理となっているため、このようにstop()→resume()など連続で処理する場合には、適切にawaitを使わないと意図通り動かない場合があるので注意してください。

コメント

タイトルとURLをコピーしました