2025-09-24 11:37:15 +08:00

253 lines
7.3 KiB
Dart

import 'dart:io';
import 'package:flutter_kinetra/kt_pages/kt_explore/state.dart';
import 'package:get/get.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import '../../dio_cilent/kt_apis.dart';
import '../../dio_cilent/kt_request.dart';
import '../../kt_model/kt_short_video_bean.dart';
import '../../kt_utils/kt_device_info_utils.dart';
import '../../kt_widgets/kt_status_widget.dart';
import '../kt_main_page/view.dart';
class KtExploreLogic extends GetxController {
final state = KtExploreState();
final EasyRefreshController refreshCtrl = EasyRefreshController(
controlFinishLoad: true,
);
final PageController pageController = PageController(viewportFraction: .95);
final int preloadRange = 1;
bool isRefresh = false;
@override
void onReady() {
super.onReady();
fetchDiscoverList();
}
@override
void onClose() {
super.onClose();
clearController();
refreshCtrl.dispose();
pageController.dispose();
}
clearController() {
for (var item in state.controllers) {
item?.pause();
item?.dispose();
}
state.controllers.clear();
}
fetchDiscoverList({bool refresh = false}) async {
state.loadStatus = KtLoadStatusType.loading;
if (refresh) {
isRefresh = true;
state.curIndex = 1;
state.videoList.clear();
clearController();
}
if (refresh) refreshCtrl.finishLoad();
try {
ApiResponse res = await KtHttpClient().request(
KtApis.getRecommands,
queryParameters: {'current_page': state.curIndex, 'page_size': 20},
method: HttpMethod.get,
);
if (refresh) {
isRefresh = false;
update();
}
if (res.success) {
state.loadStatus = KtLoadStatusType.loadSuccess;
List<KtShortVideoBean> list = [
...res.data['list'].map((item) => KtShortVideoBean.fromJson(item)),
];
state.videoList.addAll(list);
// if (videoId == -1) {
// video = state.videoList.first;
// videoId = state.videoList.first.id ?? -1;
// }
state.controllers = List<VideoPlayerController?>.filled(
state.videoList.length,
null,
growable: true,
);
if (state.videoList.isNotEmpty && state.curIndex == 1) {
state.currentPage = 0;
_initializeController(0);
}
update();
} else {
if (refresh) refreshCtrl.finishRefresh(IndicatorResult.fail);
state.loadStatus = KtLoadStatusType.loadFailed;
}
} catch (e) {
if (refresh) {
isRefresh = false;
update();
}
state.loadStatus = KtLoadStatusType.loadFailed;
}
update();
}
// 切换剧集时处理视频状态
Future<void> onPageChanged(int index, {bool isToggle = false}) async {
if (index < 0 || index >= state.videoList.length) return;
// 暂停当前视频
if (state.controllers[state.currentPage]?.value.isPlaying ?? false) {
await state.controllers[state.currentPage]?.pause();
}
state.currentPage = index;
if (isToggle) {
// loadStatusType = LoadStatusType.loading;
// update();
await _initializeController(index);
// loadStatusType = LoadStatusType.loadSuccess;
update();
WidgetsBinding.instance.addPostFrameCallback((_) {
pageController.jumpToPage(index);
});
}
if (state.controllers[index] != null) {
state.controllers[index]?.play();
} else {
if (!isToggle) await _initializeController(index);
state.controllers[index]?.play();
}
// 预加载新的相邻视频,并释放多余控制器
_preloadAdjacentVideos();
update();
// });
}
// 释放非当前、前后的视频控制器,减少内存占用
void _releaseUnusedControllers() {
for (int i = 0; i < state.controllers.length; i++) {
if (i < state.currentPage - 1 || i > state.currentPage + 1) {
state.controllers[i]?.dispose();
state.controllers[i] = null;
}
}
}
// 初始化视频控制器
Future<void> _initializeController(int index) async {
if (index < 0 || index >= state.videoList.length) return;
if (state.controllers[index] != null) return;
final episode = state.videoList[index];
VideoPlayerController controller =
Platform.isAndroid && KtDeviceInfoUtil().osVersion == '10'
? VideoPlayerController.networkUrl(
Uri.parse(episode.videoInfo!.videoUrl!),
formatHint: VideoFormat.hls,
viewType: VideoViewType.platformView,
)
: VideoPlayerController.networkUrl(
Uri.parse(episode.videoInfo!.videoUrl!),
formatHint: VideoFormat.hls,
);
state.controllers[index] = controller;
try {
await controller.initialize();
if (index == state.currentPage) {
final mainLogic = Get.find<KtMainLogic>();
if(mainLogic.curIndex == 1) controller.play();
update();
}
controller.addListener(() {
if (state.currentPage == index) update();
if (controller.value.isCompleted && !controller.value.isBuffering) {
onPageChanged(index + 1, isToggle: true);
}
});
} catch (e) {
// 可根据需要处理异常
// UserUtil().reportErrorEvent(
// 'video initialize failed',
// UserUtil.videoError,
// errMsg: e.toString(),
// payData: episode.toJson(),
// shortPlayId: episode.shortPlayId ?? 0,
// shortPlayVideoId: episode.shortPlayVideoId ?? 0,
// );
debugPrint('---err:$e');
}
}
// 预加载相邻视频
void _preloadAdjacentVideos() {
if (state.currentPage > 0) _initializeController(state.currentPage - 1);
if (state.currentPage < state.videoList.length - 1) {
_initializeController(state.currentPage + 1);
}
_releaseUnusedControllers();
}
likeVideo(KtShortVideoBean video) {
if (video.isCollect ?? false) {
video.collectTotal = video.collectTotal! - 1;
if (video.collectTotal! < 0) {
video.collectTotal = 0;
}
KtHttpClient().request(
KtApis.deleteFavoriteVideo,
data: {
"short_play_id": video.shortPlayId,
"video_id": video.videoInfo!.id,
},
);
} else {
video.collectTotal = video.collectTotal! + 1;
KtHttpClient().request(
KtApis.collectVideo,
data: {
"short_play_id": video.shortPlayId,
"video_id": video.videoInfo!.id,
},
);
}
video.isCollect = !(video.isCollect ?? false);
update();
}
KtShortVideoBean get curVideo => state.videoList[state.currentPage];
setCollectVideo(int shortPlayId, {bool isCollect = true}) {
KtShortVideoBean? video = state.videoList.firstWhereOrNull(
(item) => item.shortPlayId == shortPlayId,
);
if (video == null) return;
video.isCollect = isCollect;
video.collectTotal = video.collectTotal! + (isCollect ? 1 : -1);
update();
}
//
// Future<void> onRefresh() async {
// state.currentPage = 0;
// state.curIndex = 1;
// // clearController();
// // update();
// WidgetsBinding.instance.addPostFrameCallback((_) async {
// await fetchDiscoverList(refresh: true);
// });
// }
}