4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

レコチョクAdvent Calendar 2021

Day 1

Flutterメディア再生のすすめ

Last updated at Posted at 2021-12-02

この記事はレコチョク Advent Calendar 2021の1日目の記事となります。

株式会社レコチョクでAndroidアプリ開発をしている木村です。
弊社では音楽に関する複数のサービスを提供しており、オーディオや動画などのメディア再生は中核を担う機能の一つです。

今回はマルチプラットフォームフレームワークとして定番となっているFlutterを利用してメディアを再生する方法を調べてみました。

  • この記事では以下のプラットフォームを対象とします
    • Android
    • iOS
  • 2021年11月時点の情報を元に構成しています

Flutterで提供されているパッケージ

Flutterではpub.dev というサイトで多くのパッケージ(ライブラリ)が提供されており、これらを利用することで高速に開発を行えます。
pub.devで公開されているパッケージは3つのスコアで評価されており、これらの値がパッケージを選定する際の参考になります。

score.png

  • LIKES
    • LIKE(お気に入り)された数
  • PUB POINTS
    • 品質に関する評価ポイント
  • POPULARITY
    • パッケージの人気度

以下のリンクでは評価基準の詳細について解説されています。


動画を再生する

動画再生を実現するためのパッケージをピックアップしてみました。

video_player

LIKES PUB POINTS POPULARITY
1200+ 130 99%
  • Flutter公式の動画プレイヤーパッケージ
  • 公式サイトに導入のためのドキュメントが掲載されています

プレイヤー実装

OS Player
Android ExoPlayer
iOS AVPlayer

使い方

// コントローラを初期化する
VideoPlayerController _controller = VideoPlayerController.network(<URL>)..initialize();

// VideoPlayerウィジェットにコントローラ渡すだけで表示が可能
Center(
  child: VideoPlayer(_controller),
);

// コントローラの制御周り
_controller.play();
_controller.pause();
_controller.value.isPlaying;
_controller.dispose();

chewie

LIKES PUB POINTS POPULARITY
700+ 120 99%
  • video_player をラップしてより簡単に再生を行うことができるようにしたパッケージ
  • デフォルトで標準的なUIが実装されているため使い勝手がいい

プレイヤー実装

  • video_player に準拠

使い方

// VideoPlayerControllerを初期化する
VideoPlayerController _controller = VideoPlayerController.network(<URL>)..initialize();
// ChewieControllerを作成する
ChewieController = ChewieController(
  videoPlayerController: _videoPlayerController,
  autoPlay: true,
  looping: true,
);

// VideoPlayerウィジェットにコントローラ渡すだけで表示が可能
Center(
  child: Chewie(controller: _chewieController),
);

// コントローラの制御周り
_chewieController.play();
_chewieController.pause();
_chewieController.isPlaying;
_chewieController.dispose();

ビデオ再生の調査結果

手っ取り早く動画プレイヤーを実装するなら chewie はかなり使いやすいと感じました。
ただ、UIを独自で実装したい場合は公式パッケージの video_player を使った方が自由度は高そうです。
いずれにせよ video_player を利用するため大きく使用感は変わらないかと思います。


オーディオを再生する

オーディオ再生を実現するためのパッケージをピックアップしてみました。
動画と違って公式のオーディオプレイヤーが提供されていないためか選択肢は多い印象を受けました。

just_audio

LIKES PUB POINTS POPULARITY
1300+ 130 99%
  • 機能が豊富なオーディオプレイヤー
  • 今回ピックアップした中で一番スコアが良かったパッケージ
  • 追加機能がプラグインとして別なパッケージで提供されているため、用途に合わせて組み合わせて利用できる

プラグイン

  • audio_service
    • バックグラウンド再生・Androidの通知領域のプレイヤー・iOSのコントロールセンターなどを実現できるプラグイン
  • just_audio_background
    • audio_serviceに比べてシンプルにバックグラウンド再生やコントロールを行うことができるプラグイン
    • 2021年11月時点ではベータ版としての提供
  • audio_session
    • 電話やゲームなど他のアプリの音声の通知などを行うプラグイン
      • AndroidのAudioFocus周りの制御などが実装されている
  • just_waveform
    • 再生中のオーディオの波形を視覚化するプラグイン

プレイヤー実装

OS Player
Android ExoPlayer
iOS AVQueuePlayer

使い方

// プレイヤーのインスタンスを作成
final _player = AudioPlayer();
// オーディオソースをセット
_player.setAudioSource(AudioSource.uri(Uri.parse(<URL>)));

// プレイヤー操作
_player.play();
_player.pause();
_player.seek(Duration(position);
_player.setSpeed(1.0);
_player.stop();
_player.dispose();

audioplayers

LIKES PUB POINTS POPULARITY
1100+ 130 99%

実装

OS Player
Android MediaPlayer
iOS AVPlayer

使い方

// インスタンス作成
final _player = AudioPlayer();

// プレイヤー操作
_player.play(<URL>, position: Duration.zero);
_player.pause();

// コールバック
_player.onAudioPositionChanged.listen((Duration d) {});
_player.onPlayerStateChanged.listen((PlayerState state) {});

flutter_sound

LIKES PUB POINTS POPULARITY
600+ 130 97%
  • オーディオの再生だけではなく録音も行うことができるパッケージ
  • 使い勝手が独特で慣れないと使いづらい
  • 利用時にiOSでビルドエラーが起きたためXcodeのファイル類を修正する必要があった

実装

OS Player
Android MediaPlayer
iOS AVAudioPlayer
OS Recorder
Android MediaRecorder
iOS AVAudioRecorder

使い方

// インスタンス作成
final FlutterSoundPlayer player = FlutterSoundPlayer();

// プレイヤー操作
_boumData = await getAssetData('assets/samples.aac');
player.startPlayer(
  fromDataBuffer: _boumData,
  codec: Codec.aacADTS,
  whenFinished: () {
    setState(() {});
  }
);
player.stopPlayer();

soundpool

LIKES PUB POINTS POPULARITY
90+ 130 94%
  • AndroidのSoundPoolを参考に効果音の再生を目的として作られたパッケージ
    • 繰り返し利用する短い効果音の再生に適している
    • 音楽ファイルの利用は推奨されていない

実装

OS Player
Android SoundPool
iOS AVAudioPlayer

使い方

// インスタンス生成
Soundpool pool = Soundpool.fromOptions();

// リソースのロード
_soundId = await rootBundle.load("assets/beep.mp3").then((ByteData soundData) {
  return pool.load(soundData);
});

// 再生
pool.play(_soundId);

その他のオーディオで考慮すべきポイント

今回試すことはできなかったのですがプレイヤー周りでは他にも考慮する点が多くあるため実際の導入時には対応方針の検討が必要です。

再生方式

  • ストリーミング再生
    • URLを渡してネットワーク経由で再生する方法
    • 動画周りは特に様々な配信方式があるため利用するパッケージの対応状況に注意が必要
  • アセット再生
    • アプリ内に音源を内包して再生する方法
    • アプリ容量が大きくなるためあまり大きなファイルは内包するべきではない
  • ローカルファイル再生
    • 端末のアプリ外の領域にあるオーディオファイルを参照して再生する方法
    • 端末のストレージにアクセスすることからAndroid/iOSによる差が大きい
      • path_provider というパッケージを利用することでOS間の差異を考慮したファイルアクセスが実現できる
    • ストレージのアクセスについては権限の許可が必要だったりバージョンを重ねるごとにセキュリティ面で厳しくなるなど影響が出やすい部分なので実装する際は慎重に対応する必要がある

バックグラウンド再生

オーディオプレイヤーアプリを作る場合は必須と言っていいほど重要な機能ですが、AndroidManifest.xmlやInfo.plistへの記述が必要なためOS毎の動作確認はしっかりする必要があります。
audio_serviceを使うことで just_audioaudioplayers ばバックグラウンド再生に対応できるようです。

オーディオ再生の調査結果

好みの部分もあるかと思いますが簡単に使うだけなら audioplayers が組み込みやすく、
しっかりとプレイヤーを実装したい場合はプラグインも豊富な just_audio が良さそうです。
flutter_sound については録音機能は今回試しませんでしたがプレイヤーは若干使いにくい部分が目立ちました。


まとめ

今回は各パッケージで最低限の簡単な再生を試してみましたがいかがでしょうか?
Android/iOSそれぞれの内部実装は同じものを利用しているケースが多かったですがパッケージの使い勝手はそれぞれ特色がありました。
用途に合わせて利用する際の参考になれば幸いです。

紹介した各パッケージの簡単なサンプルをまとめました。


最後まで読んでいただきありがとうございました。
明日のレコチョク Advent Calendar 2021は2日目 murketでのSassの変数・@mixinのご紹介 となります。お楽しみに!


この記事はレコチョクのエンジニアブログの記事を転載したものとなります。

4
3
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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?