Commit d690c31f571a130d1443b3dc338a06ff2e6b599c
1 parent
0fdcdd81
no message
Showing
3 changed files
with
170 additions
and
62 deletions
CNLivePlayer/Classes/Player/CNLivePlayer.h
| @@ -15,14 +15,15 @@ | @@ -15,14 +15,15 @@ | ||
| 15 | 15 | ||
| 16 | NS_ASSUME_NONNULL_BEGIN | 16 | NS_ASSUME_NONNULL_BEGIN |
| 17 | typedef NS_ENUM(NSUInteger, CNLivePlayerType) { | 17 | typedef NS_ENUM(NSUInteger, CNLivePlayerType) { |
| 18 | - CNLivePlayerVod, //点播 | ||
| 19 | - CNLivePlayerLive //直播 | 18 | + CNLivePlayerVod, //点播 |
| 19 | + CNLivePlayerLive, //直播 | ||
| 20 | + CNLivePlayerAudio //音频 | ||
| 20 | 21 | ||
| 21 | }; | 22 | }; |
| 22 | // 成功回调 | 23 | // 成功回调 |
| 23 | typedef void(^AuthSuccessBlock)(void); | 24 | typedef void(^AuthSuccessBlock)(void); |
| 24 | // 失败回调 | 25 | // 失败回调 |
| 25 | -typedef void(^AuthFailedBlock)(NSDictionary *errorInfo); | 26 | +typedef void(^AuthFailureBlock)(NSDictionary *errorInfo); |
| 26 | 27 | ||
| 27 | @interface CNLivePlayer : NSObject | 28 | @interface CNLivePlayer : NSObject |
| 28 | /* | 29 | /* |
| @@ -43,7 +44,7 @@ typedef void(^AuthFailedBlock)(NSDictionary *errorInfo); | @@ -43,7 +44,7 @@ typedef void(^AuthFailedBlock)(NSDictionary *errorInfo); | ||
| 43 | * authFailed 初始化失败block 回调一个errorInfo的字典 | 44 | * authFailed 初始化失败block 回调一个errorInfo的字典 |
| 44 | * | 45 | * |
| 45 | */ | 46 | */ |
| 46 | -- (instancetype)initVodPlayerWithVideoId:(NSString *)videoId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailed:(AuthFailedBlock)authFailedBlock; | 47 | +- (instancetype)initVodPlayerWithVideoId:(NSString *)videoId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock; |
| 47 | 48 | ||
| 48 | 49 | ||
| 49 | /* 初始化直播播放器(* 以channelId播放) 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | 50 | /* 初始化直播播放器(* 以channelId播放) 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) |
| @@ -58,7 +59,7 @@ typedef void(^AuthFailedBlock)(NSDictionary *errorInfo); | @@ -58,7 +59,7 @@ typedef void(^AuthFailedBlock)(NSDictionary *errorInfo); | ||
| 58 | * NO:获取失败,不影响视频播放,但是获取不到主播离开、回来、直播结束等通知。可通过 | 59 | * NO:获取失败,不影响视频播放,但是获取不到主播离开、回来、直播结束等通知。可通过 |
| 59 | * - (void)retryToGetAnchorStatusResult:(void(^)(BOOL result))result;方法重新获取 | 60 | * - (void)retryToGetAnchorStatusResult:(void(^)(BOOL result))result;方法重新获取 |
| 60 | */ | 61 | */ |
| 61 | -- (instancetype)initLivePlayerWithChannelId:(NSString *)channelId activityId:(NSString *)activityId anchorStatus:(BOOL)agree authSuccess:(AuthSuccessBlock)authSuccessBlock authFailed:(AuthFailedBlock)authFailedBlock getAnchorStatusResult:(void(^)(BOOL result))result; | 62 | +- (instancetype)initLivePlayerWithChannelId:(NSString *)channelId activityId:(NSString *)activityId anchorStatus:(BOOL)agree authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock getAnchorStatusResult:(void(^)(BOOL result))result; |
| 62 | 63 | ||
| 63 | 64 | ||
| 64 | /* 初始化音频播放器 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | 65 | /* 初始化音频播放器 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) |
| @@ -68,8 +69,15 @@ typedef void(^AuthFailedBlock)(NSDictionary *errorInfo); | @@ -68,8 +69,15 @@ typedef void(^AuthFailedBlock)(NSDictionary *errorInfo); | ||
| 68 | * authFailed 初始化失败block 回调一个errorInfo的字典 | 69 | * authFailed 初始化失败block 回调一个errorInfo的字典 |
| 69 | * | 70 | * |
| 70 | */ | 71 | */ |
| 71 | -- (instancetype)initAudioPlayerWithAudioId:(NSString *)audioId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailed:(AuthFailedBlock)authFailedBlock; | 72 | +- (instancetype)initAudioPlayerWithAudioId:(NSString *)audioId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock; |
| 72 | 73 | ||
| 74 | +/* 设置播放器进成功后(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | ||
| 75 | + * | ||
| 76 | + * contentId 内容Id | ||
| 77 | + * type 内容类型 | ||
| 78 | + * | ||
| 79 | + */ | ||
| 80 | +- (void)setPlayerWithContentId:(NSString *)contentId type:(CNLivePlayerType)type authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock; | ||
| 73 | 81 | ||
| 74 | /** | 82 | /** |
| 75 | @abstract 包含视频播放内容的VIEW(只读)。 | 83 | @abstract 包含视频播放内容的VIEW(只读)。 |
CNLivePlayer/Classes/Player/CNLivePlayer.m
| @@ -61,21 +61,24 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -61,21 +61,24 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 61 | * | 61 | * |
| 62 | * videoId 点播视频Id | 62 | * videoId 点播视频Id |
| 63 | * authSuccess 初始化成功block | 63 | * authSuccess 初始化成功block |
| 64 | - * authFailed 初始化失败block 回调一个errorInfo的字典 | 64 | + * authFailure 初始化失败block 回调一个errorInfo的字典 |
| 65 | * | 65 | * |
| 66 | */ | 66 | */ |
| 67 | -- (instancetype)initVodPlayerWithVideoId:(NSString *)videoId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailed:(AuthFailedBlock)authFailedBlock { | 67 | +- (instancetype)initVodPlayerWithVideoId:(NSString *)videoId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock { |
| 68 | if (self = [super init]) { | 68 | if (self = [super init]) { |
| 69 | if (![videoId isKindOfClass:[NSString class]] || !videoId) { | 69 | if (![videoId isKindOfClass:[NSString class]] || !videoId) { |
| 70 | videoId = videoId ? [NSString stringWithFormat:@"%@",videoId] : @""; | 70 | videoId = videoId ? [NSString stringWithFormat:@"%@",videoId] : @""; |
| 71 | 71 | ||
| 72 | } | 72 | } |
| 73 | + | ||
| 74 | + self.type = CNLivePlayerVod; | ||
| 75 | + | ||
| 73 | _idName = @"vid"; | 76 | _idName = @"vid"; |
| 74 | _contentType = @"vod"; | 77 | _contentType = @"vod"; |
| 75 | _contentId = videoId; | 78 | _contentId = videoId; |
| 76 | _isAudio = NO; | 79 | _isAudio = NO; |
| 77 | 80 | ||
| 78 | - [self createPlayerWithContentId:videoId authSuccess:authSuccessBlock authFailed:authFailedBlock]; | 81 | + [self createPlayerWithContentId:videoId authSuccess:authSuccessBlock authFailure:authFailureBlock]; |
| 79 | 82 | ||
| 80 | } | 83 | } |
| 81 | return self; | 84 | return self; |
| @@ -88,13 +91,13 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -88,13 +91,13 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 88 | * activityId 活动Id | 91 | * activityId 活动Id |
| 89 | * agree 是否允许获取主播状态 YES:获取 NO:不获取 | 92 | * agree 是否允许获取主播状态 YES:获取 NO:不获取 |
| 90 | * authSuccess 初始化成功block | 93 | * authSuccess 初始化成功block |
| 91 | - * authFailed 初始化失败block 回调一个errorInfo的字典 | 94 | + * authFailure 初始化失败block 回调一个errorInfo的字典 |
| 92 | * | 95 | * |
| 93 | * result 获取主播状态 YES:获取状态成功 | 96 | * result 获取主播状态 YES:获取状态成功 |
| 94 | * NO:获取失败,不影响视频播放,但是获取不到主播离开、回来、直播结束等通知。可通过 | 97 | * NO:获取失败,不影响视频播放,但是获取不到主播离开、回来、直播结束等通知。可通过 |
| 95 | * - (void)retryToGetAnchorStatusResult:(void(^)(BOOL result))result;方法重新获取 | 98 | * - (void)retryToGetAnchorStatusResult:(void(^)(BOOL result))result;方法重新获取 |
| 96 | */ | 99 | */ |
| 97 | -- (instancetype)initLivePlayerWithChannelId:(NSString *)channelId activityId:(NSString *)activityId anchorStatus:(BOOL)agree authSuccess:(AuthSuccessBlock)authSuccessBlock authFailed:(AuthFailedBlock)authFailedBlock getAnchorStatusResult:(void(^)(BOOL result))result{ | 100 | +- (instancetype)initLivePlayerWithChannelId:(NSString *)channelId activityId:(NSString *)activityId anchorStatus:(BOOL)agree authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock getAnchorStatusResult:(void(^)(BOOL result))result{ |
| 98 | if (self = [super init]) { | 101 | if (self = [super init]) { |
| 99 | if (![channelId isKindOfClass:[NSString class]] || !channelId) { | 102 | if (![channelId isKindOfClass:[NSString class]] || !channelId) { |
| 100 | channelId = channelId ? [NSString stringWithFormat:@"%@",channelId] : @""; | 103 | channelId = channelId ? [NSString stringWithFormat:@"%@",channelId] : @""; |
| @@ -103,6 +106,8 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -103,6 +106,8 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 103 | activityId = activityId ? [NSString stringWithFormat:@"%@",activityId] : @""; | 106 | activityId = activityId ? [NSString stringWithFormat:@"%@",activityId] : @""; |
| 104 | } | 107 | } |
| 105 | 108 | ||
| 109 | + self.type = CNLivePlayerLive; | ||
| 110 | + | ||
| 106 | _idName = @"cid"; | 111 | _idName = @"cid"; |
| 107 | _contentType = @"live"; | 112 | _contentType = @"live"; |
| 108 | _contentId = channelId; | 113 | _contentId = channelId; |
| @@ -113,7 +118,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -113,7 +118,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 113 | [self initRCloudWithAppId:PLAYER_AppID appKey:PLAYER_AppKey connectResult:result]; | 118 | [self initRCloudWithAppId:PLAYER_AppID appKey:PLAYER_AppKey connectResult:result]; |
| 114 | } | 119 | } |
| 115 | 120 | ||
| 116 | - [self createPlayerWithContentId:channelId authSuccess:authSuccessBlock authFailed:authFailedBlock]; | 121 | + [self createPlayerWithContentId:channelId authSuccess:authSuccessBlock authFailure:authFailureBlock]; |
| 117 | 122 | ||
| 118 | } | 123 | } |
| 119 | return self; | 124 | return self; |
| @@ -124,35 +129,38 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -124,35 +129,38 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 124 | * | 129 | * |
| 125 | * audioId 音频Id | 130 | * audioId 音频Id |
| 126 | * authSuccess 初始化成功block | 131 | * authSuccess 初始化成功block |
| 127 | - * authFailed 初始化失败block 回调一个errorInfo的字典 | 132 | + * authFailure 初始化失败block 回调一个errorInfo的字典 |
| 128 | * | 133 | * |
| 129 | */ | 134 | */ |
| 130 | -- (instancetype)initAudioPlayerWithAudioId:(NSString *)audioId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailed:(AuthFailedBlock)authFailedBlock{ | 135 | +- (instancetype)initAudioPlayerWithAudioId:(NSString *)audioId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock{ |
| 131 | if (self = [super init]) { | 136 | if (self = [super init]) { |
| 132 | if (![audioId isKindOfClass:[NSString class]] || !audioId) { | 137 | if (![audioId isKindOfClass:[NSString class]] || !audioId) { |
| 133 | audioId = audioId ? [NSString stringWithFormat:@"%@",audioId] : @""; | 138 | audioId = audioId ? [NSString stringWithFormat:@"%@",audioId] : @""; |
| 134 | 139 | ||
| 135 | } | 140 | } |
| 141 | + | ||
| 142 | + self.type = CNLivePlayerAudio; | ||
| 143 | + | ||
| 136 | _idName = @"vid"; | 144 | _idName = @"vid"; |
| 137 | _contentType = @"vod"; | 145 | _contentType = @"vod"; |
| 138 | _contentId = audioId; | 146 | _contentId = audioId; |
| 139 | _isAudio = YES; | 147 | _isAudio = YES; |
| 140 | 148 | ||
| 141 | - [self createPlayerWithContentId:audioId authSuccess:authSuccessBlock authFailed:authFailedBlock]; | 149 | + [self createPlayerWithContentId:audioId authSuccess:authSuccessBlock authFailure:authFailureBlock]; |
| 142 | 150 | ||
| 143 | } | 151 | } |
| 144 | return self; | 152 | return self; |
| 145 | 153 | ||
| 146 | } | 154 | } |
| 147 | 155 | ||
| 148 | -- (void)createPlayerWithContentId:(NSString *)contentId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailed:(AuthFailedBlock)authFailedBlock{ | 156 | +- (void)createPlayerWithContentId:(NSString *)contentId authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock{ |
| 149 | [UIApplication sharedApplication].idleTimerDisabled = YES; | 157 | [UIApplication sharedApplication].idleTimerDisabled = YES; |
| 150 | 158 | ||
| 151 | _retryTime = 0; | 159 | _retryTime = 0; |
| 152 | [self addMovieNotificationObservers]; | 160 | [self addMovieNotificationObservers]; |
| 153 | 161 | ||
| 154 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ | 162 | dispatch_async(dispatch_get_global_queue(0, 0), ^{ |
| 155 | - [self getContentId:contentId authSuccess:authSuccessBlock authFailed:authFailedBlock]; | 163 | + [self getUrlSuccess:authSuccessBlock failure:authFailureBlock]; |
| 156 | 164 | ||
| 157 | }); | 165 | }); |
| 158 | } | 166 | } |
| @@ -177,10 +185,49 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -177,10 +185,49 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 177 | [self removeRCloudNotificationObservers]; | 185 | [self removeRCloudNotificationObservers]; |
| 178 | 186 | ||
| 179 | } | 187 | } |
| 188 | +- (void)setPlayerWithContentId:(NSString *)contentId type:(CNLivePlayerType)type authSuccess:(AuthSuccessBlock)authSuccessBlock authFailure:(AuthFailureBlock)authFailureBlock{ | ||
| 189 | + _type = type; | ||
| 190 | + switch (type) { | ||
| 191 | + case CNLivePlayerVod: | ||
| 192 | + { | ||
| 193 | + _idName = @"vid"; | ||
| 194 | + _contentType = @"vod"; | ||
| 195 | + _contentId = contentId; | ||
| 196 | + _isAudio = NO; | ||
| 197 | + } | ||
| 198 | + break; | ||
| 199 | + case CNLivePlayerLive: | ||
| 200 | + { | ||
| 201 | + _idName = @"cid"; | ||
| 202 | + _contentType = @"live"; | ||
| 203 | +// _contentId = channelId; | ||
| 204 | +// _activityId = [NSString stringWithFormat:@"%@",activityId]; | ||
| 205 | + _isAudio = NO; | ||
| 206 | + } | ||
| 207 | + break; | ||
| 208 | + case CNLivePlayerAudio: | ||
| 209 | + { | ||
| 210 | + _idName = @"vid"; | ||
| 211 | + _contentType = @"vod"; | ||
| 212 | + _contentId = contentId; | ||
| 213 | + _isAudio = YES; | ||
| 214 | + } | ||
| 215 | + break; | ||
| 216 | + | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + __weak typeof(self) weakSelf = self; | ||
| 220 | + dispatch_async(dispatch_get_global_queue(0, 0), ^{ | ||
| 221 | + __strong typeof(self) strongSelf = weakSelf; | ||
| 222 | + [strongSelf getUrlSuccess:authSuccessBlock failure:authFailureBlock]; | ||
| 223 | + | ||
| 224 | + }); | ||
| 225 | + | ||
| 226 | +} | ||
| 180 | 227 | ||
| 181 | #pragma mark - 查找本地是否有缓存url | 228 | #pragma mark - 查找本地是否有缓存url |
| 182 | -- (void)getContentId:(NSString *)contentId authSuccess:(void (^)(void))authSuccessBlock authFailed:(void (^)(NSDictionary *errorDic))authFailedBlock { | ||
| 183 | - NSString *key = [NSString stringWithFormat:@"%@:%@",_contentType,contentId]; | 229 | +- (void)getUrlSuccess:(void (^)(void))authSuccessBlock failure:(void (^)(NSDictionary *errorDic))authFailureBlock { |
| 230 | + NSString *key = [NSString stringWithFormat:@"%@:%@",_contentType,_contentId]; | ||
| 184 | id data = [CNLivePlayerCache player_ReadCache:key]; | 231 | id data = [CNLivePlayerCache player_ReadCache:key]; |
| 185 | //1.判断是否存在缓存url | 232 | //1.判断是否存在缓存url |
| 186 | if (data && [data isKindOfClass:[NSString class]]) { | 233 | if (data && [data isKindOfClass:[NSString class]]) { |
| @@ -188,15 +235,22 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -188,15 +235,22 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 188 | dispatch_async(dispatch_get_main_queue(), ^{ | 235 | dispatch_async(dispatch_get_main_queue(), ^{ |
| 189 | __strong typeof(self) strongSelf = weakSelf; | 236 | __strong typeof(self) strongSelf = weakSelf; |
| 190 | strongSelf.videoUrl = (NSString *)data; | 237 | strongSelf.videoUrl = (NSString *)data; |
| 191 | - strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:strongSelf.videoUrl]]; | ||
| 192 | - [strongSelf.view addSubview:self.player.view]; | ||
| 193 | - strongSelf.player.view.frame = self.view.bounds; | ||
| 194 | - strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | ||
| 195 | - strongSelf.player.shouldEnableKSYStatModule = NO; | ||
| 196 | - if (PLAYER_TestEnvironment) { | ||
| 197 | - NSLog(@"CNLivePlayer-->缓存数据,播放器初始化成功,可以对播放器进行设置并准备播放"); | 238 | + if(!strongSelf.player){ |
| 239 | + strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:strongSelf.videoUrl]]; | ||
| 240 | + [strongSelf.view addSubview:self.player.view]; | ||
| 241 | + strongSelf.player.view.frame = self.view.bounds; | ||
| 242 | + strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | ||
| 243 | + strongSelf.player.shouldEnableKSYStatModule = NO; | ||
| 244 | + if (PLAYER_TestEnvironment) { | ||
| 245 | + NSLog(@"CNLivePlayer-->缓存数据,播放器初始化成功,可以对播放器进行设置并准备播放"); | ||
| 246 | + } | ||
| 247 | + authSuccessBlock ? authSuccessBlock() : nil; | ||
| 248 | + }else{ | ||
| 249 | + [strongSelf.player reset:YES]; | ||
| 250 | + [strongSelf.player setUrl:[NSURL URLWithString:strongSelf.videoUrl]]; | ||
| 198 | } | 251 | } |
| 199 | authSuccessBlock ? authSuccessBlock() : nil; | 252 | authSuccessBlock ? authSuccessBlock() : nil; |
| 253 | + | ||
| 200 | }); | 254 | }); |
| 201 | 255 | ||
| 202 | } else { | 256 | } else { |
| @@ -205,10 +259,10 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -205,10 +259,10 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 205 | if(privilegeDic&&[privilegeDic[@"resultCode"] isEqualToString:@"0"]){ | 259 | if(privilegeDic&&[privilegeDic[@"resultCode"] isEqualToString:@"0"]){ |
| 206 | //3.存在鉴权成功,直接请求url | 260 | //3.存在鉴权成功,直接请求url |
| 207 | if([_contentType isEqualToString:@"vod"]){ | 261 | if([_contentType isEqualToString:@"vod"]){ |
| 208 | - [self getVodVideoURLSuccess:authSuccessBlock failure:authFailedBlock]; | 262 | + [self getVodVideoURLSuccess:authSuccessBlock failure:authFailureBlock]; |
| 209 | 263 | ||
| 210 | }else{ | 264 | }else{ |
| 211 | - [self getLiveVideoURLSuccess:authSuccessBlock failure:authFailedBlock]; | 265 | + [self getLiveVideoURLSuccess:authSuccessBlock failure:authFailureBlock]; |
| 212 | 266 | ||
| 213 | } | 267 | } |
| 214 | 268 | ||
| @@ -219,14 +273,14 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -219,14 +273,14 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 219 | //5.鉴权成功,再请求url | 273 | //5.鉴权成功,再请求url |
| 220 | __strong typeof(self) strongSelf = weakSelf; | 274 | __strong typeof(self) strongSelf = weakSelf; |
| 221 | if([strongSelf->_contentType isEqualToString:@"vod"]){ | 275 | if([strongSelf->_contentType isEqualToString:@"vod"]){ |
| 222 | - [strongSelf getVodVideoURLSuccess:authSuccessBlock failure:authFailedBlock]; | 276 | + [strongSelf getVodVideoURLSuccess:authSuccessBlock failure:authFailureBlock]; |
| 223 | 277 | ||
| 224 | }else{ | 278 | }else{ |
| 225 | - [strongSelf getLiveVideoURLSuccess:authSuccessBlock failure:authFailedBlock]; | 279 | + [strongSelf getLiveVideoURLSuccess:authSuccessBlock failure:authFailureBlock]; |
| 226 | 280 | ||
| 227 | } | 281 | } |
| 228 | 282 | ||
| 229 | - } failure:authFailedBlock]; | 283 | + } failure:authFailureBlock]; |
| 230 | } | 284 | } |
| 231 | 285 | ||
| 232 | } | 286 | } |
| @@ -234,7 +288,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -234,7 +288,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 234 | } | 288 | } |
| 235 | 289 | ||
| 236 | #pragma mark - 鉴权 | 290 | #pragma mark - 鉴权 |
| 237 | -- (void)authenticateSuccess:(AuthSuccessBlock)authSuccessBlock failure:(AuthFailedBlock)authFailedBlock { | 291 | +- (void)authenticateSuccess:(AuthSuccessBlock)authSuccessBlock failure:(AuthFailureBlock)authFailureBlock { |
| 238 | 292 | ||
| 239 | NSDictionary *parameter = @{@"platform_id": [NSBundle mainBundle].bundleIdentifier, | 293 | NSDictionary *parameter = @{@"platform_id": [NSBundle mainBundle].bundleIdentifier, |
| 240 | @"timestamp": [CNLivePlayerTools getTimestamp], | 294 | @"timestamp": [CNLivePlayerTools getTimestamp], |
| @@ -246,7 +300,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -246,7 +300,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 246 | [[CNLivePlayerNetworkManager manager] authenticate:videoUrl success:^(NSURLResponse * _Nullable response, id _Nullable responseObject) { | 300 | [[CNLivePlayerNetworkManager manager] authenticate:videoUrl success:^(NSURLResponse * _Nullable response, id _Nullable responseObject) { |
| 247 | __strong typeof(self) strongSelf = weakSelf; | 301 | __strong typeof(self) strongSelf = weakSelf; |
| 248 | if(!responseObject||![responseObject isKindOfClass:[NSDictionary class]]){ | 302 | if(!responseObject||![responseObject isKindOfClass:[NSDictionary class]]){ |
| 249 | - authFailedBlock ? authFailedBlock(responseObject) : nil; | 303 | + authFailureBlock ? authFailureBlock(responseObject) : nil; |
| 250 | 304 | ||
| 251 | } | 305 | } |
| 252 | 306 | ||
| @@ -263,7 +317,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -263,7 +317,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 263 | if (PLAYER_TestEnvironment) { | 317 | if (PLAYER_TestEnvironment) { |
| 264 | NSLog(@"CNLivePlayer-->播放器初始化失败,失败原因:%@", authErrorDic); | 318 | NSLog(@"CNLivePlayer-->播放器初始化失败,失败原因:%@", authErrorDic); |
| 265 | } | 319 | } |
| 266 | - authFailedBlock ? authFailedBlock(responseObject) : nil; | 320 | + authFailureBlock ? authFailureBlock(responseObject) : nil; |
| 267 | [CNLivePlayerTools errorStat:authErrorDic[@"errorMessage"] contentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; | 321 | [CNLivePlayerTools errorStat:authErrorDic[@"errorMessage"] contentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; |
| 268 | 322 | ||
| 269 | } | 323 | } |
| @@ -279,7 +333,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -279,7 +333,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 279 | if (PLAYER_TestEnvironment) { | 333 | if (PLAYER_TestEnvironment) { |
| 280 | NSLog(@"CNLivePlayer-->播放器初始化失败,失败原因:%@", authErrorDic); | 334 | NSLog(@"CNLivePlayer-->播放器初始化失败,失败原因:%@", authErrorDic); |
| 281 | } | 335 | } |
| 282 | - authFailedBlock ? authFailedBlock(authErrorDic) : nil; | 336 | + authFailureBlock ? authFailureBlock(authErrorDic) : nil; |
| 283 | [CNLivePlayerTools errorStat:authErrorDic[@"errorMessage"] contentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; | 337 | [CNLivePlayerTools errorStat:authErrorDic[@"errorMessage"] contentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; |
| 284 | 338 | ||
| 285 | }]; | 339 | }]; |
| @@ -287,7 +341,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -287,7 +341,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 287 | } | 341 | } |
| 288 | 342 | ||
| 289 | #pragma mark - 获取点播视频url | 343 | #pragma mark - 获取点播视频url |
| 290 | -- (void)getVodVideoURLSuccess:(AuthSuccessBlock)authSuccessBlock failure:(AuthFailedBlock)authFailedBlock { | 344 | +- (void)getVodVideoURLSuccess:(AuthSuccessBlock)authSuccessBlock failure:(AuthFailureBlock)authFailureBlock { |
| 291 | NSString *stamp = [CNLivePlayerTools getTimestamp]; | 345 | NSString *stamp = [CNLivePlayerTools getTimestamp]; |
| 292 | NSDictionary *parameter = @{@"appId": PLAYER_AppID, | 346 | NSDictionary *parameter = @{@"appId": PLAYER_AppID, |
| 293 | @"vId": _contentId, | 347 | @"vId": _contentId, |
| @@ -307,22 +361,29 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -307,22 +361,29 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 307 | __weak typeof(self) weakSelf = self; | 361 | __weak typeof(self) weakSelf = self; |
| 308 | [CNLivePlayerNetworkManager getVideoURL:videoUrl success:^(NSString * _Nullable videoURL, NSInteger code) { | 362 | [CNLivePlayerNetworkManager getVideoURL:videoUrl success:^(NSString * _Nullable videoURL, NSInteger code) { |
| 309 | __strong typeof(self) strongSelf = weakSelf; | 363 | __strong typeof(self) strongSelf = weakSelf; |
| 310 | -// NSString *key = [NSString stringWithFormat:@"%@:%@",strongSelf->_contentType, strongSelf->_contentId]; | ||
| 311 | -// [CNLivePlayerCache player_SaveDataCache:videoURL forKey:key]; | 364 | + NSString *key = [NSString stringWithFormat:@"%@:%@",strongSelf->_contentType, strongSelf->_contentId]; |
| 365 | + [CNLivePlayerCache player_SaveDataCache:videoURL forKey:key]; | ||
| 312 | __weak typeof(self) weakSelf = strongSelf; | 366 | __weak typeof(self) weakSelf = strongSelf; |
| 313 | dispatch_async(dispatch_get_main_queue(), ^{ | 367 | dispatch_async(dispatch_get_main_queue(), ^{ |
| 314 | __strong typeof(self) strongSelf = weakSelf; | 368 | __strong typeof(self) strongSelf = weakSelf; |
| 315 | - strongSelf.videoUrl = videoUrl; | ||
| 316 | - strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:videoUrl]]; | ||
| 317 | - [strongSelf.view addSubview:strongSelf.player.view]; | ||
| 318 | - strongSelf.player.view.frame = strongSelf.view.bounds; | ||
| 319 | - strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | ||
| 320 | - strongSelf.player.shouldEnableKSYStatModule = NO; | ||
| 321 | - | ||
| 322 | - [CNLivePlayerTools statSDKWithContentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; | 369 | + strongSelf.videoUrl = videoURL; |
| 370 | + if(!strongSelf.player){ | ||
| 371 | + strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:videoUrl]]; | ||
| 372 | + [strongSelf.view addSubview:strongSelf.player.view]; | ||
| 373 | + strongSelf.player.view.frame = strongSelf.view.bounds; | ||
| 374 | + strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | ||
| 375 | + strongSelf.player.shouldEnableKSYStatModule = NO; | ||
| 376 | + | ||
| 377 | + [CNLivePlayerTools statSDKWithContentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; | ||
| 378 | + | ||
| 379 | + if (PLAYER_TestEnvironment) { | ||
| 380 | + NSLog(@"CNLivePlayer-->请求数据,点播播放器初始化成功,可以对播放器进行设置并准备播放"); | ||
| 381 | + } | ||
| 382 | + | ||
| 383 | + }else{ | ||
| 384 | + [strongSelf.player reset:YES]; | ||
| 385 | + [strongSelf.player setUrl:[NSURL URLWithString:strongSelf.videoUrl]]; | ||
| 323 | 386 | ||
| 324 | - if (PLAYER_TestEnvironment) { | ||
| 325 | - NSLog(@"CNLivePlayer-->请求数据,点播播放器初始化成功,可以对播放器进行设置并准备播放"); | ||
| 326 | } | 387 | } |
| 327 | if (authSuccessBlock) { | 388 | if (authSuccessBlock) { |
| 328 | authSuccessBlock(); | 389 | authSuccessBlock(); |
| @@ -333,7 +394,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -333,7 +394,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 333 | } | 394 | } |
| 334 | 395 | ||
| 335 | #pragma mark - 获取直播视频url | 396 | #pragma mark - 获取直播视频url |
| 336 | -- (void)getLiveVideoURLSuccess:(AuthSuccessBlock)authSuccessBlock failure:(AuthFailedBlock)authFailedBlock { | 397 | +- (void)getLiveVideoURLSuccess:(AuthSuccessBlock)authSuccessBlock failure:(AuthFailureBlock)authFailureBlock { |
| 337 | NSString *timestamp = [CNLivePlayerTools getTimestamp]; | 398 | NSString *timestamp = [CNLivePlayerTools getTimestamp]; |
| 338 | NSDictionary *parameter = @{@"appId": PLAYER_AppID, | 399 | NSDictionary *parameter = @{@"appId": PLAYER_AppID, |
| 339 | @"channelId": _contentId, | 400 | @"channelId": _contentId, |
| @@ -382,16 +443,23 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -382,16 +443,23 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 382 | dispatch_async(dispatch_get_main_queue(), ^{ | 443 | dispatch_async(dispatch_get_main_queue(), ^{ |
| 383 | __strong typeof(self) strongSelf = weakSelf; | 444 | __strong typeof(self) strongSelf = weakSelf; |
| 384 | strongSelf.videoUrl = url; | 445 | strongSelf.videoUrl = url; |
| 385 | - strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:url]]; | ||
| 386 | - [strongSelf.view addSubview:strongSelf.player.view]; | ||
| 387 | - strongSelf.player.view.frame = strongSelf.view.bounds; | ||
| 388 | - strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | ||
| 389 | - strongSelf.player.shouldEnableKSYStatModule = NO; | ||
| 390 | - | ||
| 391 | - [CNLivePlayerTools statSDKWithContentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; | 446 | + if(!strongSelf.player){ |
| 447 | + strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:url]]; | ||
| 448 | + [strongSelf.view addSubview:strongSelf.player.view]; | ||
| 449 | + strongSelf.player.view.frame = strongSelf.view.bounds; | ||
| 450 | + strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | ||
| 451 | + strongSelf.player.shouldEnableKSYStatModule = NO; | ||
| 452 | + | ||
| 453 | + [CNLivePlayerTools statSDKWithContentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; | ||
| 454 | + | ||
| 455 | + if (PLAYER_TestEnvironment) { | ||
| 456 | + NSLog(@"CNLivePlayer-->请求数据,直播播放器初始化成功,可以对播放器进行设置并准备播放"); | ||
| 457 | + } | ||
| 458 | + | ||
| 459 | + }else{ | ||
| 460 | + [strongSelf.player reset:YES]; | ||
| 461 | + [strongSelf.player setUrl:[NSURL URLWithString:strongSelf.videoUrl]]; | ||
| 392 | 462 | ||
| 393 | - if (PLAYER_TestEnvironment) { | ||
| 394 | - NSLog(@"CNLivePlayer-->请求数据,直播播放器初始化成功,可以对播放器进行设置并准备播放"); | ||
| 395 | } | 463 | } |
| 396 | if (authSuccessBlock) { | 464 | if (authSuccessBlock) { |
| 397 | authSuccessBlock(); | 465 | authSuccessBlock(); |
Example/CNLivePlayer/CNLiveViewController.m
| @@ -23,16 +23,37 @@ | @@ -23,16 +23,37 @@ | ||
| 23 | { | 23 | { |
| 24 | [super viewDidLoad]; | 24 | [super viewDidLoad]; |
| 25 | // Do any additional setup after loading the view, typically from a nib. | 25 | // Do any additional setup after loading the view, typically from a nib. |
| 26 | - _player = [[CNLivePlayer alloc]initVodPlayerWithVideoId:@"82_c8ff347048414b7295cef882f8361073" authSuccess:^{ | 26 | + |
| 27 | +// _player = [[CNLivePlayer alloc]initVodPlayerWithVideoId:@"82_c8ff347048414b7295cef882f8361073" authSuccess:^{ | ||
| 28 | +// NSLog(@"---------------初始化播放器成功---------------"); | ||
| 29 | +// _player.view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.width*9/16.0); | ||
| 30 | +// [_player prepareToPlay]; | ||
| 31 | +// [self.view addSubview:_player.view]; | ||
| 32 | +// } authFailed:^(NSDictionary * _Nonnull errorInfo) { | ||
| 33 | +// NSLog(@"%@", errorInfo); | ||
| 34 | +// | ||
| 35 | +// }]; | ||
| 36 | + | ||
| 37 | + _player = [[CNLivePlayer alloc]initAudioPlayerWithAudioId:@"1066_716fabeaafb64236b60ecf74167c5c96" authSuccess:^{ | ||
| 27 | NSLog(@"---------------初始化播放器成功---------------"); | 38 | NSLog(@"---------------初始化播放器成功---------------"); |
| 28 | - _player.view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.width*9/16.0); | ||
| 29 | [_player prepareToPlay]; | 39 | [_player prepareToPlay]; |
| 30 | [self.view addSubview:_player.view]; | 40 | [self.view addSubview:_player.view]; |
| 31 | - } authFailed:^(NSDictionary * _Nonnull errorInfo) { | 41 | + |
| 42 | + } authFailure:^(NSDictionary * _Nonnull errorInfo) { | ||
| 32 | NSLog(@"%@", errorInfo); | 43 | NSLog(@"%@", errorInfo); |
| 33 | - | 44 | + |
| 34 | }]; | 45 | }]; |
| 35 | 46 | ||
| 47 | + UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; | ||
| 48 | + btn.frame =CGRectMake(0, 0, 100, 100); | ||
| 49 | + btn.center = self.view.center; | ||
| 50 | + btn.backgroundColor = [UIColor redColor]; | ||
| 51 | + [btn addTarget:self action:@selector(btnDidClicked) forControlEvents:UIControlEventTouchUpInside]; | ||
| 52 | + [self.view addSubview:btn]; | ||
| 53 | + | ||
| 54 | + | ||
| 55 | + | ||
| 56 | + | ||
| 36 | // KSYMoviePlayerController *player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:@"http://wideo02.cnlive.com/video/data1/2017/0423/206473/800/c8ff347048414b7295cef882f8361073_206473_800.m3u8"]]; | 57 | // KSYMoviePlayerController *player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:@"http://wideo02.cnlive.com/video/data1/2017/0423/206473/800/c8ff347048414b7295cef882f8361073_206473_800.m3u8"]]; |
| 37 | // player.view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.width*9/16.0); | 58 | // player.view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.width*9/16.0); |
| 38 | // player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | 59 | // player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; |
| @@ -40,6 +61,17 @@ | @@ -40,6 +61,17 @@ | ||
| 40 | // [self.view addSubview:player.view]; | 61 | // [self.view addSubview:player.view]; |
| 41 | 62 | ||
| 42 | } | 63 | } |
| 64 | +- (void)btnDidClicked{ | ||
| 65 | + [_player setPlayerWithContentId:@"82_c8ff347048414b7295cef882f8361073" type:CNLivePlayerVod authSuccess:^{ | ||
| 66 | + | ||
| 67 | + _player.view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.width*9/16.0); | ||
| 68 | + [_player prepareToPlay]; | ||
| 69 | + | ||
| 70 | + } authFailure:^(NSDictionary * _Nonnull errorInfo) { | ||
| 71 | + | ||
| 72 | + }]; | ||
| 73 | + | ||
| 74 | +} | ||
| 43 | 75 | ||
| 44 | - (void)didReceiveMemoryWarning | 76 | - (void)didReceiveMemoryWarning |
| 45 | { | 77 | { |