flutter 自定义播放器进度条

flutter 自定义播放器进度条FijkPlayer第三方的一个视频播放器,这是一个大佬基于比利比利播放器封装的,有常用的API可自定义样式pub传送门默认的样式展示:自定义的样式展示:**使用:**fijkplayer:^0.8.4///声明一个FijkPlayerfinalFijkPlayerplayer=FijkPlayer();@overridevoidinitState(){///指定视频地址player.setDataSource(“ht…

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,
            );
          },
        ),
      ),),
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
自定义的底部

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  / 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){

                            ///转化成double
                            setState(() => this.sliderValue = val.floorToDouble());
                            /// 设置进度
                            player.seekTo(this.sliderValue.toInt());
//                            print(this.sliderValue);
                          },
                        ),
                      ),
                      ),
                      Text(“${durrentPos} / ${duration}”,style: TextStyle(color: Colors.white),),
                    ],
                  ),
                ),
              ],
            )
        ),
      ),
    );
  }

  @override
  void dispose() {

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

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

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

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • phpstorm激活码2022.01.13(JetBrains全家桶)2022.03.06

    (phpstorm激活码2022.01.13)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年4月2日
  • 树莓派搭建MQTT服务器(基于EMQ)「建议收藏」

    树莓派搭建MQTT服务器(基于EMQ)「建议收藏」文章目录1.准备工作1.1知识储备2.安装EMQ3.测试MQTT服务器3.1新建服务器管理员3.2登录到服务器后台3.3MQTT客户端测试1.准备工作1.1知识储备关于MQTT协议能点进来的基本都知道MQTT协议是啥了吧,不知道的自行百度吧,这里就默认各位都知道了。关于EMQEMQX是一款完全开源,高度可伸缩,高可用的分布式MQTT消息服务器,适用于IoT、M2M和移动应用程序,可处理千万级别的并发客户端。EMQX是跨平台的,支持Linux、Unix、macOS以

    2022年5月28日
  • 在线即时展现 Html、JS、CSS 编辑工具 – JSFiddle

    在线即时展现 Html、JS、CSS 编辑工具 – JSFiddle

    2022年2月7日
  • 计算机入门基础知识

    计算机入门基础知识好久以前帮学弟学妹们总结的计算机入门基础资料,我觉得算是很好的科普入门资料了。毕竟是我辛苦一字一字写出来的。。。目录1.1.1计算机的发展史1946年ENIAC在宾夕法尼亚大学被制作,数字积分

    2022年8月4日
  • JSON字符串转对象_微信小程序配置文件

    JSON字符串转对象_微信小程序配置文件微信就是最大的坑!!!!!之前做的小程序,前台都是默认参数(返回json之类的),使用也都正常然而,今天发现的问题也是愁死个人,返回的json就是字符串,自然取不到里面的数据.小程序的js还有好多函数他不支持,坑.之前都是returnjson_encode($arr);这样子返回数据,代码都是一样,就这次莫名不好使.网上的答案也是千篇一律.最后有两篇文章都提到了一个问题,一试,果然有效.转jso…

    2022年9月28日
  • implicitly declaring library_no such object available

    implicitly declaring library_no such object availableAPAP论文源码中全局单应GH的部分!

    2022年9月23日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号