Flutter video_player 从点击开始重新启动视频

Flutter video_player restart video from start on tap

我用的是flutter video_player package to play a short video file using in my application. I inspired from the flutter cookbook: Play and pause a video.

我想让用户点击视频从头开始播放。所以我用 GestureDetector.

包装了 VideoPlayer

我目前有以下代码:

class MyVideoPlayer extends StatefulWidget {
  final File videoFile;

  MyVideoPlayer({Key key, this.videoFile}) : super(key: key);

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

class _MyVideoPlayerState extends State<MyVideoPlayer> {
  VideoPlayerController _controller;
  Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    _controller = VideoPlayerController.file(widget.videoFile);
    _initializeVideoPlayerFuture = _controller.initialize();
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _initializeVideoPlayerFuture,
      builder: (context, snapshot) {
        print(snapshot.connectionState);
        if (snapshot.connectionState == ConnectionState.done) {
          // Play video once it's loaded
          _controller.play();

          return AspectRatio(
            aspectRatio: _controller.value.aspectRatio,
            child: GestureDetector(
              onTap: () async {
                await _controller.seekTo(Duration.zero);
                _controller.play();
              },
              child: VideoPlayer(_controller),
            ),
          );
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }
}

视频文件加载后(连接状态变为完成后)视频播放良好,但是,当我尝试点击视频再次播放时,它不会从开始。音频再次开始播放,但视频没有重新播放。有什么想法吗?

编辑 1

之后,我尝试将调用包装在 setState 中以再次触发构建方法:

return AspectRatio(
  aspectRatio: _controller.value.aspectRatio,
  child: GestureDetector(
    onTap: () async {
      await _controller.seekTo(Duration.zero);
      setState(() {
        _controller.play();
      });
    },
    child: VideoPlayer(_controller),
  ),
);

但是视频还是没有重播,只有声音。还有其他想法吗?

如果您对视频播放进行了任何更改,则需要重建 VideoPlayer。针对您的情况,最简单的解决方案是通过 setState 调用再次触发构建方法。

/// ... after some code
child: GestureDetector(
          onTap: () async {
            await _controller.seekTo(Duration.zero);
            setState( () {
              _controller.play();
            } );
          },
          child: VideoPlayer(_controller),
        ),

如果视频不再播放(即视频已经播放完毕),我终于找到了解决问题的方法,方法是在点击事件的控制器上再次调用 initialize()

return AspectRatio(
  aspectRatio: _controller.value.aspectRatio,
  child: GestureDetector(
    onTap: () {
      if (!_controller.value.isPlaying) {
         setState(() {});
         _controller.initialize();
      }
    },
    child: VideoPlayer(_controller),
  ),
);

我是这样解决这个问题的

GestureDetector(
    onTap() {  
    if(_controller.value.position==_controller.value.duration){
            _controller.initialize();  
       }
     }
)

_controller.value.duration 存储视频时长, _controller.value.position 存储视频的实际位置,如果视频到达结尾,_controller.value.position 将等于_controller.value.duration.

你可以在 onTap 上做这样的事情

/// get the duration of the video
 final duration = await _controller.position;

/// check if video has ended
 if (duration.inSeconds ==_controller.value.duration.inSeconds) {
 /// restart the video by setting current position to 0
    _controller.seekTo(Duration.zero);
 } else {
    _controller.value.isPlaying
        ? _controller.pause()
        : _controller.play();
 }