opt: make heartbeat when changing episode

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-01-05 18:26:49 +08:00
parent 78180a1dd1
commit 8ae92b859f
5 changed files with 66 additions and 41 deletions

View File

@@ -377,6 +377,8 @@ class BangumiIntroController extends CommonController {
final videoDetailCtr =
Get.find<VideoDetailController>(tag: Get.arguments['heroTag'])
..makeHeartBeat()
..playedTime = null
..vttSubtitlesIndex = null
..savedDanmaku = null
..epId = epId

View File

@@ -170,7 +170,6 @@ class VideoDetailController extends GetxController
SearchType videoType = Get.arguments['videoType'] ?? SearchType.video;
/// tabs相关配置
int tabInitialIndex = 0;
late TabController tabCtr;
// 请求返回的视频信息
@@ -194,7 +193,6 @@ class VideoDetailController extends GetxController
final scaffoldKey = GlobalKey<ScaffoldState>();
final childKey = GlobalKey<ScaffoldState>();
RxString bgCover = ''.obs;
PlPlayerController plPlayerController = PlPlayerController.getInstance()
..setCurrBrightness(-1.0);
@@ -202,13 +200,13 @@ class VideoDetailController extends GetxController
late AudioItem firstAudio;
String? videoUrl;
String? audioUrl;
late Duration defaultST = Duration.zero;
Duration? defaultST;
Duration? playedTime;
// 亮度
double? brightness;
// 默认记录历史记录
bool enableHeart = true;
dynamic userInfo;
late bool isFirstTime = true;
Floating? floating;
late PreferredSizeWidget headerControl;
@@ -966,7 +964,7 @@ class VideoDetailController extends GetxController
/// TODO 继续进度播放
updatePlayer() {
isShowCover.value = false;
defaultST = plPlayerController.position.value;
playedTime = plPlayerController.position.value;
plPlayerController.removeListeners();
plPlayerController.isBuffering.value = false;
plPlayerController.buffered.value = Duration.zero;
@@ -1069,7 +1067,7 @@ class VideoDetailController extends GetxController
// 硬解
enableHA: enableHA.value,
hwdec: hwdec.value,
seekTo: seekToTime ?? defaultST,
seekTo: seekToTime ?? defaultST ?? playedTime,
duration: duration ?? data.timeLength == null
? null
: Duration(milliseconds: data.timeLength!),
@@ -1096,6 +1094,10 @@ class VideoDetailController extends GetxController
/// 开启自动全屏时在player初始化完成后立即传入headerControl
plPlayerController.headerControl = headerControl;
if (defaultST != null) {
defaultST = null;
}
}
bool isQuerying = false;
@@ -1128,6 +1130,7 @@ class VideoDetailController extends GetxController
);
if (result['status']) {
data = result['data'];
if (enableSponsorBlock) {
await _querySponsorBlock();
}
@@ -1153,12 +1156,16 @@ class VideoDetailController extends GetxController
isShowCover.value = false;
await playerInit();
}
return result;
videoState.value = LoadingState.success(null);
isQuerying = false;
return;
}
if (data.dash == null) {
SmartDialog.showToast('视频资源不存在');
isShowCover.value = false;
return result;
videoState.value = LoadingState.success(null);
isQuerying = false;
return;
}
final List<VideoItem> allVideosList = data.dash!.video!;
// debugPrint("allVideosList:${allVideosList}");
@@ -2011,4 +2018,29 @@ class VideoDetailController extends GetxController
);
}
}
void makeHeartBeat() {
if (enableHeart && playedTime != null) {
plPlayerController.makeHeartBeat(
data.timeLength != null
? (data.timeLength! - playedTime!.inMilliseconds).abs() <= 1000
? -1
: playedTime!.inSeconds
: playedTime!.inSeconds,
type: 'status',
isManual: true,
bvid: bvid,
cid: cid.value,
epid: videoType == SearchType.media_bangumi ? epId : null,
seasonId: videoType == SearchType.media_bangumi ? seasonId : null,
subType: videoType == SearchType.media_bangumi ? subType : null,
);
}
}
@override
void onClose() {
tabCtr.dispose();
super.onClose();
}
}

View File

@@ -558,6 +558,8 @@ class VideoIntroController extends GetxController
Future changeSeasonOrbangu(epid, bvid, cid, aid, cover) async {
// 重新获取视频资源
final videoDetailCtr = Get.find<VideoDetailController>(tag: heroTag)
..makeHeartBeat()
..playedTime = null
..updateMediaListHistory(aid)
..vttSubtitlesIndex = null
..savedDanmaku = null

View File

@@ -199,15 +199,15 @@ class _VideoDetailPageState extends State<VideoDetailPage>
if (videoDetailController.autoPlay.value) {
plPlayerController = videoDetailController.plPlayerController;
plPlayerController!.addStatusLister(playerListener);
plPlayerController!.addPositionListener(positionListener);
if (videoDetailController.enableHeart) {
plPlayerController!.addPositionListener(positionListener);
}
await plPlayerController!.autoEnterFullscreen();
}
}
void positionListener(Duration position) {
if (position.inSeconds != videoDetailController.defaultST.inSeconds) {
videoDetailController.defaultST = position;
}
videoDetailController.playedTime = position;
}
@override
@@ -296,7 +296,9 @@ class _VideoDetailPageState extends State<VideoDetailPage>
videoDetailController.isShowCover.value = false;
await videoDetailController.playerInit(autoplay: true);
plPlayerController!.addStatusLister(playerListener);
plPlayerController!.addPositionListener(positionListener);
if (videoDetailController.enableHeart) {
plPlayerController!.addPositionListener(positionListener);
}
await plPlayerController!.autoEnterFullscreen();
videoDetailController.autoPlay.value = true;
}
@@ -322,25 +324,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
// );
// }
void _makeHeartBeat() {
plPlayerController!.makeHeartBeat(
videoDetailController.defaultST.inSeconds,
type: 'status',
isManual: true,
bvid: videoDetailController.bvid,
cid: videoDetailController.cid.value,
epid: videoDetailController.videoType == SearchType.media_bangumi
? videoDetailController.epId
: null,
seasonId: videoDetailController.videoType == SearchType.media_bangumi
? videoDetailController.seasonId
: null,
subType: videoDetailController.videoType == SearchType.media_bangumi
? videoDetailController.subType
: null,
);
}
@override
void dispose() {
_listenerDetail?.cancel();
@@ -368,9 +351,11 @@ class _VideoDetailPageState extends State<VideoDetailPage>
shutdownTimerService.handleWaitingFinished();
// _bufferedListener?.cancel();
if (plPlayerController != null) {
_makeHeartBeat();
videoDetailController.makeHeartBeat();
plPlayerController!.removeStatusLister(playerListener);
plPlayerController!.removePositionListener(positionListener);
if (videoDetailController.enableHeart) {
plPlayerController!.removePositionListener(positionListener);
}
plPlayerController!.dispose();
} else {
PlPlayerController.updatePlayCount();
@@ -405,12 +390,14 @@ class _VideoDetailPageState extends State<VideoDetailPage>
videoDetailController.brightness = plPlayerController?.brightness.value;
// }
if (plPlayerController != null) {
_makeHeartBeat();
videoDetailController.makeHeartBeat();
videoDetailController.vttSubtitlesIndex =
plPlayerController!.vttSubtitlesIndex.value;
videoDetailController.showVP = plPlayerController!.showVP.value;
plPlayerController!.removeStatusLister(playerListener);
plPlayerController!.removePositionListener(positionListener);
if (videoDetailController.enableHeart) {
plPlayerController!.removePositionListener(positionListener);
}
plPlayerController!.pause();
}
isShowing = false;
@@ -442,7 +429,6 @@ class _VideoDetailPageState extends State<VideoDetailPage>
}
}
super.didPopNext();
videoDetailController.isFirstTime = false;
// final bool autoplay = autoPlayEnable;
videoDetailController.autoPlay.value =
!videoDetailController.isShowCover.value;
@@ -479,7 +465,9 @@ class _VideoDetailPageState extends State<VideoDetailPage>
AutoOrientation.fullAutoMode();
});
plPlayerController?.addStatusLister(playerListener);
plPlayerController?.addPositionListener(positionListener);
if (videoDetailController.enableHeart) {
plPlayerController?.addPositionListener(positionListener);
}
}
@override

View File

@@ -445,7 +445,7 @@ class PlPlayerController {
// 默认不循环
PlaylistMode looping = PlaylistMode.none,
// 初始化播放位置
Duration seekTo = Duration.zero,
Duration? seekTo,
// 初始化播放速度
double speed = 1.0,
// 硬件加速
@@ -500,7 +500,8 @@ class PlPlayerController {
dataSource, _looping, enableHA, hwdec, width, height);
// 获取视频时长 00:00
_duration.value = duration ?? _videoPlayerController!.state.duration;
_position.value = _sliderPosition.value = _buffered.value = seekTo;
_position.value =
_sliderPosition.value = _buffered.value = seekTo ?? Duration.zero;
updateDurationSecond();
updatePositionSecond();
updateBufferedSecond();
@@ -512,7 +513,7 @@ class PlPlayerController {
if (!_listenersInitialized) {
startListeners();
}
await _initializePlayer(seekTo: seekTo);
await _initializePlayer(seekTo: seekTo ?? Duration.zero);
setSubtitle(this.vttSubtitlesIndex.value);
} catch (err, stackTrace) {
dataStatus.status.value = DataStatus.error;