Commit 40033d591b59d22355a1d9081340e26227de113e

Authored by zhangxiaowen
1 parent af90c4cc

no message

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
... ... @@ -10,12 +10,10 @@
10 10 * 播放器协议
11 11 */
12 12  
13   -#import <Foundation/Foundation.h>
  13 +#import <UIKit/UIKit.h>
14 14  
15 15 NS_ASSUME_NONNULL_BEGIN
16 16  
17   -@class UIView;
18   -@class UIImageView;
19 17 @class CNLivePlayer;
20 18 /**
21 19 发送队列的代理协议。
... ...
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 );
... ...