この記事はレコチョク Advent Calendar 2021の1日目の記事となります。
株式会社レコチョクでAndroidアプリ開発をしている木村です。
弊社では音楽に関する複数のサービスを提供しており、オーディオや動画などのメディア再生は中核を担う機能の一つです。
今回はマルチプラットフォームフレームワークとして定番となっているFlutterを利用してメディアを再生する方法を調べてみました。
- この記事では以下のプラットフォームを対象とします
- Android
- iOS
- 2021年11月時点の情報を元に構成しています
Flutterで提供されているパッケージ
Flutterではpub.dev というサイトで多くのパッケージ(ライブラリ)が提供されており、これらを利用することで高速に開発を行えます。
pub.devで公開されているパッケージは3つのスコアで評価されており、これらの値がパッケージを選定する際の参考になります。
- 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% |
- バックグラウンド再生するには前述のaudio_serviceプラグインを利用する必要がある
- 使い方がわかりやすく簡単に利用できる
- プレイヤーのクラス名が
just_audio
と同じなのが紛らわしい・・・
実装
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_audio
と audioplayers
ばバックグラウンド再生に対応できるようです。
オーディオ再生の調査結果
好みの部分もあるかと思いますが簡単に使うだけなら audioplayers
が組み込みやすく、
しっかりとプレイヤーを実装したい場合はプラグインも豊富な just_audio
が良さそうです。
flutter_sound
については録音機能は今回試しませんでしたがプレイヤーは若干使いにくい部分が目立ちました。
まとめ
今回は各パッケージで最低限の簡単な再生を試してみましたがいかがでしょうか?
Android/iOSそれぞれの内部実装は同じものを利用しているケースが多かったですがパッケージの使い勝手はそれぞれ特色がありました。
用途に合わせて利用する際の参考になれば幸いです。
紹介した各パッケージの簡単なサンプルをまとめました。
最後まで読んでいただきありがとうございました。
明日のレコチョク Advent Calendar 2021は2日目 murketでのSassの変数・@mixinのご紹介
となります。お楽しみに!
この記事はレコチョクのエンジニアブログの記事を転載したものとなります。