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的一系列引用
相关推荐
凌晨两点的菜鸡几秒前
前端部署-CICD
前端·nginx
林太白11 分钟前
NestJS-字典类型模块
前端·javascript·nestjs
林太白13 分钟前
NestJS-字典数据模块
前端·javascript·nestjs
林太白23 分钟前
Rust搜索优化
前端·后端·rust
用户38022585982431 分钟前
vue3源码解析:编译之解析器实现原理
前端·vue.js·源码阅读
Ygrowly32 分钟前
搭建 Mock 服务,实现前端自调
前端
火车叼位36 分钟前
threejs api速查表, 你的下一个鼠标垫图案素材
前端·api·three.js
铃铃六39 分钟前
typescript中tpye和interface的区别
前端·typescript
页面魔术41 分钟前
🔥来听听尤雨溪是怎么亲述无虚拟dom的吧
前端·vue.js·前端框架
小old弟41 分钟前
⭐ NestJS入门指南:从零开始构建高效Node.js服务端应用
前端