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,11 +29,11 @@ Pod::Spec.new do |s| | ||
| 29 | # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' | 29 | # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' |
| 30 | 30 | ||
| 31 | s.ios.deployment_target = '9.0' | 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 | s.source_files = 'CNLivePlayer/Classes/**/*' | 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 | s.dependency 'PLPlayerKit', '~> 3.4.3' | 37 | s.dependency 'PLPlayerKit', '~> 3.4.3' |
| 38 | s.dependency 'FMDB', '~> 2.7.5' | 38 | s.dependency 'FMDB', '~> 2.7.5' |
| 39 | 39 | ||
| @@ -41,4 +41,5 @@ Pod::Spec.new do |s| | @@ -41,4 +41,5 @@ Pod::Spec.new do |s| | ||
| 41 | 41 | ||
| 42 | s.frameworks = 'Foundation', 'UIKit', 'AVFoundation', 'AVKit', 'MediaPlayer', 'VideoToolbox', 'CoreTelephony', 'CoreMedia', 'OpenGLES', 'QuartzCore', 'Accelerate', 'AudioToolbox', 'CoreAudio','CoreGraphics' | 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 | end | 45 | end |
CNLivePlayer/Classes/DataRequest/CNLivePlayerRequest.h
| @@ -17,18 +17,18 @@ typedef void (^ResultsBlock) (NSString * _Nullable videoUrl, NSError * _Nullable | @@ -17,18 +17,18 @@ typedef void (^ResultsBlock) (NSString * _Nullable videoUrl, NSError * _Nullable | ||
| 17 | 17 | ||
| 18 | @interface CNLivePlayerRequest : NSObject | 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 | #pragma mark - 点播 | 25 | #pragma mark - 点播 |
| 21 | // 获取点播播放地址 | 26 | // 获取点播播放地址 |
| 22 | + (void)getVodVideoURLWithVideoId:(NSString *)videoId rate:(NSString *)rate block:(nullable ResultsBlock)block; | 27 | + (void)getVodVideoURLWithVideoId:(NSString *)videoId rate:(NSString *)rate block:(nullable ResultsBlock)block; |
| 23 | 28 | ||
| 24 | #pragma mark - 直播 | 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 | #pragma mark - 公共方法 | 33 | #pragma mark - 公共方法 |
| 34 | // 获取播放地址 | 34 | // 获取播放地址 |
CNLivePlayer/Classes/DataRequest/CNLivePlayerRequest.m
| @@ -13,61 +13,48 @@ | @@ -13,61 +13,48 @@ | ||
| 13 | #import "CNLivePlayerManager.h" | 13 | #import "CNLivePlayerManager.h" |
| 14 | 14 | ||
| 15 | @implementation CNLivePlayerRequest | 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 | NSString *dicString = [NSString stringWithFormat:@"%@&key=%@", [self dictionaryToSignValue:parameter], Player_AppKey]; | 35 | NSString *dicString = [NSString stringWithFormat:@"%@&key=%@", [self dictionaryToSignValue:parameter], Player_AppKey]; |
| 39 | - | ||
| 40 | NSString *signString = [[self sha1:dicString] uppercaseString]; | 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 | #pragma mark - 点播 | 60 | #pragma mark - 点播 |
| @@ -106,47 +93,61 @@ | @@ -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 | NSString *dicString = [NSString stringWithFormat:@"%@&key=%@", [self dictionaryToSignValue:parameter], Player_AppKey]; | 118 | NSString *dicString = [NSString stringWithFormat:@"%@&key=%@", [self dictionaryToSignValue:parameter], Player_AppKey]; |
| 119 | + | ||
| 128 | NSString *signString = [[self sha1:dicString] uppercaseString]; | 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 | [urlRequest setHTTPMethod:@"GET"]; | 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 | #pragma mark - 公共方法 | 153 | #pragma mark - 公共方法 |
CNLivePlayer/Classes/Header/CNLivePlayerDelegate.h
| @@ -10,12 +10,10 @@ | @@ -10,12 +10,10 @@ | ||
| 10 | * 播放器协议 | 10 | * 播放器协议 |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | -#import <Foundation/Foundation.h> | 13 | +#import <UIKit/UIKit.h> |
| 14 | 14 | ||
| 15 | NS_ASSUME_NONNULL_BEGIN | 15 | NS_ASSUME_NONNULL_BEGIN |
| 16 | 16 | ||
| 17 | -@class UIView; | ||
| 18 | -@class UIImageView; | ||
| 19 | @class CNLivePlayer; | 17 | @class CNLivePlayer; |
| 20 | /** | 18 | /** |
| 21 | 发送队列的代理协议。 | 19 | 发送队列的代理协议。 |
CNLivePlayer/Classes/Player/CNLivePlayer.h
| @@ -16,6 +16,9 @@ | @@ -16,6 +16,9 @@ | ||
| 16 | #import "CNLivePlayerDelegate.h" // 协议 | 16 | #import "CNLivePlayerDelegate.h" // 协议 |
| 17 | 17 | ||
| 18 | NS_ASSUME_NONNULL_BEGIN | 18 | NS_ASSUME_NONNULL_BEGIN |
| 19 | +// 切换直播视频 | ||
| 20 | +// v:videoId a:activityId | ||
| 21 | +#define PlayerLiveVideoId(v, a) [NSString stringWithFormat:@"%@:%@",v,a] | ||
| 19 | 22 | ||
| 20 | typedef void (^SuccessBlock) (void); | 23 | typedef void (^SuccessBlock) (void); |
| 21 | typedef void (^FailureBlock) (NSError *error); | 24 | typedef void (^FailureBlock) (NSError *error); |
| @@ -29,7 +32,7 @@ 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 | @param success 初始化成功block | 36 | @param success 初始化成功block |
| 34 | @param failure 初始化失败block 回调一个NSError的对象 | 37 | @param failure 初始化失败block 回调一个NSError的对象 |
| 35 | 38 | ||
| @@ -44,8 +47,8 @@ typedef void (^FailureBlock) (NSError *error); | @@ -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 | @param success 初始化成功block | 52 | @param success 初始化成功block |
| 50 | @param failure 初始化失败block 回调一个NSError的对象 | 53 | @param failure 初始化失败block 回调一个NSError的对象 |
| 51 | 54 | ||
| @@ -53,15 +56,15 @@ typedef void (^FailureBlock) (NSError *error); | @@ -53,15 +56,15 @@ typedef void (^FailureBlock) (NSError *error); | ||
| 53 | 56 | ||
| 54 | @since v0.0.1 | 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 | #pragma mark - 切换视频 | 63 | #pragma mark - 切换视频 |
| 61 | /** | 64 | /** |
| 62 | 切换视频 | 65 | 切换视频 |
| 63 | 66 | ||
| 64 | -@param videoId 视频id | 67 | +@param videoId 视频id 直播视频videoId <- activityId:channelId 点播视频videoId <- videoId |
| 65 | @param type 视频类型 vod 点播视频 live 直播视频 | 68 | @param type 视频类型 vod 点播视频 live 直播视频 |
| 66 | 69 | ||
| 67 | @since v0.0.1 | 70 | @since v0.0.1 |
| @@ -73,6 +76,7 @@ typedef void (^FailureBlock) (NSError *error); | @@ -73,6 +76,7 @@ typedef void (^FailureBlock) (NSError *error); | ||
| 73 | 切换码率 | 76 | 切换码率 |
| 74 | 77 | ||
| 75 | @param level 视频清晰度 | 78 | @param level 视频清晰度 |
| 79 | + 注意:仅适用于点播视频 | ||
| 76 | 80 | ||
| 77 | @since v0.0.1 | 81 | @since v0.0.1 |
| 78 | */ | 82 | */ |
CNLivePlayer/Classes/Player/CNLivePlayer.m
| @@ -18,8 +18,13 @@ | @@ -18,8 +18,13 @@ | ||
| 18 | #define PlayerStringToKey(a, b) [NSString stringWithFormat:@"%@:%@",a,b] | 18 | #define PlayerStringToKey(a, b) [NSString stringWithFormat:@"%@:%@",a,b] |
| 19 | 19 | ||
| 20 | @interface CNLivePlayer ()<PLPlayerDelegate>{ | 20 | @interface CNLivePlayer ()<PLPlayerDelegate>{ |
| 21 | + // 点播视频 | ||
| 21 | NSString * _videoId; | 22 | NSString * _videoId; |
| 23 | + | ||
| 24 | + // 直播视频 | ||
| 22 | NSString * _activityId; | 25 | NSString * _activityId; |
| 26 | + NSString * _channelId; | ||
| 27 | + | ||
| 23 | NSString * _type; | 28 | NSString * _type; |
| 24 | // 1-流畅,2-标清,3-高清,4-超清,默认为2 | 29 | // 1-流畅,2-标清,3-高清,4-超清,默认为2 |
| 25 | NSString *_rate; | 30 | NSString *_rate; |
| @@ -49,7 +54,7 @@ | @@ -49,7 +54,7 @@ | ||
| 49 | /** | 54 | /** |
| 50 | 初始化点播播放器 初始化成功后才能对播放器进行设置 | 55 | 初始化点播播放器 初始化成功后才能对播放器进行设置 |
| 51 | 56 | ||
| 52 | -@param videoId 视频Id | 57 | +@param videoId 视频ID |
| 53 | @param success 初始化成功block | 58 | @param success 初始化成功block |
| 54 | @param failure 初始化失败block 回调一个NSError的对象 | 59 | @param failure 初始化失败block 回调一个NSError的对象 |
| 55 | 60 | ||
| @@ -62,6 +67,8 @@ | @@ -62,6 +67,8 @@ | ||
| 62 | if (self) { | 67 | if (self) { |
| 63 | _switchRate = NO; | 68 | _switchRate = NO; |
| 64 | _videoId = videoId; | 69 | _videoId = videoId; |
| 70 | + _activityId = @""; | ||
| 71 | + _channelId = @""; | ||
| 65 | _type = @"vod"; | 72 | _type = @"vod"; |
| 66 | _rate = @"2"; | 73 | _rate = @"2"; |
| 67 | [self getCacheURLSuccess:success failure:failure]; | 74 | [self getCacheURLSuccess:success failure:failure]; |
| @@ -75,8 +82,8 @@ | @@ -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 | @param success 初始化成功block | 87 | @param success 初始化成功block |
| 81 | @param failure 初始化失败block 回调一个NSError的对象 | 88 | @param failure 初始化失败block 回调一个NSError的对象 |
| 82 | 89 | ||
| @@ -84,20 +91,21 @@ | @@ -84,20 +91,21 @@ | ||
| 84 | 91 | ||
| 85 | @since v0.0.1 | 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 | self = [super init]; | 95 | self = [super init]; |
| 89 | if (self) { | 96 | if (self) { |
| 90 | _switchRate = NO; | 97 | _switchRate = NO; |
| 91 | - _videoId = videoId; | ||
| 92 | _activityId = activityId; | 98 | _activityId = activityId; |
| 99 | + _channelId = channelId; | ||
| 100 | + _videoId = @""; | ||
| 93 | _type = @"live"; | 101 | _type = @"live"; |
| 94 | _rate = @"2"; | 102 | _rate = @"2"; |
| 95 | [self getCacheURLSuccess:success failure:failure]; | 103 | [self getCacheURLSuccess:success failure:failure]; |
| 96 | } | 104 | } |
| 97 | return self; | 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,11 +119,12 @@ | ||
| 111 | _switchPlayer.delegate = self; | 119 | _switchPlayer.delegate = self; |
| 112 | _switchPlayer.playerView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); | 120 | _switchPlayer.playerView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); |
| 113 | _switchPlayer.playerView.contentMode = UIViewContentModeScaleAspectFit; | 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 | [_switchPlayer play]; | 123 | [_switchPlayer play]; |
| 116 | [self.view addSubview:self.switchPlayer.playerView]; | 124 | [self.view addSubview:self.switchPlayer.playerView]; |
| 117 | [self.view bringSubviewToFront:self.player.playerView]; | 125 | [self.view bringSubviewToFront:self.player.playerView]; |
| 118 | - }else{ | 126 | + } |
| 127 | + else{ | ||
| 119 | if(self.player){ // 切换视频 | 128 | if(self.player){ // 切换视频 |
| 120 | [self.player playWithURL:URL sameSource:NO]; | 129 | [self.player playWithURL:URL sameSource:NO]; |
| 121 | } | 130 | } |
| @@ -124,7 +133,7 @@ | @@ -124,7 +133,7 @@ | ||
| 124 | _player.delegate = self; | 133 | _player.delegate = self; |
| 125 | _player.playerView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); | 134 | _player.playerView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); |
| 126 | _player.playerView.contentMode = UIViewContentModeScaleAspectFit; | 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 | if(!_player.isPlaying){ | 137 | if(!_player.isPlaying){ |
| 129 | [_player play]; | 138 | [_player play]; |
| 130 | } | 139 | } |
| @@ -155,20 +164,29 @@ | @@ -155,20 +164,29 @@ | ||
| 155 | case CNLivePlayerDataTypeVod: | 164 | case CNLivePlayerDataTypeVod: |
| 156 | { | 165 | { |
| 157 | _type = @"vod"; | 166 | _type = @"vod"; |
| 167 | + _videoId = videoId; | ||
| 168 | + _activityId = @""; | ||
| 169 | + _channelId = @""; | ||
| 158 | } | 170 | } |
| 159 | break; | 171 | break; |
| 160 | case CNLivePlayerDataTypeLive: | 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 | break; | 182 | break; |
| 165 | case CNLivePlayerDataTypeAudio: | 183 | case CNLivePlayerDataTypeAudio: |
| 166 | { | 184 | { |
| 167 | _type = @"vod"; | 185 | _type = @"vod"; |
| 186 | + _videoId = videoId; | ||
| 168 | } | 187 | } |
| 169 | break; | 188 | break; |
| 170 | } | 189 | } |
| 171 | - _videoId = videoId; | ||
| 172 | [self getCacheURLSuccess:nil failure:nil]; | 190 | [self getCacheURLSuccess:nil failure:nil]; |
| 173 | 191 | ||
| 174 | } | 192 | } |
| @@ -306,7 +324,7 @@ | @@ -306,7 +324,7 @@ | ||
| 306 | }else if([_type isEqualToString:@"live"]){ | 324 | }else if([_type isEqualToString:@"live"]){ |
| 307 | //直播播放地址 | 325 | //直播播放地址 |
| 308 | __weak typeof(self) weakSelf = self; | 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 | __strong typeof(weakSelf) strongSelf = weakSelf; | 328 | __strong typeof(weakSelf) strongSelf = weakSelf; |
| 311 | if(!strongSelf){ | 329 | if(!strongSelf){ |
| 312 | return ; | 330 | return ; |
| @@ -566,7 +584,24 @@ | @@ -566,7 +584,24 @@ | ||
| 566 | case PLPlayerStatusPlaying: | 584 | case PLPlayerStatusPlaying: |
| 567 | { | 585 | { |
| 568 | if(player == self.switchPlayer&&_switchRate){ | 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 | playerState = CNLivePlayerStatusPlaying; | 606 | playerState = CNLivePlayerStatusPlaying; |
| 572 | } | 607 | } |
Example/CNLivePlayer.xcodeproj/project.pbxproj
| @@ -396,13 +396,11 @@ | @@ -396,13 +396,11 @@ | ||
| 396 | ); | 396 | ); |
| 397 | inputPaths = ( | 397 | inputPaths = ( |
| 398 | "${PODS_ROOT}/Target Support Files/Pods-CNLivePlayer_Example/Pods-CNLivePlayer_Example-frameworks.sh", | 398 | "${PODS_ROOT}/Target Support Files/Pods-CNLivePlayer_Example/Pods-CNLivePlayer_Example-frameworks.sh", |
| 399 | - "${BUILT_PRODUCTS_DIR}/CNLivePlayer/CNLivePlayer.framework", | ||
| 400 | "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework", | 399 | "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework", |
| 401 | "${PODS_ROOT}/PLPlayerKit/Pod/Library/PLPlayerKit.framework", | 400 | "${PODS_ROOT}/PLPlayerKit/Pod/Library/PLPlayerKit.framework", |
| 402 | ); | 401 | ); |
| 403 | name = "[CP] Embed Pods Frameworks"; | 402 | name = "[CP] Embed Pods Frameworks"; |
| 404 | outputPaths = ( | 403 | outputPaths = ( |
| 405 | - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLivePlayer.framework", | ||
| 406 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework", | 404 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework", |
| 407 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PLPlayerKit.framework", | 405 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PLPlayerKit.framework", |
| 408 | ); | 406 | ); |