Commit c7d9b14980fe27f546ef3614264f2bdb4e75fb6f
1 parent
ee67e19b
no message
Showing
12 changed files
with
237 additions
and
188 deletions
CNLivePlayer.podspec
| @@ -47,10 +47,13 @@ TODO: Add long description of the pod here. | @@ -47,10 +47,13 @@ TODO: Add long description of the pod here. | ||
| 47 | ss.source_files = 'CNLivePlayer/Classes/Tools/*.{h,m}' | 47 | ss.source_files = 'CNLivePlayer/Classes/Tools/*.{h,m}' |
| 48 | end | 48 | end |
| 49 | 49 | ||
| 50 | + s.static_framework = true | ||
| 51 | + | ||
| 50 | # s.public_header_files = 'Pod/Classes/**/*.h' | 52 | # s.public_header_files = 'Pod/Classes/**/*.h' |
| 51 | s.frameworks = 'UIKit', 'MediaPlayer' | 53 | s.frameworks = 'UIKit', 'MediaPlayer' |
| 52 | s.dependency 'libksygpulive/KSYGPUResource' | 54 | s.dependency 'libksygpulive/KSYGPUResource' |
| 53 | s.dependency 'libksygpulive/libksygpulive' | 55 | s.dependency 'libksygpulive/libksygpulive' |
| 56 | + s.dependency 'ksyhttpcache' | ||
| 54 | s.dependency 'GPUImage' | 57 | s.dependency 'GPUImage' |
| 55 | s.dependency 'YYCache' | 58 | s.dependency 'YYCache' |
| 56 | 59 |
CNLivePlayer/Classes/DataRequest/CNLivePlayerCache.h
CNLivePlayer/Classes/DataRequest/CNLivePlayerCache.m
| @@ -18,7 +18,7 @@ static YYCache *_dataCache; | @@ -18,7 +18,7 @@ static YYCache *_dataCache; | ||
| 18 | [super initialize]; | 18 | [super initialize]; |
| 19 | // 实例化方式一 | 19 | // 实例化方式一 |
| 20 | _dataCache = [[YYCache alloc] initWithName:PlayerCache]; | 20 | _dataCache = [[YYCache alloc] initWithName:PlayerCache]; |
| 21 | - [CNLivePlayerCache setCostLimit:1024*1024*20]; | 21 | + [CNLivePlayerCache player_SetCostLimit:1024*1024*30]; |
| 22 | 22 | ||
| 23 | } | 23 | } |
| 24 | 24 | ||
| @@ -29,7 +29,6 @@ static YYCache *_dataCache; | @@ -29,7 +29,6 @@ static YYCache *_dataCache; | ||
| 29 | * @param key 保存的key | 29 | * @param key 保存的key |
| 30 | */ | 30 | */ |
| 31 | + (void)player_SaveDataCache:(id)data forKey:(NSString *)key { | 31 | + (void)player_SaveDataCache:(id)data forKey:(NSString *)key { |
| 32 | - // [[self sharedManager]setObject:data forKey:key]; | ||
| 33 | // 默认会开启线程缓存 | 32 | // 默认会开启线程缓存 |
| 34 | [_dataCache setObject:data forKey:key withBlock:nil]; | 33 | [_dataCache setObject:data forKey:key withBlock:nil]; |
| 35 | 34 | ||
| @@ -111,7 +110,9 @@ static YYCache *_dataCache; | @@ -111,7 +110,9 @@ static YYCache *_dataCache; | ||
| 111 | * 磁盘最大缓存开销 | 110 | * 磁盘最大缓存开销 |
| 112 | * 默认是30*1024*1024 | 111 | * 默认是30*1024*1024 |
| 113 | */ | 112 | */ |
| 114 | -+ (void)setCostLimit:(NSInteger)costLimit { | 113 | ++ (void)player_SetCostLimit:(NSInteger)costLimit { |
| 115 | [_dataCache.diskCache setCostLimit:costLimit];//磁盘最大缓存开销 | 114 | [_dataCache.diskCache setCostLimit:costLimit];//磁盘最大缓存开销 |
| 115 | + | ||
| 116 | } | 116 | } |
| 117 | + | ||
| 117 | @end | 118 | @end |
CNLivePlayer/Classes/DataRequest/CNLivePlayerNetworkManager.h
| @@ -9,6 +9,7 @@ | @@ -9,6 +9,7 @@ | ||
| 9 | #import <Foundation/Foundation.h> | 9 | #import <Foundation/Foundation.h> |
| 10 | 10 | ||
| 11 | NS_ASSUME_NONNULL_BEGIN | 11 | NS_ASSUME_NONNULL_BEGIN |
| 12 | +typedef void(^GetVideoURLSuccessBlock)(NSString * _Nullable videoURL, NSInteger code); | ||
| 12 | 13 | ||
| 13 | @interface CNLivePlayerNetworkManager : NSObject | 14 | @interface CNLivePlayerNetworkManager : NSObject |
| 14 | /** | 15 | /** |
| @@ -51,7 +52,7 @@ NS_ASSUME_NONNULL_BEGIN | @@ -51,7 +52,7 @@ NS_ASSUME_NONNULL_BEGIN | ||
| 51 | /** | 52 | /** |
| 52 | * 获取视频url | 53 | * 获取视频url |
| 53 | */ | 54 | */ |
| 54 | -+ (void)getVideoURL:(nullable NSString *)URL success:(nullable void (^)(NSString *_Nullable videoURL, NSInteger code))success; | 55 | ++ (void)getVideoURL:(nullable NSString *)URL success:(GetVideoURLSuccessBlock)success; |
| 55 | 56 | ||
| 56 | 57 | ||
| 57 | @end | 58 | @end |
CNLivePlayer/Classes/DataRequest/CNLivePlayerNetworkManager.m
| @@ -26,8 +26,6 @@ static NSTimeInterval TimeoutInterval = 30.0 ; | @@ -26,8 +26,6 @@ static NSTimeInterval TimeoutInterval = 30.0 ; | ||
| 26 | */ | 26 | */ |
| 27 | static NSURLRequestCachePolicy CachePolicy = NSURLRequestUseProtocolCachePolicy; | 27 | static NSURLRequestCachePolicy CachePolicy = NSURLRequestUseProtocolCachePolicy; |
| 28 | 28 | ||
| 29 | -typedef void(^GetVideoURLSuccessBlock)(NSString * _Nullable videoURL, NSInteger code); | ||
| 30 | - | ||
| 31 | @interface CNLivePlayerNetworkManager()<NSURLSessionDelegate> | 29 | @interface CNLivePlayerNetworkManager()<NSURLSessionDelegate> |
| 32 | @property (nonatomic, assign) BOOL result; | 30 | @property (nonatomic, assign) BOOL result; |
| 33 | @property (nonatomic, copy) GetVideoURLSuccessBlock successBlock; | 31 | @property (nonatomic, copy) GetVideoURLSuccessBlock successBlock; |
| @@ -119,7 +117,8 @@ static CNLivePlayerNetworkManager *_manager = nil; | @@ -119,7 +117,8 @@ static CNLivePlayerNetworkManager *_manager = nil; | ||
| 119 | dispatch_async(dispatch_get_main_queue(), ^{ | 117 | dispatch_async(dispatch_get_main_queue(), ^{ |
| 120 | if (error) { | 118 | if (error) { |
| 121 | failure(response,error); | 119 | failure(response,error); |
| 122 | - }else{ | 120 | + } |
| 121 | + else{ | ||
| 123 | if ([response isKindOfClass:[NSHTTPURLResponse class]]) { | 122 | if ([response isKindOfClass:[NSHTTPURLResponse class]]) { |
| 124 | NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; | 123 | NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; |
| 125 | if (httpResponse.statusCode < 400) { | 124 | if (httpResponse.statusCode < 400) { |
| @@ -129,7 +128,8 @@ static CNLivePlayerNetworkManager *_manager = nil; | @@ -129,7 +128,8 @@ static CNLivePlayerNetworkManager *_manager = nil; | ||
| 129 | NSError *failureError = [NSError errorWithDomain:NSURLErrorDomain code:httpResponse.statusCode userInfo:httpResponse.allHeaderFields]; | 128 | NSError *failureError = [NSError errorWithDomain:NSURLErrorDomain code:httpResponse.statusCode userInfo:httpResponse.allHeaderFields]; |
| 130 | failure(httpResponse, failureError); | 129 | failure(httpResponse, failureError); |
| 131 | } | 130 | } |
| 132 | - } else { | 131 | + } |
| 132 | + else { | ||
| 133 | failure(response, error); | 133 | failure(response, error); |
| 134 | } | 134 | } |
| 135 | } | 135 | } |
| @@ -176,7 +176,7 @@ static CNLivePlayerNetworkManager *_manager = nil; | @@ -176,7 +176,7 @@ static CNLivePlayerNetworkManager *_manager = nil; | ||
| 176 | /** | 176 | /** |
| 177 | * 获取视频url | 177 | * 获取视频url |
| 178 | */ | 178 | */ |
| 179 | -+ (void)getVideoURL:(NSString *)URL success:(void (^)(NSString * _Nullable, NSInteger))success { | 179 | ++ (void)getVideoURL:(nullable NSString *)URL success:(GetVideoURLSuccessBlock)success { |
| 180 | [CNLivePlayerNetworkManager manager].successBlock = success; | 180 | [CNLivePlayerNetworkManager manager].successBlock = success; |
| 181 | _manager.result = NO; | 181 | _manager.result = NO; |
| 182 | 182 |
CNLivePlayer/Classes/Player/CNLivePlayer.h
| @@ -17,10 +17,33 @@ | @@ -17,10 +17,33 @@ | ||
| 17 | #import "CNLivePlayerManager.h" | 17 | #import "CNLivePlayerManager.h" |
| 18 | 18 | ||
| 19 | NS_ASSUME_NONNULL_BEGIN | 19 | NS_ASSUME_NONNULL_BEGIN |
| 20 | +typedef NS_ENUM(NSUInteger, CNLivePlayerType) { | ||
| 21 | + CNLivePlayerVod, //点播 | ||
| 22 | + CNLivePlayerLive //直播 | ||
| 23 | + | ||
| 24 | +}; | ||
| 20 | 25 | ||
| 21 | @interface CNLivePlayer : NSObject | 26 | @interface CNLivePlayer : NSObject |
| 27 | +/* | ||
| 28 | + * 播放器类型 | ||
| 29 | + */ | ||
| 30 | +@property (nonatomic, assign) CNLivePlayerType type; | ||
| 22 | 31 | ||
| 32 | +/* | ||
| 33 | + * 播放器 | ||
| 34 | + */ | ||
| 23 | @property (nonatomic, strong) KSYMoviePlayerController *player; | 35 | @property (nonatomic, strong) KSYMoviePlayerController *player; |
| 36 | +// | ||
| 37 | +///* 初始化点播播放器 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | ||
| 38 | +// * | ||
| 39 | +// * contentId 点播视频Id | ||
| 40 | +// * authSuccess 初始化成功block | ||
| 41 | +// * authFailed 初始化失败block 回调一个errorInfo的字典 | ||
| 42 | +// * | ||
| 43 | +// */ | ||
| 44 | +//- (instancetype)initPlayerWithType:(CNLivePlayerType)type contentId:(NSString *)contentId authSuccess:(void(^)(void))authSuccessBlock authFailed:(void(^)(NSDictionary *errorInfo))authFailedBlock; | ||
| 45 | +// | ||
| 46 | +//- (void)setPlayerWithType:(CNLivePlayerType)type contentId:(NSString *)contentId; | ||
| 24 | 47 | ||
| 25 | /* 初始化点播播放器 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) | 48 | /* 初始化点播播放器 初始化成功后才能对播放器进行设置(如:自动播放、是否开启硬件解码等)和调用准备播放视频方法(prepareToPlay) |
| 26 | * | 49 | * |
CNLivePlayer/Classes/Player/CNLivePlayer.m
| @@ -8,6 +8,11 @@ | @@ -8,6 +8,11 @@ | ||
| 8 | 8 | ||
| 9 | #import "CNLivePlayer.h" | 9 | #import "CNLivePlayer.h" |
| 10 | #import "CNLivePlayerManager.h" | 10 | #import "CNLivePlayerManager.h" |
| 11 | +//缓存视频 | ||
| 12 | +#import <KSYHTTPCache/KSYHTTPProxyService.h> | ||
| 13 | +#import <KSYHTTPCache/HTTPCacheDefines.h> | ||
| 14 | + | ||
| 15 | +//缓存url | ||
| 11 | #import "CNLivePlayerCache.h" | 16 | #import "CNLivePlayerCache.h" |
| 12 | #import "CommonCrypto/CommonDigest.h" | 17 | #import "CommonCrypto/CommonDigest.h" |
| 13 | //数据请求 | 18 | //数据请求 |
| @@ -112,18 +117,42 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -112,18 +117,42 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 112 | }); | 117 | }); |
| 113 | } | 118 | } |
| 114 | 119 | ||
| 120 | +- (void)dealloc { | ||
| 121 | + [self removeMovieNotificationObservers]; | ||
| 122 | + [self removeRCloudNotificationObservers]; | ||
| 123 | + | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +- (void)destroyPlayer { | ||
| 127 | + if (_statTimer) { | ||
| 128 | + [_statTimer invalidate]; | ||
| 129 | + _statTimer = nil; | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + if (_player) { | ||
| 133 | + _player = nil; | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + [self removeMovieNotificationObservers]; | ||
| 137 | + [self removeRCloudNotificationObservers]; | ||
| 138 | + | ||
| 139 | +} | ||
| 140 | + | ||
| 115 | #pragma mark - 查找本地是否有缓存url | 141 | #pragma mark - 查找本地是否有缓存url |
| 116 | - (void)getVideoId:(NSString *)videoId authSuccess:(void (^)(void))authSuccessBlock authFailed:(void (^)(NSDictionary *errorDic))authFailedBlock { | 142 | - (void)getVideoId:(NSString *)videoId authSuccess:(void (^)(void))authSuccessBlock authFailed:(void (^)(NSDictionary *errorDic))authFailedBlock { |
| 117 | NSString *key = [NSString stringWithFormat:@"%@:%@",_contentType,videoId]; | 143 | NSString *key = [NSString stringWithFormat:@"%@:%@",_contentType,videoId]; |
| 118 | id data = [CNLivePlayerCache player_ReadCache:key]; | 144 | id data = [CNLivePlayerCache player_ReadCache:key]; |
| 119 | - if (data) { | 145 | + //1.判断是否存在缓存url |
| 146 | + if (data && [data isKindOfClass:[NSString class]]) { | ||
| 147 | + __weak typeof(self) weakSelf = self; | ||
| 120 | dispatch_async(dispatch_get_main_queue(), ^{ | 148 | dispatch_async(dispatch_get_main_queue(), ^{ |
| 121 | - self.videoUrl = (NSString *)data; | ||
| 122 | - self.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:self.videoUrl]]; | ||
| 123 | - [self.view addSubview:self.player.view]; | ||
| 124 | - self.player.view.frame = self.view.bounds; | ||
| 125 | - self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | ||
| 126 | - self.player.shouldEnableKSYStatModule = NO; | 149 | + __strong typeof(self) strongSelf = weakSelf; |
| 150 | + strongSelf.videoUrl = (NSString *)data; | ||
| 151 | + strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:strongSelf.videoUrl]]; | ||
| 152 | + [strongSelf.view addSubview:self.player.view]; | ||
| 153 | + strongSelf.player.view.frame = self.view.bounds; | ||
| 154 | + strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | ||
| 155 | + strongSelf.player.shouldEnableKSYStatModule = NO; | ||
| 127 | if (PLAYER_TestEnvironment) { | 156 | if (PLAYER_TestEnvironment) { |
| 128 | NSLog(@"CNLivePlayer-->缓存数据,播放器初始化成功,可以对播放器进行设置并准备播放"); | 157 | NSLog(@"CNLivePlayer-->缓存数据,播放器初始化成功,可以对播放器进行设置并准备播放"); |
| 129 | } | 158 | } |
| @@ -131,42 +160,98 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -131,42 +160,98 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 131 | }); | 160 | }); |
| 132 | 161 | ||
| 133 | } else { | 162 | } else { |
| 163 | + //2.判断是否鉴权 | ||
| 134 | NSDictionary *privilegeDic = [[NSUserDefaults standardUserDefaults] objectForKey:kCNLivePlayerSDKAuthentication]; | 164 | NSDictionary *privilegeDic = [[NSUserDefaults standardUserDefaults] objectForKey:kCNLivePlayerSDKAuthentication]; |
| 135 | if(privilegeDic&&[privilegeDic[@"resultCode"] isEqualToString:@"0"]){ | 165 | if(privilegeDic&&[privilegeDic[@"resultCode"] isEqualToString:@"0"]){ |
| 166 | + //3.存在鉴权成功,直接请求url | ||
| 136 | if([_contentType isEqualToString:@"vod"]){ | 167 | if([_contentType isEqualToString:@"vod"]){ |
| 137 | - [self getVodVideoURLSuccess:authSuccessBlock authFailed:authFailedBlock]; | 168 | + [self getVodVideoURLSuccess:authSuccessBlock failure:authFailedBlock]; |
| 138 | 169 | ||
| 139 | }else{ | 170 | }else{ |
| 140 | - [self getLiveVideoURLSuccess:authSuccessBlock authFailed:authFailedBlock]; | 171 | + [self getLiveVideoURLSuccess:authSuccessBlock failure:authFailedBlock]; |
| 141 | 172 | ||
| 142 | } | 173 | } |
| 143 | 174 | ||
| 144 | }else{ | 175 | }else{ |
| 145 | __weak typeof(self) weakSelf = self; | 176 | __weak typeof(self) weakSelf = self; |
| 146 | - //鉴权 | 177 | + //4.不存在鉴权成功,先请求鉴权 |
| 147 | [weakSelf authenticateSuccess:^{ | 178 | [weakSelf authenticateSuccess:^{ |
| 179 | + //5.鉴权成功,再请求url | ||
| 148 | __strong typeof(self) strongSelf = weakSelf; | 180 | __strong typeof(self) strongSelf = weakSelf; |
| 149 | if([strongSelf->_contentType isEqualToString:@"vod"]){ | 181 | if([strongSelf->_contentType isEqualToString:@"vod"]){ |
| 150 | - [self getVodVideoURLSuccess:authSuccessBlock authFailed:authFailedBlock]; | 182 | + [strongSelf getVodVideoURLSuccess:authSuccessBlock failure:authFailedBlock]; |
| 151 | 183 | ||
| 152 | }else{ | 184 | }else{ |
| 153 | - [self getLiveVideoURLSuccess:authSuccessBlock authFailed:authFailedBlock]; | 185 | + [strongSelf getLiveVideoURLSuccess:authSuccessBlock failure:authFailedBlock]; |
| 154 | 186 | ||
| 155 | } | 187 | } |
| 156 | 188 | ||
| 157 | - } authenticateFailed:authFailedBlock]; | 189 | + } failure:authFailedBlock]; |
| 158 | } | 190 | } |
| 159 | 191 | ||
| 160 | } | 192 | } |
| 161 | 193 | ||
| 162 | } | 194 | } |
| 163 | 195 | ||
| 164 | -#pragma mark - 获取点播视频url | ||
| 165 | -- (void)getVodVideoURLSuccess:(void(^)(void))authSuccessBlock authFailed:(void(^)(NSDictionary *errorInfo))authFailedBlock { | 196 | +#pragma mark - 鉴权 |
| 197 | +- (void)authenticateSuccess:(void(^)(void))authSuccessBlock failure:(void(^)(NSDictionary *errorInfo))authFailedBlock { | ||
| 198 | + | ||
| 199 | + NSDictionary *parameter = @{@"platform_id": [NSBundle mainBundle].bundleIdentifier, | ||
| 200 | + @"timestamp": [CNLivePlayerTools getTimestamp], | ||
| 201 | + @"appId": PLAYER_AppID}; | ||
| 202 | + | ||
| 203 | + NSString *videoUrl = [CNLivePlayerTools encryptionSignWithUrl:authUrl parameter:parameter]; | ||
| 204 | + | ||
| 205 | + __weak typeof(self) weakSelf = self; | ||
| 206 | + [[CNLivePlayerNetworkManager manager] authenticate:videoUrl success:^(NSURLResponse * _Nullable response, id _Nullable responseObject) { | ||
| 207 | + __strong typeof(self) strongSelf = weakSelf; | ||
| 208 | + if(!responseObject||![responseObject isKindOfClass:[NSDictionary class]]){ | ||
| 209 | + authFailedBlock ? authFailedBlock(responseObject) : nil; | ||
| 210 | + | ||
| 211 | + } | ||
| 212 | + | ||
| 213 | + NSDictionary *authErrorDic = @{@"code":responseObject[@"errorCode"], | ||
| 214 | + @"resultCode":@"0", | ||
| 215 | + @"errorMessage":responseObject[@"errorMessage"]}; | ||
| 216 | + [[NSUserDefaults standardUserDefaults] setObject:authErrorDic forKey:kCNLivePlayerSDKAuthentication]; | ||
| 217 | + [[NSUserDefaults standardUserDefaults] synchronize]; | ||
| 218 | + if ([responseObject[@"errorCode"] isEqualToString:@"0"]) { | ||
| 219 | + authSuccessBlock ? authSuccessBlock() : nil; | ||
| 220 | + | ||
| 221 | + } | ||
| 222 | + else { | ||
| 223 | + if (PLAYER_TestEnvironment) { | ||
| 224 | + NSLog(@"CNLivePlayer-->播放器初始化失败,失败原因:%@", authErrorDic); | ||
| 225 | + } | ||
| 226 | + authFailedBlock ? authFailedBlock(responseObject) : nil; | ||
| 227 | + [CNLivePlayerTools errorStat:authErrorDic[@"errorMessage"] contentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; | ||
| 228 | + | ||
| 229 | + } | ||
| 230 | + | ||
| 231 | + } failure:^(NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
| 232 | + __strong typeof(self) strongSelf = weakSelf; | ||
| 233 | + NSDictionary *authErrorDic = @{@"code":[NSString stringWithFormat:@"%ld", error.code], | ||
| 234 | + @"resultCode":@"1", | ||
| 235 | + @"errorMessage":[NSString stringWithFormat:@"%@", error.localizedDescription]}; | ||
| 236 | + [[NSUserDefaults standardUserDefaults] setObject:authErrorDic forKey:kCNLivePlayerSDKAuthentication]; | ||
| 237 | + [[NSUserDefaults standardUserDefaults] synchronize]; | ||
| 238 | + | ||
| 239 | + if (PLAYER_TestEnvironment) { | ||
| 240 | + NSLog(@"CNLivePlayer-->播放器初始化失败,失败原因:%@", authErrorDic); | ||
| 241 | + } | ||
| 242 | + authFailedBlock ? authFailedBlock(authErrorDic) : nil; | ||
| 243 | + [CNLivePlayerTools errorStat:authErrorDic[@"errorMessage"] contentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; | ||
| 244 | + | ||
| 245 | + }]; | ||
| 246 | + | ||
| 247 | +} | ||
| 166 | 248 | ||
| 249 | +#pragma mark - 获取点播视频url | ||
| 250 | +- (void)getVodVideoURLSuccess:(void(^)(void))authSuccessBlock failure:(void(^)(NSDictionary *errorInfo))authFailedBlock { | ||
| 251 | + NSString *stamp = [CNLivePlayerTools getTimestamp]; | ||
| 167 | NSDictionary *parameter = @{@"appId": PLAYER_AppID, | 252 | NSDictionary *parameter = @{@"appId": PLAYER_AppID, |
| 168 | @"vId": _contentId, | 253 | @"vId": _contentId, |
| 169 | - @"timestamp": [CNLivePlayerTools getTimestamp], | 254 | + @"timestamp": stamp, |
| 170 | @"isHLS": @"1", | 255 | @"isHLS": @"1", |
| 171 | @"plat": @"i", | 256 | @"plat": @"i", |
| 172 | @"playType": _isAudio ? @"a": @"v", | 257 | @"playType": _isAudio ? @"a": @"v", |
| @@ -175,7 +260,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -175,7 +260,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 175 | @"tag": PLAYER_Tag, | 260 | @"tag": PLAYER_Tag, |
| 176 | @"from": @"apple", | 261 | @"from": @"apple", |
| 177 | @"sid": PLAYER_UserId, | 262 | @"sid": PLAYER_UserId, |
| 178 | - @"uid": [CNLivePlayerTools getUidForStat:[NSDate date]]}; | 263 | + @"uid": [CNLivePlayerTools getUidForStat:stamp]}; |
| 179 | 264 | ||
| 180 | NSString *videoUrl = [CNLivePlayerTools encryptionSignWithUrl:vodUrl parameter:parameter]; | 265 | NSString *videoUrl = [CNLivePlayerTools encryptionSignWithUrl:vodUrl parameter:parameter]; |
| 181 | 266 | ||
| @@ -184,7 +269,9 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -184,7 +269,9 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 184 | __strong typeof(self) strongSelf = weakSelf; | 269 | __strong typeof(self) strongSelf = weakSelf; |
| 185 | // NSString *key = [NSString stringWithFormat:@"%@:%@",strongSelf->_contentType, strongSelf->_contentId]; | 270 | // NSString *key = [NSString stringWithFormat:@"%@:%@",strongSelf->_contentType, strongSelf->_contentId]; |
| 186 | // [CNLivePlayerCache player_SaveDataCache:videoURL forKey:key]; | 271 | // [CNLivePlayerCache player_SaveDataCache:videoURL forKey:key]; |
| 272 | + __weak typeof(self) weakSelf = strongSelf; | ||
| 187 | dispatch_async(dispatch_get_main_queue(), ^{ | 273 | dispatch_async(dispatch_get_main_queue(), ^{ |
| 274 | + __strong typeof(self) strongSelf = weakSelf; | ||
| 188 | strongSelf.videoUrl = videoUrl; | 275 | strongSelf.videoUrl = videoUrl; |
| 189 | strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:videoUrl]]; | 276 | strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:videoUrl]]; |
| 190 | [strongSelf.view addSubview:strongSelf.player.view]; | 277 | [strongSelf.view addSubview:strongSelf.player.view]; |
| @@ -192,7 +279,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -192,7 +279,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 192 | strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | 279 | strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; |
| 193 | strongSelf.player.shouldEnableKSYStatModule = NO; | 280 | strongSelf.player.shouldEnableKSYStatModule = NO; |
| 194 | 281 | ||
| 195 | - [strongSelf statSDK]; | 282 | + [CNLivePlayerTools statSDKWithContentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; |
| 196 | 283 | ||
| 197 | if (PLAYER_TestEnvironment) { | 284 | if (PLAYER_TestEnvironment) { |
| 198 | NSLog(@"CNLivePlayer-->请求数据,点播播放器初始化成功,可以对播放器进行设置并准备播放"); | 285 | NSLog(@"CNLivePlayer-->请求数据,点播播放器初始化成功,可以对播放器进行设置并准备播放"); |
| @@ -206,7 +293,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -206,7 +293,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 206 | } | 293 | } |
| 207 | 294 | ||
| 208 | #pragma mark - 获取直播视频url | 295 | #pragma mark - 获取直播视频url |
| 209 | -- (void)getLiveVideoURLSuccess:(void(^)(void))authSuccessBlock authFailed:(void(^)(NSDictionary *errorInfo))authFailedBlock { | 296 | +- (void)getLiveVideoURLSuccess:(void(^)(void))authSuccessBlock failure:(void(^)(NSDictionary *errorInfo))authFailedBlock { |
| 210 | NSString *timestamp = [CNLivePlayerTools getTimestamp]; | 297 | NSString *timestamp = [CNLivePlayerTools getTimestamp]; |
| 211 | NSDictionary *parameter = @{@"appId": PLAYER_AppID, | 298 | NSDictionary *parameter = @{@"appId": PLAYER_AppID, |
| 212 | @"channelId": _contentId, | 299 | @"channelId": _contentId, |
| @@ -220,7 +307,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -220,7 +307,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 220 | @"tag": PLAYER_Tag, | 307 | @"tag": PLAYER_Tag, |
| 221 | @"from": @"apple", | 308 | @"from": @"apple", |
| 222 | @"sid": PLAYER_UserId, | 309 | @"sid": PLAYER_UserId, |
| 223 | - @"uid": [CNLivePlayerTools getUidForStat:[NSDate date]]}; | 310 | + @"uid": [CNLivePlayerTools getUidForStat:timestamp]}; |
| 224 | 311 | ||
| 225 | NSString *videoUrl = [CNLivePlayerTools encryptionSignWithUrl:liveUrl parameter:parameter]; | 312 | NSString *videoUrl = [CNLivePlayerTools encryptionSignWithUrl:liveUrl parameter:parameter]; |
| 226 | 313 | ||
| @@ -229,26 +316,31 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -229,26 +316,31 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 229 | [urlRequest setHTTPMethod:@"GET"]; | 316 | [urlRequest setHTTPMethod:@"GET"]; |
| 230 | [urlRequest setTimeoutInterval:30]; | 317 | [urlRequest setTimeoutInterval:30]; |
| 231 | 318 | ||
| 319 | + __weak typeof(self) weakSelf = self; | ||
| 232 | [NSURLConnection sendAsynchronousRequest:urlRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { | 320 | [NSURLConnection sendAsynchronousRequest:urlRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { |
| 233 | - __weak typeof(self) weakSelf = self; | 321 | + __strong typeof(self) strongSelf = weakSelf; |
| 322 | + NSString *url = nil; | ||
| 323 | + if (connectionError) { | ||
| 324 | + NSError *error = connectionError.userInfo[NSUnderlyingErrorKey]; | ||
| 325 | + NSString *videoUrl302 = error.userInfo[NSURLErrorFailingURLStringErrorKey]; | ||
| 326 | + if (!videoUrl302 || ![videoUrl302 isKindOfClass:[NSString class]] || videoUrl302.length <= 0) { | ||
| 327 | + videoUrl302 = nil; | ||
| 328 | + } | ||
| 329 | + url = videoUrl302; | ||
| 330 | + | ||
| 331 | + } else if (response) { | ||
| 332 | + url = response.URL.absoluteString; | ||
| 333 | + | ||
| 334 | + } else { | ||
| 335 | + url = videoUrl; | ||
| 336 | + | ||
| 337 | + } | ||
| 338 | + NSString *key = [NSString stringWithFormat:@"%@:%@",strongSelf->_contentType, strongSelf->_contentId]; | ||
| 339 | + [CNLivePlayerCache player_SaveDataCache:url forKey:key]; | ||
| 340 | + | ||
| 341 | + __weak typeof(self) weakSelf = strongSelf; | ||
| 234 | dispatch_async(dispatch_get_main_queue(), ^{ | 342 | dispatch_async(dispatch_get_main_queue(), ^{ |
| 235 | __strong typeof(self) strongSelf = weakSelf; | 343 | __strong typeof(self) strongSelf = weakSelf; |
| 236 | - NSString *url = nil; | ||
| 237 | - if (connectionError) { | ||
| 238 | - NSError *error = connectionError.userInfo[NSUnderlyingErrorKey]; | ||
| 239 | - NSString *videoUrl302 = error.userInfo[NSURLErrorFailingURLStringErrorKey]; | ||
| 240 | - if (!videoUrl302 || ![videoUrl302 isKindOfClass:[NSString class]] || videoUrl302.length <= 0) { | ||
| 241 | - videoUrl302 = nil; | ||
| 242 | - } | ||
| 243 | - url = videoUrl302; | ||
| 244 | - | ||
| 245 | - } else if (response) { | ||
| 246 | - url = response.URL.absoluteString; | ||
| 247 | - | ||
| 248 | - } else { | ||
| 249 | - url = videoUrl; | ||
| 250 | - | ||
| 251 | - } | ||
| 252 | strongSelf.videoUrl = url; | 344 | strongSelf.videoUrl = url; |
| 253 | strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:url]]; | 345 | strongSelf.player = [[KSYMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:url]]; |
| 254 | [strongSelf.view addSubview:strongSelf.player.view]; | 346 | [strongSelf.view addSubview:strongSelf.player.view]; |
| @@ -256,11 +348,8 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -256,11 +348,8 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 256 | strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; | 348 | strongSelf.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; |
| 257 | strongSelf.player.shouldEnableKSYStatModule = NO; | 349 | strongSelf.player.shouldEnableKSYStatModule = NO; |
| 258 | 350 | ||
| 259 | - NSString *key = [NSString stringWithFormat:@"%@:%@",strongSelf->_contentType, strongSelf->_contentId]; | ||
| 260 | - [CNLivePlayerCache player_SaveDataCache:url forKey:key]; | ||
| 261 | - | ||
| 262 | - [strongSelf statSDK]; | ||
| 263 | - | 351 | + [CNLivePlayerTools statSDKWithContentId:strongSelf->_activityId ? strongSelf->_activityId : strongSelf->_contentId idName:strongSelf->_idName]; |
| 352 | + | ||
| 264 | if (PLAYER_TestEnvironment) { | 353 | if (PLAYER_TestEnvironment) { |
| 265 | NSLog(@"CNLivePlayer-->请求数据,直播播放器初始化成功,可以对播放器进行设置并准备播放"); | 354 | NSLog(@"CNLivePlayer-->请求数据,直播播放器初始化成功,可以对播放器进行设置并准备播放"); |
| 266 | } | 355 | } |
| @@ -272,66 +361,15 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -272,66 +361,15 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 272 | }]; | 361 | }]; |
| 273 | } | 362 | } |
| 274 | 363 | ||
| 275 | -#pragma mark - 鉴权 | ||
| 276 | -- (void)authenticateSuccess:(void(^)(void))authSuccessBlock authenticateFailed:(void(^)(NSDictionary *errorInfo))authFailedBlock { | ||
| 277 | - | ||
| 278 | - NSDictionary *parameter = @{@"platform_id": [NSBundle mainBundle].bundleIdentifier, | ||
| 279 | - @"timestamp": [CNLivePlayerTools getTimestamp], | ||
| 280 | - @"appId": PLAYER_AppID}; | ||
| 281 | - | ||
| 282 | - NSString *videoUrl = [CNLivePlayerTools encryptionSignWithUrl:authUrl parameter:parameter]; | ||
| 283 | - | ||
| 284 | - | ||
| 285 | - [[CNLivePlayerNetworkManager manager] authenticate:videoUrl success:^(NSURLResponse * _Nullable response, id _Nullable responseObject) { | ||
| 286 | - | ||
| 287 | - if(!responseObject||![responseObject isKindOfClass:[NSDictionary class]]){ | ||
| 288 | - authFailedBlock ? authFailedBlock(responseObject) : nil; | ||
| 289 | - | ||
| 290 | - } | ||
| 291 | - | ||
| 292 | - NSDictionary *authErrorDic = @{@"code":responseObject[@"errorCode"], | ||
| 293 | - @"resultCode":@"0", | ||
| 294 | - @"errorMessage":responseObject[@"errorMessage"]}; | ||
| 295 | - [[NSUserDefaults standardUserDefaults] setObject:authErrorDic forKey:kCNLivePlayerSDKAuthentication]; | ||
| 296 | - [[NSUserDefaults standardUserDefaults] synchronize]; | ||
| 297 | - | ||
| 298 | - if ([responseObject[@"errorCode"] isEqualToString:@"0"]) { | ||
| 299 | - authSuccessBlock ? authSuccessBlock() : nil; | ||
| 300 | - | ||
| 301 | - } | ||
| 302 | - else { | ||
| 303 | - if (PLAYER_TestEnvironment) { | ||
| 304 | - NSLog(@"CNLivePlayer-->播放器初始化失败,失败原因:%@", authErrorDic); | ||
| 305 | - } | ||
| 306 | - authFailedBlock ? authFailedBlock(responseObject) : nil; | ||
| 307 | - [self errorStat:authErrorDic[@"errorMessage"]]; | ||
| 308 | - } | ||
| 309 | - | ||
| 310 | - } failure:^(NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
| 311 | - | ||
| 312 | - NSDictionary *authErrorDic = @{@"code":[NSString stringWithFormat:@"%ld", error.code], | ||
| 313 | - @"resultCode":@"1", | ||
| 314 | - @"errorMessage":[NSString stringWithFormat:@"%@", error.localizedDescription]}; | ||
| 315 | - [[NSUserDefaults standardUserDefaults] setObject:authErrorDic forKey:kCNLivePlayerSDKAuthentication]; | ||
| 316 | - [[NSUserDefaults standardUserDefaults] synchronize]; | ||
| 317 | - | ||
| 318 | - if (PLAYER_TestEnvironment) { | ||
| 319 | - NSLog(@"CNLivePlayer-->播放器初始化失败,失败原因:%@", authErrorDic); | ||
| 320 | - } | ||
| 321 | - authFailedBlock ? authFailedBlock(authErrorDic) : nil; | ||
| 322 | - [self errorStat:authErrorDic[@"errorMessage"]]; | ||
| 323 | - | ||
| 324 | - }]; | ||
| 325 | - | ||
| 326 | -} | ||
| 327 | - | ||
| 328 | #pragma mark - 注册通知 | 364 | #pragma mark - 注册通知 |
| 329 | - (void)addMovieNotificationObservers { | 365 | - (void)addMovieNotificationObservers { |
| 366 | + // 视频加载状态 | ||
| 330 | [[NSNotificationCenter defaultCenter] addObserver:self | 367 | [[NSNotificationCenter defaultCenter] addObserver:self |
| 331 | selector:@selector(loadStateDidChange:) | 368 | selector:@selector(loadStateDidChange:) |
| 332 | name:MPMoviePlayerLoadStateDidChangeNotification | 369 | name:MPMoviePlayerLoadStateDidChangeNotification |
| 333 | object:nil]; | 370 | object:nil]; |
| 334 | 371 | ||
| 372 | + // 视频播放结束 | ||
| 335 | [[NSNotificationCenter defaultCenter] addObserver:self | 373 | [[NSNotificationCenter defaultCenter] addObserver:self |
| 336 | selector:@selector(moviePlayBackDidFinish:) | 374 | selector:@selector(moviePlayBackDidFinish:) |
| 337 | name:MPMoviePlayerPlaybackDidFinishNotification | 375 | name:MPMoviePlayerPlaybackDidFinishNotification |
| @@ -342,6 +380,18 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -342,6 +380,18 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 342 | name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification | 380 | name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification |
| 343 | object:nil]; | 381 | object:nil]; |
| 344 | 382 | ||
| 383 | + // 缓存状态 | ||
| 384 | + [[NSNotificationCenter defaultCenter] addObserver:self | ||
| 385 | + selector:@selector(mediaCacheDidChanged:) | ||
| 386 | + name:CacheStatusNotification | ||
| 387 | + object:nil]; | ||
| 388 | + | ||
| 389 | + // 缓存出错 | ||
| 390 | + [[NSNotificationCenter defaultCenter] addObserver:self | ||
| 391 | + selector:@selector(mediaCacheErrorDidChanged:) | ||
| 392 | + name:CacheErrorNotification | ||
| 393 | + object:nil]; | ||
| 394 | + | ||
| 345 | } | 395 | } |
| 346 | 396 | ||
| 347 | - (void)addRCloudNotificationObservers { | 397 | - (void)addRCloudNotificationObservers { |
| @@ -351,17 +401,16 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -351,17 +401,16 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 351 | } | 401 | } |
| 352 | 402 | ||
| 353 | - (void)removeMovieNotificationObservers { | 403 | - (void)removeMovieNotificationObservers { |
| 354 | - [[NSNotificationCenter defaultCenter] removeObserver:self | ||
| 355 | - name:MPMoviePlayerLoadStateDidChangeNotification | ||
| 356 | - object:nil]; | 404 | + [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:nil]; |
| 405 | + | ||
| 406 | + [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil]; | ||
| 357 | 407 | ||
| 358 | - [[NSNotificationCenter defaultCenter] removeObserver:self | ||
| 359 | - name:MPMoviePlayerPlaybackDidFinishNotification | ||
| 360 | - object:nil]; | 408 | + [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification object:nil]; |
| 409 | + | ||
| 410 | + [[NSNotificationCenter defaultCenter] removeObserver:self name:CacheStatusNotification object:nil]; | ||
| 411 | + | ||
| 412 | + [[NSNotificationCenter defaultCenter] removeObserver:self name:CacheErrorNotification object:nil]; | ||
| 361 | 413 | ||
| 362 | - [[NSNotificationCenter defaultCenter] removeObserver:self | ||
| 363 | - name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification | ||
| 364 | - object:nil]; | ||
| 365 | } | 414 | } |
| 366 | 415 | ||
| 367 | - (void)removeRCloudNotificationObservers { | 416 | - (void)removeRCloudNotificationObservers { |
| @@ -391,6 +440,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -391,6 +440,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 391 | [self mediaIsPreparedToPlayDidChange:nil]; | 440 | [self mediaIsPreparedToPlayDidChange:nil]; |
| 392 | } | 441 | } |
| 393 | } | 442 | } |
| 443 | + | ||
| 394 | } | 444 | } |
| 395 | 445 | ||
| 396 | - (void)moviePlayBackDidFinish:(NSNotification *)notification { | 446 | - (void)moviePlayBackDidFinish:(NSNotification *)notification { |
| @@ -418,7 +468,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -418,7 +468,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 418 | 468 | ||
| 419 | case MPMovieFinishReasonPlaybackError://视频异常探针 | 469 | case MPMovieFinishReasonPlaybackError://视频异常探针 |
| 420 | { | 470 | { |
| 421 | - [self errorStat:notification.userInfo.description]; | 471 | + [CNLivePlayerTools errorStat:notification.userInfo.description contentId:_activityId ? _activityId : _contentId idName:_idName]; |
| 422 | } | 472 | } |
| 423 | break; | 473 | break; |
| 424 | 474 | ||
| @@ -426,6 +476,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -426,6 +476,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 426 | 476 | ||
| 427 | break; | 477 | break; |
| 428 | } | 478 | } |
| 479 | + | ||
| 429 | } | 480 | } |
| 430 | 481 | ||
| 431 | - (void)mediaIsPreparedToPlayDidChange:(NSNotification *)notification { | 482 | - (void)mediaIsPreparedToPlayDidChange:(NSNotification *)notification { |
| @@ -441,27 +492,6 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -441,27 +492,6 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 441 | 492 | ||
| 442 | } | 493 | } |
| 443 | 494 | ||
| 444 | -- (void)dealloc { | ||
| 445 | - [self removeMovieNotificationObservers]; | ||
| 446 | - [self removeRCloudNotificationObservers]; | ||
| 447 | - | ||
| 448 | -} | ||
| 449 | - | ||
| 450 | -- (void)destroyPlayer { | ||
| 451 | - if (_statTimer) { | ||
| 452 | - [_statTimer invalidate]; | ||
| 453 | - _statTimer = nil; | ||
| 454 | - } | ||
| 455 | - | ||
| 456 | - if (_player) { | ||
| 457 | - _player = nil; | ||
| 458 | - } | ||
| 459 | - | ||
| 460 | - [self removeMovieNotificationObservers]; | ||
| 461 | - [self removeRCloudNotificationObservers]; | ||
| 462 | - | ||
| 463 | -} | ||
| 464 | - | ||
| 465 | #pragma mark - 播放时长计算 | 495 | #pragma mark - 播放时长计算 |
| 466 | - (void)statTimerAction{ | 496 | - (void)statTimerAction{ |
| 467 | if (!_contentType || _contentType.length == 0) { | 497 | if (!_contentType || _contentType.length == 0) { |
| @@ -470,21 +500,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -470,21 +500,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 470 | _playTime++; | 500 | _playTime++; |
| 471 | 501 | ||
| 472 | NSString *stamp = [CNLivePlayerTools getTimestamp]; | 502 | NSString *stamp = [CNLivePlayerTools getTimestamp]; |
| 473 | - NSString *url = [NSString stringWithFormat:@"%@?sver=%@&uid=%@&tm=%@&from=apple&spid=&appid=%@&version=1001_%@&eventid=1001&uri=%@&sid=&plat=i_%@&objid=%@_%@", StatUrl, StatVersion, [CNLivePlayerTools uidForStat:stamp], stamp, PLAYER_AppID, PlayerSDKVersion, [NSString stringWithFormat:@"%d_30", _playTime], StatAppVersion,_contentId, _idName]; | ||
| 474 | - [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] delegate:nil]; | ||
| 475 | - | ||
| 476 | -} | ||
| 477 | - | ||
| 478 | -#pragma mark - 工具方法 | ||
| 479 | -- (void)errorStat:(NSString *)errorString { | ||
| 480 | - NSString *stamp = [CNLivePlayerTools getTimestamp]; | ||
| 481 | - NSString *url = [NSString stringWithFormat:@"%@?sver=%@&uid=%@&tm=%@&from=apple&spid=&appid=%@&version=1001_%@&eventid=1000&uri=%@&sid=&plat=i_%@&objid=%@_%@", StatUrl, StatVersion, [CNLivePlayerTools uidForStat:stamp], stamp, PLAYER_AppID, PlayerSDKVersion, errorString, StatAppVersion, _activityId ? _activityId : _contentId, _idName]; | ||
| 482 | - [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] delegate:nil]; | ||
| 483 | - | ||
| 484 | -} | ||
| 485 | -- (void)statSDK { | ||
| 486 | - NSString *stamp = [CNLivePlayerTools getTimestamp]; | ||
| 487 | - NSString *url = [NSString stringWithFormat:@"%@?sver=%@&uid=%@&tm=%@&from=apple&spid=&appid=%@&version=1001_%@&eventid=1400&uri=&sid=&plat=i_%@&objid=%@_%@", StatUrl, StatVersion, [CNLivePlayerTools uidForStat:stamp], stamp, PLAYER_AppID, PlayerSDKVersion, StatAppVersion, _activityId ? _activityId : _contentId , _idName]; | 503 | + NSString *url = [NSString stringWithFormat:@"%@?sver=%@&uid=%@&tm=%@&from=apple&spid=&appid=%@&version=1001_%@&eventid=1001&uri=%@&sid=&plat=i_%@&objid=%@_%@", StatUrl, StatVersion, [CNLivePlayerTools getUidForStat:stamp], stamp, PLAYER_AppID, PlayerSDKVersion, [NSString stringWithFormat:@"%ld_30", (long)_playTime], StatAppVersion,_contentId, _idName]; |
| 488 | [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] delegate:nil]; | 504 | [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] delegate:nil]; |
| 489 | 505 | ||
| 490 | } | 506 | } |
| @@ -516,6 +532,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | @@ -516,6 +532,7 @@ NSString * const CNLiveAnchorStatusChangedNotification = @"CNLiveAnchorStatusCha | ||
| 516 | */ | 532 | */ |
| 517 | - (void)prepareToPlay { | 533 | - (void)prepareToPlay { |
| 518 | [_player prepareToPlay]; | 534 | [_player prepareToPlay]; |
| 535 | + | ||
| 519 | } | 536 | } |
| 520 | 537 | ||
| 521 | @end | 538 | @end |
CNLivePlayer/Classes/Player/CNLivePlayerConst.h
| @@ -10,7 +10,7 @@ | @@ -10,7 +10,7 @@ | ||
| 10 | #define CNLivePlayerConst_h | 10 | #define CNLivePlayerConst_h |
| 11 | 11 | ||
| 12 | #pragma mark - 版本号 | 12 | #pragma mark - 版本号 |
| 13 | -#define PlayerSDKVersion @"0.0.1" //SDK版本 | 13 | +#define PlayerSDKVersion @"0.0.1" //播放器SDK版本 |
| 14 | 14 | ||
| 15 | #pragma mark - 探针 | 15 | #pragma mark - 探针 |
| 16 | #define StatUrl [CNLivePlayerManager manager].isTestEnvironment?@"http://app.sta.cnlive.com/app.jpg": @"http://app.sta.cnlive.com/app.jpg" | 16 | #define StatUrl [CNLivePlayerManager manager].isTestEnvironment?@"http://app.sta.cnlive.com/app.jpg": @"http://app.sta.cnlive.com/app.jpg" |
CNLivePlayer/Classes/Player/CNLivePlayerManager.m
| @@ -58,9 +58,9 @@ static CNLivePlayerManager * _instance = nil; | @@ -58,9 +58,9 @@ static CNLivePlayerManager * _instance = nil; | ||
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | - (void)setAppId:(NSString *)appId appKey:(NSString *)appKey isTestEnvironment:(BOOL)isTestEnvironment { | 60 | - (void)setAppId:(NSString *)appId appKey:(NSString *)appKey isTestEnvironment:(BOOL)isTestEnvironment { |
| 61 | - self.appId = appId ? [NSString stringWithFormat:@"%@",appId] : @""; | ||
| 62 | - self.appKey = appKey ? [NSString stringWithFormat:@"%@",appKey] : @""; | ||
| 63 | - self.isTestEnvironment = isTestEnvironment; | 61 | + [CNLivePlayerManager manager].appId = appId ? [NSString stringWithFormat:@"%@",appId] : @""; |
| 62 | + [CNLivePlayerManager manager].appKey = appKey ? [NSString stringWithFormat:@"%@",appKey] : @""; | ||
| 63 | + [CNLivePlayerManager manager].isTestEnvironment = isTestEnvironment; | ||
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | + (NSString *)getVersion { | 66 | + (NSString *)getVersion { |
CNLivePlayer/Classes/Tools/CNLivePlayerTools.h
| @@ -17,10 +17,10 @@ | @@ -17,10 +17,10 @@ | ||
| 17 | 17 | ||
| 18 | + (NSString *)signvalue:(NSDictionary*)parameter; | 18 | + (NSString *)signvalue:(NSDictionary*)parameter; |
| 19 | 19 | ||
| 20 | -//获取uuid | ||
| 21 | -+ (NSString *)getUidForStat:(NSDate *)date; | ||
| 22 | - | ||
| 23 | -+ (NSString *)uidForStat:(NSString *)date; | 20 | +/** |
| 21 | + * 获取UUID | ||
| 22 | + */ | ||
| 23 | ++ (NSString *)getUidForStat:(NSString *)date; | ||
| 24 | 24 | ||
| 25 | //错误信息 | 25 | //错误信息 |
| 26 | + (NSError *)customErrorWithResponseObject:(id)responseObject errorInfo:(NSString *)errorInfo; | 26 | + (NSError *)customErrorWithResponseObject:(id)responseObject errorInfo:(NSString *)errorInfo; |
| @@ -36,4 +36,9 @@ | @@ -36,4 +36,9 @@ | ||
| 36 | + (NSString *)getTimestamp; | 36 | + (NSString *)getTimestamp; |
| 37 | 37 | ||
| 38 | 38 | ||
| 39 | +#pragma mark - 方法 | ||
| 40 | ++ (void)errorStat:(NSString *)errorString contentId:(NSString *)contentId idName:(NSString *)idName; | ||
| 41 | + | ||
| 42 | ++ (void)statSDKWithContentId:(NSString *)contentId idName:(NSString *)idName; | ||
| 43 | + | ||
| 39 | @end | 44 | @end |
CNLivePlayer/Classes/Tools/CNLivePlayerTools.m
| @@ -62,32 +62,7 @@ | @@ -62,32 +62,7 @@ | ||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | #pragma mark - UUID | 64 | #pragma mark - UUID |
| 65 | -+ (NSString *)getUidForStat:(NSDate *)date { | ||
| 66 | - NSString *uid = @""; | ||
| 67 | - | ||
| 68 | - NSUserDefaults *defauts = [NSUserDefaults standardUserDefaults]; | ||
| 69 | - | ||
| 70 | - if ([defauts objectForKey:@"kCNLiveUserDefaultsUIDKey"]) { | ||
| 71 | - uid = [[defauts objectForKey:@"kCNLiveUserDefaultsUIDKey"] copy]; | ||
| 72 | - return uid; | ||
| 73 | - } | ||
| 74 | - else { | ||
| 75 | - | ||
| 76 | - NSString *stamp = [NSString stringWithFormat:@"%.3f", [date timeIntervalSince1970]]; | ||
| 77 | - stamp = [stamp stringByReplacingOccurrencesOfString:@"." withString:@""]; | ||
| 78 | - | ||
| 79 | - NSString *idfv = [[[[UIDevice currentDevice] identifierForVendor] UUIDString] stringByReplacingOccurrencesOfString:@"-" withString:@""]; | ||
| 80 | - uid = [NSString stringWithFormat:@"%@_%@", idfv, stamp]; | ||
| 81 | - | ||
| 82 | - [defauts setObject:uid forKey:@"kCNLiveUserDefaultsUIDKey"]; | ||
| 83 | - [defauts synchronize]; | ||
| 84 | - } | ||
| 85 | - | ||
| 86 | - return uid; | ||
| 87 | - | ||
| 88 | -} | ||
| 89 | - | ||
| 90 | -+ (NSString *)uidForStat:(NSString *)date { | 65 | ++ (NSString *)getUidForStat:(NSString *)date { |
| 91 | 66 | ||
| 92 | NSString *uid = @""; | 67 | NSString *uid = @""; |
| 93 | 68 | ||
| @@ -127,7 +102,7 @@ | @@ -127,7 +102,7 @@ | ||
| 127 | return error; | 102 | return error; |
| 128 | } | 103 | } |
| 129 | 104 | ||
| 130 | - | 105 | +#pragma mark - 字符串判空 |
| 131 | + (BOOL)isEmptyString:(NSString *)string { | 106 | + (BOOL)isEmptyString:(NSString *)string { |
| 132 | if (!string || ![string isKindOfClass:[NSString class]] || string.length == 0 || [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length == 0) { | 107 | if (!string || ![string isKindOfClass:[NSString class]] || string.length == 0 || [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length == 0) { |
| 133 | return YES; | 108 | return YES; |
| @@ -135,10 +110,26 @@ | @@ -135,10 +110,26 @@ | ||
| 135 | return NO; | 110 | return NO; |
| 136 | } | 111 | } |
| 137 | 112 | ||
| 113 | +#pragma mark - 获取时间戳 | ||
| 138 | + (NSString *)getTimestamp{ | 114 | + (NSString *)getTimestamp{ |
| 139 | NSInteger time = [[NSDate date] timeIntervalSince1970]; | 115 | NSInteger time = [[NSDate date] timeIntervalSince1970]; |
| 140 | NSString *timestamp = [NSString stringWithFormat:@"%ld", (long)time]; | 116 | NSString *timestamp = [NSString stringWithFormat:@"%ld", (long)time]; |
| 141 | return timestamp; | 117 | return timestamp; |
| 142 | } | 118 | } |
| 143 | 119 | ||
| 120 | + | ||
| 121 | +#pragma mark - 方法 | ||
| 122 | ++ (void)errorStat:(NSString *)errorString contentId:(NSString *)contentId idName:(NSString *)idName{ | ||
| 123 | + NSString *stamp = [CNLivePlayerTools getTimestamp]; | ||
| 124 | + NSString *url = [NSString stringWithFormat:@"%@?sver=%@&uid=%@&tm=%@&from=apple&spid=&appid=%@&version=1001_%@&eventid=1000&uri=%@&sid=&plat=i_%@&objid=%@_%@", StatUrl, StatVersion, [CNLivePlayerTools getUidForStat:stamp], stamp, PLAYER_AppID, PlayerSDKVersion, errorString, StatAppVersion, contentId, idName]; | ||
| 125 | + [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] delegate:nil]; | ||
| 126 | + | ||
| 127 | +} | ||
| 128 | ++ (void)statSDKWithContentId:(NSString *)contentId idName:(NSString *)idName { | ||
| 129 | + NSString *stamp = [CNLivePlayerTools getTimestamp]; | ||
| 130 | + NSString *url = [NSString stringWithFormat:@"%@?sver=%@&uid=%@&tm=%@&from=apple&spid=&appid=%@&version=1001_%@&eventid=1400&uri=&sid=&plat=i_%@&objid=%@_%@", StatUrl, StatVersion, [CNLivePlayerTools getUidForStat:stamp], stamp, PLAYER_AppID, PlayerSDKVersion, StatAppVersion, contentId , idName]; | ||
| 131 | + [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]] delegate:nil]; | ||
| 132 | + | ||
| 133 | +} | ||
| 134 | + | ||
| 144 | @end | 135 | @end |
Example/CNLivePlayer.xcodeproj/project.pbxproj
| @@ -348,7 +348,8 @@ | @@ -348,7 +348,8 @@ | ||
| 348 | ); | 348 | ); |
| 349 | inputPaths = ( | 349 | inputPaths = ( |
| 350 | "${PODS_ROOT}/Target Support Files/Pods-CNLivePlayer_Example/Pods-CNLivePlayer_Example-frameworks.sh", | 350 | "${PODS_ROOT}/Target Support Files/Pods-CNLivePlayer_Example/Pods-CNLivePlayer_Example-frameworks.sh", |
| 351 | - "${BUILT_PRODUCTS_DIR}/CNLivePlayer/CNLivePlayer.framework", | 351 | + "${BUILT_PRODUCTS_DIR}/CocoaAsyncSocket/CocoaAsyncSocket.framework", |
| 352 | + "${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework", | ||
| 352 | "${BUILT_PRODUCTS_DIR}/GPUImage/GPUImage.framework", | 353 | "${BUILT_PRODUCTS_DIR}/GPUImage/GPUImage.framework", |
| 353 | "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework", | 354 | "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework", |
| 354 | "${BUILT_PRODUCTS_DIR}/libksygpulive/libksygpulive.framework", | 355 | "${BUILT_PRODUCTS_DIR}/libksygpulive/libksygpulive.framework", |
| @@ -357,7 +358,8 @@ | @@ -357,7 +358,8 @@ | ||
| 357 | outputFileListPaths = ( | 358 | outputFileListPaths = ( |
| 358 | ); | 359 | ); |
| 359 | outputPaths = ( | 360 | outputPaths = ( |
| 360 | - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLivePlayer.framework", | 361 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaAsyncSocket.framework", |
| 362 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaLumberjack.framework", | ||
| 361 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GPUImage.framework", | 363 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GPUImage.framework", |
| 362 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework", | 364 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework", |
| 363 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libksygpulive.framework", | 365 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libksygpulive.framework", |
| @@ -477,6 +479,7 @@ | @@ -477,6 +479,7 @@ | ||
| 477 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; | 479 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; |
| 478 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | 480 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; |
| 479 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | 481 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; |
| 482 | + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; | ||
| 480 | GCC_WARN_UNDECLARED_SELECTOR = YES; | 483 | GCC_WARN_UNDECLARED_SELECTOR = YES; |
| 481 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | 484 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
| 482 | GCC_WARN_UNUSED_FUNCTION = YES; | 485 | GCC_WARN_UNUSED_FUNCTION = YES; |
| @@ -485,6 +488,7 @@ | @@ -485,6 +488,7 @@ | ||
| 485 | ONLY_ACTIVE_ARCH = YES; | 488 | ONLY_ACTIVE_ARCH = YES; |
| 486 | SDKROOT = iphoneos; | 489 | SDKROOT = iphoneos; |
| 487 | TARGETED_DEVICE_FAMILY = "1,2"; | 490 | TARGETED_DEVICE_FAMILY = "1,2"; |
| 491 | + WARNING_CFLAGS = ""; | ||
| 488 | }; | 492 | }; |
| 489 | name = Debug; | 493 | name = Debug; |
| 490 | }; | 494 | }; |
| @@ -510,6 +514,7 @@ | @@ -510,6 +514,7 @@ | ||
| 510 | GCC_C_LANGUAGE_STANDARD = gnu99; | 514 | GCC_C_LANGUAGE_STANDARD = gnu99; |
| 511 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | 515 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; |
| 512 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | 516 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; |
| 517 | + GCC_WARN_INHIBIT_ALL_WARNINGS = YES; | ||
| 513 | GCC_WARN_UNDECLARED_SELECTOR = YES; | 518 | GCC_WARN_UNDECLARED_SELECTOR = YES; |
| 514 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | 519 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
| 515 | GCC_WARN_UNUSED_FUNCTION = YES; | 520 | GCC_WARN_UNUSED_FUNCTION = YES; |
| @@ -518,6 +523,7 @@ | @@ -518,6 +523,7 @@ | ||
| 518 | SDKROOT = iphoneos; | 523 | SDKROOT = iphoneos; |
| 519 | TARGETED_DEVICE_FAMILY = "1,2"; | 524 | TARGETED_DEVICE_FAMILY = "1,2"; |
| 520 | VALIDATE_PRODUCT = YES; | 525 | VALIDATE_PRODUCT = YES; |
| 526 | + WARNING_CFLAGS = ""; | ||
| 521 | }; | 527 | }; |
| 522 | name = Release; | 528 | name = Release; |
| 523 | }; | 529 | }; |
| @@ -534,6 +540,7 @@ | @@ -534,6 +540,7 @@ | ||
| 534 | PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.video; | 540 | PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.video; |
| 535 | PRODUCT_NAME = "$(TARGET_NAME)"; | 541 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 536 | SWIFT_VERSION = 4.0; | 542 | SWIFT_VERSION = 4.0; |
| 543 | + WARNING_CFLAGS = ""; | ||
| 537 | WRAPPER_EXTENSION = app; | 544 | WRAPPER_EXTENSION = app; |
| 538 | }; | 545 | }; |
| 539 | name = Debug; | 546 | name = Debug; |
| @@ -551,6 +558,7 @@ | @@ -551,6 +558,7 @@ | ||
| 551 | PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.video; | 558 | PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.video; |
| 552 | PRODUCT_NAME = "$(TARGET_NAME)"; | 559 | PRODUCT_NAME = "$(TARGET_NAME)"; |
| 553 | SWIFT_VERSION = 4.0; | 560 | SWIFT_VERSION = 4.0; |
| 561 | + WARNING_CFLAGS = ""; | ||
| 554 | WRAPPER_EXTENSION = app; | 562 | WRAPPER_EXTENSION = app; |
| 555 | }; | 563 | }; |
| 556 | name = Release; | 564 | name = Release; |