diff --git a/lib/pages/audio/controller.dart b/lib/pages/audio/controller.dart index 0cdc58a08..fdb1ad174 100644 --- a/lib/pages/audio/controller.dart +++ b/lib/pages/audio/controller.dart @@ -300,8 +300,9 @@ class AudioController extends GetxController player = null; return; } + final stream = player!.stream; _subscriptions = [ - player!.stream.position.listen((position) { + stream.position.listen((position) { if (isDragging) return; if (position.inSeconds != this.position.value.inSeconds) { this.position.value = position; @@ -309,8 +310,8 @@ class AudioController extends GetxController videoPlayerServiceHandler?.onPositionChange(position); } }), - player!.stream.duration.listen(duration.call), - player!.stream.playing.listen((playing) { + stream.duration.listen(duration.call), + stream.playing.listen((playing) { final PlayerStatus playerStatus; if (playing) { animController.forward(); @@ -321,7 +322,7 @@ class AudioController extends GetxController } videoPlayerServiceHandler?.onStatusChange(playerStatus, false, false); }), - player!.stream.completed.listen((completed) { + stream.completed.listen((completed) { _videoDetailController?.playedTime = duration.value; videoPlayerServiceHandler?.onStatusChange( PlayerStatus.completed, @@ -774,6 +775,7 @@ class AudioController extends GetxController ..onSeek = null ..onVideoDetailDispose(hashCode.toString()); _subscriptions?.forEach((e) => e.cancel()); + _subscriptions?.clear(); _subscriptions = null; player?.dispose(); player = null; diff --git a/lib/pages/video/controller.dart b/lib/pages/video/controller.dart index bd2ba4219..52fa69514 100644 --- a/lib/pages/video/controller.dart +++ b/lib/pages/video/controller.dart @@ -635,7 +635,6 @@ class VideoDetailController extends GetxController _autoPlay.value = true; playedTime = plPlayerController.position; plPlayerController - ..removeListeners() ..isBuffering.value = false ..buffered.value = Duration.zero; diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 5ed07e272..c93071cb2 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -63,6 +63,8 @@ import 'package:path/path.dart' as path; import 'package:wakelock_plus/wakelock_plus.dart'; import 'package:window_manager/window_manager.dart'; +typedef PlayCallback = Future? Function(); + class PlPlayerController with BlockConfigMixin { Player? _videoPlayerController; VideoController? _videoController; @@ -484,11 +486,11 @@ class PlPlayerController with BlockConfigMixin { return _instance != null; } - static void setPlayCallBack(Future? Function()? playCallBack) { + static void setPlayCallBack(PlayCallback? playCallBack) { _playCallBack = playCallBack; } - static Future? Function()? _playCallBack; + static PlayCallback? _playCallBack; static Future? playIfExists() { // await _instance?.play(repeat: repeat, hideControls: hideControls); @@ -625,6 +627,7 @@ class PlPlayerController with BlockConfigMixin { await _createVideoController(dataSource, seekTo, volume); if (_playerCount == 0) { + _removeListeners(); _videoPlayerController?.dispose(); _videoPlayerController = null; _videoController = null; @@ -640,8 +643,6 @@ class PlPlayerController with BlockConfigMixin { // 数据加载完成 dataStatus.value = DataStatus.loaded; - // listen the video player events - startListeners(); await _initializePlayer(); onInit?.call(); } catch (err, stackTrace) { @@ -751,6 +752,9 @@ class PlPlayerController with BlockConfigMixin { referer: HttpString.baseUrl, ); // await player.setAudioTrack(.auto()); + + _startListeners(player); + return player; } @@ -760,8 +764,6 @@ class PlPlayerController with BlockConfigMixin { Duration? seekTo, Volume? volume, ) async { - // 每次配置时先移除监听 - removeListeners(); isBuffering.value = false; buffered.value = Duration.zero; _heartDuration = 0; @@ -774,6 +776,7 @@ class PlPlayerController with BlockConfigMixin { if (player == null) { player = await _initPlayer(); if (_playerCount == 0) { + _removeListeners(); player.dispose(); player = null; _videoController = null; @@ -916,15 +919,16 @@ class PlPlayerController with BlockConfigMixin { return null; } - List subscriptions = []; - final Set _positionListeners = {}; - final Set _statusListeners = {}; + List? _subscriptions; + final Set> _positionListeners = {}; + final Set> _statusListeners = {}; /// 播放事件监听 - void startListeners() { - final controllerStream = videoPlayerController!.stream; - subscriptions = [ - controllerStream.playing.listen((event) { + void _startListeners(NativePlayer player) { + assert(_subscriptions == null); + final stream = player.stream; + _subscriptions = [ + stream.playing.listen((event) { WakelockPlus.toggle(enable: event); if (event) { if (_shouldSetPip) { @@ -953,7 +957,7 @@ class PlPlayerController with BlockConfigMixin { makeHeartBeat(positionSeconds.value, type: HeartBeatType.status); } }), - controllerStream.completed.listen((event) { + stream.completed.listen((event) { if (event) { playerStatus.value = PlayerStatus.completed; @@ -966,7 +970,7 @@ class PlPlayerController with BlockConfigMixin { } makeHeartBeat(positionSeconds.value, type: HeartBeatType.completed); }), - controllerStream.position.listen((event) { + stream.position.listen((event) { position = event; updatePositionSecond(); if (!isSliderMoving.value) { @@ -980,14 +984,14 @@ class PlPlayerController with BlockConfigMixin { } makeHeartBeat(event.inSeconds); }), - controllerStream.duration.listen((Duration event) { + stream.duration.listen((Duration event) { duration.value = event; }), - controllerStream.buffer.listen((Duration event) { + stream.buffer.listen((Duration event) { buffered.value = event; updateBufferedSecond(); }), - controllerStream.buffering.listen((bool event) { + stream.buffering.listen((bool event) { isBuffering.value = event; videoPlayerServiceHandler?.onStatusChange( playerStatus.value, @@ -996,14 +1000,14 @@ class PlPlayerController with BlockConfigMixin { ); }), if (kDebugMode) - controllerStream.log.listen(((PlayerLog log) { + stream.log.listen(((PlayerLog log) { if (log.level == 'error' || log.level == 'fatal') { Utils.reportError('${log.level}: ${log.prefix}: ${log.text}', null); } else { debugPrint(log.toString()); } })), - controllerStream.error.listen((String event) { + stream.error.listen((String event) { if (dataSource is FileSource && event.startsWith("Failed to open file")) { return; @@ -1078,8 +1082,10 @@ class PlPlayerController with BlockConfigMixin { } /// 移除事件监听 - Future removeListeners() { - return Future.wait(subscriptions.map((e) => e.cancel())); + void _removeListeners() { + _subscriptions?.forEach((e) => e.cancel()); + _subscriptions?.clear(); + _subscriptions = null; } void _cancelSubForSeek() { @@ -1488,20 +1494,20 @@ class PlPlayerController with BlockConfigMixin { } } - void addPositionListener(Function(Duration position) listener) { + void addPositionListener(ValueChanged listener) { if (_playerCount == 0) return; _positionListeners.add(listener); } - void removePositionListener(Function(Duration position) listener) => + void removePositionListener(ValueChanged listener) => _positionListeners.remove(listener); - void addStatusLister(Function(PlayerStatus status) listener) { + void addStatusLister(ValueChanged listener) { if (_playerCount == 0) return; _statusListeners.add(listener); } - void removeStatusLister(Function(PlayerStatus status) listener) => + void removeStatusLister(ValueChanged listener) => _statusListeners.remove(listener); // 记录播放记录 @@ -1625,8 +1631,7 @@ class PlPlayerController with BlockConfigMixin { windowManager.setAlwaysOnTop(false); } - removeListeners(); - subscriptions.clear(); + _removeListeners(); _positionListeners.clear(); _statusListeners.clear(); if (playerStatus.isPlaying) {