flutter实现视频轮播
Posted 阳光照不到的王国
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了flutter实现视频轮播相关的知识,希望对你有一定的参考价值。
只要逻辑行得通,代码实现只是迟早的问题。产品经理想要视频轮播的功能,经过分析轮播的逻辑是很简单,只要当一个视频播放完成之后自动播放下一个视频,然后周而复始。前后也花了好几天的时间去尝试,皇天不负有心人,终于有所突破,在此记录一下,给需要的读者参考。
其中需要解决的问题如下:
1、如何获取播放完成的事件
2、在播放完成的事件触发之后如何更改视频源
代码中做注释会解答上面的1、2问题,其实在做的过程中还会遇到其它的棘手问题,尤其是状态改变之后会触发多次build,目前是通过标记位的方式来解决的,现在只是实现了两个视频轮播。
具体代码如下
import 'dart:async';
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
///视频加载组件
class VideoLoader extends StatefulWidget
@override
_VideoLoader createState()
return _VideoLoader();
class _VideoLoader extends State<VideoLoader>
late VideoPlayerController _controller;
//视频源列表,读者在使用代码时需要将视频源换成你自己的视频源
List<String> _listVideoUrls = [
"http://192.168.30.34/ims/resource/17d87da3-4021-48b8-9c68-0d53d0c349df.mp4",
"http://192.168.30.34/ims/resource/17d87da3-4021-48b8-9c68.mp4"
];
//定义两个标记位用来保证setstate()中的函数只执行一次.
List<bool> flags = [false, false];
@override
void initState()
super.initState();
playVideo1();
//播放视频源1
void playVideo1() async
_controller = VideoPlayerController.network(_listVideoUrls.elementAt(0));
print('视频1加载完成');
_controller.addListener(() async
Duration? res = await _controller.position;
setState(()
if (res! >= _controller.value.duration)
if (!flags.elementAt(0))
flags[0] = true;
print('视频1播放完成');
//移除当前_controller的监听事件
_controller.removeListener(() );
_controller.dispose();
if (flags[1] == true)
flags[1] = false;
print('初始化flags[1] 为false');
playVideo2();
);
);
_controller.setLooping(false);
_controller.initialize().then((_) => setState(() ));
_controller.play();
void playVideo2() async
_controller = VideoPlayerController.network(_listVideoUrls.elementAt(1));
print('视频2资源设置完成');
_controller.addListener(() async
Duration? res = await _controller.position;
setState(()
if (res! >= _controller.value.duration)
// print('_controller.value.duration:$_controller.value.duration');
if (!flags.elementAt(1))
flags[1] = true;
_controller.removeListener(() );
_controller.dispose();
print('视频2播放完成');
if (flags[0] == true)
flags[0] = false;
print('初始化flags[0] 为false');
playVideo1();
);
);
_controller.setLooping(false);
_controller.initialize().then((_) => setState(() ));
_controller.play();
@override
void dispose()
_controller.dispose();
super.dispose();
@override
Widget build(BuildContext context)
print('build---------------');
return Scaffold(
// appBar: CupertinoNavigationBar(
// backgroundColor: Colors.white,
// middle: const Text('视频播放'),
// ),
body: Center(
child: Container(
// padding: const EdgeInsets.all(10.0),
alignment: Alignment.center,
child: GestureDetector(
onTap: () ,
child: Stack(
alignment: Alignment.bottomCenter,
children: <Widget>[
VideoPlayer(_controller),
//播放倍速
_ControlsOverlay(controller: _controller),
//播放进度条
VideoProgressIndicator(_controller, allowScrubbing: true),
],
),
),
)),
);
class _ControlsOverlay extends StatelessWidget
const _ControlsOverlay(Key? key, required this.controller)
: super(key: key);
static const _examplePlaybackRates = [
0.25,
0.5,
1.0,
1.5,
2.0,
3.0,
5.0,
10.0,
];
final VideoPlayerController controller;
@override
Widget build(BuildContext context)
return Stack(
children: <Widget>[
AnimatedSwitcher(
duration: Duration(milliseconds: 50),
reverseDuration: Duration(milliseconds: 200),
child: controller.value.isPlaying
? SizedBox.shrink()
: Container(
color: Colors.black26,
child: Center(
child: Icon(
Icons.play_arrow,
color: Colors.white,
size: 100.0,
),
),
),
),
GestureDetector(
onTap: ()
controller.value.isPlaying ? controller.pause() : controller.play();
,
),
Align(
alignment: Alignment.topRight,
child: PopupMenuButton<double>(
initialValue: controller.value.playbackSpeed,
tooltip: 'Playback speed',
onSelected: (speed)
controller.setPlaybackSpeed(speed);
,
itemBuilder: (context)
return [
for (final speed in _examplePlaybackRates)
PopupMenuItem(
value: speed,
child: Text('$speedx'),
)
];
,
child: Padding(
padding: const EdgeInsets.symmetric(
// Using less vertical padding as the text is also longer
// horizontally, so it feels like it would need more spacing
// horizontally (matching the aspect ratio of the video).
vertical: 12,
horizontal: 16,
),
child: Text('$controller.value.playbackSpeedx'),
),
),
),
],
);
注意,如果项目中没有添加video_player包的话需要先在pubspec.yaml中添加。
添加方式
在项目中执行 flutter pub add video_player
添加完成之后 执行 flutter pub get命令。
添加好的pubspec.yaml结构如下:
依赖好之后就可以在项目中使用VideoPlayer相关资源了。
祝君成功,如有疑问可联系笔者交流!
以上是关于flutter实现视频轮播的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 中轮播图详解[Flutter专题31]#yyds干货盘点#
Flutter学习日记之Flutter_swiper实现轮播图功能