Flutter实现视频进视口自动播放、移出暂停的方案咨询
实现滚动时视频自动播放/暂停的Flutter视频播放器组件
要实现社交APP帖子中视频随滚动自动播放/暂停的需求,我们可以借助visibility_detector包监听组件视口可见性,结合视频控制器的播放暂停方法来实现。以下是修改后的完整方案:
依赖准备
首先在pubspec.yaml中添加依赖:
dependencies: visibility_detector: ^0.4.0+2 # 保留原有的custom_video_player相关依赖
修改后的组件代码
import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:visibility_detector/visibility_detector.dart'; // 导入你的custom_video_player相关包 class Videoplayer extends StatefulWidget { const Videoplayer({Key? key, this.width = 400, this.height = 400}) : super(key: key); final double? width; final double? height; @override _VideoplayerState createState() => _VideoplayerState(); } class _VideoplayerState extends State<Videoplayer> { late VideoPlayerController _videoPlayerController, _videoPlayerController2, _videoPlayerController3; late CustomVideoPlayerController _customVideoPlayerController; late CustomVideoPlayerWebController _customVideoPlayerWebController; final CustomVideoPlayerSettings _customVideoPlayerSettings = const CustomVideoPlayerSettings(); final CustomVideoPlayerWebSettings _customVideoPlayerWebSettings = CustomVideoPlayerWebSettings( src: longVideo, ); bool _isVisible = false; @override void initState() { super.initState(); _videoPlayerController = VideoPlayerController.network(longVideo) ..initialize().then((_) { setState(() {}); // 初始暂停,设置循环播放适配社交场景 _videoPlayerController.setLooping(true); _videoPlayerController.pause(); }); _videoPlayerController2 = VideoPlayerController.network(video240); _videoPlayerController3 = VideoPlayerController.network(video480); _customVideoPlayerController = CustomVideoPlayerController( context: context, videoPlayerController: _videoPlayerController, customVideoPlayerSettings: _customVideoPlayerSettings, additionalVideoSources: { "240p": _videoPlayerController2, "480p": _videoPlayerController3, "720p": _videoPlayerController, }, ); _customVideoPlayerWebController = CustomVideoPlayerWebController( webVideoPlayerSettings: _customVideoPlayerWebSettings, ); } @override void dispose() { _customVideoPlayerController.dispose(); _customVideoPlayerWebController.dispose(); _videoPlayerController2.dispose(); _videoPlayerController3.dispose(); super.dispose(); } // 处理视频可见性变化逻辑 void _onVisibilityChanged(VisibilityInfo info) { final visiblePercentage = info.visibleFraction * 100; setState(() { _isVisible = visiblePercentage > 50; // 可见比例超50%判定为进入视口 }); if (_isVisible) { kIsWeb ? _customVideoPlayerWebController.play() : _customVideoPlayerController.videoPlayerController.play(); } else { kIsWeb ? _customVideoPlayerWebController.pause() : _customVideoPlayerController.videoPlayerController.pause(); } } @override Widget build(BuildContext context) { return SafeArea( child: ListView( children: [ // 用VisibilityDetector包裹视频组件监听可见性 VisibilityDetector( key: Key('video-player-${widget.key}'), // 唯一key确保监听准确 onVisibilityChanged: _onVisibilityChanged, child: SizedBox( width: widget.width, height: widget.height, child: kIsWeb ? CustomVideoPlayerWeb( customVideoPlayerWebController: _customVideoPlayerWebController, ) : CustomVideoPlayer( customVideoPlayerController: _customVideoPlayerController, ), ), ), CupertinoButton( child: const Text("Play Fullscreen"), onPressed: () { if (kIsWeb) { _customVideoPlayerWebController.setFullscreen(true); _customVideoPlayerWebController.play(); } else { _customVideoPlayerController.setFullscreen(true); _customVideoPlayerController.videoPlayerController.play(); } }, ), ], ), ); } }
关键改动说明
- 视口监听:通过
VisibilityDetector组件实时获取视频在视口中的可见比例 - 播放暂停触发:当视频可见比例超过50%时自动播放,低于阈值则暂停,可根据需求调整比例
- 初始化优化:初始状态暂停视频,避免未进入视口就播放;添加循环播放适配社交场景
- 资源管理:完善所有控制器的销毁逻辑,防止内存泄漏
- 跨端兼容:分别处理移动端和Web端的视频控制器播放暂停逻辑
内容的提问来源于stack exchange,提问作者nischal nayak
相关产品推荐
相关产品推荐

