Commit caafca38 by suolong

添加倒计时 付费屋

parent 7175d0cc
...@@ -19,128 +19,16 @@ ...@@ -19,128 +19,16 @@
<BreakpointProxy <BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent <BreakpointContent
uuid = "39FF1C38-2542-4416-A8C4-0315968F3941" uuid = "557ED31B-F4DE-4254-9E50-0D51EFABE241"
shouldBeEnabled = "Yes" shouldBeEnabled = "Yes"
ignoreCount = "0" ignoreCount = "0"
continueAfterRunningActions = "No" continueAfterRunningActions = "No"
filePath = "DevelopmentPods/FUSFoundation/FUSFoundation/Classes/FUSFoundation/Views/ActionSheet/FUSActionSheetView.m" filePath = "Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Controller/FUSLiveMainViewController.m"
startingColumnNumber = "9223372036854775807" startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807"
startingLineNumber = "149" startingLineNumber = "1648"
endingLineNumber = "149" endingLineNumber = "1648"
landmarkName = "-showAcionSheetWithTitle:cancelTitle:enterTitle:otherTitles:buttonColors:clickBlock:" landmarkName = "-payRoomSwitch:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "1E153074-605C-4A42-B48F-38DF7C360A71"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "DevelopmentPods/FUSFoundation/FUSFoundation/Classes/FUSFoundation/Views/StreamView/LiveStreamView/Push/Capture/ByteRTC/FUSByteRTCPKStreamCaptureHelper.m"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "405"
endingLineNumber = "405"
landmarkName = "-fus_restartStreamPush"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "88E06B63-A6EE-4AA2-97A3-2DD86F138229"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "DevelopmentPods/FUSFoundation/FUSFoundation/Classes/FUSFoundation/Views/StreamView/LiveStreamView/Push/Capture/ByteRTC/FUSByteRTCPKStreamCaptureHelper.m"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "191"
endingLineNumber = "191"
landmarkName = "-fus_endLivePush"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "2178470A-240F-4C11-802C-507A47CD6F3D"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/View/FunctionView/LinkMicro/Other/FUSAgoraHelper.m"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "592"
endingLineNumber = "592"
landmarkName = "-fus_switchAgoraLinkMicMode:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "A06C7465-3FBC-4337-ADC2-4320EA06A76B"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/View/FunctionView/LinkMicro/Other/FUSAgoraHelper.m"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "180"
endingLineNumber = "180"
landmarkName = "-fus_enableVideo:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "4F5B7872-1C1A-4EA0-911F-1A4E6EFDF43E"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "DevelopmentPods/FUSFoundation/FUSFoundation/Classes/FUSFoundation/Views/StreamView/LiveStreamView/Push/Capture/TTSDK/Base/FUSStreamCatureHelper.m"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "626"
endingLineNumber = "626"
landmarkName = "-fus_setupCaptureEnable:"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "4B4C9D12-5F36-4B96-BE77-C1250DFEBE1B"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/View/Push/LiveStartView/FUSLiveStartSetPrivacyView.swift"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "355"
endingLineNumber = "355"
landmarkName = "fus_requestLiveBeforeReadyIfNeeded(completion:)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "47DDFACE-B633-4A68-B5D3-CC4B6253CB4F"
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Other/FUSLiveHelper.m"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "954"
endingLineNumber = "954"
landmarkName = "-joinRoomFailuerWithErrorDict:code:msg:currentRoomId:password:behaviorSrc:otherInfo:"
landmarkType = "7"> landmarkType = "7">
</BreakpointContent> </BreakpointContent>
</BreakpointProxy> </BreakpointProxy>
......
...@@ -1404,6 +1404,8 @@ typedef NS_ENUM(NSInteger, FUSStreamState) { ...@@ -1404,6 +1404,8 @@ typedef NS_ENUM(NSInteger, FUSStreamState) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(liveStatus:) name:STR(ROOM_CID_LIVE_STATU) object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(liveStatus:) name:STR(ROOM_CID_LIVE_STATU) object:nil];
// 被踢出直播 // 被踢出直播
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(forceKick:) name:STR(ROOM_CID_FORCEKICK_NOTICE) object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(forceKick:) name:STR(ROOM_CID_FORCEKICK_NOTICE) object:nil];
// 付费房模式切换
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(payRoomSwitch:) name:STR(ROOM_CID_PAYROOM_SWITCH) object:nil];
// 包房重连 // 包房重连
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(roomReconnected:) name:FUSLiveNotificationKeys.fus_Baofang_Socket_Reconnected object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(roomReconnected:) name:FUSLiveNotificationKeys.fus_Baofang_Socket_Reconnected object:nil];
// 5555 回调 // 5555 回调
...@@ -1602,6 +1604,13 @@ typedef NS_ENUM(NSInteger, FUSStreamState) { ...@@ -1602,6 +1604,13 @@ typedef NS_ENUM(NSInteger, FUSStreamState) {
FUSSocketMessageModel *messageModel = noti.object; FUSSocketMessageModel *messageModel = noti.object;
NSDictionary *dict = [messageModel fus_getJsonDict]; NSDictionary *dict = [messageModel fus_getJsonDict];
if ([dict[@"exitType"] integerValue] == 1) {
NSString *roomId = [FUSLiveHelper shareInstance].roomInfoModel.roomId;
[[FUSLiveHelper shareInstance] fus_endPayRoomPreviewWithRoomId:roomId];
[FUSDialogView fus_showDialog:[FUSFormatContentHelper fus_getContentFromArr:dict[@"multiContents"]]];
return;
}
if ([[FUSLiveHelper shareInstance] liveType] == FUSLiveTypeAudience) { if ([[FUSLiveHelper shareInstance] liveType] == FUSLiveTypeAudience) {
// 播放 // 播放
[_streamView.playView fus_stopALLPlayer]; [_streamView.playView fus_stopALLPlayer];
...@@ -1634,6 +1643,26 @@ typedef NS_ENUM(NSInteger, FUSStreamState) { ...@@ -1634,6 +1643,26 @@ typedef NS_ENUM(NSInteger, FUSStreamState) {
[FUSLiveHelper fus_quitLiveWithCompletion:nil]; [FUSLiveHelper fus_quitLiveWithCompletion:nil];
} }
- (void)payRoomSwitch:(NSNotification *)noti
{
FUSSocketMessageModel *messageModel = noti.object;
NSDictionary *dict = [messageModel fus_getJsonDict];
NSString *roomId = [[dict[@"roomId"] description] length] ? [dict[@"roomId"] description] : [dict[@"roomid"] description];
if ([NSString isNull:roomId]) {
roomId = [NSString stringWithFormat:@"%d", messageModel.extend1];
}
if (![roomId isEqualToString:[FUSLiveHelper shareInstance].roomInfoModel.roomId]) {
return;
}
if ([dict[@"mode"] integerValue] != 0) {
return;
}
[[FUSLiveHelper shareInstance] fus_handlePayRoomSwitchToNormalPlayWithRoomId:roomId];
}
-(void)recieveScreenCaptureNotification:(NSNotification *)notification { -(void)recieveScreenCaptureNotification:(NSNotification *)notification {
if ([FUSConfig sharedInstanced].devConfigs.appStatus == NO) { if ([FUSConfig sharedInstanced].devConfigs.appStatus == NO) {
......
...@@ -274,6 +274,12 @@ typedef NS_ENUM(NSInteger,FUSLiveRoomScopeType) { ...@@ -274,6 +274,12 @@ typedef NS_ENUM(NSInteger,FUSLiveRoomScopeType) {
+ (void)fus_quitLiveWithCompletion:(void(^_Nullable)(void))completion animated:(BOOL)animated; + (void)fus_quitLiveWithCompletion:(void(^_Nullable)(void))completion animated:(BOOL)animated;
/// 结束付费房试看:停止拉流并回到付费入口磨砂弹层
- (void)fus_endPayRoomPreviewWithRoomId:(NSString *)roomId;
/// 付费房模式切到非付费(mode=0):恢复正常UI并重置播放
- (void)fus_handlePayRoomSwitchToNormalPlayWithRoomId:(NSString *)roomId;
// 最小化直播间 // 最小化直播间
+ (void)fus_minimizeLiveCompletion: (void (^ __nullable)(void))completion; + (void)fus_minimizeLiveCompletion: (void (^ __nullable)(void))completion;
......
...@@ -61,6 +61,13 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor ...@@ -61,6 +61,13 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
/// 是否关闭主播推流的声音 /// 是否关闭主播推流的声音
@property (nonatomic, assign) BOOL audioMute; @property (nonatomic, assign) BOOL audioMute;
/// 付费房试看倒计时定时器(GCD timer,运行在主队列,避免 runloop 模式导致 UI 不刷新)
@property (nonatomic, strong) dispatch_source_t payRoomPreviewCountdownTimer;
/// 付费房试看倒计时按钮(展示右上角剩余秒数,并提供点击退出入口)
@property (nonatomic, strong) UIButton *payRoomPreviewCountdownButton;
/// 付费房试看剩余秒数(用于驱动按钮文案与自动结束)
@property (nonatomic, assign) NSInteger payRoomPreviewCountdownSeconds;
@end @end
@implementation FUSLiveHelper @implementation FUSLiveHelper
...@@ -954,8 +961,54 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor ...@@ -954,8 +961,54 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
[[NSNotificationCenter defaultCenter] postNotificationName:FUSLiveNotificationKeys.fus_BaoFang_Did_End_Live_Notification object:currentRoomId]; [[NSNotificationCenter defaultCenter] postNotificationName:FUSLiveNotificationKeys.fus_BaoFang_Did_End_Live_Notification object:currentRoomId];
[[NSNotificationCenter defaultCenter] postNotificationName:FUSLiveNotificationKeys.fus_BaoFang_Refresh object:nil]; [[NSNotificationCenter defaultCenter] postNotificationName:FUSLiveNotificationKeys.fus_BaoFang_Refresh object:nil];
} else if (code == -20065) { } else if (code == -20065) {
FUSStreamPlayStatus status = [self.liveVC.playView fus_statusForUID:currentRoomId];
if (status == FUSStreamPlayStatusPlaying
|| status == FUSStreamPlayStatusLoading
|| status == FUSStreamPlayStatusPause) {
[self.liveVC.playView fus_stopWithUID:currentRoomId];
[self.liveVC.playView fus_destroyAllPlayer];
[self.liveVC fus_stopPlay];
[self.liveVC destroyPlayPictureInPicture];
}
[self fus_handlePayRoomFrostedGlassWithRoomId:currentRoomId];
return;
} else if (code == -20060) {
[[NSNotificationCenter defaultCenter] postNotificationName:FUSLiveNotificationKeys.fus_BaoFang_Refresh object:nil];
// V6.1.0 改成直接退出toast提示
[FUSLiveHelper fus_quitLiveWithCompletion:nil];
[FUSDialogView fus_showDialog:[NSString fus_localString:@"您已被踢出房间,暂时不能进入"]];
// // 您已被移除直播,暂时不能进入
} else if (code == -20080) {
[[NSNotificationCenter defaultCenter] postNotificationName:FUSLiveNotificationKeys.fus_BaoFang_Refresh object:nil];
// 没有私密房权限
[self.currentFunctionView fus_hideAllFunctionLayers];
[FUSAlertView showAlertWithTitle:nil message:errorDict[@"msg"] cancelButtonTitle:[NSString fus_localString:@"确定"] otherButtonTitles:nil clickBlock:^(NSInteger buttonIndex) {
[FUSLiveHelper fus_quitLiveWithCompletion:nil];
}];
} else {
// 其他情况
[FUSAlertView showAlertWithTitle:nil message:msg cancelButtonTitle:nil otherButtonTitles:@[[NSString fus_localString:@"确定"], [NSString fus_localString:@"退出"]] clickBlock:^(NSInteger buttonIndex) {
if (buttonIndex == 0) {
[self fus_audienceJoinRoomWithRoomId:currentRoomId password:password behaviorSrc:behaviorSrc otherInfo:otherInfo];
}else{
[FUSLiveHelper fus_quitLiveWithCompletion:nil];
}
}];
}
if(self.enterRoomFailureBlock){
self.enterRoomFailureBlock();
}
}
/**
付费房磨砂弹层(-20065)处理:拉取磨砂数据并展示付费入口视图
*/
- (void)fus_handlePayRoomFrostedGlassWithRoomId:(NSString *)roomId
{
NSString *uid = [[FUSCacheDataShare shareStore].userVerifyInfo.uid description] ?: @""; NSString *uid = [[FUSCacheDataShare shareStore].userVerifyInfo.uid description] ?: @"";
NSString *roomId = [currentRoomId description] ?: @"";
__weak typeof(self) weakSelf = self; __weak typeof(self) weakSelf = self;
[FUSLiveHttpHelper fus_requestGetPayRoomFrostedGlassDataWithUid:uid RoomId:roomId succeed:^(NSDictionary *dataDict) { [FUSLiveHttpHelper fus_requestGetPayRoomFrostedGlassDataWithUid:uid RoomId:roomId succeed:^(NSDictionary *dataDict) {
...@@ -1009,7 +1062,8 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor ...@@ -1009,7 +1062,8 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
NSString *roundId = [dataModel.roomData.roundId description] ?: @""; NSString *roundId = [dataModel.roomData.roundId description] ?: @"";
__weak typeof(strongSelf) weakStrongSelf = strongSelf; __weak typeof(strongSelf) weakStrongSelf = strongSelf;
[FUSPayRoomEntryMainView fus_showOnView:rootView viewModel:viewModel actionHandler:^(FUSPayRoomEntryMainViewAction action) { __block __weak FUSPayRoomEntryMainView *weakEntryView = nil;
FUSPayRoomEntryMainView *entryView = [FUSPayRoomEntryMainView fus_showOnView:rootView viewModel:viewModel actionHandler:^(FUSPayRoomEntryMainViewAction action) {
__strong typeof(weakStrongSelf) strongSelf = weakStrongSelf; __strong typeof(weakStrongSelf) strongSelf = weakStrongSelf;
if (!strongSelf) { if (!strongSelf) {
return; return;
...@@ -1019,51 +1073,110 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor ...@@ -1019,51 +1073,110 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
return; return;
} }
if (action == FUSPayRoomEntryMainViewActionTrial) { if (action == FUSPayRoomEntryMainViewActionTrial) {
[strongSelf fus_requestPayRoomPreviewWithUid:uid roomId:roomId channelId:channelId roundId:roundId]; [strongSelf fus_requestPayRoomPreviewWithUid:uid roomId:roomId channelId:channelId roundId:roundId entryView:weakEntryView];
return; return;
} }
}]; }];
weakEntryView = entryView;
}); });
} failure:^(NSString *msg, NSInteger code) { } failure:^(NSString *msg, NSInteger code) {
}]; }];
return; }
} else if (code == -20060) {
[[NSNotificationCenter defaultCenter] postNotificationName:FUSLiveNotificationKeys.fus_BaoFang_Refresh object:nil]; /**
// V6.1.0 改成直接退出toast提示 结束付费房试看:清理倒计时并停止拉流,然后复用 -20065 的磨砂弹层流程
[FUSLiveHelper fus_quitLiveWithCompletion:nil]; */
[FUSDialogView fus_showDialog:[NSString fus_localString:@"您已被踢出房间,暂时不能进入"]]; - (void)fus_endPayRoomPreviewWithRoomId:(NSString *)roomId
// // 您已被移除直播,暂时不能进入 {
} else if (code == -20080) { dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:FUSLiveNotificationKeys.fus_BaoFang_Refresh object:nil]; [self fus_stopPayRoomPreviewCountdown];
// 没有私密房权限 [self.liveVC fus_showLiveLoadingViewWithType:liveLoadingDismiss];
[self.currentFunctionView fus_hideAllFunctionLayers]; [self.liveVC.playView fus_stopWithUID:roomId];
[FUSAlertView showAlertWithTitle:nil message:errorDict[@"msg"] cancelButtonTitle:[NSString fus_localString:@"确定"] otherButtonTitles:nil clickBlock:^(NSInteger buttonIndex) { [self.liveVC.playView fus_destroyAllPlayer];
[FUSLiveHelper fus_quitLiveWithCompletion:nil]; [self.liveVC fus_stopPlay];
}]; [self.liveVC destroyPlayPictureInPicture];
} else { self.hiddenBackgroundImage = NO;
// 其他情况 self.liveVC.backgroundImageView.hidden = NO;
[FUSAlertView showAlertWithTitle:nil message:msg cancelButtonTitle:nil otherButtonTitles:@[[NSString fus_localString:@"确定"], [NSString fus_localString:@"退出"]] clickBlock:^(NSInteger buttonIndex) { self.liveVC.liveFunctionView.hidden = NO;
self.liveVC.scrollEnableCount = 0;
[self.currentFunctionView fus_showAllFunctionLayers];
[self fus_handlePayRoomFrostedGlassWithRoomId:roomId];
});
}
if (buttonIndex == 0) { - (void)fus_handlePayRoomSwitchToNormalPlayWithRoomId:(NSString *)roomId
[self fus_audienceJoinRoomWithRoomId:currentRoomId password:password behaviorSrc:behaviorSrc otherInfo:otherInfo]; {
}else{ dispatch_async(dispatch_get_main_queue(), ^{
[FUSLiveHelper fus_quitLiveWithCompletion:nil]; [self fus_stopPayRoomPreviewCountdown];
UIView *rootView = self.liveVC.view ?: [UIViewController fus_topViewController].view;
for (UIView *subview in rootView.subviews.copy) {
if ([subview isKindOfClass:FUSPayRoomEntryMainView.class]) {
[(FUSPayRoomEntryMainView *)subview fus_dismissAnimated:YES];
} }
}];
} }
if(self.enterRoomFailureBlock){ self.hiddenBackgroundImage = NO;
self.enterRoomFailureBlock(); self.liveVC.backgroundImageView.hidden = NO;
self.liveVC.liveFunctionView.hidden = NO;
self.liveVC.scrollEnableCount = 0;
[self.currentFunctionView fus_showAllFunctionLayers];
[self.liveVC fus_showLiveLoadingViewWithType:liveLoadingDismiss];
NSString *mainRoomId = (roomId ?: self.roomInfoModel.roomId);
if ([NSString isNull:mainRoomId]) {
return;
}
[self.liveVC initPlayView];
[self.liveVC.playView fus_stopWithUID:mainRoomId];
[self.liveVC.playView fus_destroyWithUID:mainRoomId];
NSString *streamUrl = self.streamModel.url;
if ([NSString isNull:streamUrl]) {
streamUrl = self.roomInfoModel.publishUrl;
} }
if ([NSString isNull:streamUrl]) {
return;
}
[self.liveVC.playView fus_playWithUID:mainRoomId Url:streamUrl];
});
} }
- (void)fus_requestPayRoomPreviewWithUid:(NSString *)uid - (void)fus_requestPayRoomPreviewWithUid:(NSString *)uid
roomId:(NSString *)roomId roomId:(NSString *)roomId
channelId:(NSString *)channelId channelId:(NSString *)channelId
roundId:(NSString *)roundId roundId:(NSString *)roundId
entryView:(FUSPayRoomEntryMainView *)entryView
{ {
/**
付费房试看:请求 /payRoom/preview,拿到 pullUrl 后切换到“纯播放”模式。
约束与约定:
- 该方法只负责:请求 -> 成功后驱动 UI(关闭入口弹窗、进入试看播放)-> 失败弹 toast。
- pullUrl 由服务端下发,属于临时拉流地址,直接交给播放层播放即可。
- 成功/失败回调都在主线程收口 UI 相关操作,避免跨线程触碰 UIKit。
注意:
- entryView 通过弱引用传入,避免强引用链导致入口视图无法释放。
*/
__weak typeof(self) weakSelf = self;
__weak FUSPayRoomEntryMainView *weakEntryView = entryView;
[FUSLiveHttpHelper fus_requestPayRoomPreviewWithUid:(uid ?: @"") RoomId:(roomId ?: @"") previewType:@"1" channelId:(channelId ?: @"") roundId:(roundId ?: @"") succeed:^(NSDictionary *dataDict) { [FUSLiveHttpHelper fus_requestPayRoomPreviewWithUid:(uid ?: @"") RoomId:(roomId ?: @"") previewType:@"1" channelId:(channelId ?: @"") roundId:(roundId ?: @"") succeed:^(NSDictionary *dataDict) {
__strong typeof(weakSelf) strongSelf = weakSelf;
NSDictionary *payload = ([dataDict[@"data"] isKindOfClass:NSDictionary.class] ? dataDict[@"data"] : dataDict);
NSDictionary *userData = ([payload[@"userData"] isKindOfClass:NSDictionary.class] ? payload[@"userData"] : nil);
NSString *pullUrl = [(userData ?: payload)[@"pullUrl"] description];
if ([NSString isNull:pullUrl]) {
dispatch_async(dispatch_get_main_queue(), ^{
[FUSDialogView fus_showDialog:[NSString fus_localString:@"拉流地址为空"]];
});
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
[weakEntryView fus_dismissAnimated:YES];
[strongSelf fus_playPayRoomPreviewWithPullUrl:pullUrl];
});
} failure:^(NSString *msg, NSInteger code) { } failure:^(NSString *msg, NSInteger code) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[FUSDialogView fus_showDialog:(msg ?: @"")]; [FUSDialogView fus_showDialog:(msg ?: @"")];
...@@ -1072,6 +1185,133 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor ...@@ -1072,6 +1185,133 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
} }
/** /**
将直播间切换为“试看播放态”:
- 使用 preview 接口返回的 pullUrl 播放
- 隐藏所有业务/互动 UI,仅保留视频播放画面
- 右上角展示 20 秒倒计时,并提供点击退出
*/
- (void)fus_playPayRoomPreviewWithPullUrl:(NSString *)pullUrl
{
FUSLiveMainViewController *liveVC = self.liveVC;
if (!liveVC) {
return;
}
[liveVC initPlayView];
[liveVC fus_setupScrollEnable:NO];
[liveVC fus_showLiveLoadingViewWithType:liveLoadingDismiss];
liveVC.backgroundImageView.hidden = YES;
[self.currentFunctionView fus_hideAllFunctionLayers];
liveVC.liveFunctionView.hidden = YES;
[liveVC fus_playStreamWithUrl:(pullUrl ?: @"")];
[self fus_startPayRoomPreviewCountdownSeconds:20];
}
/**
开始试看倒计时(GCD Timer)
- 使用 dispatch_source_t,避免 NSTimer 依赖 runloop mode 导致滑动/交互时不触发
- 计时与 UI 更新都在主队列执行,保证按钮文案与布局安全更新
*/
- (void)fus_startPayRoomPreviewCountdownSeconds:(NSInteger)seconds
{
[self fus_stopPayRoomPreviewCountdown];
self.payRoomPreviewCountdownSeconds = MAX(0, seconds);
UIView *hostView = self.liveVC.view ?: [UIViewController fus_topViewController].view;
if (!hostView) {
return;
}
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
[button setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:13];
button.clipsToBounds = YES;
button.layer.cornerRadius = 12;
button.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;
[button addTarget:self action:@selector(fus_onPayRoomPreviewCountdownButtonTap) forControlEvents:UIControlEventTouchUpInside];
[hostView addSubview:button];
self.payRoomPreviewCountdownButton = button;
[self fus_updatePayRoomPreviewCountdownButton];
__weak typeof(self) weakSelf = self;
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, (int64_t)NSEC_PER_SEC), (uint64_t)NSEC_PER_SEC, (uint64_t)(0.1 * NSEC_PER_SEC));
dispatch_source_set_event_handler(timer, ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
strongSelf.payRoomPreviewCountdownSeconds = MAX(0, strongSelf.payRoomPreviewCountdownSeconds - 1);
if (strongSelf.payRoomPreviewCountdownSeconds <= 0) {
[strongSelf fus_endPayRoomPreviewWithRoomId:strongSelf.roomInfoModel.roomId];
return;
}
[strongSelf fus_updatePayRoomPreviewCountdownButton];
});
dispatch_resume(timer);
self.payRoomPreviewCountdownTimer = timer;
}
/// 点击右上角倒计时按钮:弹窗二次确认结束试看(仅清理倒计时,不退出直播间)
- (void)fus_onPayRoomPreviewCountdownButtonTap
{
__weak typeof(self) weakSelf = self;
[FUSAlertView showAlertWithTitle:@"" message:[NSString fus_localString:@"结束试看"] cancelButtonTitle:[NSString fus_localString:@"取消"] otherButtonTitles:@[[NSString fus_localString:@"结束"]] clickBlock:^(NSInteger buttonIndex) {
if (buttonIndex != 1) {
return;
}
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) {
return;
}
[strongSelf fus_endPayRoomPreviewWithRoomId:strongSelf.roomInfoModel.roomId];
}];
}
/// 刷新倒计时按钮文案与位置(右上角,考虑 safeArea)
- (void)fus_updatePayRoomPreviewCountdownButton
{
UIButton *button = self.payRoomPreviewCountdownButton;
UIView *hostView = button.superview ?: (self.liveVC.view ?: [UIViewController fus_topViewController].view);
if (!button || !hostView) {
return;
}
[button setTitle:[NSString stringWithFormat:@"%@:%lds", [NSString fus_localString:@"试看"],(long)self.payRoomPreviewCountdownSeconds] forState:UIControlStateNormal];
CGFloat topInset = 20;
if (@available(iOS 11.0, *)) {
topInset = MAX(topInset, hostView.safeAreaInsets.top);
}
CGFloat height = 24;
CGFloat maxWidth = MAX(52, hostView.bounds.size.width - 24);
CGFloat width = MIN(MAX(52, [button sizeThatFits:CGSizeMake(CGFLOAT_MAX, height)].width + 16), maxWidth);
CGFloat x = MAX(0, hostView.bounds.size.width - width - 12);
CGFloat y = topInset + 8;
button.frame = CGRectMake(x, y, width, height);
}
/// 停止倒计时并移除按钮,释放 timer 资源(避免页面退出后仍回调导致异常)
- (void)fus_stopPayRoomPreviewCountdown
{
if (self.payRoomPreviewCountdownTimer) {
dispatch_source_cancel(self.payRoomPreviewCountdownTimer);
self.payRoomPreviewCountdownTimer = nil;
}
[self.payRoomPreviewCountdownButton removeFromSuperview];
self.payRoomPreviewCountdownButton = nil;
self.payRoomPreviewCountdownSeconds = 0;
}
/**
结束观看直播 结束观看直播
*/ */
+ (void)fus_quitLiveWithCompletion:(void(^)(void))completion animated:(BOOL)animated { + (void)fus_quitLiveWithCompletion:(void(^)(void))completion animated:(BOOL)animated {
...@@ -2040,6 +2280,7 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor ...@@ -2040,6 +2280,7 @@ static NSString *const KLiveDataCenter_store_liveRTCData = @"LiveDataCenter_stor
#pragma mark - Other #pragma mark - Other
- (void)dealloc - (void)dealloc
{ {
[self fus_stopPayRoomPreviewCountdown];
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment