当前位置:网站首页>Flutter custom player progress bar
Flutter custom player progress bar
2022-07-26 08:27:00 【Peanut - Summer】
FijkPlayer A third party video player , This is a big guy based on Billy Billy player package , There is a common API Customizable styles
pub Portal
Default style Exhibition :
Custom style Exhibition :
** Use :**
fijkplayer: ^0.8.4
/// Make a statement FijkPlayer
final FijkPlayer player = FijkPlayer();
@override
void initState() {
/// Specify the video address
player.setDataSource("http://video.kekedj.com/20190215/mp4/20190527/TWICE%20-%20BDZ%20(Korean%20Ver.)%20(Stage%20Mix)%EF%BC%88%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%AD%97%E5%B9%95%EF%BC%89.mp4", autoPlay: true);
super.initState();
}
@override
void dispose() {
super.dispose();
player.release();
}
/// Use FijkView
body: SafeArea(child: Center(
child: FijkView(
color: Colors.black,
player: player,
panelBuilder: (FijkPlayer player, FijkData data, BuildContext context, Size viewSize, Rect texturePos) {
/// Use a custom layout
return CustomFijkPanel(
player: player,
buildContext: context,
viewSize: viewSize,
texturePos: texturePos,
);
},
),
),),
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Custom bottom
class CustomFijkWidgetBottom extends StatefulWidget {
final FijkPlayer player;
final BuildContext buildContext;
final Size viewSize;
final Rect texturePos;
const CustomFijkPanel({
@required this.player,
this.buildContext,
this.viewSize,
this.texturePos,
});
@override
_CustomFijkWidgetBottomState createState() => _CustomFijkWidgetBottomState();
}
class _CustomFijkWidgetBottomState extends State<CustomFijkWidgetBottom > {
FijkPlayer get player => widget.player;
/// Play status
bool _playing = false;
/// Is the status bar displayed + menu bar
bool isPlayShowCont = true;
/// Total duration
String duration = "00:00:00";
/// Played for
String durrentPos = "00:00:00";
/// Total length of progress bar
double maxDurations = 0.0;
/// Stream listener
StreamSubscription _currentPosSubs;
/// Timer
Timer _timer;
/// Progress bar current progress
double sliderValue = 0.0;
@override
void initState() {
/// Advance loading
/// monitor
widget.player.addListener(_playerValueChanged);
/// Receive stream
_currentPosSubs = widget.player.onCurrentPosUpdate.listen((v) {
setState(() {
/// Get the current playback progress in real time ( Progress bar )
this.sliderValue = v.inMilliseconds.toDouble();
/// Get the current playback progress in real time ( Digital display )
durrentPos = v.toString().substring(0,v.toString().indexOf("."));
});
});
/// initialization
super.initState();
}
/// Monitor
void _playerValueChanged() {
FijkValue value = player.value;
/// Get the total time of progress bar
maxDurations = value.duration.inMilliseconds.toDouble();
/// Get the duration of the presentation
duration = value.duration.toString().substring(0,value.duration.toString().indexOf("."));
/// Play status
bool playing = (value.state == FijkState.started);
if (playing != _playing) setState(() =>_playing = playing);
}
@override
Widget build(BuildContext context) {
Rect rect = Rect.fromLTRB(
max(0.0, widget.texturePos.left),
max(0.0, widget.texturePos.top),
min(widget.viewSize.width, widget.texturePos.right),
min(widget.viewSize.height, widget.texturePos.bottom),
);
return Positioned.fromRect(
rect: rect,
child: GestureDetector(
onTap: (){
setState(() {
/// Show 、 hide Progress bar + The title bar
isPlayShowCont = !isPlayShowCont;
/// If it shows , 3 Seconds later Hide progress bar + The title bar
if(isPlayShowCont) _timer = Timer(Duration(seconds: 3),()=>isPlayShowCont = false);
});
},
child:Container(
color: Color.fromRGBO(0, 0, 0, 0.0),
alignment: Alignment.bottomLeft,
child:Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
/// The title bar
!isPlayShowCont ? SizedBox() :Container(
color: Color.fromRGBO(0, 0, 0, 0.65),
height: 35,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(icon: Icon(Icons.chevron_left,color: Colors.white,), onPressed: (){
Navigator.pop(context);
}),
],
),
),
/// Control bar
!isPlayShowCont ? SizedBox() : Container(
color: Color.fromRGBO(0, 0, 0, 0.65),
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(
_playing ? Icons.pause : Icons.play_arrow,
color: Colors.white,
),
onPressed: () => _playing ? widget.player.pause() : widget.player.start(),
),
/// Progress bar Use Slider Slide component implementation
Expanded(child: SliderTheme(
data: SliderTheme.of(context).copyWith(
// Dragged color
activeTrackColor: Colors.greenAccent,
// Colors not dragged
inactiveTrackColor: Colors.green,
// Background color of bubbles indicating progress
valueIndicatorColor: Colors.green,
// Color of bubble text indicating progress
valueIndicatorTextStyle: TextStyle(
color:Colors.white,
),
// The color of the slider center
thumbColor: Colors.green,
// The color of the slider edge
overlayColor: Colors.white,
// After dividing the progress line , The color of the interval between intermittent lines
inactiveTickMarkColor: Colors.white,
),
child: Slider(
value: this.sliderValue,
label: '${int.parse((this.sliderValue / 3600000).toStringAsFixed(0))<10?'0'+(this.sliderValue / 3600000).toStringAsFixed(0):(this.sliderValue / 3600000).toStringAsFixed(0)}:${int.parse(((this.sliderValue % 3600000) / 60000).toStringAsFixed(0))<10?'0'+((this.sliderValue % 3600000) / 60000).toStringAsFixed(0):((this.sliderValue % 3600000) / 60000).toStringAsFixed(0)}:${int.parse(((this.sliderValue % 60000) / 1000).toStringAsFixed(0))<10?'0'+((this.sliderValue % 60000) / 1000).toStringAsFixed(0):((this.sliderValue % 60000) / 1000).toStringAsFixed(0)}',
min: 0.0,
max: maxDurations,
divisions: 1000,
onChanged: (val){
/// Turn it into double
setState(() => this.sliderValue = val.floorToDouble());
/// Set the schedule
player.seekTo(this.sliderValue.toInt());
// print(this.sliderValue);
},
),
),
),
Text("${durrentPos} / ${duration}",style: TextStyle(color: Colors.white),),
],
),
),
],
)
),
),
);
}
@override
void dispose() {
/// lsnrctl stop
player.removeListener(_playerValueChanged);
/// Close flow callback
_currentPosSubs?.cancel();
super.dispose();
}
}
边栏推荐
- Burp suite Chapter 6 how to use burp spider
- Beauty naked chat for a while, naked chat over the crematorium!
- 2022 / 7 / 16 exam summary
- The first ide overlord in the universe, replaced...
- 2022-7-8 personal qualifying 5 competition experience (supplementary)
- 2022/7/12 exam summary
- Random distribution learning notes
- Dev gridcontrol captures key events
- 请问flink sql client 在sink表,有什么办法增大写出速率吗。通过sink表的同步时
- 我,35岁了。
猜你喜欢

外卖小哥,才是这个社会最大的托底

One click deployment lamp and LNMP architecture

日常一记(11)--word公式输入任意矩阵

22-07-12 personal training match 1 competition experience

Let's talk about the three core issues of concurrent programming.

Nodejs2day (modularization of nodejs, NPM download package, module loading mechanism)

Prefix infix suffix expression (written conversion)

2022-7-7 personal qualifying 4 competition experience

Kotlin operator
![[GUI] swing package (window, pop-up window, label, panel, button, list, text box)](/img/05/8e7483768a4ad2036497cac136b77d.png)
[GUI] swing package (window, pop-up window, label, panel, button, list, text box)
随机推荐
分享高压超低噪声LDO测试结果(High Voltage Ultra-low Noise LDO)
OSPF总结
BGP --- 边界网关协议
JS tool function Encyclopedia
SPSS用KMeans、两阶段聚类、RFM模型在P2P网络金融研究借款人、出款人行为规律数据
Kotlin operator
第三天作业
BGP的基本配置
2022-7-6 personal qualifying 3 competition experience
flex三列布局
2022-7-9 personal qualifying 6 competition experience
Apple's tough new rule: third-party payment also requires a percentage, and developers lose a lot!
2022/7/7 exam summary
Beauty naked chat for a while, naked chat over the crematorium!
Burp suite Chapter 9 how to use burp repeater
2022/7/12 exam summary
[June 29, 2022] examination summary
[time complexity, space complexity]
import error: ‘Icon‘ is not exported from ‘antd‘. Import icon error
mysql函数汇总之条件判断函数