【Flutter】超便利な動画(video)再生ウィジェットChewie

#概要
Flutterで動画プレイヤーを実装したい時、ググってまず出てくるのがvideo_playerプラグインだと思います。（https://pub.dev/packages/video_player)
こちらでも実装は可能なのですが、再生や停止、インジゲーターの表示などもControllerを用いて自身で管理しなければいけないので少々面倒です。そこで、これらを自動的に構成してくれる**chewieウィジェット**というものをご紹介したいと思います。ちなみにvideo_playerとは完全に別物ではなく、chewieもvideo_playerをベースとしています。 (https://pub.dev/packages/chewie)

ちなみになぜchewie（チューインガム）というのかはわかりません（笑）

# 前提条件


```
[✓] Flutter (Channel stable, 1.22.2, on Mac OS X 10.15.7 19H2, locale ja-JP)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 12.0.1)
[✓] Android Studio (version 4.0)
[✓] Connected device (1 available)

• No issues found!
```

#手順
##0.完成形

シンプルに画面中央にビデオプレイヤーを配置する画面を作っていきます。
動画のソースはgithubに公開されているものを使用しています。
<img width="300" alt="Screenshot_1603861186.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/726987/80ba7b9d-38d1-37f8-81ed-a073fdfc4da2.png">

##1.パッケージの導入
pubspec.yamlにchewieとvideo_playerのパッケージを追加します。
記事作成時（2020年10月27日）時点のchewieの最新版は**0.9.10**ですが、依存関係となっているvideo_playerは**0.10.0**までしか対応していませんので一旦は以下のバージョンにしましょう。

```yaml:pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  chewie: ^0.9.10
  video_player: ^0.10.0
```
記述したら、Pub getを実行。

##2.パッケージのインポート
以下の三つをインポートしてください。

```dart:main.dart
import 'package:chewie/chewie.dart';
import 'package:chewie/src/chewie_player.dart';
import 'package:video_player/video_player.dart';
```

##3.コントローラーもろもろ

概要でも記載した通り、ChewieControllerはVideoPlayerControllerと依存関係にあるので、Stateクラス内にVideoPlayerControllerとChewieControllerの両方を初期化します。

```dart:main.dart
class _MyHomePageState extends State<MyHomePage> {
//コントローラーの定義
  VideoPlayerController _videoPlayerController;
  ChewieController _chewieController;

//初期化
  @override
  void initState() {
    super.initState();
    _videoPlayerController = VideoPlayerController.network(
        'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4');
    _chewieController = ChewieController(
      videoPlayerController: _videoPlayerController,
      aspectRatio: 3 / 2,  //アスペクト比
      autoPlay: false,  //自動再生
      looping: true,  //繰り返し再生

      // 以下はオプション（なくてもOK）
      showControls: false,  //コントロールバーの表示（デフォルトではtrue）
      materialProgressColors: ChewieProgressColors(
        playedColor: Colors.red,  //再生済み部分（左側）の色
        handleColor: Colors.blue,  //再生地点を示すハンドルの色
        backgroundColor: Colors.grey,  //再生前のプログレスバーの色
        bufferedColor: Colors.lightGreen,  //未再生部分（右側）の色
      ),
      placeholder: Container(
        color: Colors.grey,  //動画読み込み前の背景色
      ),
      autoInitialize: true,  //widget呼び出し時に動画を読み込むかどうか
    );
  }
//コントローラーの破棄
  @override
  void dispose() {
    _videoPlayerController.dispose();
    _chewieController.dispose();
    super.dispose();
  }
//・・・

```

##4.画面表示

超シンプルですね！

```dart:main.dart

child: Chewie(
   controller: _chewieController,
),
  
```

##5.ソースコード全体

全体のコードは以下のようになります。

```dart:main.dart

import 'package:flutter/material.dart';
import 'package:chewie/chewie.dart';
import 'package:chewie/src/chewie_player.dart';
import 'package:video_player/video_player.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Chewie Sample',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Chewie Sample'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  VideoPlayerController _videoPlayerController;
  ChewieController _chewieController;

  @override
  void initState() {
    super.initState();
    _videoPlayerController = VideoPlayerController.network(
        'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4');
    _chewieController = ChewieController(
      videoPlayerController: _videoPlayerController,
      aspectRatio: 3 / 2,
      autoPlay: false,
      looping: true,
      // Try playing around with some of these other options:

      //showControls: false,
      materialProgressColors: ChewieProgressColors(
        playedColor: Colors.red,
        handleColor: Colors.blue,
        backgroundColor: Colors.grey,
        bufferedColor: Colors.lightGreen,
      ),
      placeholder: Container(
        color: Colors.grey,
      ),
      autoInitialize: true,
    );
  }
  @override
  void dispose() {
    _videoPlayerController.dispose();
    _chewieController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Expanded(
              child: Center(
                child: Chewie(
                  controller: _chewieController,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

```

##注意
現状、iOSエミュレータでは正常に動作しないようです。実際に試したところ、Controllerを定義しているのにもかかわらず、
***controller != null, 'You must provide a chewie controller'***
みたいなエラーが表示されます。Androidエミュレータや実機（iOS含め）では正常に動作しますのでそちらで試してみてください。


#さいごに
video_playerのみだと、ステートの管理が面倒なところをchewieがいい感じに全部やってくれます。いろいろ自分でカスタマイズしたいときはvideo_playerが良いかと思いますが、とりあえず動画が見れればいい！という場合はchewieで十分だと思います。
Flutterはまだまだ日本語の情報が少ないため、今後も役に立つ情報を発信できたらと思います！

#参考サイト
https://pub.dev/packages/video_player
https://pub.dev/packages/chewie