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 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.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 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 _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(); final mainLogic = Get.find(); if (index == state.currentPage && mainLogic.curIndex == 1) { controller.play(); update(); } controller.addListener(() { if (state.currentPage == index && mainLogic.curIndex == 1) 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 onRefresh() async { // state.currentPage = 0; // state.curIndex = 1; // // clearController(); // // update(); // WidgetsBinding.instance.addPostFrameCallback((_) async { // await fetchDiscoverList(refresh: true); // }); // } }