Commit 40033d591b59d22355a1d9081340e26227de113e
1 parent
af90c4cc
no message
Showing
7 changed files
with
151 additions
and
114 deletions
CNLivePlayer.podspec
| ... | ... | @@ -29,11 +29,11 @@ Pod::Spec.new do |s| |
| 29 | 29 | # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' |
| 30 | 30 | |
| 31 | 31 | s.ios.deployment_target = '9.0' |
| 32 | + | |
| 33 | + #s.public_header_files = 'CNLivePlayer/Classes/Player/CNLivePlayer.h','CNLivePlayer/Classes/Player/CNLivePlayerManager.h','CNLivePlayer/Classes/Header/CNLivePlayerDelegate.h','CNLivePlayer/Classes/Header/CNLivePlayerHeader.h','CNLivePlayer/Classes/Header/CNLivePlayerTypeDef.h','CNLivePlayer/Classes/Database/CNLivePlayerDBTool.h' | |
| 32 | 34 | |
| 33 | 35 | s.source_files = 'CNLivePlayer/Classes/**/*' |
| 34 | 36 | |
| 35 | - s.public_header_files = 'CNLivePlayer/Classes/Player/CNLivePlayer.h','CNLivePlayer/Classes/Player/CNLivePlayerManager.h','CNLivePlayer/Classes/Header/CNLivePlayerDelegate.h','CNLivePlayer/Classes/Header/CNLivePlayerHeader.h','CNLivePlayer/Classes/Header/CNLivePlayerTypeDef.h','CNLivePlayer/Classes/Database/CNLivePlayerDBTool.h' | |
| 36 | - | |
| 37 | 37 | s.dependency 'PLPlayerKit', '~> 3.4.3' |
| 38 | 38 | s.dependency 'FMDB', '~> 2.7.5' |
| 39 | 39 | |
| ... | ... | @@ -41,4 +41,5 @@ Pod::Spec.new do |s| |
| 41 | 41 | |
| 42 | 42 | s.frameworks = 'Foundation', 'UIKit', 'AVFoundation', 'AVKit', 'MediaPlayer', 'VideoToolbox', 'CoreTelephony', 'CoreMedia', 'OpenGLES', 'QuartzCore', 'Accelerate', 'AudioToolbox', 'CoreAudio','CoreGraphics' |
| 43 | 43 | |
| 44 | + s.static_framework = true | |
| 44 | 45 | end | ... | ... |
CNLivePlayer/Classes/DataRequest/CNLivePlayerRequest.h
| ... | ... | @@ -17,18 +17,18 @@ typedef void (^ResultsBlock) (NSString * _Nullable videoUrl, NSError * _Nullable |
| 17 | 17 | |
| 18 | 18 | @interface CNLivePlayerRequest : NSObject |
| 19 | 19 | |
| 20 | +#pragma mark - 鉴权 | |
| 21 | +// 获取鉴权 | |
| 22 | ++ (void)getAuthentication; | |
| 23 | ++ (void)getAuthenticationBlock:(void (^)(NSString * _Nullable code, NSError * _Nullable error))block; | |
| 24 | + | |
| 20 | 25 | #pragma mark - 点播 |
| 21 | 26 | // 获取点播播放地址 |
| 22 | 27 | + (void)getVodVideoURLWithVideoId:(NSString *)videoId rate:(NSString *)rate block:(nullable ResultsBlock)block; |
| 23 | 28 | |
| 24 | 29 | #pragma mark - 直播 |
| 25 | 30 | // 获取直播播放地址 |
| 26 | -+ (void)getLiveVideoURLWithVideoId:(NSString *)videoId activityId:(NSString *)activityId block:(nullable ResultsBlock)block; | |
| 27 | - | |
| 28 | -#pragma mark - 鉴权 | |
| 29 | -// 获取鉴权 | |
| 30 | -+ (void)getAuthentication; | |
| 31 | -+ (void)getAuthenticationBlock:(void (^)(NSString * _Nullable code, NSError * _Nullable error))block; | |
| 31 | ++ (void)getLiveVideoURLWithActivityId:(NSString *)activityId channelId:(NSString *)channelId block:(nullable ResultsBlock)block; | |
| 32 | 32 | |
| 33 | 33 | #pragma mark - 公共方法 |
| 34 | 34 | // 获取播放地址 | ... | ... |
CNLivePlayer/Classes/DataRequest/CNLivePlayerRequest.m
| ... | ... | @@ -13,61 +13,48 @@ |
| 13 | 13 | #import "CNLivePlayerManager.h" |
| 14 | 14 | |
| 15 | 15 | @implementation CNLivePlayerRequest |
| 16 | -#pragma mark - 直播 | |
| 17 | -// 获取直播播放地址 | |
| 18 | -+ (void)getLiveVideoURLWithVideoId:(NSString *)videoId activityId:(NSString *)activityId block:(nullable ResultsBlock)block{ | |
| 19 | - NSDictionary *parameter = @{@"appId": Player_AppID, | |
| 20 | - @"channelId": videoId, | |
| 21 | - @"activityId": activityId ? activityId : @"", | |
| 22 | - @"timestamp": [self getTimestamp], | |
| 23 | - @"isHLS": @"1", | |
| 24 | - @"plat": @"i", | |
| 25 | - @"playType": @"v", | |
| 26 | - @"platform_id": [NSBundle mainBundle].bundleIdentifier, | |
| 27 | - @"channelName": Player_ChannelName, | |
| 28 | - @"tag": Player_Tag, | |
| 29 | - @"from": @"apple", | |
| 30 | - @"sid": Player_UserId, | |
| 31 | - @"uid": [self getUid]}; | |
| 32 | - [self getVideoURL:liveUrl parameter:parameter block:block]; | |
| 33 | 16 | |
| 17 | +#pragma mark - 鉴权 | |
| 18 | +// 获取鉴权 | |
| 19 | ++ (void)getAuthentication{ | |
| 20 | + [self getAuthenticationBlock:^(NSString * _Nullable code, NSError * _Nullable error) { | |
| 21 | + [[NSUserDefaults standardUserDefaults] setObject:code forKey:@"kCNLivePlayerAuthentication"]; | |
| 22 | + [[NSUserDefaults standardUserDefaults] synchronize]; | |
| 23 | + }]; | |
| 24 | + | |
| 34 | 25 | } |
| 35 | 26 | |
| 36 | -// 获取播放地址 | |
| 37 | -+ (void)getVideoURL:(nullable NSString *)URL parameter:(nullable NSDictionary *)parameter block:(nullable ResultsBlock)block{ | |
| 27 | ++ (void)getAuthenticationBlock:(void (^)(NSString * _Nullable code, NSError * _Nullable error))block { | |
| 28 | + if(Player_Authentication){ | |
| 29 | + block?block(@"0", nil):@""; | |
| 30 | + return; | |
| 31 | + } | |
| 32 | + NSDictionary *parameter = @{@"platform_id": [NSBundle mainBundle].bundleIdentifier, | |
| 33 | + @"timestamp": [self getTimestamp], | |
| 34 | + @"appId": Player_AppID}; | |
| 38 | 35 | NSString *dicString = [NSString stringWithFormat:@"%@&key=%@", [self dictionaryToSignValue:parameter], Player_AppKey]; |
| 39 | - | |
| 40 | 36 | NSString *signString = [[self sha1:dicString] uppercaseString]; |
| 41 | - | |
| 42 | - NSString *videoUrl = [NSString stringWithFormat:@"%@?%@&sign=%@", vodUrl, [self dictionaryToSignValue:parameter], signString]; | |
| 43 | - NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:videoUrl]]; | |
| 44 | - [urlRequest setHTTPMethod:@"GET"]; | |
| 45 | - [urlRequest setTimeoutInterval:30]; | |
| 46 | 37 | |
| 47 | - [NSURLConnection sendAsynchronousRequest:urlRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { | |
| 48 | - dispatch_async(dispatch_get_main_queue(), ^{ | |
| 49 | - if (connectionError) { | |
| 50 | - NSError *error = connectionError.userInfo[NSUnderlyingErrorKey]; | |
| 51 | - NSString *videoUrl302 = error.userInfo[NSURLErrorFailingURLStringErrorKey]; | |
| 52 | - if (!videoUrl302 || ![videoUrl302 isKindOfClass:[NSString class]] || videoUrl302.length <= 0) { | |
| 53 | - videoUrl302 = nil; | |
| 54 | - } | |
| 55 | - block?block(videoUrl302, nil):@""; | |
| 56 | - | |
| 57 | - } else if (response) { | |
| 58 | - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; | |
| 59 | - block?block([httpResponse.URL absoluteString], nil):@""; | |
| 38 | + NSString *url = [NSString stringWithFormat:@"%@?%@&sign=%@", authUrl, [self dictionaryToSignValue:parameter], signString]; | |
| 39 | + | |
| 40 | + NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; | |
| 41 | + [urlRequest setHTTPMethod:@"GET"]; | |
| 42 | + [urlRequest setTimeoutInterval:30.0]; | |
| 43 | + NSURLSessionDataTask *task = [self dataTaskWithRequest:urlRequest success:^(NSURLResponse * _Nullable response, id _Nullable data) { | |
| 44 | + if (data && [data isKindOfClass:[NSDictionary class]]) { | |
| 45 | + NSDictionary *dic = (NSDictionary *)data; | |
| 46 | + [[NSUserDefaults standardUserDefaults] setObject:dic[@"errorCode"] forKey:@"kCNLivePlayerAuthentication"]; | |
| 47 | + [[NSUserDefaults standardUserDefaults] synchronize]; | |
| 48 | + block?block(dic[@"errorCode"], nil):@""; | |
| 49 | + }else{ | |
| 50 | + block?block(nil, nil):@""; | |
| 51 | + } | |
| 60 | 52 | |
| 61 | - } else { | |
| 62 | - NSString *domain = @"com.CNLive.Application.ErrorDomain"; | |
| 63 | - NSString *desc = @"获取播放地址错误"; | |
| 64 | - NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : desc }; | |
| 65 | - NSError *error = [NSError errorWithDomain:domain code:8888 userInfo:userInfo]; | |
| 66 | - block?block(videoUrl, error):@""; | |
| 67 | - | |
| 68 | - } | |
| 69 | - }); | |
| 53 | + } failure:^(NSURLResponse * _Nullable response, NSError * _Nullable error) { | |
| 54 | + NSString *code = [NSString stringWithFormat:@"%ld",(long)error.code]; | |
| 55 | + block?block(code, error):@""; | |
| 70 | 56 | }]; |
| 57 | + [task resume]; | |
| 71 | 58 | } |
| 72 | 59 | |
| 73 | 60 | #pragma mark - 点播 |
| ... | ... | @@ -106,47 +93,61 @@ |
| 106 | 93 | |
| 107 | 94 | } |
| 108 | 95 | |
| 109 | -#pragma mark - 鉴权 | |
| 110 | -// 获取鉴权 | |
| 111 | -+ (void)getAuthentication{ | |
| 112 | - [self getAuthenticationBlock:^(NSString * _Nullable code, NSError * _Nullable error) { | |
| 113 | - [[NSUserDefaults standardUserDefaults] setObject:code forKey:@"kCNLivePlayerAuthentication"]; | |
| 114 | - [[NSUserDefaults standardUserDefaults] synchronize]; | |
| 115 | - }]; | |
| 116 | - | |
| 96 | +#pragma mark - 直播 | |
| 97 | +// 获取直播播放地址 | |
| 98 | ++ (void)getLiveVideoURLWithActivityId:(NSString *)activityId channelId:(NSString *)channelId block:(nullable ResultsBlock)block { | |
| 99 | + NSDictionary *parameter = @{@"appId": Player_AppID, | |
| 100 | + @"channelId": channelId ? channelId : @"", | |
| 101 | + @"activityId": activityId ? activityId : @"", | |
| 102 | + @"timestamp": [self getTimestamp], | |
| 103 | + @"isHLS": @"1", | |
| 104 | + @"plat": @"i", | |
| 105 | + @"playType": @"v", | |
| 106 | + @"platform_id": [NSBundle mainBundle].bundleIdentifier, | |
| 107 | + @"channelName": Player_ChannelName, | |
| 108 | + @"tag": Player_Tag, | |
| 109 | + @"from": @"apple", | |
| 110 | + @"sid": Player_UserId, | |
| 111 | + @"uid": [self getUid]}; | |
| 112 | + [self getVideoURL:liveUrl parameter:parameter block:block]; | |
| 113 | + | |
| 117 | 114 | } |
| 118 | 115 | |
| 119 | -+ (void)getAuthenticationBlock:(void (^)(NSString * _Nullable code, NSError * _Nullable error))block { | |
| 120 | - if(Player_Authentication){ | |
| 121 | - block?block(@"0", nil):@""; | |
| 122 | - return; | |
| 123 | - } | |
| 124 | - NSDictionary *parameter = @{@"platform_id": [NSBundle mainBundle].bundleIdentifier, | |
| 125 | - @"timestamp": [self getTimestamp], | |
| 126 | - @"appId": Player_AppID}; | |
| 116 | +// 获取播放地址 | |
| 117 | ++ (void)getVideoURL:(nullable NSString *)URL parameter:(nullable NSDictionary *)parameter block:(nullable ResultsBlock)block{ | |
| 127 | 118 | NSString *dicString = [NSString stringWithFormat:@"%@&key=%@", [self dictionaryToSignValue:parameter], Player_AppKey]; |
| 119 | + | |
| 128 | 120 | NSString *signString = [[self sha1:dicString] uppercaseString]; |
| 129 | - | |
| 130 | - NSString *url = [NSString stringWithFormat:@"%@?%@&sign=%@", authUrl, [self dictionaryToSignValue:parameter], signString]; | |
| 131 | - | |
| 132 | - NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; | |
| 121 | + | |
| 122 | + NSString *videoUrl = [NSString stringWithFormat:@"%@?%@&sign=%@", vodUrl, [self dictionaryToSignValue:parameter], signString]; | |
| 123 | + NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:videoUrl]]; | |
| 133 | 124 | [urlRequest setHTTPMethod:@"GET"]; |
| 134 | - [urlRequest setTimeoutInterval:30.0]; | |
| 135 | - NSURLSessionDataTask *task = [self dataTaskWithRequest:urlRequest success:^(NSURLResponse * _Nullable response, id _Nullable data) { | |
| 136 | - if (data && [data isKindOfClass:[NSDictionary class]]) { | |
| 137 | - NSDictionary *dic = (NSDictionary *)data; | |
| 138 | - [[NSUserDefaults standardUserDefaults] setObject:dic[@"errorCode"] forKey:@"kCNLivePlayerAuthentication"]; | |
| 139 | - [[NSUserDefaults standardUserDefaults] synchronize]; | |
| 140 | - block?block(dic[@"errorCode"], nil):@""; | |
| 141 | - }else{ | |
| 142 | - block?block(nil, nil):@""; | |
| 143 | - } | |
| 125 | + [urlRequest setTimeoutInterval:30]; | |
| 126 | + | |
| 127 | + [NSURLConnection sendAsynchronousRequest:urlRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { | |
| 128 | + dispatch_async(dispatch_get_main_queue(), ^{ | |
| 129 | + if (connectionError) { | |
| 130 | + NSError *error = connectionError.userInfo[NSUnderlyingErrorKey]; | |
| 131 | + NSString *videoUrl302 = error.userInfo[NSURLErrorFailingURLStringErrorKey]; | |
| 132 | + if (!videoUrl302 || ![videoUrl302 isKindOfClass:[NSString class]] || videoUrl302.length <= 0) { | |
| 133 | + videoUrl302 = nil; | |
| 134 | + } | |
| 135 | + block?block(videoUrl302, nil):@""; | |
| 136 | + | |
| 137 | + } else if (response) { | |
| 138 | + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response; | |
| 139 | + block?block([httpResponse.URL absoluteString], nil):@""; | |
| 144 | 140 | |
| 145 | - } failure:^(NSURLResponse * _Nullable response, NSError * _Nullable error) { | |
| 146 | - NSString *code = [NSString stringWithFormat:@"%ld",(long)error.code]; | |
| 147 | - block?block(code, error):@""; | |
| 141 | + } else { | |
| 142 | + NSString *domain = @"com.CNLive.Application.ErrorDomain"; | |
| 143 | + NSString *desc = @"获取播放地址错误"; | |
| 144 | + NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : desc }; | |
| 145 | + NSError *error = [NSError errorWithDomain:domain code:8888 userInfo:userInfo]; | |
| 146 | + block?block(videoUrl, error):@""; | |
| 147 | + | |
| 148 | + } | |
| 149 | + }); | |
| 148 | 150 | }]; |
| 149 | - [task resume]; | |
| 150 | 151 | } |
| 151 | 152 | |
| 152 | 153 | #pragma mark - 公共方法 | ... | ... |
CNLivePlayer/Classes/Header/CNLivePlayerDelegate.h
CNLivePlayer/Classes/Player/CNLivePlayer.h
| ... | ... | @@ -16,6 +16,9 @@ |
| 16 | 16 | #import "CNLivePlayerDelegate.h" // 协议 |
| 17 | 17 | |
| 18 | 18 | NS_ASSUME_NONNULL_BEGIN |
| 19 | +// 切换直播视频 | |
| 20 | +// v:videoId a:activityId | |
| 21 | +#define PlayerLiveVideoId(v, a) [NSString stringWithFormat:@"%@:%@",v,a] | |
| 19 | 22 | |
| 20 | 23 | typedef void (^SuccessBlock) (void); |
| 21 | 24 | typedef void (^FailureBlock) (NSError *error); |
| ... | ... | @@ -29,7 +32,7 @@ typedef void (^FailureBlock) (NSError *error); |
| 29 | 32 | /** |
| 30 | 33 | 初始化点播播放器 初始化成功后才能对播放器进行设置 |
| 31 | 34 | |
| 32 | - @param videoId 视频Id | |
| 35 | + @param videoId 视频ID | |
| 33 | 36 | @param success 初始化成功block |
| 34 | 37 | @param failure 初始化失败block 回调一个NSError的对象 |
| 35 | 38 | |
| ... | ... | @@ -44,8 +47,8 @@ typedef void (^FailureBlock) (NSError *error); |
| 44 | 47 | /** |
| 45 | 48 | 初始化直播播放器 |
| 46 | 49 | |
| 47 | - @param videoId 视频Id | |
| 48 | - @param activityId 活动Id | |
| 50 | + @param activityId 活动ID | |
| 51 | + @param channelId 频道ID(或主播ID) | |
| 49 | 52 | @param success 初始化成功block |
| 50 | 53 | @param failure 初始化失败block 回调一个NSError的对象 |
| 51 | 54 | |
| ... | ... | @@ -53,15 +56,15 @@ typedef void (^FailureBlock) (NSError *error); |
| 53 | 56 | |
| 54 | 57 | @since v0.0.1 |
| 55 | 58 | */ |
| 56 | -- (instancetype)initLivePlayWithVideoId:(NSString *)videoId activityId:(NSString *)activityId success:(SuccessBlock _Nullable)success failure:(FailureBlock _Nullable)failure; | |
| 59 | +- (instancetype)initLivePlayWithActivityId:(NSString *)activityId channelId:(NSString *)channelId success:(SuccessBlock _Nullable)success failure:(FailureBlock _Nullable)failure; | |
| 57 | 60 | // 推荐使用 |
| 58 | -- (instancetype)initLivePlayWithVideoId:(NSString *)videoId activityId:(NSString *)activityId; | |
| 61 | +- (instancetype)initLivePlayWithActivityId:(NSString *)activityId channelId:(NSString *)channelId; | |
| 59 | 62 | |
| 60 | 63 | #pragma mark - 切换视频 |
| 61 | 64 | /** |
| 62 | 65 | 切换视频 |
| 63 | 66 | |
| 64 | -@param videoId 视频id | |
| 67 | +@param videoId 视频id 直播视频videoId <- activityId:channelId 点播视频videoId <- videoId | |
| 65 | 68 | @param type 视频类型 vod 点播视频 live 直播视频 |
| 66 | 69 | |
| 67 | 70 | @since v0.0.1 |
| ... | ... | @@ -73,6 +76,7 @@ typedef void (^FailureBlock) (NSError *error); |
| 73 | 76 | 切换码率 |
| 74 | 77 | |
| 75 | 78 | @param level 视频清晰度 |
| 79 | + 注意:仅适用于点播视频 | |
| 76 | 80 | |
| 77 | 81 | @since v0.0.1 |
| 78 | 82 | */ | ... | ... |
CNLivePlayer/Classes/Player/CNLivePlayer.m
| ... | ... | @@ -18,8 +18,13 @@ |
| 18 | 18 | #define PlayerStringToKey(a, b) [NSString stringWithFormat:@"%@:%@",a,b] |
| 19 | 19 | |
| 20 | 20 | @interface CNLivePlayer ()<PLPlayerDelegate>{ |
| 21 | + // 点播视频 | |
| 21 | 22 | NSString * _videoId; |
| 23 | + | |
| 24 | + // 直播视频 | |
| 22 | 25 | NSString * _activityId; |
| 26 | + NSString * _channelId; | |
| 27 | + | |
| 23 | 28 | NSString * _type; |
| 24 | 29 | // 1-流畅,2-标清,3-高清,4-超清,默认为2 |
| 25 | 30 | NSString *_rate; |
| ... | ... | @@ -49,7 +54,7 @@ |
| 49 | 54 | /** |
| 50 | 55 | 初始化点播播放器 初始化成功后才能对播放器进行设置 |
| 51 | 56 | |
| 52 | -@param videoId 视频Id | |
| 57 | +@param videoId 视频ID | |
| 53 | 58 | @param success 初始化成功block |
| 54 | 59 | @param failure 初始化失败block 回调一个NSError的对象 |
| 55 | 60 | |
| ... | ... | @@ -62,6 +67,8 @@ |
| 62 | 67 | if (self) { |
| 63 | 68 | _switchRate = NO; |
| 64 | 69 | _videoId = videoId; |
| 70 | + _activityId = @""; | |
| 71 | + _channelId = @""; | |
| 65 | 72 | _type = @"vod"; |
| 66 | 73 | _rate = @"2"; |
| 67 | 74 | [self getCacheURLSuccess:success failure:failure]; |
| ... | ... | @@ -75,8 +82,8 @@ |
| 75 | 82 | /** |
| 76 | 83 | 初始化直播播放器 |
| 77 | 84 | |
| 78 | -@param videoId 视频Id | |
| 79 | -@param activityId 活动Id | |
| 85 | +@param activityId 活动ID | |
| 86 | +@param channelId 频道ID(或主播ID) | |
| 80 | 87 | @param success 初始化成功block |
| 81 | 88 | @param failure 初始化失败block 回调一个NSError的对象 |
| 82 | 89 | |
| ... | ... | @@ -84,20 +91,21 @@ |
| 84 | 91 | |
| 85 | 92 | @since v0.0.1 |
| 86 | 93 | */ |
| 87 | -- (instancetype)initLivePlayWithVideoId:(NSString *)videoId activityId:(NSString *)activityId success:(SuccessBlock)success failure:(FailureBlock)failure{ | |
| 94 | +- (instancetype)initLivePlayWithActivityId:(NSString *)activityId channelId:(NSString *)channelId success:(SuccessBlock _Nullable)success failure:(FailureBlock _Nullable)failure{ | |
| 88 | 95 | self = [super init]; |
| 89 | 96 | if (self) { |
| 90 | 97 | _switchRate = NO; |
| 91 | - _videoId = videoId; | |
| 92 | 98 | _activityId = activityId; |
| 99 | + _channelId = channelId; | |
| 100 | + _videoId = @""; | |
| 93 | 101 | _type = @"live"; |
| 94 | 102 | _rate = @"2"; |
| 95 | 103 | [self getCacheURLSuccess:success failure:failure]; |
| 96 | 104 | } |
| 97 | 105 | return self; |
| 98 | 106 | } |
| 99 | -- (instancetype)initLivePlayWithVideoId:(NSString *)videoId activityId:(NSString *)activityId { | |
| 100 | - return [self initLivePlayWithVideoId:videoId activityId:activityId success:nil failure:nil]; | |
| 107 | +- (instancetype)initLivePlayWithActivityId:(NSString *)activityId channelId:(NSString *)channelId{ | |
| 108 | + return [self initLivePlayWithActivityId:activityId channelId:channelId success:nil failure:nil]; | |
| 101 | 109 | } |
| 102 | 110 | /** |
| 103 | 111 | 初始化播放器 |
| ... | ... | @@ -111,11 +119,12 @@ |
| 111 | 119 | _switchPlayer.delegate = self; |
| 112 | 120 | _switchPlayer.playerView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); |
| 113 | 121 | _switchPlayer.playerView.contentMode = UIViewContentModeScaleAspectFit; |
| 114 | -// _switchPlayer.launchView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"cnlive_player_bg"]]; | |
| 122 | + _switchPlayer.launchView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"cnlive_player_bg"]]; | |
| 115 | 123 | [_switchPlayer play]; |
| 116 | 124 | [self.view addSubview:self.switchPlayer.playerView]; |
| 117 | 125 | [self.view bringSubviewToFront:self.player.playerView]; |
| 118 | - }else{ | |
| 126 | + } | |
| 127 | + else{ | |
| 119 | 128 | if(self.player){ // 切换视频 |
| 120 | 129 | [self.player playWithURL:URL sameSource:NO]; |
| 121 | 130 | } |
| ... | ... | @@ -124,7 +133,7 @@ |
| 124 | 133 | _player.delegate = self; |
| 125 | 134 | _player.playerView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); |
| 126 | 135 | _player.playerView.contentMode = UIViewContentModeScaleAspectFit; |
| 127 | -// _player.launchView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"cnlive_player_bg"]]; | |
| 136 | + _player.launchView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"cnlive_player_bg"]]; | |
| 128 | 137 | if(!_player.isPlaying){ |
| 129 | 138 | [_player play]; |
| 130 | 139 | } |
| ... | ... | @@ -155,20 +164,29 @@ |
| 155 | 164 | case CNLivePlayerDataTypeVod: |
| 156 | 165 | { |
| 157 | 166 | _type = @"vod"; |
| 167 | + _videoId = videoId; | |
| 168 | + _activityId = @""; | |
| 169 | + _channelId = @""; | |
| 158 | 170 | } |
| 159 | 171 | break; |
| 160 | 172 | case CNLivePlayerDataTypeLive: |
| 161 | 173 | { |
| 162 | - _type = @"live"; | |
| 174 | + NSArray *array = [videoId componentsSeparatedByString:@":"]; | |
| 175 | + if(array.count >= 2){ | |
| 176 | + _activityId = array[0]; | |
| 177 | + _channelId = array[1]; | |
| 178 | + } | |
| 179 | + _videoId = @""; | |
| 180 | + _type = @"live"; | |
| 163 | 181 | } |
| 164 | 182 | break; |
| 165 | 183 | case CNLivePlayerDataTypeAudio: |
| 166 | 184 | { |
| 167 | 185 | _type = @"vod"; |
| 186 | + _videoId = videoId; | |
| 168 | 187 | } |
| 169 | 188 | break; |
| 170 | 189 | } |
| 171 | - _videoId = videoId; | |
| 172 | 190 | [self getCacheURLSuccess:nil failure:nil]; |
| 173 | 191 | |
| 174 | 192 | } |
| ... | ... | @@ -306,7 +324,7 @@ |
| 306 | 324 | }else if([_type isEqualToString:@"live"]){ |
| 307 | 325 | //直播播放地址 |
| 308 | 326 | __weak typeof(self) weakSelf = self; |
| 309 | - [CNLivePlayerRequest getLiveVideoURLWithVideoId:_videoId activityId:_activityId block:^(NSString * _Nonnull videoUrl, NSError *error) { | |
| 327 | + [CNLivePlayerRequest getLiveVideoURLWithActivityId:_activityId channelId:_channelId block:^(NSString * _Nonnull videoUrl, NSError *error) { | |
| 310 | 328 | __strong typeof(weakSelf) strongSelf = weakSelf; |
| 311 | 329 | if(!strongSelf){ |
| 312 | 330 | return ; |
| ... | ... | @@ -566,7 +584,24 @@ |
| 566 | 584 | case PLPlayerStatusPlaying: |
| 567 | 585 | { |
| 568 | 586 | if(player == self.switchPlayer&&_switchRate){ |
| 569 | - [self.switchPlayer seekTo:_switchRateTime]; | |
| 587 | + // 点播切换码率 | |
| 588 | + if([_type isEqualToString:@"vod"]){ | |
| 589 | + [self.switchPlayer seekTo:_switchRateTime]; | |
| 590 | + } | |
| 591 | + // 直播切换码率 | |
| 592 | + else if ([_type isEqualToString:@"live"]){ | |
| 593 | + PLPlayer *temp = self.player; | |
| 594 | + self.player = self.switchPlayer; | |
| 595 | + self.switchPlayer = temp; | |
| 596 | + [self.switchPlayer.playerView removeFromSuperview]; | |
| 597 | + self.switchPlayer = nil; | |
| 598 | + // 切换码率完成 | |
| 599 | + if (self.delegate && [self.delegate respondsToSelector:@selector(player:switchRateCompleted:)]) { | |
| 600 | + [self.delegate player:self switchRateCompleted:YES]; | |
| 601 | + } | |
| 602 | + _switchRate = NO; | |
| 603 | + | |
| 604 | + } | |
| 570 | 605 | } |
| 571 | 606 | playerState = CNLivePlayerStatusPlaying; |
| 572 | 607 | } | ... | ... |
Example/CNLivePlayer.xcodeproj/project.pbxproj
| ... | ... | @@ -396,13 +396,11 @@ |
| 396 | 396 | ); |
| 397 | 397 | inputPaths = ( |
| 398 | 398 | "${PODS_ROOT}/Target Support Files/Pods-CNLivePlayer_Example/Pods-CNLivePlayer_Example-frameworks.sh", |
| 399 | - "${BUILT_PRODUCTS_DIR}/CNLivePlayer/CNLivePlayer.framework", | |
| 400 | 399 | "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework", |
| 401 | 400 | "${PODS_ROOT}/PLPlayerKit/Pod/Library/PLPlayerKit.framework", |
| 402 | 401 | ); |
| 403 | 402 | name = "[CP] Embed Pods Frameworks"; |
| 404 | 403 | outputPaths = ( |
| 405 | - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLivePlayer.framework", | |
| 406 | 404 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework", |
| 407 | 405 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PLPlayerKit.framework", |
| 408 | 406 | ); | ... | ... |