diff --git a/lib/pages/history/controller.dart b/lib/pages/history/controller.dart index 2d47726b..7dc8e3a5 100644 --- a/lib/pages/history/controller.dart +++ b/lib/pages/history/controller.dart @@ -70,6 +70,7 @@ class HistoryController extends GetxController { SmartDialog.showToast( !pauseStatus.value ? '暂停观看历史' : '恢复观看历史'); pauseStatus.value = !pauseStatus.value; + localCache.put(LocalCacheKey.historyPause, pauseStatus.value); } SmartDialog.dismiss(); }, @@ -85,7 +86,7 @@ class HistoryController extends GetxController { Future historyStatus() async { var res = await UserHttp.historyStatus(); pauseStatus.value = res.data['data']; - localCache.put(LocalCacheKey.historyStatus, res.data['data']); + localCache.put(LocalCacheKey.historyPause, res.data['data']); } // 清空观看历史 diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index 3cc890b3..fe19ae0d 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -61,7 +61,6 @@ class VideoDetailController extends GetxController ReplyItemModel? firstFloor; final scaffoldKey = GlobalKey(); - Timer? timer; RxString bgCover = ''.obs; PlPlayerController plPlayerController = PlPlayerController.getInstance(); @@ -69,6 +68,8 @@ class VideoDetailController extends GetxController late String videoUrl; late String audioUrl; late Duration defaultST; + // 默认记录历史记录 + bool enableHeart = true; @override void onInit() { @@ -90,6 +91,11 @@ class VideoDetailController extends GetxController autoPlay.value = setting.get(SettingBoxKey.autoPlayEnable, defaultValue: true); enableHA.value = setting.get(SettingBoxKey.enableHA, defaultValue: true); + + if (user.get(UserBoxKey.userMid) == null || + localCache.get(LocalCacheKey.historyPause) == true) { + enableHeart = false; + } } showReplyReplyPanel() { @@ -164,6 +170,9 @@ class VideoDetailController extends GetxController : 'vertical', // 默认1倍速 speed: 1.0, + bvid: bvid, + cid: cid, + enableHeart: enableHeart, ); } @@ -265,34 +274,4 @@ class VideoDetailController extends GetxController } return result; } - - void loopHeartBeat() { - timer = Timer.periodic(const Duration(seconds: 5), (timer) { - markHeartBeat(); - }); - } - - void markHeartBeat() async { - if (user.get(UserBoxKey.userMid) == null) { - return; - } - if (localCache.get(LocalCacheKey.historyStatus) == true) { - return; - } - Duration progress = plPlayerController.position.value; - await VideoHttp.heartBeat( - bvid: bvid, - cid: cid, - progress: progress.inSeconds, - ); - } - - @override - void onClose() { - markHeartBeat(); - if (timer != null && timer!.isActive) { - timer!.cancel(); - } - super.onClose(); - } } diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index 2aefbfb1..e582e69d 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -70,15 +70,10 @@ class _VideoDetailPageState extends State void playerListener() { plPlayerController!.onPlayerStatusChanged.listen( (PlayerStatus status) async { - videoDetailController.markHeartBeat(); playerStatus = status; if (status == PlayerStatus.playing) { videoDetailController.isShowCover.value = false; - videoDetailController.loopHeartBeat(); } else { - if (videoDetailController.timer != null) { - videoDetailController.timer!.cancel(); - } // 播放完成停止 or 切换下一个 if (status == PlayerStatus.completed) { // 当只有1p或多p未打开自动播放时,播放完成还原进度条,展示控制栏 @@ -102,18 +97,12 @@ class _VideoDetailPageState extends State void dispose() { plPlayerController!.pause(); plPlayerController!.dispose(); - if (videoDetailController.timer != null) { - videoDetailController.timer!.cancel(); - } super.dispose(); } @override // 离开当前页面时 void didPushNext() async { - if (videoDetailController.timer!.isActive) { - videoDetailController.timer!.cancel(); - } videoDetailController.defaultST = plPlayerController!.position.value; plPlayerController!.pause(); super.didPushNext(); @@ -127,9 +116,6 @@ class _VideoDetailPageState extends State await Future.delayed(const Duration(milliseconds: 300)); plPlayerController!.play(); } - if (!videoDetailController.timer!.isActive) { - videoDetailController.loopHeartBeat(); - } super.didPopNext(); } diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index 5e6a4f15..0cff9f4c 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -8,6 +8,7 @@ import 'package:get/get.dart'; import 'package:hive/hive.dart'; import 'package:media_kit/media_kit.dart'; import 'package:media_kit_video/media_kit_video.dart'; +import 'package:pilipala/http/video.dart'; import 'package:pilipala/plugin/pl_player/models/data_source.dart'; import 'package:pilipala/utils/feed_back.dart'; import 'package:pilipala/utils/storage.dart'; @@ -74,6 +75,12 @@ class PlPlayerController { bool _autoPlay = false; final bool _listenersInitialized = false; + // 记录历史记录 + String _bvid = ''; + int _cid = 0; + int _heartDuration = 0; + bool _enableHeart = true; + Timer? _timer; Timer? _timerForSeek; Timer? _timerForVolume; @@ -228,7 +235,11 @@ class PlPlayerController { Duration? duration, // 方向 String? direction, - // 全屏模式 + // 记录历史记录 + String bvid = '', + int cid = 0, + // 历史记录开关 + bool enableHeart = true, }) async { try { _autoPlay = autoplay; @@ -239,6 +250,9 @@ class PlPlayerController { dataStatus.status.value = DataStatus.loading; // 初始化全屏方向 _direction.value = direction ?? 'horizontal'; + _bvid = bvid; + _cid = cid; + _enableHeart = enableHeart; if (_videoPlayerController != null && _videoPlayerController!.state.playing) { @@ -277,6 +291,9 @@ class PlPlayerController { removeListeners(); isBuffering.value = false; buffered.value = Duration.zero; + _heartDuration = 0; + _position.value = Duration.zero; + Player player = _videoPlayerController ?? Player( configuration: const PlayerConfiguration( @@ -383,6 +400,7 @@ class PlPlayerController { } else { // playerStatus.status.value = PlayerStatus.paused; } + makeHeartBeat(_position.value.inSeconds, type: 'status'); }), videoPlayerController!.stream.completed.listen((event) { if (event) { @@ -390,12 +408,14 @@ class PlPlayerController { } else { // playerStatus.status.value = PlayerStatus.playing; } + makeHeartBeat(_position.value.inSeconds, type: 'status'); }), videoPlayerController!.stream.position.listen((event) { _position.value = event; if (!isSliderMoving.value) { _sliderPosition.value = event; } + makeHeartBeat(event.inSeconds); }), videoPlayerController!.stream.duration.listen((event) { duration.value = event; @@ -684,10 +704,36 @@ class PlPlayerController { videoFitChangedTimer?.cancel(); } + // 记录播放记录 + Future makeHeartBeat(progress, {type = 'playing'}) async { + if (!_enableHeart) { + return false; + } + // 播放状态变化时,更新 + if (type == 'status') { + await VideoHttp.heartBeat( + bvid: _bvid, + cid: _cid, + progress: + playerStatus.status.value == PlayerStatus.completed ? -1 : progress, + ); + } else + // 正常播放时,间隔5秒更新一次 + if (progress - _heartDuration >= 5) { + _heartDuration = progress; + await VideoHttp.heartBeat( + bvid: _bvid, + cid: _cid, + progress: progress, + ); + } + } + Future dispose({String type = 'single'}) async { // 每次减1,最后销毁 if (type == 'single') { _playerCount.value -= 1; + _heartDuration = 0; if (playerCount.value > 0) { return; } diff --git a/lib/utils/data.dart b/lib/utils/data.dart index e6ab2ae3..e4361f92 100644 --- a/lib/utils/data.dart +++ b/lib/utils/data.dart @@ -10,7 +10,11 @@ class Data { static Future historyStatus() async { Box localCache = GStrorage.localCache; + Box user = GStrorage.user; + if (user.get(UserBoxKey.userMid) == null) { + return; + } var res = await UserHttp.historyStatus(); - localCache.put(LocalCacheKey.historyStatus, res.data['data']); + localCache.put(LocalCacheKey.historyPause, res.data['data']); } } diff --git a/lib/utils/storage.dart b/lib/utils/storage.dart index e3743908..7fd8b3a5 100644 --- a/lib/utils/storage.dart +++ b/lib/utils/storage.dart @@ -122,8 +122,8 @@ class SettingBoxKey { } class LocalCacheKey { - // 历史记录暂停状态 默认false - static const String historyStatus = 'historyStatus'; + // 历史记录暂停状态 默认false 记录 + static const String historyPause = 'historyPause'; } class VideoBoxKey {