【Flutter】Flutterで動画ウィジェット(video_player)を再生し完了したらリプレイボタンを表示する実装の紹介

もくじ

こんにちは。スマホアプリをメインに開発しているロッキーカナイです。

今回紹介するのは前回の続編ということで、まだご覧でないかたは、【Flutter】Flutterで動画ウィジェット(video_player)を使用するをご確認ください。

前回作成した動画を再生するウィジェット、MoviePlayerWidgetに、webなんかでよくある再生終了したらplayボタンを表示して、リプレイ再生可能にする実装を紹介しようと思います。

実装すること

リプレイ再生を実装するにあたって行うことは以下の通りです。

  1. イベント監視リスナーの実装
  2. 再生完了状態を保持する
  3. 状態に応じてリプレイボタンの表示

MoviePlayerWidgetの修正

前回実装したMoviePlayerWidgetをベースに下記の通り修正をします。

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

/*
 * 動画ウィジェット
 */
class MoviePlayerWidget extends StatefulWidget {

  String movieURL; // 動画URL
  MoviePlayerWidget(this.movieURL) : super();

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


/*
 * ステート
 */
class _MoviePlayerWidgetState extends State<MoviePlayerWidget> {

  // コントローラー
  VideoPlayerController _controller;
  VoidCallback _listener;
  bool _isPlayComplete = false;

  @override
  void initState() {

    // 動画プレーヤーの初期化
    _controller = VideoPlayerController.network(
        widget.movieURL
    )..initialize().then((_) {

      setState(() {});

      _controller.play();

      // イベント監視
      _listener = () {
        if (!_controller.value.isPlaying) {

          // 再生完了
          setState(() {
            _isPlayComplete = true;
          });
        }
      };
      _controller.addListener(_listener);
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    if (_controller == null) return Container();

    if (_controller.value.initialized) {

      /*
       * 動画
       */
      return Container(
        child: AspectRatio(
          aspectRatio: _controller.value.aspectRatio,
          child: Stack(
            children: <Widget>[

              /*
               * 動画プレーヤー
               */
              VideoPlayer(_controller),

              _isPlayComplete ? InkWell(
                onTap: (() {

                  setState(() {
                    _isPlayComplete = false;
                  });
                  _controller.seekTo(Duration.zero);
                  _controller.play();

                }),
                child: Center(
                  child: Icon(
                    Icons.play_circle_outline,
                    color: Colors.white,
                    size: 50.0,
                  ),
                ),
              )
                  : Container()
            ],
          ),
        ),
      );
    } else {

      /*
       * インジケータを表示
       */
      return Container(
        height: 150.0,
        child: Center(
          child: CircularProgressIndicator(
            valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
          ),
        ),
      );
    }
  }

  @override
  void dispose() {
    _controller.removeListener(_listener);
    _controller.dispose();
    super.dispose();
  }
}

_controller.addListener(_listener);で_controller.value.isPlayingの状態を判断して、再生が完了したら、メンバ変数_isPlayCompleteをtrueにします。

build()で、_isPlayCompleteがfalseだと動画ウィジェットの生成、trueだとリプレイボタンの表示をしております。

呼び出し

import 'package:test_project/MoviePlayerWidget.dart';

...

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Container(
          child: MoviePlayerWidget(
            "http://egaoinc.xsrv.jp/egao-blog/movie/sample-movie.mp4",
          ),
        )
      ),
    );
  }

...

これは以前と変更ありません。

動画でなく申し訳ないのですが、動画が再生後以下のように再生ボタンが表示され、タップするとリプレイします。

まとめ

今回は動画再生完了後リプレイ再生可能にする実装を紹介しました。

これで動画再生としてはいっぱしの機能になったかと思います。

次回は未定です。なにを書こうかしら。

関連する記事

  • 映画公開予定通知botを作ってみた!

  • 【Flutter】通信ライブラリRetrofit(Dio)がいい感じ

  • 【Flutter】Riverpod+StateNotifier+freezedで作ろう

  • ChatGPTくんと仲良くなって手羽元の甘辛煮を作るまで

もっと見る