zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

flutter 自定义播放器进度条

flutter 自定义 播放器 进度条
2023-06-13 09:13:03 时间

大家好,又见面了,我是你们的朋友全栈君。

FijkPlayer 第三方的一个视频播放器,这是一个大佬基于比利比利播放器封装的,有常用的API 可自定义样式 pub传送门

默认的样式 展示:

自定义的样式 展示:

**使用:** fijkplayer: ^0.8.4

/// 声明一个FijkPlayer final FijkPlayer player = FijkPlayer(); @override void initState() { /// 指定视频地址 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(); } /// 使用FijkView body: SafeArea(child: Center( child: FijkView( color: Colors.black, player: player, panelBuilder: (FijkPlayer player, FijkData data, BuildContext context, Size viewSize, Rect texturePos) { /// 使用自定义的布局 return CustomFijkPanel( player: player, buildContext: context, viewSize: viewSize, texturePos: texturePos, ); }, ), ),), 自定义的底部

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; /// 播放状态 bool _playing = false; /// 是否显示状态栏+菜单栏 bool isPlayShowCont = true; /// 总时长 String duration = “00:00:00”; /// 已播放时长 String durrentPos = “00:00:00”; /// 进度条总长度 double maxDurations = 0.0; /// 流监听器 StreamSubscription _currentPosSubs; /// 定时器 Timer _timer; /// 进度条当前进度 double sliderValue = 0.0;

@override void initState() { /// 提前加载 /// 进行监听 widget.player.addListener(_playerValueChanged); /// 接收流 _currentPosSubs = widget.player.onCurrentPosUpdate.listen((v) { setState(() { /// 实时获取当前播放进度(进度条) this.sliderValue = v.inMilliseconds.toDouble(); /// 实时获取当前播放进度(数字展示) durrentPos = v.toString().substring(0,v.toString().indexOf(“.”)); }); }); /// 初始化 super.initState(); }

/// 监听器 void _playerValueChanged() { FijkValue value = player.value; /// 获取进度条总时长 maxDurations = value.duration.inMilliseconds.toDouble(); /// 获取展示的时长 duration = value.duration.toString().substring(0,value.duration.toString().indexOf(“.”)); /// 播放状态 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(() { /// 显示 、隐藏 进度条+标题栏 isPlayShowCont = !isPlayShowCont; /// 如果显示了 , 3秒后 隐藏进度条+标题栏 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>[ /// 标题栏 !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); }),

], ), ), /// 控制条 !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(), ), /// 进度条 使用Slider滑动组件实现 Expanded(child: SliderTheme( data: SliderTheme.of(context).copyWith( //已拖动的颜色 activeTrackColor: Colors.greenAccent, //未拖动的颜色 inactiveTrackColor: Colors.green, //提示进度的气泡的背景色 valueIndicatorColor: Colors.green, //提示进度的气泡文本的颜色 valueIndicatorTextStyle: TextStyle( color:Colors.white, ), //滑块中心的颜色 thumbColor: Colors.green, //滑块边缘的颜色 overlayColor: Colors.white, //对进度线分割后,断续线中间间隔的颜色 inactiveTickMarkColor: Colors.white, ), child: Slider( value: this.sliderValue, label: ‘{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){ ///转化成double setState(() => this.sliderValue = val.floorToDouble()); /// 设置进度 player.seekTo(this.sliderValue.toInt()); // print(this.sliderValue); }, ), ), ), Text(“

@override void dispose() { /// 关闭监听 player.removeListener(_playerValueChanged); /// 关闭流回调 _currentPosSubs?.cancel(); super.dispose(); } }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/234057.html原文链接:https://javaforall.cn