初始化
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
import 'package:hgdj/hj_model/list_base_model.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgdj/hj_model/video_model.dart';
|
||||
import 'package:hgdj/hj_page/live/live_service.dart';
|
||||
import 'package:hgdj/hj_utils/date_time_util.dart';
|
||||
import 'package:hgdj/tools_base/event_bus/event_bus_util.dart';
|
||||
import 'package:hgdj/tools_base/event_bus/events.dart';
|
||||
import 'package:hgdj/tools_base/toast.dart';
|
||||
import 'package:hgdj/tools_base/global_store/store.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
import 'package:hgdj/hj_utils/video_view_type.dart';
|
||||
|
||||
import '../../alert/video/share_media_dialog.dart';
|
||||
import '../mine/mine_vip/mine_charge_vip_page.dart';
|
||||
import 'live_model.dart';
|
||||
|
||||
//直播详情
|
||||
class LiveDetailLogic extends GetxController {
|
||||
LiveAnchor? anchor; //直播
|
||||
int currentPage = 1;
|
||||
bool loading = true; //是否在加载推荐列表
|
||||
bool loadingUserInfo = true; //加载用户会员信息等
|
||||
List<LiveAnchor> recommendList = []; //
|
||||
|
||||
RefreshController? controller; //由 pullYsRefresh 的 onInit 注入,组件负责释放
|
||||
VideoPlayerController? playerController;
|
||||
|
||||
bool initedVideoController = false; //视频控制器是否加载
|
||||
RxBool isLoading = true.obs; //是否在切换视频
|
||||
|
||||
//视频真实比例, 竖屏的比例,采用最大高度400,横屏的比例,保持原有比例
|
||||
//是否是竖向视频
|
||||
double? aspectRatio = 16 / 9; //0.75
|
||||
bool get isVerticalVideo => (aspectRatio ?? 1) > 1;
|
||||
|
||||
bool isDispose = false;
|
||||
|
||||
//判断播放权限
|
||||
bool get canWatchLive =>
|
||||
DateTimeUtil.isExpireDate(globalStore.meInfo?.broadcastExpire);
|
||||
|
||||
LiveDetailLogic({this.anchor});
|
||||
|
||||
StreamSubscription? _pauseVideoSub;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
// 耳机/蓝牙断开、来电中断时暂停,防止外放泄露
|
||||
_pauseVideoSub =
|
||||
eventBus.on<PauseVideoEvent>((_) => playerController?.pause());
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() async {
|
||||
super.onReady();
|
||||
Future.wait([globalStore.updateUserInfo(), loadData(initVideo: false)])
|
||||
.then(
|
||||
(value) {
|
||||
update(); //接口调用成功刷新一次直播状态
|
||||
loadingUserInfo = false;
|
||||
initPlayer();
|
||||
},
|
||||
);
|
||||
loadrecommendAnchors();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() async {
|
||||
isDispose = true;
|
||||
_pauseVideoSub?.cancel();
|
||||
playerDispose();
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
playerDispose() {
|
||||
if (playerController != null) {
|
||||
initedVideoController = false;
|
||||
playerController?.removeListener(_listenerCallback);
|
||||
playerController?.pause();
|
||||
playerController?.dispose();
|
||||
playerController = null;
|
||||
}
|
||||
}
|
||||
|
||||
initPlayer({bool isRetry = false}) async {
|
||||
if (anchor?.url != null && anchor?.url?.isNotEmpty == true) {
|
||||
playerController = PlayerFactory.network(anchor?.url);
|
||||
|
||||
try {
|
||||
await playerController?.initialize();
|
||||
if (isRetry)
|
||||
confirmPlatformView(); // 仅重试成功(同视频 textureView 挂、platformView 放出)才落本地
|
||||
playerController?.addListener(_listenerCallback);
|
||||
if (isDispose) {
|
||||
playerController?.pause();
|
||||
playerController?.dispose();
|
||||
return;
|
||||
}
|
||||
initedVideoController = true;
|
||||
aspectRatio = playerController?.value.aspectRatio ?? 16 / 9;
|
||||
update();
|
||||
if (canWatchLive) playerController?.play();
|
||||
} catch (e) {
|
||||
playerController?.dispose();
|
||||
// 首次芯片解码/渲染报错:仅内存切 platformView 重试,成功后才落本地
|
||||
if (isDecoderError(e) && switchToPlatformView()) {
|
||||
initPlayer(isRetry: true);
|
||||
return;
|
||||
}
|
||||
//播放器初始化失败,强制设置为离线
|
||||
anchor?.isOnline = false;
|
||||
update(['player']);
|
||||
}
|
||||
} else {
|
||||
anchor?.isOnline = false;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
//添加监听
|
||||
_listenerCallback() {
|
||||
isLoading.value = playerController?.value.isBuffering == true;
|
||||
}
|
||||
|
||||
//获取直播详情
|
||||
Future loadData({bool initVideo = true}) async {
|
||||
LiveAnchor? result =
|
||||
await LiveService.getLiveAnchorDetail(id: anchor?.id ?? '');
|
||||
controller?.refreshCompleted();
|
||||
if (result != null) {
|
||||
//不需要赋值图片url,因为图片随时在变,防止图片闪动
|
||||
anchor?.isOnline = result.isOnline;
|
||||
anchor?.url = result.url;
|
||||
anchor?.viewCount = result.viewCount;
|
||||
if (initVideo) initPlayer();
|
||||
} else {
|
||||
anchor?.isOnline = false;
|
||||
}
|
||||
}
|
||||
|
||||
//直播推荐列表
|
||||
loadrecommendAnchors({int pageNum = 1}) async {
|
||||
ListBaseModel<LiveAnchor>? liveMainModels =
|
||||
await LiveService.getLiveAnchorRecom(
|
||||
country: anchor?.country ?? '',
|
||||
pageNumber: pageNum,
|
||||
pageSize: 20,
|
||||
);
|
||||
loading = false;
|
||||
if (liveMainModels != null) {
|
||||
currentPage = pageNum;
|
||||
if (currentPage == 1) recommendList.clear();
|
||||
if (liveMainModels.list != null &&
|
||||
liveMainModels.list?.isNotEmpty == true) {
|
||||
recommendList.addAll(liveMainModels.list ?? []);
|
||||
}
|
||||
}
|
||||
controller?.refreshCompleted();
|
||||
update(['recommend']);
|
||||
liveMainModels?.hasNext == true
|
||||
? controller?.loadComplete()
|
||||
: controller?.loadNoData();
|
||||
}
|
||||
|
||||
loadMoreData() => loadrecommendAnchors(pageNum: currentPage + 1);
|
||||
|
||||
//切换直播
|
||||
onChangeLiveAction(LiveAnchor change) {
|
||||
if (change.id == anchor?.id) {
|
||||
showToast('当前在此直播间哦~');
|
||||
return;
|
||||
}
|
||||
anchor = change;
|
||||
if (playerController != null) {
|
||||
final old = playerController;
|
||||
old?.pause();
|
||||
isLoading.value = true;
|
||||
playerController?.removeListener(_listenerCallback);
|
||||
}
|
||||
initedVideoController = false;
|
||||
if (anchor?.vidWidth != 0 && anchor?.vidHeight != 0) {
|
||||
aspectRatio = (anchor?.vidWidth ?? 1) / (anchor?.vidHeight ?? 1);
|
||||
} else {
|
||||
aspectRatio = 16 / 9;
|
||||
}
|
||||
update();
|
||||
loadData();
|
||||
}
|
||||
|
||||
//跳转充值
|
||||
onChargeAction() async {
|
||||
Get.to(MineChargeVipPage(), preventDuplicates: false);
|
||||
await globalStore.updateUserInfo();
|
||||
|
||||
//true表示支付成功
|
||||
if (canWatchLive) update();
|
||||
}
|
||||
|
||||
//分享
|
||||
onShareAction() {
|
||||
VideoModel videoModel = VideoModel()..cover = anchor?.coverImg;
|
||||
|
||||
Get.dialog(ShareMediaDialog(videoModel: videoModel, needDecrypt: false),
|
||||
useSafeArea: false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user