flutter 视频播放器 FijkPlayer视频播放器的使用

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  / 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();
  }
}
  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
Flutter 提供了一个名为 `video_player` 的插件,可以用于在 Flutter 应用程序中播放视频。使用 `video_player` 插件,你可以轻松地将视频嵌入到你的应用程序中,并控制视频的播放、暂停、停止等操作。 以下是一个简单的示例代码,演示如何使用 `video_player` 插件播放本地视频文件: ```dart import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Video Player Demo', home: VideoPlayerScreen(), ); } } class VideoPlayerScreen extends StatefulWidget { @override _VideoPlayerScreenState createState() => _VideoPlayerScreenState(); } class _VideoPlayerScreenState extends State<VideoPlayerScreen> { VideoPlayerController _controller; @override void initState() { super.initState(); _controller = VideoPlayerController.asset('assets/sample_video.mp4') ..initialize().then((_) { setState(() {}); }); } @override void dispose() { super.dispose(); _controller.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Video Player Demo'), ), body: Center( child: _controller.value.initialized ? AspectRatio( aspectRatio: _controller.value.aspectRatio, child: VideoPlayer(_controller), ) : Container(), ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { _controller.value.isPlaying ? _controller.pause() : _controller.play(); }); }, child: Icon( _controller.value.isPlaying ? Icons.pause : Icons.play_arrow, ), ), ); } } ``` 在上面的示例代码中,我们首先创建了一个 `VideoPlayerController` 对象,并使用 `asset` 方法加载了一个本地视频文件。然后,在 `initState` 方法中,我们初始化了 `VideoPlayerController` 对象,并在初始化完成后调用了 `setState` 方法,以便更新 UI。接下来,在 `build` 方法中,我们使用 `AspectRatio` 和 `VideoPlayer` 将视频嵌入到应用程序中,并使用一个浮动操作按钮控制视频的播放和暂停。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值