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的一系列引用
相关推荐
极客密码7 小时前
感谢雷总!Mimo大模型价值¥659/月的 MAX 套餐,让我免费领到了!
前端·ai编程·claude
深念Y8 小时前
我明白为什么B站没法在浏览器开直播了——Windows Chrome推流踩坑全记录
前端·chrome·webrtc·浏览器·srs·直播·flv
zhangxingchao8 小时前
AI应用开发七:可以替代 RAG 的技术
前端·人工智能·后端
Sun@happy8 小时前
现代 Web 前端渗透——基础篇(1)
前端·web安全
希冀1239 小时前
【CSS学习第十一篇】
前端·css·学习
隔窗听雨眠9 小时前
doctype、charset、meta如何控制整个渲染流水线
java·服务器·前端
kyriewen9 小时前
写组件文档写到吐?我用AI自动生成Storybook,同事以后直接抄
前端·javascript·面试
excel9 小时前
🧠 Prisma 表名大写 vs SQL 导出小写问题深度解析(附踩坑与解决方案)
前端·后端
周淳APP9 小时前
【前端工程化原理通识:从源头到运行时的理论阐述】
前端·编译·打包·前端工程化
莞凰9 小时前
昇腾CANN的“传音入密“:hccl仓库探秘
flutter·ui·transformer