flutter封装vlcplayer的控制器
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();}});}}}
引用
GlobalVlcController _glc = GlobalVlcController();
///....对_glc的一系列引用