Flutterの動画再生用ライブラリmedia_kitを触ってみた

# 目 的
* Flutterでローカルストレージの複数の画像、動画ファイルを表示、再生したい。
* ___Linuxアプリでビルドしたい。___
# なぜmedia_kitなのか
Flutterの動画再生ライブラリで有名なのはこの２つです。
* [video_player](https://pub.dev/packages/video_player) 
* [chewie](https://pub.dev/packages/chewie)
参考サイト：[Flutter Gems Top Flutter Video packages](https://fluttergems.dev/video/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287677/cec22476-b6fe-ec56-9478-29eb3ece6394.png)

ところが、この２つのライブラリ、Linuxはサポートされていません😭

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287677/dbb9d634-48a6-895a-2083-257abef4e261.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287677/cf4650aa-99ea-4894-d372-9d23e6e0ddc2.png)

そこで、ライブラリについて調査したところ、media_kitがみつかりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287677/dcb57b35-fcc7-c07d-c6f2-504001598f7c.png)
まさかのフルプラットホームサポートです。
ぎりぎりバージョンは1以上みたいです。
今回はmedia_kitが使えるかどうか、試してみました。

# 実行環境
* OS: Ubuntu 22.04LTS
* Flutter: 3.10.4
* Dart: 3.0.3
    * media_kit: 1.0.2
# 実際にやってみた
最初に[必要なパッケージ](https://pub.dev/packages/media_kit#gnulinux-2)をインストールします。

```bash
$ sudo apt install libmpv-dev mpv

```
次に[Example](https://pub.dev/packages/media_kit/example)を動かします。
適当にflutter createして、プロジェクトを作成します。

dependenciesにmedia_kit関連のライブラリを追記します。
```yaml:pubsec.yml
dependencies:
  media_kit: ^1.0.2
  media_kit_video: ^1.0.2
  media_kit_libs_linux: ^1.0.2 # プラットフォームに合わせて追加
```
再生できました。
gifなので伝わりませんが、実際は音が出ています。
![samle_linux.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287677/b31a9733-13bd-915b-c00e-38131f0602b9.gif)



今回はローカルストレージの動画、静止画を再生したいので、少しコードを変えていきます。

確認用のフリーのコンテンツをダウンロードしました。
動画は[HYBRID CREATIVE MOVIE サクラ](https://www.home-movie.biz/free_movie.html)さんの、「飛行機・曲技飛行・編隊（2）」動画をダウンロードしました。
静止画は、いらすとやの[艦隊のイラスト](https://www.irasutoya.com/2014/06/blog-post_10.html)をダウンロードしました。

Flutterのプロジェクト直下にassetsフォルダを作成し、ダウンロードしたファイルを配置します。

```bash
$ cd (path_to_flutter_project)
$ ls assets         
mov_hts-samp010.mp4  senkan_kantai.png
```
pubsec.ymlに、assetsを登録します。
```yaml:pubsec.yml
assets:
  - assets/ #assets配下のファイルを全て登録 
```


サンプルの、MyScreenState内のinitState()を書き換えて、プレイリストを作成します。
assets配下のファイルを登録します。
```dart:main.dart
  @override
  void initState() {
    super.initState();
    final playable = Playlist(
      [Media('assets/mov_hts-samp010.mp4'), Media('assets/senkan_kantai.png')],
    );
    player.open(playable);
  }
```

再生できました。
航空機の編隊飛行の動画から、艦隊の静止画に切り替わりました。
![playable_example.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287677/792617ea-ea7c-109d-8f0f-8d2d45919453.gif)

初期状態ではPlaylistModeがnoneに設定されており、最後まで再生されると、自動で止まります。
PlaylistModeは以下の３つあるので、必要に応じて変更が必要です。
1. PlaylistMode.none: End playback once end of the playlist is reached.
1. PlaylistMode.single: Indefinitely loop over the currently playing file in the playlist.
1. PlaylistMode.loop: Loop over the playlist & restart it from beginning once end is reached.
公式ドキュメントの[Loop or repeat](https://pub.dev/packages/media_kit#loop-or-repeat)に記載があります。

# 気づき事項
* 静止画の背景透過はされないようです。
    * 上記のgifを見ての通り、灰色の格子模様が表示されます。
* 静止画をプレイリストに入れると、3秒程度で次のMediaに切り替わります。
    * この辺りを制御したい場合は[Handle playback events](https://pub.dev/packages/media_kit#handle-playback-events)を参考にして、イベントを制御する必要がありそうです。
* player.jump(int index)を呼ぶことで、特定のMediaに切り替えることができます。
* controller（再生、音量操作など）の有効・無効は切り替えられないようです。[AbsorbPointer](https://api.flutter.dev/flutter/widgets/AbsorbPointer-class.html)を使って、クリック操作を禁止するしかなさそうです。

# まとめ
* media_kitライブラリを使用し、静止画及び動画を表示することができました。
* (png透過できない問題を除き、)特に不自由なくローカルストレージの画像、動画ファイルを表示、再生ができました。
* 紙芝居的なものならすぐに作れそうです。