You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中使用video_player如何判断视频是否播放至末尾?

判断video_player视频是否播放至末尾并实现重播逻辑

要实现这个需求,核心是监听VideoPlayerController的播放位置和总时长,当位置到达时长终点时触发结束逻辑,同时控制UI显示重播按钮。具体步骤如下:

1. 基础准备

确保你的pubspec.yaml中已引入video_player依赖:

dependencies:
  flutter:
    sdk: flutter
  video_player: ^2.8.1 # 可替换为最新稳定版本

2. 实现核心逻辑

通过VideoPlayerController的监听回调,对比当前播放位置与视频总时长,判断是否播放结束。同时维护一个状态变量控制重播图标的显示。

完整示例代码:

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

class VideoWithReplay extends StatefulWidget {
  final String videoUrl;

  const VideoWithReplay({super.key, required this.videoUrl});

  @override
  State<VideoWithReplay> createState() => _VideoWithReplayState();
}

class _VideoWithReplayState extends State<VideoWithReplay> {
  late VideoPlayerController _controller;
  bool _isPlayFinished = false;

  @override
  void initState() {
    super.initState();
    // 初始化控制器(网络视频示例,本地视频用VideoPlayerController.asset)
    _controller = VideoPlayerController.network(widget.videoUrl)
      ..initialize().then((_) {
        setState(() {});
        _controller.play();
      });

    // 添加播放状态监听
    _controller.addListener(_checkPlayStatus);
  }

  void _checkPlayStatus() {
    final totalDuration = _controller.value.duration;
    final currentPosition = _controller.value.position;

    // 加入100ms误差范围,避免因精度问题导致判断失效
    if (totalDuration != null &&
        currentPosition != null &&
        currentPosition >= totalDuration - const Duration(milliseconds: 100)) {
      setState(() {
        _isPlayFinished = true;
      });
      _controller.pause();
      // 这里可以添加播放结束后的自定义逻辑,比如发送统计、显示提示等
    }
  }

  void _restartVideo() {
    setState(() {
      _isPlayFinished = false;
    });
    _controller.seekTo(Duration.zero); // 跳转到视频开头
    _controller.play();
  }

  @override
  void dispose() {
    // 移除监听并释放控制器资源
    _controller.removeListener(_checkPlayStatus);
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      alignment: Alignment.center,
      children: [
        // 视频播放器
        if (_controller.value.isInitialized)
          AspectRatio(
            aspectRatio: _controller.value.aspectRatio,
            child: VideoPlayer(_controller),
          ),
        // 播放结束时显示重播按钮
        if (_isPlayFinished)
          IconButton(
            icon: const Icon(Icons.replay, size: 60, color: Colors.white),
            onPressed: _restartVideo,
          ),
      ],
    );
  }
}

关键说明

  • 误差处理:判断时加入100ms的误差范围,因为部分视频的position可能不会完全等于duration,避免出现判断不触发的情况。
  • 状态维护:用_isPlayFinished变量控制重播图标的显示,确保UI状态与播放状态同步。
  • 资源释放:在dispose方法中移除监听并释放控制器,避免内存泄漏。

内容的提问来源于stack exchange,提问作者viki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 12:35:19