flutter视频播放插件chewie的使用
# 因为使用flutter_html已经包含以下插件了
flutter_html: 1.0.2
# Plugins for rendering the <video> tag.
video_player: ^0.10.11+2
chewie: ^0.9.10
预览(半屏截图)

主要代码 (aspectRatio视频比例很重要)
import 'package:flutter/material.dart';
import 'package:flutter_tk/common.dart';
import 'package:logger/logger.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
import 'package:flutter_tk/widgets/Dialog.dart';
/// 视频播放组件
class VideoWidFull extends StatefulWidget {
/// 视频地址
final String url;
// 外部缩略图
final String thumbUse;
/// 点击播放的事件
final Function onplayFunction;
/// 视频比例
final double aspectRatio;
final bool autoPlay;
/// 是否弹窗播放
final bool useModel;
final bool looping;
final bool showControls;
const VideoWidFull(
this.url, {
Key key,
this.onplayFunction,
this.thumbUse,
this.aspectRatio = 19 / 8,
this.useModel = false,
this.looping = false,
this.autoPlay = false,
this.showControls = true,
}) : super(key: key);
@override
_VideoWidFullState createState() => _VideoWidFullState();
}
class _VideoWidFullState extends State<VideoWidFull> {
/// 播放组件
Widget playerWidget;
ChewieController chewieController;
VideoPlayerController videoPlayerController;
@override
void initState() {
initData();
}
@override
void dispose() {
super.dispose();
videoPlayerController?.pause();
chewieController?.pause();
chewieController?.dispose();
videoPlayerController?.dispose();
}
Future initData() async {
videoPlayerController = VideoPlayerController.network('${widget.url}');
await videoPlayerController.initialize();
chewieController = ChewieController(
videoPlayerController: videoPlayerController,
autoPlay: widget.autoPlay,
looping: widget.looping,
aspectRatio: widget.aspectRatio == null ? 18 / 9 : 9 / 18,
showControls: widget.showControls,
);
playerWidget = Chewie(
controller: chewieController,
);
if (mounted) {
setState(() {});
}
if (widget.autoPlay && widget?.onplayFunction != null) {
widget.onplayFunction();
}
}
@override
Widget build(BuildContext context) {
return Container(
child: playerWidget == null
? Container()
: Container(
child: Stack(
children: [
videoPlayerController.value.isPlaying
? playerWidget
: (widget?.thumbUse != null
? Positioned(
child: Image(
width: double.infinity,
height: double.infinity,
image: NetworkImage(
widget.thumbUse,
),
fit: BoxFit.fill,
))
: playerWidget),
if (videoPlayerController.value.isPlaying == false)
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
widget.onplayFunction();
if (widget.useModel) {
Logger().d('弹窗播放');
// 弹窗播放
screenDialogWid(
context: context,
child: Container(
child: VideoWidFull(
'${widget.url}',
autoPlay: true,
useModel: false,
aspectRatio: widget.aspectRatio,
)),
url: widget.url,
close: () {},
);
} else {
Logger().d('直接播放');
// 直接播放
chewieController?.play();
setState(() {});
}
},
child: Container(
child: Center(
child: Container(
width: Common.width(120),
height: Common.width(120),
decoration: BoxDecoration(
color: Color.fromRGBO(0, 0, 0, 0.3),
borderRadius: BorderRadius.all(
Radius.circular(Common.width(120))),
),
child: Center(
child: Image.asset(
'asset/images/res/play_48x48.png',
width: Common.width(48),
height: Common.width(48),
fit: BoxFit.contain,
),
),
),
),
),
)
],
),
));
}
}
全屏弹窗组件 (核心是showGeneralDialog)
import 'package:flutter/material.dart';
import 'package:flutter_custom_dialog/flutter_custom_dialog.dart';
import 'package:flutter_tk/common.dart';
import 'package:flutter_tk/lib/download.dart';
import 'package:flutter_tk/widgets/GestureDetectorWid.dart';
import 'package:flutter_tk/widgets/PageLayout.dart';
import 'package:logger/logger.dart';
typedef void HandleClose();
Future<void> screenDialogWid<T>(
{BuildContext context,
Widget child,
String url,
HandleClose close,
Function fullScreen,
/// 是否是横屏
bool isHoScreen: false}) async {
await showGeneralDialog(
context: context,
barrierLabel: "",
barrierDismissible: true,
transitionDuration: Duration(milliseconds: 300),
pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return Material(
color: Colors.black,
child: GestureDetectorWid(
onTap: () async {
if (close != null) {
close();
}
Common.toJumpPage(context: context);
},
child: Stack(
children: [
Positioned(
left: 0,
right: 0,
bottom: Common.width(120),
top: 0,
child: Center(
child: child,
),
),
Positioned(
right: Common.width(40),
bottom: Common.width(40),
child: GestureDetectorWid(
child: Image.asset(
'asset/images/res/download_64x64.png',
width: Common.width(64),
height: Common.width(64),
),
onTap: () async {
await Download.download(
[url],
onDone: (String text) {
Common.toast(text);
},
onError: (String text) {
Common.toast(text);
},
onReceiveProgress: (String text) {
Common.loading(
msg: text,
context: context,
);
},
);
},
),
),
],
),
),
);
},
);
}