flutter封装vlcplayer的控制器

dart 复制代码
import 'dart:async';

import 'package:flutter_vlc_player/flutter_vlc_player.dart';
import 'package:flutter/material.dart';

class GlobalVlcController extends ChangeNotifier {

  //设置单例
  /*static final GlobalVlcController _instance = GlobalVlcController._internal();

  factory GlobalVlcController() => _instance;

  GlobalVlcController._internal();*/

  late VlcPlayerController _controller;
  String? _currentUrl;

  bool _isInitialized = false;

  VlcPlayerController get controller => _controller;

  bool get isInitialized => _isInitialized;

  VoidCallback? _onInitListener;
  bool isSetLoop = false;

  //初始化控制器
  Future<void> initialize({String? url}) async {
    print('视频播放器初始化==========$_isInitialized');
    if (_isInitialized) {
      if (_currentUrl != url && url != null && url.isNotEmpty) {
        await setDataSource(url);
      }
      return;
    }
    _doInit(url);
  }

  /*
    * 这个方法自带初始化无需再调用initialized()
    * 控制器虽然初始化完成但是元数据还未解析完成。
    * _controller.value.isInitialized为true,但是获取视频宽高时可能获取不到。
    * 可以使用轮询Timer.periodic()去获取,获取到后取消轮询[可看获取 宽、高示例]
    * */
  _doInit(String? url){
    _controller = VlcPlayerController.network(
        url?? '',
        autoPlay: false,
        options: VlcPlayerOptions(
          advanced: VlcAdvancedOptions([
            VlcAdvancedOptions.networkCaching(200),
          ]),
          rtp: VlcRtpOptions([
            VlcRtpOptions.rtpOverRtsp(true),
          ]),
          http: VlcHttpOptions([
            VlcHttpOptions.httpReconnect(true),
          ]),
        )
    );

    _currentUrl = url;
    _isInitialized = true;
    notifyListeners();
  }


  //设置播放资源
  Future<void> setDataSource(String url) async {
    if (_currentUrl == url) return;

    _currentUrl = url;
    await _controller.stop();
    await _controller.setMediaFromNetwork(url);
    notifyListeners();
  }

  //播放
  Future<void> play() async {
    await _controller.play();
  }

  //暂停
  Future<void> pause() async {
    await _controller.pause();
  }

  //初始化监听-只会调用一次
  Future<void> addOnInitListener(VoidCallback listener) async {
    if (_isInitialized) {
      _onInitListener = listener;
      _controller.addOnInitListener(_onInitListener!);
    }
  }

  //添加监听
  addListener(VoidCallback listener) {
    if(_isInitialized){
      _controller.addListener(listener);
    }
  }

  //移除监听
  removeListener(VoidCallback listener){
    if(_isInitialized){
      _controller.removeListener(listener);
    }
  }


  //设置循环播放-vlcPlayer设置循环播放失效,以这种方式循环播放
  addLoopListener(){
    if(_isInitialized){
      _controller.addListener(loopListener);
    }
  }

  loopListener(){
    if (_controller.value.playingState == PlayingState.ended) {
      _controller.stop().then((_){
        _controller.setVolume(0);
        _controller.play();
        isSetLoop = true;
        notifyListeners();
        print('isSetLoop===== $isSetLoop');
      });
    }
  }

  //销毁控制器
  Future<void> disposeController() async {
    print('=播放器销毁释放===');
    try {
      if (_isInitialized && controller.value.isInitialized) {
        if(_onInitListener != null){
          _controller.removeOnInitListener(_onInitListener!);
        }
        if(isSetLoop == true){
          _controller.removeListener(loopListener);
          isSetLoop = false;
        }
        if(_controller.value.isInitialized == true){
          /*if(_controller.value.isPlaying){
          _controller.pause();
        }*/
          await _controller.stop();
          await _controller.dispose().then((_){
            _isInitialized = false;
            _currentUrl = null;
            notifyListeners();
          });
        }
      }
    }catch(e){
      print('销毁出错:${e}');
    }
  }


  /*
  * 获取宽、高示例
  * */
  getVideoSizeInfo() async {
    if (_isInitialized && _controller.value.isInitialized) {
      int _attempt = 0;
      Timer.periodic(Duration(milliseconds: 300), (timer) {
        final _size = _controller.value.size;
        if (_size.width > 0 && _size.height > 0) {
          timer.cancel(); // 宽高有值了,停止轮询
          print('width===== ${_size.width}');
          print('height===== ${_size.height}');
        }else if(_attempt>= 200){//1分钟后还未获取到停止轮询
          timer.cancel();
        }
      });
    }
  }

}

引用

dart 复制代码
GlobalVlcController _glc = GlobalVlcController();
///....对_glc的一系列引用
相关推荐
中微子36 分钟前
React状态管理最佳实践
前端
烛阴1 小时前
void 0 的奥秘:解锁 JavaScript 中 undefined 的正确打开方式
前端·javascript
中微子1 小时前
JavaScript 事件与 React 合成事件完全指南:从入门到精通
前端
Hexene...1 小时前
【前端Vue】如何实现echarts图表根据父元素宽度自适应大小
前端·vue.js·echarts
初遇你时动了情1 小时前
腾讯地图 vue3 使用 封装 地图组件
javascript·vue.js·腾讯地图
dssxyz1 小时前
uniapp打包微信小程序主包过大问题_uniapp 微信小程序时主包太大和vendor.js过大
javascript·微信小程序·uni-app
天天扭码2 小时前
《很全面的前端面试题》——HTML篇
前端·面试·html
xw52 小时前
我犯了错,我于是为我的uni-app项目引入环境标志
前端·uni-app
!win !2 小时前
被老板怼后,我为uni-app项目引入环境标志
前端·小程序·uni-app
Burt2 小时前
tsdown vs tsup, 豆包回答一坨屎,还是google AI厉害
前端