flutter 自定义播放器进度条

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

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

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();
  }
}

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • idea mybatisplus插件_浏览器中的插件是什么

    idea mybatisplus插件_浏览器中的插件是什么IDEA中的MyBatis插件MybatispluginFreeMybatispluginMybatistoolsMybatisCodeHelperPro因为idea自己不支持xml和映射器接口之间的跳转,所以搜了一下Mybatis的插件,自己记录一下,备忘。其他的插件有空再试试。Mybatisplugin功能强大,7天免费试用。网上很多激活成功教程教程,我没有试过FreeMybat…

  • Linux 修改目录下所有文件权限

    Linux 修改目录下所有文件权限sudochmod777/目录/-R

  • vuerouter配置_vue面包屑

    vuerouter配置_vue面包屑介绍VueRouter是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:嵌套的路由/视图表模块化的、基于组件的路由配置路由参

  • 修改phpstorm的字体样式和大小

    修改phpstorm的字体样式和大小

    2021年10月15日
  • Web前端和Web后端的区分「建议收藏」

    一、绪论1、前台:呈现给用户的视觉和基本的操作。后台:用户浏览网页时,我们看不见的后台数据跑动。后台包括前端、后端。前端:对应我们写的html、css、javascript等网页语言作用在前端网页。后端:对应jsp、javaBean、dao层、action层和service层的业务逻辑代码。(包括数据库)为什么jsp是后端呢?主要是jsp的运行原理是在tomcat服务器运…

  • Spring Cloud 从入门到精通

    SpringCloud是一套完整的微服务解决方案,基于SpringBoot框架,准确的说,它不是一个框架,而是一个大的容器,它将市面上较好的微服务框架集成进来,从而简化了开发者的代码量。本课程由浅入深带领大家一步步攻克SpringCloud各大模块,接着通过一个实例带领大家了解大型分布式微服务架构的搭建过程,最后深入源码加深对它的了解。本课程共分为四个部分:第一部分(第…

发表回复

您的电子邮箱地址不会被公开。

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