Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
G
gz_video_player
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蒋俊
gz_video_player
Commits
c24d98cd
提交
c24d98cd
authored
9月 15, 2023
作者:
jungleiOS
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
loading 组件背景设为黑色,挡住亮度组件初始化时闪现问题,退出播放器恢复亮度
上级
2abe3aa0
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
451 行增加
和
403 行删除
+451
-403
main.dart
example/lib/main.dart
+418
-379
video.dart
lib/video.dart
+10
-4
video_loading_view.dart
lib/widget/video_loading_view.dart
+23
-20
没有找到文件。
example/lib/main.dart
浏览文件 @
c24d98cd
...
@@ -10,19 +10,60 @@ import 'package:gz_video_player/video_style.dart';
...
@@ -10,19 +10,60 @@ import 'package:gz_video_player/video_style.dart';
import
'package:gz_video_player/video_subtitles.dart'
;
import
'package:gz_video_player/video_subtitles.dart'
;
import
'package:gz_video_player/video_top_bar_style.dart'
;
import
'package:gz_video_player/video_top_bar_style.dart'
;
void
main
(
)
{
void
main
(
)
{
runApp
(
const
MyApp
());
runApp
(
const
MyApp
());
}
}
class
MyApp
extends
State
ful
Widget
{
class
MyApp
extends
State
less
Widget
{
const
MyApp
({
super
.
key
});
const
MyApp
({
super
.
key
});
@override
@override
State
<
MyApp
>
createState
()
=>
_MyAppState
();
Widget
build
(
BuildContext
context
)
{
return
const
MaterialApp
(
home:
HomePage
(),
);
}
}
class
HomePage
extends
StatelessWidget
{
const
HomePage
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
'HomePage'
),
),
body:
Center
(
child:
GestureDetector
(
onTap:
()
{
Navigator
.
of
(
context
).
push
(
MaterialPageRoute
(
builder:
(
BuildContext
context
)
{
return
const
VideoPlayerPage
();
}),
);
},
child:
Container
(
width:
120.0
,
height:
30.0
,
color:
Colors
.
blue
,
alignment:
Alignment
.
center
,
child:
const
Text
(
'to video player'
),
),
),
),
);
}
}
class
VideoPlayerPage
extends
StatefulWidget
{
const
VideoPlayerPage
({
super
.
key
});
@override
State
<
VideoPlayerPage
>
createState
()
=>
_VideoPlayerPageState
();
}
}
class
_
MyAppState
extends
State
<
MyApp
>
{
class
_
VideoPlayerPageState
extends
State
<
VideoPlayerPage
>
{
// String videoUrl = "https://www.runoob.com/try/demo_source/movie.mp4";
// String videoUrl = "https://www.runoob.com/try/demo_source/movie.mp4";
// String videoUrl = "https://yun.zxziyuan-yun.com/20180221/4C6ivf8O/index.m3u8";
// String videoUrl = "https://yun.zxziyuan-yun.com/20180221/4C6ivf8O/index.m3u8";
...
@@ -52,7 +93,7 @@ class _MyAppState extends State<MyApp> {
...
@@ -52,7 +93,7 @@ class _MyAppState extends State<MyApp> {
dataList
=
[
dataList
=
[
VideoModel
(
VideoModel
(
url:
url:
'https://mpv.videocc.net/8f38fa3352/5/8f38fa3352cdb65e6773173ae8c767b5_1.mp4'
,
'https://mpv.videocc.net/8f38fa3352/5/8f38fa3352cdb65e6773173ae8c767b5_1.mp4'
,
title:
'高正视频'
,
title:
'高正视频'
,
),
),
VideoModel
(
VideoModel
(
...
@@ -65,404 +106,402 @@ class _MyAppState extends State<MyApp> {
...
@@ -65,404 +106,402 @@ class _MyAppState extends State<MyApp> {
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
MaterialApp
(
return
Scaffold
(
home:
Scaffold
(
appBar:
!
_isFullscreen
?
AppBar
(
title:
const
Text
(
'video player'
))
:
null
,
appBar:
body:
Column
(
children:
<
Widget
>[
!
_isFullscreen
?
AppBar
(
title:
const
Text
(
'video player'
))
:
null
,
videoUrl
!=
""
body:
Column
(
children:
<
Widget
>[
?
GZVideoPlayer
(
videoUrl
!=
""
dataSource:
videoUrl
,
?
GZVideoPlayer
(
sourceType:
DataSourceType
.
network
,
dataSource:
videoUrl
,
sourceType:
DataSourceType
.
network
,
/// 视频播放配置
/// 视频播放配置
playOptions:
VideoPlayOptions
(
playOptions:
VideoPlayOptions
(
seekSeconds:
30
,
seekSeconds:
30
,
//左侧垂直手势调节视频亮度的单位(0~1之间,不能小于0,不能大于1)
//左侧垂直手势调节视频亮度的单位(0~1之间,不能小于0,不能大于1)
brightnessGestureUnit:
0.01
,
brightnessGestureUnit:
0.01
,
//右侧垂直手势调节视频音量的单位(0~1之间,不能小于0,不能大于1)
//右侧垂直手势调节视频音量的单位(0~1之间,不能小于0,不能大于1)
volumeGestureUnit:
0.005
,
volumeGestureUnit:
0.005
,
//横行手势调节视频进度的单位毫秒数
//横行手势调节视频进度的单位毫秒数
progressGestureUnit:
2000
,
progressGestureUnit:
2000
,
aspectRatio:
16
/
9
,
aspectRatio:
16
/
9
,
loop:
false
,
loop:
false
,
autoplay:
true
,
autoplay:
true
,
allowScrubbing:
true
,
allowScrubbing:
true
,
startPosition:
const
Duration
(
seconds:
0
),
startPosition:
const
Duration
(
seconds:
0
),
),
),
/// 自定义视频样式
videoStyle:
VideoStyle
(
/// 自定义视频暂停时视频中部的播放按钮
playIcon:
const
Icon
(
Icons
.
play_circle_outline
,
size:
60
,
color:
Colors
.
white
,
),
/// 暂停时是否显示视频中部播放按钮
/// 自定义视频样式
showPlayIcon:
true
,
videoStyle:
VideoStyle
(
/// 自定义视频暂停时视频中部的播放按钮
videoLoadingStyle:
VideoLoadingStyle
(
playIcon:
const
Icon
(
/// 重写部分(二选一)
Icons
.
play_circle_outline
,
// 重写Loading的widget
size:
60
,
// customLoadingIcon: CircularProgressIndicator(strokeWidth: 2.0),
color:
Colors
.
white
,
// 重写Loading 下方的Text widget
),
// customLoadingText: Text("加载中..."),
/// 设置部分(二选一)
// 设置Loading icon 下方的文字
loadingText:
"Loading..."
,
// 设置loading icon 下方的文字颜色
loadingTextFontColor:
Colors
.
white
,
// 设置loading icon 下方的文字大小
loadingTextFontSize:
20
,
),
/// 自定义顶部控制栏
/// 暂停时是否显示视频中部播放按钮
videoTopBarStyle:
VideoTopBarStyle
(
showPlayIcon:
true
,
show:
true
,
//是否显示
videoLoadingStyle:
VideoLoadingStyle
(
height:
60
,
/// 重写部分(二选一)
padding:
const
EdgeInsets
.
symmetric
(
// 重写Loading的widget
vertical:
8
,
horizontal:
10
),
// customLoadingIcon: CircularProgressIndicator(strokeWidth: 2.0),
barBackgroundColor:
const
Color
.
fromRGBO
(
0
,
0
,
0
,
0.5
),
// 重写Loading 下方的Text widget
popIcon:
const
Icon
(
// customLoadingText: Text("加载中..."),
Icons
.
arrow_back
,
/// 设置部分(二选一)
size:
25
,
// 设置Loading icon 下方的文字
color:
Colors
.
white
,
loadingText:
"Loading..."
,
),
// 设置loading icon 下方的文字颜色
contents:
[
loadingTextFontColor:
Colors
.
white
,
Center
(
// 设置loading icon 下方的文字大小
child:
Container
(
loadingTextFontSize:
20
,
margin:
const
EdgeInsets
.
symmetric
(
horizontal:
10
),
),
child:
const
Text
(
'123'
,
/// 自定义顶部控制栏
style:
videoTopBarStyle:
VideoTopBarStyle
(
TextStyle
(
color:
Colors
.
white
,
fontSize:
14
),
show:
true
,
),
//是否显示
),
height:
60
,
)
padding:
],
const
EdgeInsets
.
symmetric
(
vertical:
8
,
horizontal:
10
),
//自定义顶部控制栏中间显示区域
barBackgroundColor:
const
Color
.
fromRGBO
(
0
,
0
,
0
,
0.5
),
actions:
[
popIcon:
const
Icon
(
GestureDetector
(
Icons
.
arrow_back
,
behavior:
HitTestBehavior
.
translucent
,
onTap:
()
{
///1. 可配合自定义拓展元素使用,例如广告
setState
(()
{
showAdvertCover
=
true
;
});
///
},
child:
const
Icon
(
Icons
.
more_horiz
,
size:
25
,
size:
25
,
color:
Colors
.
white
,
color:
Colors
.
white
,
),
),
)
contents:
[
],
//自定义顶部控制栏右侧显示区域
Center
(
/// 设置cusotmBar之后,以上属性均无效(除了`show`之外)
child:
Container
(
// customBar: Positioned(
margin:
const
EdgeInsets
.
symmetric
(
horizontal:
10
),
// top: 0,
child:
const
Text
(
// left: 0,
'123'
,
// right: 0,
style:
TextStyle
(
color:
Colors
.
white
,
fontSize:
14
),
// child: Container(
),
// width: double.infinity,
),
// height: 50,
)
// color: Colors.yellow,
],
// child: Text("12312312"),
//自定义顶部控制栏中间显示区域
// ),
actions:
[
// ),
GestureDetector
(
// customBar: Align(
behavior:
HitTestBehavior
.
translucent
,
// alignment: Alignment.topLeft,
onTap:
()
{
// child: Container(
///1. 可配合自定义拓展元素使用,例如广告
// width: double.infinity,
setState
(()
{
// height: 30,
showAdvertCover
=
true
;
// color: Colors.yellow,
});
// child: GestureDetector(
// onTap: () {
///
// debugPrint("yes");
},
// },
child:
const
Icon
(
// child: Text("123123132")
Icons
.
more_horiz
,
// )
size:
25
,
// ),
color:
Colors
.
white
,
// ),
),
),
)
],
//自定义顶部控制栏右侧显示区域
/// 设置cusotmBar之后,以上属性均无效(除了`show`之外)
// customBar: Positioned(
// top: 0,
// left: 0,
// right: 0,
// child: Container(
// width: double.infinity,
// height: 50,
// color: Colors.yellow,
// child: Text("12312312"),
// ),
// ),
// customBar: Align(
// alignment: Alignment.topLeft,
// child: Container(
// width: double.infinity,
// height: 30,
// color: Colors.yellow,
// child: GestureDetector(
// onTap: () {
// debugPrint("yes");
// },
// child: Text("123123132")
// )
// ),
// ),
),
/// 自定义底部控制栏
/// 自定义底部控制栏
videoControlBarStyle:
VideoControlBarStyle
(
videoControlBarStyle:
VideoControlBarStyle
(
/// 自定义颜色
/// 自定义颜色
// barBackgroundColor: Colors.blue,
// barBackgroundColor: Colors.blue,
/// 自定义时间TextStyle
/// 自定义时间TextStyle
timeTextStyle:
const
TextStyle
(
fontSize:
14.0
,
color:
Colors
.
white
),
timeTextStyle:
const
TextStyle
(
fontSize:
14.0
,
color:
Colors
.
white
),
///添加边距
padding:
const
EdgeInsets
.
symmetric
(
///添加边距
vertical:
8
,
horizontal:
10
),
padding:
const
EdgeInsets
.
symmetric
(
vertical:
8
,
horizontal:
10
),
///设置控制拦的高度,默认为30,如果图标设置过大但是高度不够就会出现图标被裁剪的现象
height:
60
,
///设置控制拦的高度,默认为30,如果图标设置过大但是高度不够就会出现图标被裁剪的现象
progressStyle:
VideoProgressStyle
(
height:
60
,
playedColor:
Colors
.
blue
,
progressStyle:
VideoProgressStyle
(
),
playedColor:
Colors
.
blue
,
),
/// 自定义进度条样式
/// 自定义进度条样式
// progressStyle: VideoProgressStyle(
// progressStyle: VideoProgressStyle(
// // padding: EdgeInsets.all(0),
// // padding: EdgeInsets.all(0),
// padding: EdgeInsets.symmetric(
// padding: EdgeInsets.symmetric(
// vertical: 0,
// vertical: 0,
// horizontal: 10), //vertical不能设置太大,不然被把进度条压缩肉眼无法识别
// horizontal: 10), //vertical不能设置太大,不然被把进度条压缩肉眼无法识别
// playedColor: Colors.red,
// playedColor: Colors.red,
// bufferedColor: Colors.yellow,
// bufferedColor: Colors.yellow,
// backgroundColor: Colors.green,
// backgroundColor: Colors.green,
// dragBarColor: Colors
// dragBarColor: Colors
// .white, //进度条为`progress`时有效,如果时`basic-progress`则无效
// .white, //进度条为`progress`时有效,如果时`basic-progress`则无效
// height: 4,
// height: 4,
// progressRadius:
// progressRadius:
// 2, //进度条为`progress`时有效,如果时`basic-progress`则无效
// 2, //进度条为`progress`时有效,如果时`basic-progress`则无效
// dragHeight:
// dragHeight:
// 5 //进度条为`progress`时有效,如果时`basic-progress`则无效
// 5 //进度条为`progress`时有效,如果时`basic-progress`则无效
// ),
// ),
/// 更改进度栏的播放按钮
/// 更改进度栏的播放按钮
playIcon:
const
Icon
(
Icons
.
play_arrow
,
playIcon:
const
Icon
(
Icons
.
play_arrow
,
color:
Colors
.
white
,
size:
25
),
color:
Colors
.
white
,
size:
25
),
/// 更改进度栏的暂停按钮
/// 更改进度栏的暂停按钮
pauseIcon:
const
Icon
(
pauseIcon:
const
Icon
(
Icons
.
pause
,
Icons
.
pause
,
color:
Colors
.
white
,
color:
Colors
.
white
,
size:
25
,
size:
25
,
),
),
/// 更改进度栏的快退按钮
/// 更改进度栏的快退按钮
rewindIcon:
const
Icon
(
rewindIcon:
const
Icon
(
Icons
.
replay_30
,
Icons
.
replay_30
,
size:
25
,
size:
25
,
color:
Colors
.
white
,
color:
Colors
.
white
,
),
),
/// 更改进度栏的快进按钮
/// 更改进度栏的快进按钮
forwardIcon:
const
Icon
(
forwardIcon:
const
Icon
(
Icons
.
forward_30
,
Icons
.
forward_30
,
size:
25
,
size:
25
,
color:
Colors
.
white
,
color:
Colors
.
white
,
),
),
/// 更改进度栏的全屏按钮
/// 更改进度栏的全屏按钮
fullscreenIcon:
const
Icon
(
fullscreenIcon:
const
Icon
(
Icons
.
fullscreen
,
Icons
.
fullscreen
,
size:
25
,
size:
25
,
color:
Colors
.
white
,
color:
Colors
.
white
,
),
),
/// 更改进度栏的退出全屏按钮
/// 更改进度栏的退出全屏按钮
fullscreenExitIcon:
const
Icon
(
fullscreenExitIcon:
const
Icon
(
Icons
.
fullscreen_exit
,
Icons
.
fullscreen_exit
,
size:
25
,
size:
25
,
color:
Colors
.
white
,
color:
Colors
.
white
,
),
),
/// 决定控制栏的元素以及排序,示例见上方图3
/// 决定控制栏的元素以及排序,示例见上方图3
itemList:
[
itemList:
[
"rewind"
,
"rewind"
,
"play"
,
"play"
,
"forward"
,
"forward"
,
"position-time"
,
//当前播放时间
"position-time"
,
//当前播放时间
"progress"
,
//线条形进度条(与‘basic-progress’二选一)
"progress"
,
//线条形进度条(与‘basic-progress’二选一)
// "basic-progress",//矩形进度条(与‘progress’二选一)
// "basic-progress",//矩形进度条(与‘progress’二选一)
"duration-time"
,
//视频总时长
"duration-time"
,
//视频总时长
// "time",//格式:当前时间/视频总时长
// "time",//格式:当前时间/视频总时长
'speed'
,
'speed'
,
"fullscreen"
"fullscreen"
],
],
),
),
/// 自定义字幕
/// 自定义字幕
videoSubtitlesStyle:
VideoSubtitles
(
videoSubtitlesStyle:
VideoSubtitles
(
mainTitle:
Align
(
mainTitle:
Align
(
alignment:
Alignment
.
bottomCenter
,
alignment:
Alignment
.
bottomCenter
,
child:
Container
(
child:
Container
(
padding:
const
EdgeInsets
.
fromLTRB
(
10
,
0
,
10
,
30
),
padding:
const
EdgeInsets
.
fromLTRB
(
10
,
0
,
10
,
30
),
child:
Text
(
mainSubtitles
,
child:
Text
(
mainSubtitles
,
maxLines:
2
,
maxLines:
2
,
textAlign:
TextAlign
.
center
,
textAlign:
TextAlign
.
center
,
style:
const
TextStyle
(
style:
const
TextStyle
(
color:
Colors
.
white
,
fontSize:
14
)),
color:
Colors
.
white
,
fontSize:
14
)),
),
),
subTitle:
Align
(
alignment:
Alignment
.
bottomCenter
,
child:
Container
(
padding:
const
EdgeInsets
.
all
(
10
),
child:
Text
(
subSubtitles
,
maxLines:
2
,
textAlign:
TextAlign
.
center
,
style:
const
TextStyle
(
color:
Colors
.
white
,
fontSize:
14
)),
),
),
),
),
),
),
subTitle:
Align
(
alignment:
Alignment
.
bottomCenter
,
/// 自定义拓展元素
child:
Container
(
children:
[
padding:
const
EdgeInsets
.
all
(
10
),
/// DEMO1 自定义视频播放状态Toast
child:
Text
(
subSubtitles
,
/// 待完善
maxLines:
2
,
textAlign:
TextAlign
.
center
,
/// DEMO2 这个将会覆盖的视频内容,因为这个层级是最高级,因此手势会失效(慎用)
style:
const
TextStyle
(
/// 这个可以用来做视频广告
color:
Colors
.
white
,
fontSize:
14
)),
showAdvertCover
),
?
Align
(
alignment:
Alignment
.
center
,
child:
Container
(
width:
200
,
height:
100
,
color:
Colors
.
blue
[
500
],
child:
Stack
(
fit:
StackFit
.
expand
,
children:
<
Widget
>[
//关闭广告
Align
(
alignment:
Alignment
.
topRight
,
child:
GestureDetector
(
onTap:
()
{
setState
(()
{
showAdvertCover
=
false
;
});
},
child:
const
Icon
(
Icons
.
cancel
,
size:
16
,
color:
Colors
.
white
,
),
),
),
Container
(
alignment:
Alignment
.
center
,
child:
const
Text
(
"一个广告封面"
,
style:
TextStyle
(
color:
Colors
.
white
),
),
)
],
),
),
)
:
const
Align
(),
Builder
(
builder:
(
BuildContext
context
)
{
state
=
GZVideoPlayer
.
of
(
context
);
return
const
SizedBox
();
})
],
/// 视频暂停回调
onPause:
(
value
)
{
debugPrint
(
"video paused"
);
setState
(()
{
isPlaying
=
false
;
});
},
/// 视频播放回调
onPlay:
(
value
)
{
debugPrint
(
"video played"
);
setState
(()
{
isPlaying
=
true
;
});
},
/// 视频播放结束回调
onEnded:
(
value
)
{
debugPrint
(
"video ended"
);
},
/// 视频播放进度回调
/// 可以用来匹配字幕
onTimeUpdate:
(
value
)
{
// debugPrint("timeupdate ${value.position.inSeconds}");
// var position = value.position.inMilliseconds / 1000;
//根据 position 来判断当前显示的字幕
},
onProgressDrag:
(
position
,
duration
)
{
debugPrint
(
"进度条拖拽的时间节点:
$position
"
);
debugPrint
(
"进度条总时长:
$duration
"
);
},
onVolume:
(
value
)
{
// debugPrint("onvolume $value");
},
onBrightness:
(
value
)
{
debugPrint
(
"onbrightness
$value
"
);
},
onFullscreen:
(
fullscreen
)
{
debugPrint
(
"is fullscreen
$fullscreen
"
);
setState
(()
{
_isFullscreen
=
fullscreen
;
});
},
onSpeedChange:
(
VideoSpeedItem
item
)
{
debugPrint
(
'current speed
${item.title}
'
);
},
/// 顶部控制栏点击返回按钮
onPop:
(
value
)
{
debugPrint
(
"返回上一页"
);
},
)
:
const
AspectRatio
(
aspectRatio:
16
/
9
,
child:
Center
(
child:
CircularProgressIndicator
(
strokeWidth:
2.0
),
),
),
),
),
),
//update data source
/// 自定义拓展元素
!
_isFullscreen
children:
[
?
Expanded
(
/// DEMO1 自定义视频播放状态Toast
child:
CustomScrollView
(
/// 待完善
slivers:
[
SliverToBoxAdapter
(
/// DEMO2 这个将会覆盖的视频内容,因为这个层级是最高级,因此手势会失效(慎用)
child:
VideoListWidget
(
/// 这个可以用来做视频广告
dataList:
dataList
,
showAdvertCover
onTapItem:
(
int
index
)
{
?
Align
(
VideoModel
model
=
dataList
[
index
];
alignment:
Alignment
.
center
,
setState
(()
{
child:
Container
(
videoUrl
=
model
.
url
;
width:
200
,
});
height:
100
,
},
color:
Colors
.
blue
[
500
],
),
child:
Stack
(
),
fit:
StackFit
.
expand
,
SliverToBoxAdapter
(
children:
<
Widget
>[
child:
Center
(
//关闭广告
child:
CustomBtn
(
Align
(
title:
'暂停/播放'
,
alignment:
Alignment
.
topRight
,
child:
GestureDetector
(
onTap:
()
{
onTap:
()
{
setState
(()
{
state
?.
togglePlay
();
showAdvertCover
=
false
;
});
},
},
child:
const
Icon
(
Icons
.
cancel
,
size:
16
,
color:
Colors
.
white
,
),
),
),
),
),
Container
(
alignment:
Alignment
.
center
,
child:
const
Text
(
"一个广告封面"
,
style:
TextStyle
(
color:
Colors
.
white
),
),
)
],
),
),
)
:
const
Align
(),
Builder
(
builder:
(
BuildContext
context
)
{
state
=
GZVideoPlayer
.
of
(
context
);
return
const
SizedBox
();
})
],
/// 视频暂停回调
onPause:
(
value
)
{
debugPrint
(
"video paused"
);
setState
(()
{
isPlaying
=
false
;
});
},
/// 视频播放回调
onPlay:
(
value
)
{
debugPrint
(
"video played"
);
setState
(()
{
isPlaying
=
true
;
});
},
/// 视频播放结束回调
onEnded:
(
value
)
{
debugPrint
(
"video ended"
);
},
/// 视频播放进度回调
/// 可以用来匹配字幕
onTimeUpdate:
(
value
)
{
// debugPrint("timeupdate ${value.position.inSeconds}");
// var position = value.position.inMilliseconds / 1000;
//根据 position 来判断当前显示的字幕
},
onProgressDrag:
(
position
,
duration
)
{
debugPrint
(
"进度条拖拽的时间节点:
$position
"
);
debugPrint
(
"进度条总时长:
$duration
"
);
},
onVolume:
(
value
)
{
// debugPrint("onvolume $value");
},
onBrightness:
(
value
)
{
debugPrint
(
"onbrightness
$value
"
);
},
onFullscreen:
(
fullscreen
)
{
debugPrint
(
"is fullscreen
$fullscreen
"
);
setState
(()
{
_isFullscreen
=
fullscreen
;
});
},
onSpeedChange:
(
VideoSpeedItem
item
)
{
debugPrint
(
'current speed
${item.title}
'
);
},
/// 顶部控制栏点击返回按钮
onPop:
(
value
)
{
debugPrint
(
"返回上一页"
);
},
)
:
const
AspectRatio
(
aspectRatio:
16
/
9
,
child:
Center
(
child:
CircularProgressIndicator
(
strokeWidth:
2.0
),
),
),
//update data source
!
_isFullscreen
?
Expanded
(
child:
CustomScrollView
(
slivers:
[
SliverToBoxAdapter
(
child:
VideoListWidget
(
dataList:
dataList
,
onTapItem:
(
int
index
)
{
VideoModel
model
=
dataList
[
index
];
setState
(()
{
videoUrl
=
model
.
url
;
});
},
),
),
SliverToBoxAdapter
(
child:
Center
(
child:
CustomBtn
(
title:
'暂停/播放'
,
onTap:
()
{
state
?.
togglePlay
();
},
),
),
),
SliverToBoxAdapter
(
),
child:
Center
(
SliverToBoxAdapter
(
child:
CustomBtn
(
child:
Center
(
title:
'播放到指定位置'
,
child:
CustomBtn
(
onTap:
()
{
title:
'播放到指定位置'
,
state
?.
seekTo
(
const
Duration
(
seconds:
10
));
onTap:
()
{
},
state
?.
seekTo
(
const
Duration
(
seconds:
10
));
),
}
,
)
,
),
),
)
,
]
,
),
),
],
)
),
:
Container
(),
)
]),
:
Container
(),
]),
),
);
);
}
}
}
}
...
...
lib/video.dart
浏览文件 @
c24d98cd
...
@@ -121,7 +121,8 @@ class GZVideoPlayerState extends State<GZVideoPlayer>
...
@@ -121,7 +121,8 @@ class GZVideoPlayerState extends State<GZVideoPlayer>
bool
_initialized
=
false
;
bool
_initialized
=
false
;
/// 屏幕亮度
/// 屏幕亮度
final
ValueNotifier
<
double
>
_brightness
=
ValueNotifier
(
0.5
);
final
ValueNotifier
<
double
>
_brightness
=
ValueNotifier
(
0.0
);
late
double
_originBrightness
;
/// 视频音量
/// 视频音量
final
ValueNotifier
<
double
>
_volume
=
ValueNotifier
(
0.5
);
final
ValueNotifier
<
double
>
_volume
=
ValueNotifier
(
0.5
);
...
@@ -221,14 +222,18 @@ class GZVideoPlayerState extends State<GZVideoPlayer>
...
@@ -221,14 +222,18 @@ class GZVideoPlayerState extends State<GZVideoPlayer>
/// 常亮
/// 常亮
Wakelock
.
toggle
(
enable:
true
);
Wakelock
.
toggle
(
enable:
true
);
/// 初始化亮度为系统亮度
/// 初始化亮度为系统亮度
ScreenBrightness
().
current
.
then
((
brightness
)
{
initBrightness
();
_brightness
.
value
=
brightness
;
});
/// 倍数按钮标题
/// 倍数按钮标题
_speedTitle
=
widget
.
videoStyle
.
videoSpeedButtonStyle
.
title
;
_speedTitle
=
widget
.
videoStyle
.
videoSpeedButtonStyle
.
title
;
_initPlayer
();
_initPlayer
();
}
}
void
initBrightness
()
async
{
double
brightness
=
await
ScreenBrightness
().
current
;
_brightness
.
value
=
brightness
;
_originBrightness
=
brightness
;
}
@override
@override
void
didUpdateWidget
(
GZVideoPlayer
oldWidget
)
{
void
didUpdateWidget
(
GZVideoPlayer
oldWidget
)
{
if
(
oldWidget
.
dataSource
!=
widget
.
dataSource
)
{
if
(
oldWidget
.
dataSource
!=
widget
.
dataSource
)
{
...
@@ -251,6 +256,7 @@ class GZVideoPlayerState extends State<GZVideoPlayer>
...
@@ -251,6 +256,7 @@ class GZVideoPlayerState extends State<GZVideoPlayer>
_subscription
.
cancel
();
_subscription
.
cancel
();
_brightness
.
dispose
();
_brightness
.
dispose
();
_volume
.
dispose
();
_volume
.
dispose
();
ScreenBrightness
().
setScreenBrightness
(
_originBrightness
);
super
.
dispose
();
super
.
dispose
();
}
}
...
...
lib/widget/video_loading_view.dart
浏览文件 @
c24d98cd
...
@@ -8,27 +8,30 @@ class VideoLoadingView extends StatelessWidget {
...
@@ -8,27 +8,30 @@ class VideoLoadingView extends StatelessWidget {
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
Align
(
return
DecoratedBox
(
alignment:
Alignment
.
center
,
decoration:
const
BoxDecoration
(
color:
Colors
.
black
),
child:
Center
(
child:
Align
(
child:
Column
(
alignment:
Alignment
.
center
,
crossAxisAlignment:
CrossAxisAlignment
.
center
,
child:
Center
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
child:
Column
(
children:
<
Widget
>[
crossAxisAlignment:
CrossAxisAlignment
.
center
,
loadingStyle
.
customLoadingIcon
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
loadingStyle
.
customLoadingText
!=
null
children:
<
Widget
>[
?
loadingStyle
.
customLoadingText
!
loadingStyle
.
customLoadingIcon
,
:
Container
(
loadingStyle
.
customLoadingText
!=
null
margin:
const
EdgeInsets
.
only
(
top:
10
),
?
loadingStyle
.
customLoadingText
!
child:
Text
(
:
Container
(
loadingStyle
.
loadingText
,
margin:
const
EdgeInsets
.
only
(
top:
10
),
style:
TextStyle
(
child:
Text
(
color:
loadingStyle
.
loadingTextFontColor
,
loadingStyle
.
loadingText
,
fontSize:
loadingStyle
.
loadingTextFontSize
,
style:
TextStyle
(
color:
loadingStyle
.
loadingTextFontColor
,
fontSize:
loadingStyle
.
loadingTextFontSize
,
),
),
),
)
,
)
)
],
]
,
)
,
),
),
),
),
);
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论