import 'dart:async';
import 'package:chewie/src/chewie_progress_colors.dart';
import 'package:chewie/src/player_with_controls.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:video_player/video_player.dart';
class Chewie extends StatefulWidget {
/// 视频播放器的控制器
final VideoPlayerController controller;
/// 启动时初始化视频,为回放做准备
final bool autoInitialize;
/// 视频一显示就播放视频
final bool autoPlay;
/// 从某个位置开始录像
final Duration startAt;
/// 视频是否可以循环播放
final bool looping;
/// 是否显示控件
final bool showControls;
/// 视频的宽高比
final double aspectRatio;
/// 用于IOS上的控件颜色。默认情况下,iOS使用的颜色样本是iOS11的原始设计
final ChewieProgressColors cupertinoProgressColors;
/// 进度条颜色。默认情况下进度条颜色是主题的颜色
final ChewieProgressColors materialProgressColors;
/// 视频初始化之前,占位符显示在视频下面
final Widget placeholder;
/// 当按下播放按钮后,是否全屏播放
final bool fullScreenByDefault;
/// 这是构造函数
Chewie(
this.controller, {
Key key,
this.aspectRatio,
this.autoInitialize = false,
this.autoPlay = false,
this.startAt,
this.looping = false,
this.fullScreenByDefault = false,
this.cupertinoProgressColors,
this.materialProgressColors,
this.placeholder,
this.showControls = true,
}) : assert(controller != null, 'You must provide a controller to play a video'),
super(key: key);
@override
State<StatefulWidget> createState() {
return new _ChewiePlayerState();
}
}
class _ChewiePlayerState extends State<Chewie> {
/// 视频控制器
VideoPlayerController _controller;
/// 是否可以全屏
bool _isFullScreen = false;
@override
Widget build(BuildContext context) {
return new PlayerWithControls(
controller: _controller,
onExpandCollapse: () => _pushFullScreenWidget(context),
aspectRatio: widget.aspectRatio ?? _calculateAspectRatio(context),
cupertinoProgressColors: widget.cupertinoProgressColors,
materialProgressColors: widget.materialProgressColors,
placeholder: widget.placeholder,
autoPlay: widget.autoPlay,
showControls: widget.showControls,
);
}
/// 初始化
@override
void initState() {
super.initState();
/// 初始化视频控制器
_controller = widget.controller;
_initialize();
}
Widget _buildFullScreenVideo(BuildContext context, Animation<double> animation) {
return new Scaffold(
resizeToAvoidBottomPadding: false,
body: new Container(
alignment: Alignment.center,
color: Colors.black,
child: new PlayerWithControls(
controller: _controller,
onExpandCollapse: () => new Future<dynamic>.value(Navigator.of(context).pop()),
aspectRatio: widget.aspectRatio ?? _calculateAspectRatio(context),
fullScreen: true,
cupertinoProgressColors: widget.cupertinoProgressColors,
materialProgressColors: widget.materialProgressColors,
),
),
);
}
Widget _fullScreenRoutePageBuilder(
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
) {
return new AnimatedBuilder(
animation: animation,
builder: (BuildContext context, Widget child) {
return _buildFullScreenVideo(context, animation);
},
);
}
Future _initialize() async {
//是否可以循环播放
await _controller.setLooping(widget.looping);
/// 如果是启动时就初始化视频或者自动播放,那么就用视频控制器去初始化视频
if (widget.autoInitialize || widget.autoPlay) {
await _controller.initialize();
}
/// 如果是自动播放,且是默认全屏
if (widget.autoPlay) {
if (widget.fullScreenByDefault) {
_isFullScreen = true;
///r如何全屏显示
await _pushFullScreenWidget(context);
}
await _controller.play();
}
/// 如果是从视频的某个地方开始播放
if (widget.startAt != null) {
/// seekTo是一个视频位置定位方法
await _controller.seekTo(widget.startAt);
}
/// 如果视频默认按下播放按钮就全屏播放
if (widget.fullScreenByDefault) {
widget.controller.addListener(() async {
if (await widget.controller.value.isPlaying && !_isFullScreen) {
_isFullScreen = true;
await _pushFullScreenWidget(context);
}
});
}
}
@override
void didUpdateWidget(Chewie oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.controller.dataSource != _controller.dataSource) {
_controller.dispose();
_controller = widget.controller;
_isFullScreen = false;
_initialize();
}
}
Future<dynamic> _pushFullScreenWidget(BuildContext context) async {
/// 安卓界面
final isAndroid = Theme.of(context).platform == TargetPlatform.android;
///TransitionRoute:具有入口和出口转换的路径。PageRouteBuilder:页面路径构造器
final TransitionRoute<Null> route = new PageRouteBuilder<Null>(
/// 设置路径
settings: new RouteSettings(isInitialRoute: false),
///页面构造器
pageBuilder: _fullScreenRoutePageBuilder,
);
/// SystemChrome:控制操作系统图形界面的特定方面以及它如何与应用程序交互。
SystemChrome.setEnabledSystemUIOverlays([]);
if (isAndroid) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
}
await Navigator.of(context).push(route);
SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
}
double _calculateAspectRatio(BuildContext context) {
final size = MediaQuery.of(context).size;
final width = size.width;
final height = size.height;
return width > height ? width / height : height / width;
}
}
Chewie源码
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- Accounts源码分析与逻辑结构2 listAccounts源码分析 位于internal/ethapi/api...
- 开始之前 android studio中配置android源码路径 android studio中有源码的路径,你...