📽️

【Flutter】「video_player」で動画を全画面表示させる

2023/07/03に公開
3

概要

全画面で動画を表示させるため、video_playerパッケージを使ってみたメモ

https://pub.dev/packages/video_player

実装

1.「video_player」パッケージをインポート

※2023/07/02時点の最新バージョン

pabspec.yaml
video_player: ^2.7.0

2.表示するmp4ファイルを追加

  • ファイルを追加
    asset/video/video.mp4

  • yamlに追記

pabspec.yaml
  assets:
    - assets/video/

3.コード

video_page.dart
class VideoPage extends StatefulWidget {
  const VideoPage({super.key});

  
  State<VideoPage> createState() => _VideoPageState();
}

class _VideoPageState extends State<VideoPage> {
  late VideoPlayerController _controller;

  
  void initState() {
    super.initState();
    _controller = VideoPlayerController.asset('assets/video/video.mp4')
      ..addListener(() => setState(() {}))
      ..setLooping(true)
      ..initialize().then((_) => setState(() {}))
      ..play();
  }

  
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: SizedBox.expand(
        child: FittedBox(
          fit: BoxFit.cover,
          child: SizedBox(
            width: _controller.value.size.width,
            height: _controller.value.size.height,
            child: VideoPlayer(_controller),
          ),
        ),
      ),
    );
  }
}

結果

実装メモ

表示サイズ

全画面表示かつ、動画が引き延ばされたりしないようアスペクト比を維持させたかったので、
VideoPlayerをラップしてFittedBoxでBoxFit.coverしましたが、以下エラーが出ました。
TextureBox object was given an infinite size during layout.

こちらのissueを参考に実装することで解決。
https://github.com/flutter/flutter/issues/31911#issuecomment-739412800

SizedBox.expand(
  child: FittedBox(
    fit: BoxFit.cover,
    child: SizedBox(
      width: _controller.value.size.width,
      height: _controller.value.size.height,
      child: VideoPlayer(_controller),
    ),
  ),
),

TextureBox学バネば
以下参考にさせていただきました!
https://qiita.com/mao_/items/aa219925270e7dfaee39

状態管理

ビルド直後は動画が表示されず(Size(0, 0)になっている)、
ホットリロードすると動画が表示される(Size(1400, 700)になっている)事象が発生したため、
今回はパッケージのサンプル通りStatefulWidgetで実装しました。

ほんとはRiverpodのProviderで実装したかったですが、
initState()している部分をうまく表現できず。。

void initState() {
  super.initState();
  _controller = VideoPlayerController.asset('assets/video/video.mp4')
  ..addListener(() => setState(() {}))
  ..setLooping(true)
  ..initialize().then((_) => setState(() {}))
  ..play();
}

Discussion

yamadayamada

貴重な記事をありがとうございます。
コードを模して試してみたのですが、ステータスバーとナビゲーションバー部分まで動画のサイズを拡大させることができず、本来ステータスバーとナビゲーションバーがある部分が真っ暗で表示されてしまい、記事内で添付されているGIF画像のように再生することができません。takuro abe様はこの問題を提示されているコード以外で解消しているのでしょうか?

takuro abetakuro abe

yamadaさん
記事見ていただきありがとうございます!

記事内のコードで対応できると思います!

yamadayamada

わかりました。もう一度読み直してみます!