Commit 9e7e874d7fc20bb023c70ddee32beadc7ccc8573
1 parent
2639f986
no message
Showing
3 changed files
with
166 additions
and
0 deletions
CNLivePlayer/Classes/Header/CNLivePlayerTypeDef.h
| ... | ... | @@ -184,4 +184,18 @@ typedef enum : NSUInteger { |
| 184 | 184 | |
| 185 | 185 | } CNLiveClarityLevel; |
| 186 | 186 | |
| 187 | +/** | |
| 188 | + * 主播直播状态 | |
| 189 | + */ | |
| 190 | +typedef NS_ENUM(NSUInteger, CNLiveAnchorStatus) { | |
| 191 | + ///主播直播中 | |
| 192 | + CNLiveAnchorStatusLiving = 0, | |
| 193 | + ///主播已离开 | |
| 194 | + CNLiveAnchorStatusLeaving, | |
| 195 | + ///直播已结束 | |
| 196 | + CNLiveAnchorStatusEnd, | |
| 197 | + ///直播错误 | |
| 198 | + CNLiveAnchorStatusError | |
| 199 | +}; | |
| 200 | + | |
| 187 | 201 | #endif /* CNLivePlayerTypeDef_h */ | ... | ... |
CNLivePlayer/Classes/Player/CNLivePlayer.h
| ... | ... | @@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN |
| 22 | 22 | |
| 23 | 23 | typedef void (^SuccessBlock) (void); |
| 24 | 24 | typedef void (^FailureBlock) (NSError *error); |
| 25 | +typedef void (^AnchorStatus)(CNLiveAnchorStatus status); | |
| 25 | 26 | |
| 26 | 27 | @interface CNLivePlayer : NSObject |
| 27 | 28 | |
| ... | ... | @@ -59,6 +60,24 @@ typedef void (^FailureBlock) (NSError *error); |
| 59 | 60 | - (instancetype)initLivePlayWithActivityId:(NSString *)activityId channelId:(NSString *)channelId success:(SuccessBlock _Nullable)success failure:(FailureBlock _Nullable)failure; |
| 60 | 61 | // 推荐使用 |
| 61 | 62 | - (instancetype)initLivePlayWithActivityId:(NSString *)activityId channelId:(NSString *)channelId; |
| 63 | +- (instancetype)initLivePlayWithActivityId:(NSString *)activityId channelId:(NSString *)channelId | |
| 64 | + success:(SuccessBlock _Nullable)success failure:(FailureBlock _Nullable)failure isAgree:(BOOL)isAgree anchorStatus:(AnchorStatus)anchorStatus; | |
| 65 | +/* | |
| 66 | + 主播直播状态(只读) | |
| 67 | + | |
| 68 | + @since v0.0.1 | |
| 69 | + */ | |
| 70 | + | |
| 71 | +@property (nonatomic, assign, readonly) CNLiveAnchorStatus anchorStatus; | |
| 72 | + | |
| 73 | +/* | |
| 74 | + 重新获取主播直播状态 | |
| 75 | + | |
| 76 | + @param result 重新获取主播直播状态 | |
| 77 | + | |
| 78 | + @since v0.0.1 | |
| 79 | + */ | |
| 80 | +- (void)retryToGetAnchorStatusResult:(AnchorStatus)result; | |
| 62 | 81 | |
| 63 | 82 | #pragma mark - 切换视频 |
| 64 | 83 | /** | ... | ... |
CNLivePlayer/Classes/Player/CNLivePlayer.m
| ... | ... | @@ -14,6 +14,7 @@ |
| 14 | 14 | #import "CNLivePlayerRequest.h" |
| 15 | 15 | #import "CommonCrypto/CommonDigest.h" |
| 16 | 16 | #import "CNLivePlayerUrl.h" |
| 17 | +#import <CNLiveMsgTools/CNLiveMsgManager.h> | |
| 17 | 18 | |
| 18 | 19 | #define PlayerStringToKey(a, b) [NSString stringWithFormat:@"%@:%@",a,b] |
| 19 | 20 | |
| ... | ... | @@ -30,6 +31,10 @@ |
| 30 | 31 | NSString *_rate; |
| 31 | 32 | BOOL _switchRate; |
| 32 | 33 | CMTime _switchRateTime; |
| 34 | + | |
| 35 | + //聊天室ID | |
| 36 | + NSString *_roomId; | |
| 37 | + | |
| 33 | 38 | } |
| 34 | 39 | @property (nonatomic, strong) PLPlayerOption *option; |
| 35 | 40 | @property (nonatomic, strong) PLPlayer *switchPlayer; |
| ... | ... | @@ -38,6 +43,11 @@ |
| 38 | 43 | @end |
| 39 | 44 | |
| 40 | 45 | @implementation CNLivePlayer |
| 46 | +//收到消息通知 | |
| 47 | +NSString * const MsgToolsPlayerReceiveNotification = @"CNLiveMsgToolsPlayerReceiveNotification"; | |
| 48 | +//获取主播状态通知 | |
| 49 | +NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusChangedNotification"; | |
| 50 | + | |
| 41 | 51 | - (instancetype)initWithUrl:(NSString *)url{ |
| 42 | 52 | self = [super init]; |
| 43 | 53 | if (self) { |
| ... | ... | @@ -107,6 +117,24 @@ |
| 107 | 117 | - (instancetype)initLivePlayWithActivityId:(NSString *)activityId channelId:(NSString *)channelId{ |
| 108 | 118 | return [self initLivePlayWithActivityId:activityId channelId:channelId success:nil failure:nil]; |
| 109 | 119 | } |
| 120 | +- (instancetype)initLivePlayWithActivityId:(NSString *)activityId channelId:(NSString *)channelId | |
| 121 | + success:(SuccessBlock _Nullable)success failure:(FailureBlock _Nullable)failure isAgree:(BOOL)isAgree anchorStatus:(AnchorStatus)anchorStatus { | |
| 122 | + self = [super init]; | |
| 123 | + if (self) { | |
| 124 | + _switchRate = NO; | |
| 125 | + _activityId = activityId; | |
| 126 | + _channelId = channelId; | |
| 127 | + _videoId = @""; | |
| 128 | + _type = @"live"; | |
| 129 | + _rate = @"2"; | |
| 130 | + [self getCacheURLSuccess:success failure:failure]; | |
| 131 | + if (isAgree) { | |
| 132 | + [self initRCloudWithAppId:Player_AppID appKey:Player_AppKey connectResult:anchorStatus]; | |
| 133 | + } | |
| 134 | + } | |
| 135 | + return self; | |
| 136 | + | |
| 137 | +} | |
| 110 | 138 | /** |
| 111 | 139 | 初始化播放器 |
| 112 | 140 | |
| ... | ... | @@ -141,6 +169,7 @@ |
| 141 | 169 | } |
| 142 | 170 | |
| 143 | 171 | - (void)dealloc { |
| 172 | + [self removeRCloudNotificationObservers]; | |
| 144 | 173 | NSLog(@"CNLivePlayer --> dealloc"); |
| 145 | 174 | } |
| 146 | 175 | |
| ... | ... | @@ -886,6 +915,110 @@ CVPixelBufferGetPixelFormatType 获取 YUV 的类型。 |
| 886 | 915 | [self.delegate player:self seekToCompleted:isCompleted]; |
| 887 | 916 | } |
| 888 | 917 | } |
| 918 | +#pragma mark - 直播获取主播状态 | |
| 919 | +#pragma mark - 初始化RM | |
| 920 | +- (void)initRCloudWithAppId:(NSString *)appId appKey:(NSString *)appKey connectResult:(AnchorStatus)anchorStatus { | |
| 921 | + [[CNLiveMsgManager sharedCNLiveMsgManager] initCNLiveMsgToolsWithAppKey:appKey appId:appId]; | |
| 922 | + //连接RM服务器 | |
| 923 | + [[CNLiveMsgManager sharedCNLiveMsgManager] justOnLineSuccess:^(NSString *toolsId) { | |
| 924 | + //加入聊天室 | |
| 925 | + [self joinRoomResult:anchorStatus]; | |
| 926 | + | |
| 927 | + } error:^(NSInteger errors) { | |
| 928 | + if (anchorStatus) { | |
| 929 | + anchorStatus(NO); | |
| 930 | + } | |
| 931 | + }]; | |
| 932 | + | |
| 933 | +} | |
| 934 | + | |
| 935 | +//加入聊天室 | |
| 936 | +- (void)joinRoomResult:(AnchorStatus)anchorStatus { | |
| 937 | + [self addRCloudNotificationObservers]; | |
| 938 | + | |
| 939 | + NSString *contentId = _activityId ? _activityId : _channelId; | |
| 940 | + if (![_channelId containsString:@"_"]) { | |
| 941 | + NSString *spId = [[Player_AppID componentsSeparatedByString:@"_"] firstObject]; | |
| 942 | + contentId = [NSString stringWithFormat:@"%@_%@", spId, _channelId]; | |
| 943 | + } | |
| 944 | + | |
| 945 | + _roomId = [NSString stringWithFormat:@"CNLiveAnchorStatus_%@",contentId]; | |
| 946 | + | |
| 947 | + //加入聊天室 | |
| 948 | + [[CNLiveMsgManager sharedCNLiveMsgManager] gatherIfNullCreate:_roomId messageCount:1 success:^(NSString *targetId) { | |
| 949 | + if (anchorStatus) { | |
| 950 | + anchorStatus(YES); | |
| 951 | + } | |
| 952 | + | |
| 953 | + } error:^(NSInteger errors, NSString *targetId) { | |
| 954 | + if (anchorStatus) { | |
| 955 | + anchorStatus(CNLiveAnchorStatusError); | |
| 956 | + } | |
| 957 | + | |
| 958 | + }]; | |
| 959 | + | |
| 960 | +} | |
| 961 | + | |
| 962 | +//重新获取主播状态(离开/已结束) | |
| 963 | +- (void)retryToGetAnchorStatusResult:(AnchorStatus)anchorStatus { | |
| 964 | + [self initRCloudWithAppId:Player_AppID appKey:Player_AppKey connectResult:anchorStatus]; | |
| 965 | + | |
| 966 | +} | |
| 967 | + | |
| 968 | +#pragma mark - 通知 | |
| 969 | +- (void)addRCloudNotificationObservers { | |
| 970 | + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveMessage:) name:MsgToolsPlayerReceiveNotification object:nil]; | |
| 971 | + | |
| 972 | +} | |
| 973 | + | |
| 974 | +- (void)removeRCloudNotificationObservers { | |
| 975 | + [[NSNotificationCenter defaultCenter] removeObserver:self name:MsgToolsPlayerReceiveNotification object:nil]; | |
| 976 | + | |
| 977 | + if (!_roomId || [_roomId isEqualToString:@""] || ![_roomId isKindOfClass:[NSString class]] || _roomId.length == 0) { | |
| 978 | + return; | |
| 979 | + } | |
| 980 | + | |
| 981 | + [[CNLiveMsgManager sharedCNLiveMsgManager] disperse:_roomId success:^(NSString *targetId) { | |
| 982 | + | |
| 983 | + } error:^(NSInteger errors, NSString *targetId) { | |
| 984 | + | |
| 985 | + }]; | |
| 986 | + | |
| 987 | +} | |
| 988 | + | |
| 989 | +#pragma mark - 聊天室 | |
| 990 | +- (void)receiveMessage:(NSNotification *)noti { | |
| 991 | + | |
| 992 | + if (!noti.userInfo[@"message"]) return; | |
| 993 | + | |
| 994 | + int newValue = [noti.userInfo[@"message"] intValue]; | |
| 995 | + | |
| 996 | + if (_anchorStatus == newValue) return; //如果新收到的状态与上一次状态一样不作处理 | |
| 997 | + _anchorStatus = newValue; | |
| 998 | + | |
| 999 | + if (newValue == 1) { | |
| 1000 | + _anchorStatus = CNLiveAnchorStatusLiving; | |
| 1001 | + [_player play]; | |
| 1002 | + | |
| 1003 | + } else if (newValue == 2) { | |
| 1004 | + _anchorStatus = CNLiveAnchorStatusEnd; | |
| 1005 | + [_player stop]; | |
| 1006 | + | |
| 1007 | + } else { | |
| 1008 | + _anchorStatus = CNLiveAnchorStatusLeaving; | |
| 1009 | + [_player pause]; | |
| 1010 | + | |
| 1011 | + } | |
| 889 | 1012 | |
| 1013 | + if (Player_TestEnvironment) { | |
| 1014 | + NSLog(@"CNLiveMoviePlayerController-->主播直播状态%lu",(unsigned long)_anchorStatus); | |
| 1015 | + } | |
| 1016 | + | |
| 1017 | + //发送通知 | |
| 1018 | + dispatch_async(dispatch_get_main_queue(), ^{ | |
| 1019 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveAnchorStatusChangedNotification object:nil userInfo:nil]; | |
| 1020 | + }); | |
| 1021 | + | |
| 1022 | +} | |
| 890 | 1023 | |
| 891 | 1024 | @end | ... | ... |