Commit de05ddb643dc8ed460e4cbfdd10f4143bd5f5efc
1 parent
df821378
no message
Showing
79 changed files
with
3205 additions
and
304 deletions
Too many changes to show.
To preserve performance only 79 of 82 files are displayed.
CNLivePlayer/Classes/Header/CNLivePlayerDefines.h
| @@ -326,4 +326,13 @@ typedef NS_ENUM(NSInteger, CNLiveRecordError) { | @@ -326,4 +326,13 @@ typedef NS_ENUM(NSInteger, CNLiveRecordError) { | ||
| 326 | }; | 326 | }; |
| 327 | 327 | ||
| 328 | 328 | ||
| 329 | +/* | ||
| 330 | + * 播放器类型 | ||
| 331 | + */ | ||
| 332 | +typedef NS_ENUM(NSUInteger, CNLiveStreamerType) { | ||
| 333 | + CNLiveStreamerVod, //视频 | ||
| 334 | + CNLiveStreamerAudio //音频 | ||
| 335 | + | ||
| 336 | +}; | ||
| 337 | + | ||
| 329 | #endif /* CNLivePlayerDefines_h */ | 338 | #endif /* CNLivePlayerDefines_h */ |
CNLivePlayer/Classes/Player/CNLivePlayerUrl.h
| @@ -8,9 +8,10 @@ | @@ -8,9 +8,10 @@ | ||
| 8 | 8 | ||
| 9 | #ifndef CNLivePlayerUrl_h | 9 | #ifndef CNLivePlayerUrl_h |
| 10 | #define CNLivePlayerUrl_h | 10 | #define CNLivePlayerUrl_h |
| 11 | +#import "CNLivePlayerManager.h" | ||
| 11 | 12 | ||
| 12 | -#pragma mark - 版本号 | ||
| 13 | -#define PlayerSDKVersion @"0.0.1" //播放器SDK版本 | 13 | +#pragma mark - 播放器版本号 |
| 14 | +#define PlayerSDKVersion @"0.0.1" | ||
| 14 | 15 | ||
| 15 | #pragma mark - 探针 | 16 | #pragma mark - 探针 |
| 16 | #define StatUrl [CNLivePlayerManager manager].isTestEnvironment?@"http://app.sta.cnlive.com/app.jpg": @"http://app.sta.cnlive.com/app.jpg" | 17 | #define StatUrl [CNLivePlayerManager manager].isTestEnvironment?@"http://app.sta.cnlive.com/app.jpg": @"http://app.sta.cnlive.com/app.jpg" |
CNLivePlayer/Classes/Streamer/CNLiveStreamerKit.h
| @@ -20,21 +20,48 @@ NS_ASSUME_NONNULL_BEGIN | @@ -20,21 +20,48 @@ NS_ASSUME_NONNULL_BEGIN | ||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | @interface CNLiveStreamerKit : NSObject | 22 | @interface CNLiveStreamerKit : NSObject |
| 23 | +#pragma mark - 初始化方法 | ||
| 23 | /** | 24 | /** |
| 24 | @abstract 初始化(不会打断其他后台的音乐播放) | 25 | @abstract 初始化(不会打断其他后台的音乐播放) |
| 25 | @warning 实例化的对象必须赋值给一个全局变量 | 26 | @warning 实例化的对象必须赋值给一个全局变量 |
| 26 | - @param mode YES:纯音频推流 | ||
| 27 | @warning 必传参数 | 27 | @warning 必传参数 |
| 28 | */ | 28 | */ |
| 29 | -- (instancetype)initWithDefaultConfigWithPureAudioMode:(BOOL)mode; | 29 | +- (instancetype)initPureAudioStreamerWithDefaultConfig; |
| 30 | 30 | ||
| 31 | /** | 31 | /** |
| 32 | @abstract 初始化(会打断其他后台的音乐播放) | 32 | @abstract 初始化(会打断其他后台的音乐播放) |
| 33 | @warning 实例化的对象必须赋值给一个全局变量 | 33 | @warning 实例化的对象必须赋值给一个全局变量 |
| 34 | - @param mode YES:纯音频推流 | ||
| 35 | @warning 必传参数 | 34 | @warning 必传参数 |
| 36 | */ | 35 | */ |
| 37 | -- (instancetype)initWithInterruptConfigWithPureAudioMode:(BOOL)mode; | 36 | +- (instancetype)initPureAudioStreamerWithInterruptConfig; |
| 37 | + | ||
| 38 | +/** | ||
| 39 | + @abstract 初始化(不会打断其他后台的音乐播放) | ||
| 40 | + @warning 实例化的对象必须赋值给一个全局变量 | ||
| 41 | + @warning 必传参数 | ||
| 42 | + */ | ||
| 43 | +- (instancetype)initVodStreamerWithDefaultConfig; | ||
| 44 | + | ||
| 45 | +/** | ||
| 46 | + @abstract 初始化(会打断其他后台的音乐播放) | ||
| 47 | + @warning 实例化的对象必须赋值给一个全局变量 | ||
| 48 | + @warning 必传参数 | ||
| 49 | + */ | ||
| 50 | +- (instancetype)initVodStreamerWithInterruptConfig; | ||
| 51 | + | ||
| 52 | +/** | ||
| 53 | + @abstract 普通推流初始化(不会打断其他后台的音乐播放) | ||
| 54 | + @warning 实例化的对象必须赋值给一个全局变量 | ||
| 55 | + @warning 必传参数 | ||
| 56 | + */ | ||
| 57 | +- (instancetype)initWithDefaultConfig:(BOOL)pureAudioMode; | ||
| 58 | + | ||
| 59 | +/** | ||
| 60 | + @abstract 普通推流初始化(会打断其他后台的音乐播放) | ||
| 61 | + @warning 实例化的对象必须赋值给一个全局变量 | ||
| 62 | + @warning 必传参数 | ||
| 63 | + */ | ||
| 64 | +- (instancetype)initWithInterruptConfig:(BOOL)pureAudioMode; | ||
| 38 | 65 | ||
| 39 | /** | 66 | /** |
| 40 | @abstract 活动ID,确保SP下的唯一性 | 67 | @abstract 活动ID,确保SP下的唯一性 |
| @@ -55,7 +82,7 @@ NS_ASSUME_NONNULL_BEGIN | @@ -55,7 +82,7 @@ NS_ASSUME_NONNULL_BEGIN | ||
| 55 | @property (nonatomic, assign) BOOL logPrintEnable; | 82 | @property (nonatomic, assign) BOOL logPrintEnable; |
| 56 | 83 | ||
| 57 | /** | 84 | /** |
| 58 | - @abstract 屏幕方向,0:垂直即竖屏 /1:水平即横屏 ,默认为0 | 85 | + @abstract 屏幕方向,0:垂直即竖屏 1:水平即横屏 ,默认为0 |
| 59 | */ | 86 | */ |
| 60 | @property (nonatomic, assign) BOOL isHorizontalScreen; | 87 | @property (nonatomic, assign) BOOL isHorizontalScreen; |
| 61 | 88 | ||
| @@ -65,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN | @@ -65,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN | ||
| 65 | @property (nonatomic, strong) NSString *activityName; | 92 | @property (nonatomic, strong) NSString *activityName; |
| 66 | 93 | ||
| 67 | /** | 94 | /** |
| 68 | - @abstract 活动状态,0:未开始 /1:已开始 /3:已结束 /4 已下线,默认为0(非必传) | 95 | + @abstract 活动状态,0:未开始 1:已开始 3:已结束 4:已下线,默认为0(非必传) |
| 69 | */ | 96 | */ |
| 70 | @property (nonatomic, strong) NSString *activityStatus; | 97 | @property (nonatomic, strong) NSString *activityStatus; |
| 71 | 98 | ||
| @@ -124,22 +151,6 @@ NS_ASSUME_NONNULL_BEGIN | @@ -124,22 +151,6 @@ NS_ASSUME_NONNULL_BEGIN | ||
| 124 | */ | 151 | */ |
| 125 | FOUNDATION_EXPORT NSString *const CNLiveServiceConnectBreakNotification NS_AVAILABLE_IOS(7_0); | 152 | FOUNDATION_EXPORT NSString *const CNLiveServiceConnectBreakNotification NS_AVAILABLE_IOS(7_0); |
| 126 | 153 | ||
| 127 | -#pragma mark - 普通推流 | ||
| 128 | - | ||
| 129 | -/** | ||
| 130 | - @abstract 初始化(不会打断其他后台的音乐播放) | ||
| 131 | - @param mode YES:纯音频推流 | ||
| 132 | - @warning 实例化的对象必须赋值给一个全局变量 | ||
| 133 | - */ | ||
| 134 | -- (instancetype)initWithDefaultConfigWithPureAudioMode:(BOOL)mode; | ||
| 135 | - | ||
| 136 | -/** | ||
| 137 | - @abstract 初始化(会打断其他后台的音乐播放) | ||
| 138 | - @param mode YES:纯音频推流 | ||
| 139 | - @warning 实例化的对象必须赋值给一个全局变量 | ||
| 140 | - */ | ||
| 141 | -- (instancetype)initWithInterruptConfigWithPureAudioMode:(BOOL)mode; | ||
| 142 | - | ||
| 143 | /** | 154 | /** |
| 144 | * 预览视图 | 155 | * 预览视图 |
| 145 | */ | 156 | */ |
| @@ -213,7 +224,7 @@ FOUNDATION_EXPORT NSString *const CNLiveServiceConnectBreakNotification NS_AVAIL | @@ -213,7 +224,7 @@ FOUNDATION_EXPORT NSString *const CNLiveServiceConnectBreakNotification NS_AVAIL | ||
| 213 | @abstract 采集及编码视频帧率 (开始采集前设置有效) | 224 | @abstract 采集及编码视频帧率 (开始采集前设置有效) |
| 214 | @discussion video frame per seconds 有效范围[1~30], 超出范围会取边界有效值 | 225 | @discussion video frame per seconds 有效范围[1~30], 超出范围会取边界有效值 |
| 215 | @discussion 默认值为15 */ | 226 | @discussion 默认值为15 */ |
| 216 | -@property (nonatomic, assign) int videoFPS; | 227 | +@property (nonatomic, assign) int videoFPS; |
| 217 | 228 | ||
| 218 | /** | 229 | /** |
| 219 | @abstract 摄像头位置 | 230 | @abstract 摄像头位置 |
| @@ -227,7 +238,7 @@ FOUNDATION_EXPORT NSString *const CNLiveServiceConnectBreakNotification NS_AVAIL | @@ -227,7 +238,7 @@ FOUNDATION_EXPORT NSString *const CNLiveServiceConnectBreakNotification NS_AVAIL | ||
| 227 | @return AVCaptureDevice* 预览开始前调用返回为nil,开始预览后,返回当前正在使用的摄像头 | 238 | @return AVCaptureDevice* 预览开始前调用返回为nil,开始预览后,返回当前正在使用的摄像头 |
| 228 | @warning 请勿修改摄像头的像素格式,帧率,分辨率等参数,修改后会导致推流工作异常或崩溃 | 239 | @warning 请勿修改摄像头的像素格式,帧率,分辨率等参数,修改后会导致推流工作异常或崩溃 |
| 229 | */ | 240 | */ |
| 230 | -- (AVCaptureDevice *) getCurrentCameraDevices; | 241 | +- (AVCaptureDevice *)getCurrentCameraDevices; |
| 231 | 242 | ||
| 232 | /** | 243 | /** |
| 233 | @abstract 采集设备状态 | 244 | @abstract 采集设备状态 |
| @@ -243,7 +254,7 @@ FOUNDATION_EXPORT NSString *const CNLiveCaptureStateDidChangeNotification NS_AVA | @@ -243,7 +254,7 @@ FOUNDATION_EXPORT NSString *const CNLiveCaptureStateDidChangeNotification NS_AVA | ||
| 243 | */ | 254 | */ |
| 244 | @property (nonatomic, readonly) CNLiveStreamState streamState; | 255 | @property (nonatomic, readonly) CNLiveStreamState streamState; |
| 245 | 256 | ||
| 246 | -FOUNDATION_EXPORT NSString *const CNLiveStreamStateDidChangeNotification NS_AVAILABLE_IOS(7_0); | 257 | +FOUNDATION_EXPORT NSString *const CNLiveStreamerStateDidChangeNotification NS_AVAILABLE_IOS(7_0); |
| 247 | 258 | ||
| 248 | /** | 259 | /** |
| 249 | * @abstract 推流错误码,用于指示推流失败的原因 | 260 | * @abstract 推流错误码,用于指示推流失败的原因 |
| @@ -257,7 +268,7 @@ FOUNDATION_EXPORT NSString *const CNLiveStreamStateDidChangeNotification NS_AVAI | @@ -257,7 +268,7 @@ FOUNDATION_EXPORT NSString *const CNLiveStreamStateDidChangeNotification NS_AVAI | ||
| 257 | @discussion 若filter 为GPUImageFilter的实例,则使用该滤镜做处理 | 268 | @discussion 若filter 为GPUImageFilter的实例,则使用该滤镜做处理 |
| 258 | @discussion filter 也可以是GPUImageFilterGroup的实例,可以将多个滤镜组合 | 269 | @discussion filter 也可以是GPUImageFilterGroup的实例,可以将多个滤镜组合 |
| 259 | */ | 270 | */ |
| 260 | -- (void)setupFilter:(GPUImageOutput<GPUImageInput>*) filter; | 271 | +- (void)setupFilter:(GPUImageOutput<GPUImageInput>*)filter; |
| 261 | 272 | ||
| 262 | #pragma mark - reconnect | 273 | #pragma mark - reconnect |
| 263 | /** | 274 | /** |
| @@ -288,7 +299,7 @@ FOUNDATION_EXPORT NSString *const CNLiveStreamStateDidChangeNotification NS_AVAI | @@ -288,7 +299,7 @@ FOUNDATION_EXPORT NSString *const CNLiveStreamStateDidChangeNotification NS_AVAI | ||
| 288 | CNLiveStreamErrorCode_CODEC_OPEN_FAILED、 | 299 | CNLiveStreamErrorCode_CODEC_OPEN_FAILED、 |
| 289 | CNLiveStreamErrorCode_ABNORMAL 时为可重连状态; | 300 | CNLiveStreamErrorCode_ABNORMAL 时为可重连状态; |
| 290 | */ | 301 | */ |
| 291 | -FOUNDATION_EXPORT NSString *const CNLiveStreamReconnectStatusChangedNotification NS_AVAILABLE_IOS(7_0); | 302 | +FOUNDATION_EXPORT NSString *const CNLiveStreamerReconnectStatusChangedNotification NS_AVAILABLE_IOS(7_0); |
| 292 | 303 | ||
| 293 | /** | 304 | /** |
| 294 | @abstract 切换摄像头 | 305 | @abstract 切换摄像头 |
| @@ -327,7 +338,7 @@ FOUNDATION_EXPORT NSString *const CNLiveStreamReconnectStatusChangedNotification | @@ -327,7 +338,7 @@ FOUNDATION_EXPORT NSString *const CNLiveStreamReconnectStatusChangedNotification | ||
| 327 | @discussion 需要访问摄像头和麦克风的权限,若授权失败,其他API都会拒绝服务 | 338 | @discussion 需要访问摄像头和麦克风的权限,若授权失败,其他API都会拒绝服务 |
| 328 | @warning: 开始推流前必须先启动预览 | 339 | @warning: 开始推流前必须先启动预览 |
| 329 | */ | 340 | */ |
| 330 | -- (void)startPreview:(UIView*) view; | 341 | +- (void)startPreview:(UIView *)view; |
| 331 | 342 | ||
| 332 | /** | 343 | /** |
| 333 | @abstract 停止预览,停止采集设备,并清理会话 | 344 | @abstract 停止预览,停止采集设备,并清理会话 |
| @@ -392,25 +403,25 @@ FOUNDATION_EXPORT NSString *const CNLiveStreamReconnectStatusChangedNotification | @@ -392,25 +403,25 @@ FOUNDATION_EXPORT NSString *const CNLiveStreamReconnectStatusChangedNotification | ||
| 392 | @param orie 旋转到目标朝向, 需要从demo中获取UI的朝向传入 | 403 | @param orie 旋转到目标朝向, 需要从demo中获取UI的朝向传入 |
| 393 | @discussion 采集到的图像的朝向还是和启动时的朝向一致 | 404 | @discussion 采集到的图像的朝向还是和启动时的朝向一致 |
| 394 | */ | 405 | */ |
| 395 | -- (void) rotatePreviewTo: (UIInterfaceOrientation) orie; | 406 | +- (void)rotatePreviewTo:(UIInterfaceOrientation) orie; |
| 396 | 407 | ||
| 397 | /** | 408 | /** |
| 398 | @abstract 根据UI的朝向旋转推流画面 | 409 | @abstract 根据UI的朝向旋转推流画面 |
| 399 | @param orie 旋转到目标朝向, 需要从demo中获取UI的朝向传入 | 410 | @param orie 旋转到目标朝向, 需要从demo中获取UI的朝向传入 |
| 400 | */ | 411 | */ |
| 401 | -- (void) rotateStreamTo: (UIInterfaceOrientation) orie; | 412 | +- (void)rotateStreamTo:(UIInterfaceOrientation) orie; |
| 402 | 413 | ||
| 403 | /** | 414 | /** |
| 404 | @abstract 当前采集设备是否支持自动变焦 | 415 | @abstract 当前采集设备是否支持自动变焦 |
| 405 | @param point 相机对焦的位置 | 416 | @param point 相机对焦的位置 |
| 406 | */ | 417 | */ |
| 407 | -- (void)focusAtPoint:(CGPoint )point; | 418 | +- (void)focusAtPoint:(CGPoint)point; |
| 408 | 419 | ||
| 409 | /** | 420 | /** |
| 410 | @abstract 当前采集设备是否支持自动曝光 | 421 | @abstract 当前采集设备是否支持自动曝光 |
| 411 | @param point 相机曝光的位置 | 422 | @param point 相机曝光的位置 |
| 412 | */ | 423 | */ |
| 413 | -- (void)exposureAtPoint:(CGPoint )point; | 424 | +- (void)exposureAtPoint:(CGPoint)point; |
| 414 | 425 | ||
| 415 | /** | 426 | /** |
| 416 | @abstract 触摸缩放因子 | 427 | @abstract 触摸缩放因子 |
CNLivePlayer/Classes/Streamer/CNLiveStreamerKit.m
| @@ -18,21 +18,27 @@ | @@ -18,21 +18,27 @@ | ||
| 18 | #import "CNLiveBgmPlayer.h" | 18 | #import "CNLiveBgmPlayer.h" |
| 19 | #import "CNLivePlayerManager.h" | 19 | #import "CNLivePlayerManager.h" |
| 20 | #import "CNLiveStreamerTools.h" | 20 | #import "CNLiveStreamerTools.h" |
| 21 | +#import "CNLivePlayerNetworkManager.h" | ||
| 22 | + | ||
| 23 | +#import "CNLiveStreamerUrl.h" | ||
| 24 | + | ||
| 25 | +#define Host @"bc.cnlive.com" | ||
| 26 | +#define Port 65432 | ||
| 21 | 27 | ||
| 22 | //采集状态通知 | 28 | //采集状态通知 |
| 23 | NSString * const CNLiveCaptureStateDidChangeNotification = @"CNLiveCaptureStateDidChangeNotification"; | 29 | NSString * const CNLiveCaptureStateDidChangeNotification = @"CNLiveCaptureStateDidChangeNotification"; |
| 24 | 30 | ||
| 25 | //推流状态通知 | 31 | //推流状态通知 |
| 26 | -NSString * const CNLiveStreamStateDidChangeNotification = @"CNLiveStreamStateDidChangeNotification"; | 32 | +NSString * const CNLiveStreamerStateDidChangeNotification = @"CNLiveStreamerStateDidChangeNotification"; |
| 27 | 33 | ||
| 28 | //自动重连失败通知 | 34 | //自动重连失败通知 |
| 29 | -NSString * const CNLiveStreamReconnectStatusChangedNotification = @"CNLiveStreamReconnectStatusChangedNotification"; | 35 | +NSString * const CNLiveStreamerReconnectStatusChangedNotification = @"CNLiveStreamerReconnectStatusChangedNotification"; |
| 30 | 36 | ||
| 31 | //获取直播时长通知 | 37 | //获取直播时长通知 |
| 32 | -NSString * const CNLiveStreamGetDurationNotification = @"CNLiveStreamGetDurationNotification"; | 38 | +NSString * const CNLiveStreamerGetDurationNotification = @"CNLiveStreamerGetDurationNotification"; |
| 33 | 39 | ||
| 34 | //收到消息通知 | 40 | //收到消息通知 |
| 35 | -NSString * const MsgToolsStreamReceiveNotification = @"CNLiveMsgToolsPlayerReceiveNotification"; | 41 | +NSString * const CNLiveStreamerMsgReceiveNotification = @"CNLiveMsgToolsPlayerReceiveNotification"; |
| 36 | 42 | ||
| 37 | //由服务端断开 | 43 | //由服务端断开 |
| 38 | NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectBreakNotification"; | 44 | NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectBreakNotification"; |
| @@ -42,7 +48,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -42,7 +48,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 42 | BOOL _activitySuccess; //活动是否创建成功 | 48 | BOOL _activitySuccess; //活动是否创建成功 |
| 43 | BOOL _isCNLiveStreaming; //是否为视讯云平台推流 | 49 | BOOL _isCNLiveStreaming; //是否为视讯云平台推流 |
| 44 | 50 | ||
| 45 | - BOOL _noti; | ||
| 46 | BOOL _pureAudioMode; //是否为纯音频推流 | 51 | BOOL _pureAudioMode; //是否为纯音频推流 |
| 47 | 52 | ||
| 48 | int _autoRetryCnt; //记录重试次数 | 53 | int _autoRetryCnt; //记录重试次数 |
| @@ -54,6 +59,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -54,6 +59,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 54 | NSString *_contentId; | 59 | NSString *_contentId; |
| 55 | NSString *_roomId; | 60 | NSString *_roomId; |
| 56 | int _originalStatus; //原始状态 | 61 | int _originalStatus; //原始状态 |
| 62 | + | ||
| 57 | CNLiveStreamerManager *_manager; | 63 | CNLiveStreamerManager *_manager; |
| 58 | 64 | ||
| 59 | BOOL _enterBackground; | 65 | BOOL _enterBackground; |
| @@ -74,66 +80,132 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -74,66 +80,132 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 74 | @end | 80 | @end |
| 75 | 81 | ||
| 76 | @implementation CNLiveStreamerKit | 82 | @implementation CNLiveStreamerKit |
| 83 | +#pragma mark - 初始化方法 | ||
| 77 | /** | 84 | /** |
| 78 | - @abstract 初始化(不会打断其他后台的音乐播放) | 85 | + @abstract 纯音频推流初始化(不会打断其他后台的音乐播放) |
| 79 | @warning 实例化的对象必须赋值给一个全局变量 | 86 | @warning 实例化的对象必须赋值给一个全局变量 |
| 80 | - @param mode YES:纯音频推流 | ||
| 81 | @warning 必传参数 | 87 | @warning 必传参数 |
| 82 | */ | 88 | */ |
| 83 | -- (instancetype)initWithDefaultConfigWithPureAudioMode:(BOOL)mode{ | 89 | +- (instancetype)initPureAudioStreamerWithDefaultConfig{ |
| 84 | if (self = [super init]) { | 90 | if (self = [super init]) { |
| 85 | _logPrintEnable = YES; | 91 | _logPrintEnable = YES; |
| 86 | - _pureAudioMode = mode; | 92 | + _pureAudioMode = YES; |
| 87 | _autoRetryCnt = 0; | 93 | _autoRetryCnt = 0; |
| 88 | _autoRetryDelay = 2.0; | 94 | _autoRetryDelay = 2.0; |
| 89 | 95 | ||
| 90 | -// _parameter = [[NSMutableDictionary alloc] init]; | ||
| 91 | - [self setStreamerCfgWithInterrupt:NO]; | ||
| 92 | -// | ||
| 93 | -// //视讯云直播,注册前后台切换通知 | ||
| 94 | -// [self addStatusChangedObservers]; | 96 | + _parameter = [[NSMutableDictionary alloc] init]; |
| 97 | + [self setStreamerWithConfig:NO]; | ||
| 98 | + | ||
| 99 | + //视讯云直播,注册前后台切换通知 | ||
| 100 | + [self addStatusChangedObservers]; | ||
| 95 | 101 | ||
| 96 | } | 102 | } |
| 97 | return self; | 103 | return self; |
| 98 | } | 104 | } |
| 99 | 105 | ||
| 100 | /** | 106 | /** |
| 101 | - @abstract 初始化(会打断其他后台的音乐播放) | 107 | + @abstract 纯音频推流初始化(会打断其他后台的音乐播放) |
| 102 | @warning 实例化的对象必须赋值给一个全局变量 | 108 | @warning 实例化的对象必须赋值给一个全局变量 |
| 103 | - @param mode YES:纯音频推流 | ||
| 104 | @warning 必传参数 | 109 | @warning 必传参数 |
| 105 | */ | 110 | */ |
| 106 | -- (instancetype)initWithInterruptConfigWithPureAudioMode:(BOOL)mode{ | 111 | +- (instancetype)initPureAudioStreamerWithInterruptConfig{ |
| 107 | if (self = [super init]) { | 112 | if (self = [super init]) { |
| 108 | _logPrintEnable = YES; | 113 | _logPrintEnable = YES; |
| 109 | - _pureAudioMode = mode; | 114 | + _pureAudioMode = YES; |
| 110 | _autoRetryCnt = 0; | 115 | _autoRetryCnt = 0; |
| 111 | _autoRetryDelay = 2.0; | 116 | _autoRetryDelay = 2.0; |
| 112 | 117 | ||
| 113 | -// _parameter = [[NSMutableDictionary alloc] init]; | ||
| 114 | - [self setStreamerCfgWithInterrupt:YES]; | ||
| 115 | -// | ||
| 116 | -// //视讯云直播,注册前后台切换通知 | ||
| 117 | -// [self addStatusChangedObservers]; | 118 | + _parameter = [[NSMutableDictionary alloc] init]; |
| 119 | + [self setStreamerWithConfig:NO]; | ||
| 120 | + | ||
| 121 | + //视讯云直播,注册前后台切换通知 | ||
| 122 | + [self addStatusChangedObservers]; | ||
| 123 | + | ||
| 124 | + } | ||
| 125 | + return self; | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +/** | ||
| 129 | + @abstract 音视频推流初始化(不会打断其他后台的音乐播放) | ||
| 130 | + @warning 实例化的对象必须赋值给一个全局变量 | ||
| 131 | + @warning 必传参数 | ||
| 132 | + */ | ||
| 133 | +- (instancetype)initVodStreamerWithDefaultConfig{ | ||
| 134 | + if (self = [super init]) { | ||
| 135 | + _logPrintEnable = YES; | ||
| 136 | + _pureAudioMode = NO; | ||
| 137 | + _autoRetryCnt = 0; | ||
| 138 | + _autoRetryDelay = 2.0; | ||
| 139 | + | ||
| 140 | + _parameter = [[NSMutableDictionary alloc] init]; | ||
| 141 | + [self setStreamerWithConfig:NO]; | ||
| 142 | + | ||
| 143 | + //视讯云直播,注册前后台切换通知 | ||
| 144 | + [self addStatusChangedObservers]; | ||
| 118 | 145 | ||
| 119 | } | 146 | } |
| 120 | return self; | 147 | return self; |
| 121 | } | 148 | } |
| 122 | 149 | ||
| 123 | -#pragma mark - 初始化KSY | ||
| 124 | -- (void)setStreamerCfgWithInterrupt:(BOOL)interrupt { | 150 | +/** |
| 151 | + @abstract 音视频推流初始化(会打断其他后台的音乐播放) | ||
| 152 | + @warning 实例化的对象必须赋值给一个全局变量 | ||
| 153 | + @warning 必传参数 | ||
| 154 | + */ | ||
| 155 | +- (instancetype)initVodStreamerWithInterruptConfig{ | ||
| 156 | + if (self = [super init]) { | ||
| 157 | + _logPrintEnable = YES; | ||
| 158 | + _pureAudioMode = NO; | ||
| 159 | + _autoRetryCnt = 0; | ||
| 160 | + _autoRetryDelay = 2.0; | ||
| 161 | + | ||
| 162 | + _parameter = [[NSMutableDictionary alloc] init]; | ||
| 163 | + [self setStreamerWithConfig:NO]; | ||
| 164 | + | ||
| 165 | + //视讯云直播,注册前后台切换通知 | ||
| 166 | + [self addStatusChangedObservers]; | ||
| 167 | + | ||
| 168 | + } | ||
| 169 | + return self; | ||
| 170 | +} | ||
| 171 | + | ||
| 172 | +//普通推流 | ||
| 173 | +//不会打断其他后台音乐 | ||
| 174 | +- (instancetype)initWithDefaultConfig:(BOOL)pureAudioMode { | ||
| 175 | + if (self = [super init]) { | ||
| 176 | + _logPrintEnable = YES; | ||
| 177 | + _pureAudioMode = pureAudioMode; | ||
| 178 | + [self setStreamerWithConfig:NO]; | ||
| 179 | + } | ||
| 180 | + return self; | ||
| 181 | +} | ||
| 182 | + | ||
| 183 | +//会打断其他后台音乐 | ||
| 184 | +- (instancetype)initWithInterruptConfig:(BOOL)pureAudioMode { | ||
| 185 | + if (self = [super init]) { | ||
| 186 | + _logPrintEnable = YES; | ||
| 187 | + _pureAudioMode = pureAudioMode; | ||
| 188 | + [self setStreamerWithConfig:YES]; | ||
| 189 | + } | ||
| 190 | + return self; | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +#pragma mark - 初始化推流器 | ||
| 194 | +- (void)setStreamerWithConfig:(BOOL)interrupt { | ||
| 125 | _manager = [CNLiveStreamerManager manager]; | 195 | _manager = [CNLiveStreamerManager manager]; |
| 126 | 196 | ||
| 127 | [UIApplication sharedApplication].idleTimerDisabled = YES; | 197 | [UIApplication sharedApplication].idleTimerDisabled = YES; |
| 128 | 198 | ||
| 129 | - if (interrupt) { //初始化金山kit | 199 | + //初始化金山kit |
| 200 | + if (interrupt) { | ||
| 130 | _manager.kit = [[KSYGPUStreamerKit alloc] initWithInterruptCfg]; | 201 | _manager.kit = [[KSYGPUStreamerKit alloc] initWithInterruptCfg]; |
| 131 | } | 202 | } |
| 132 | else { | 203 | else { |
| 133 | _manager.kit = [[KSYGPUStreamerKit alloc] initWithDefaultCfg]; | 204 | _manager.kit = [[KSYGPUStreamerKit alloc] initWithDefaultCfg]; |
| 134 | } | 205 | } |
| 135 | 206 | ||
| 136 | - if (_pureAudioMode) { //是否为纯音频推流 | 207 | + //是否为纯音频推流 |
| 208 | + if (_pureAudioMode) { | ||
| 137 | [_manager.kit.aCapDev startCapture]; | 209 | [_manager.kit.aCapDev startCapture]; |
| 138 | _manager.kit.streamerBase.bWithVideo = NO; | 210 | _manager.kit.streamerBase.bWithVideo = NO; |
| 139 | 211 | ||
| @@ -158,21 +230,16 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -158,21 +230,16 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 158 | }; | 230 | }; |
| 159 | 231 | ||
| 160 | //添加通知 | 232 | //添加通知 |
| 161 | -// [self addKSYObservers]; | 233 | + [self addKSYObservers]; |
| 162 | 234 | ||
| 163 | } | 235 | } |
| 164 | 236 | ||
| 165 | #pragma mark - 通知 | 237 | #pragma mark - 通知 |
| 166 | - (void)addKSYObservers { | 238 | - (void)addKSYObservers { |
| 167 | - if (_noti) return; | ||
| 168 | - _noti = YES; | ||
| 169 | - | ||
| 170 | //采集状态通知 | 239 | //采集状态通知 |
| 171 | - [[NSNotificationCenter defaultCenter] addObserver:self | ||
| 172 | - selector:@selector(onCaptureStateChange) | 240 | + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onCaptureStateChange) |
| 173 | name:KSYCaptureStateDidChangeNotification | 241 | name:KSYCaptureStateDidChangeNotification |
| 174 | object:nil]; | 242 | object:nil]; |
| 175 | - | ||
| 176 | //推流状态通知 | 243 | //推流状态通知 |
| 177 | [[NSNotificationCenter defaultCenter] addObserver:self | 244 | [[NSNotificationCenter defaultCenter] addObserver:self |
| 178 | selector:@selector(onStreamStateChange) | 245 | selector:@selector(onStreamStateChange) |
| @@ -219,7 +286,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -219,7 +286,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 219 | } | 286 | } |
| 220 | _streamState = (CNLiveStreamState)_manager.kit.streamerBase.streamState; | 287 | _streamState = (CNLiveStreamState)_manager.kit.streamerBase.streamState; |
| 221 | 288 | ||
| 222 | - [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamStateDidChangeNotification | 289 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerStateDidChangeNotification |
| 223 | object:nil | 290 | object:nil |
| 224 | userInfo:nil]; | 291 | userInfo:nil]; |
| 225 | 292 | ||
| @@ -227,7 +294,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -227,7 +294,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 227 | 294 | ||
| 228 | if (_autoRetryCnt < 3) { | 295 | if (_autoRetryCnt < 3) { |
| 229 | _reconnectStatus = CNLiveReconnectStatusSuccess; | 296 | _reconnectStatus = CNLiveReconnectStatusSuccess; |
| 230 | - [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamReconnectStatusChangedNotification | 297 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerReconnectStatusChangedNotification |
| 231 | object:nil | 298 | object:nil |
| 232 | userInfo:nil]; | 299 | userInfo:nil]; |
| 233 | [self recoverReconnectConfig]; | 300 | [self recoverReconnectConfig]; |
| @@ -240,7 +307,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -240,7 +307,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 240 | _isRecording = NO; | 307 | _isRecording = NO; |
| 241 | 308 | ||
| 242 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 309 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 243 | -// [self requestStopStreamerWithInfo:[NSString stringWithFormat:@"KSY error:%@",[_manager.kit.streamerBase getKSYStreamErrorCodeName:_manager.kit.streamerBase.streamErrorCode]] timeString:timeString]; | 310 | + [self requestStopStreamerWithInfo:[NSString stringWithFormat:@"KSY error:%@",[_manager.kit.streamerBase getKSYStreamErrorCodeName:_manager.kit.streamerBase.streamErrorCode]] timeString:timeString]; |
| 244 | }]; | 311 | }]; |
| 245 | 312 | ||
| 246 | [CNLiveStreamerTools errorStat:@"推流出错" activityId:_activityId]; | 313 | [CNLiveStreamerTools errorStat:@"推流出错" activityId:_activityId]; |
| @@ -249,7 +316,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -249,7 +316,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 249 | if (_retryFailed && _isCNLiveStreaming) { | 316 | if (_retryFailed && _isCNLiveStreaming) { |
| 250 | 317 | ||
| 251 | _reconnectStatus = CNLiveReconnectStatusFailed; | 318 | _reconnectStatus = CNLiveReconnectStatusFailed; |
| 252 | - [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamReconnectStatusChangedNotification | 319 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerReconnectStatusChangedNotification |
| 253 | object:nil | 320 | object:nil |
| 254 | userInfo:nil]; | 321 | userInfo:nil]; |
| 255 | [self recoverReconnectConfig]; | 322 | [self recoverReconnectConfig]; |
| @@ -263,11 +330,8 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -263,11 +330,8 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 263 | _manager.kit.streamerBase.streamErrorCode == KSYStreamErrorCode_DNS_Parse_failed || | 330 | _manager.kit.streamerBase.streamErrorCode == KSYStreamErrorCode_DNS_Parse_failed || |
| 264 | _manager.kit.streamerBase.streamErrorCode == KSYStreamErrorCode_CODEC_OPEN_FAILED) { | 331 | _manager.kit.streamerBase.streamErrorCode == KSYStreamErrorCode_CODEC_OPEN_FAILED) { |
| 265 | 332 | ||
| 266 | - // NSLog(@"ksyError---->autoRetryCnt:%d----initiativeRetry:%@----reteying:%@----retryFailed:%@", _autoRetryCnt, _initiativeRetry ? @"YES" : @"NO", _reteying?@"YES":@"NO", _retryFailed?@"YES":@"NO"); | ||
| 267 | - | ||
| 268 | if (_autoRetryCnt>0 && !_initiativeRetry) { | 333 | if (_autoRetryCnt>0 && !_initiativeRetry) { |
| 269 | [self tryReconnect]; | 334 | [self tryReconnect]; |
| 270 | - // NSLog(@"CNLiveGPUStreamerKit-->reconnect ----- 金山ERROR"); | ||
| 271 | 335 | ||
| 272 | } | 336 | } |
| 273 | } | 337 | } |
| @@ -283,12 +347,12 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -283,12 +347,12 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 283 | if (![CNLiveStreamerTools isEmptyString:PLAYER_AppID] && _enterBackground == NO && _isRecording) { | 347 | if (![CNLiveStreamerTools isEmptyString:PLAYER_AppID] && _enterBackground == NO && _isRecording) { |
| 284 | _streamErrorCode = CNLiveStreamErrorCode_ABNORMAL; | 348 | _streamErrorCode = CNLiveStreamErrorCode_ABNORMAL; |
| 285 | _streamState = CNLiveStreamStateError; | 349 | _streamState = CNLiveStreamStateError; |
| 286 | - [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamStateDidChangeNotification | 350 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerStateDidChangeNotification |
| 287 | object:nil | 351 | object:nil |
| 288 | userInfo:nil]; | 352 | userInfo:nil]; |
| 289 | 353 | ||
| 290 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 354 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 291 | -// [self requestStopStreamerWithInfo:@"CNLiveStreamErrorCode_ABNORMAL_2" timeString:timeString]; | 355 | + [self requestStopStreamerWithInfo:@"CNLiveStreamErrorCode_ABNORMAL_2" timeString:timeString]; |
| 292 | }]; | 356 | }]; |
| 293 | 357 | ||
| 294 | _isRecording = NO; | 358 | _isRecording = NO; |
| @@ -297,6 +361,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -297,6 +361,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 297 | } | 361 | } |
| 298 | } | 362 | } |
| 299 | } else { | 363 | } else { |
| 364 | + | ||
| 300 | } | 365 | } |
| 301 | 366 | ||
| 302 | NSLog(@"CNLiveGPUStreamerKit-->推流工作状态发生变化CNLiveStreamState:%ld", (unsigned long)self.streamState); | 367 | NSLog(@"CNLiveGPUStreamerKit-->推流工作状态发生变化CNLiveStreamState:%ld", (unsigned long)self.streamState); |
| @@ -304,9 +369,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -304,9 +369,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 304 | } | 369 | } |
| 305 | 370 | ||
| 306 | - (void)enterBackground { | 371 | - (void)enterBackground { |
| 307 | - // [_manager.kit.aCapDev stopCapture]; | ||
| 308 | - // NSLog(@"CNLiveGPUStreamerKit-->关闭音频采集状态"); | ||
| 309 | - | ||
| 310 | /** | 372 | /** |
| 311 | * 视讯云平台:推流过程中退到后台或者锁屏情况下,需将活动状态改为“-2”,以便观众端收到主播离开的消息 | 373 | * 视讯云平台:推流过程中退到后台或者锁屏情况下,需将活动状态改为“-2”,以便观众端收到主播离开的消息 |
| 312 | */ | 374 | */ |
| @@ -320,7 +382,8 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -320,7 +382,8 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 320 | }]; | 382 | }]; |
| 321 | 383 | ||
| 322 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 384 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 323 | -// [self requestStopStreamerWithInfo:@"CNLiveStreamErrorCode_EnterBackground" timeString:timeString]; | 385 | + [self requestStopStreamerWithInfo:@"CNLiveStreamErrorCode_EnterBackground" timeString:timeString]; |
| 386 | + | ||
| 324 | }]; | 387 | }]; |
| 325 | } | 388 | } |
| 326 | 389 | ||
| @@ -336,15 +399,15 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -336,15 +399,15 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 336 | * 视讯云平台:APP返回前台重新将活动状态改为“1”,若失败将推流状态改为error,并通知开发者 | 399 | * 视讯云平台:APP返回前台重新将活动状态改为“1”,若失败将推流状态改为error,并通知开发者 |
| 337 | */ | 400 | */ |
| 338 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 401 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 339 | -// [self requestStartStreamer:NULL failure:^(NSDictionary *errorDic) { | ||
| 340 | -// | ||
| 341 | -// _streamErrorCode = CNLiveStreamErrorCode_ABNORMAL; | ||
| 342 | -// _streamState = CNLiveStreamStateError; | ||
| 343 | -// | ||
| 344 | -// [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamStateDidChangeNotification | ||
| 345 | -// object:nil | ||
| 346 | -// userInfo:nil]; | ||
| 347 | -// } timeString:timeString]; | 402 | + [self requestStartStreamer:NULL failure:^(NSDictionary *errorDic) { |
| 403 | + | ||
| 404 | + _streamErrorCode = CNLiveStreamErrorCode_ABNORMAL; | ||
| 405 | + _streamState = CNLiveStreamStateError; | ||
| 406 | + | ||
| 407 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerStateDidChangeNotification | ||
| 408 | + object:nil | ||
| 409 | + userInfo:nil]; | ||
| 410 | + } timeString:timeString]; | ||
| 348 | }]; | 411 | }]; |
| 349 | } | 412 | } |
| 350 | 413 | ||
| @@ -416,9 +479,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -416,9 +479,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 416 | _manager.kit.videoOrientation = uiOrien; | 479 | _manager.kit.videoOrientation = uiOrien; |
| 417 | } | 480 | } |
| 418 | 481 | ||
| 419 | -#pragma mark - | ||
| 420 | #pragma mark - mirror & rotate | 482 | #pragma mark - mirror & rotate |
| 421 | - | ||
| 422 | //预览设置成镜像模式 | 483 | //预览设置成镜像模式 |
| 423 | - (void)setPreviewMirrored:(BOOL)previewMirrored { | 484 | - (void)setPreviewMirrored:(BOOL)previewMirrored { |
| 424 | _manager.kit.previewMirrored = previewMirrored; | 485 | _manager.kit.previewMirrored = previewMirrored; |
| @@ -432,8 +493,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -432,8 +493,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 432 | } | 493 | } |
| 433 | 494 | ||
| 434 | //旋转预览视图 | 495 | //旋转预览视图 |
| 435 | -- (void)rotatePreviewTo:(UIInterfaceOrientation)orie | ||
| 436 | -{ | 496 | +- (void)rotatePreviewTo:(UIInterfaceOrientation)orie { |
| 437 | [_manager.kit rotatePreviewTo:orie]; | 497 | [_manager.kit rotatePreviewTo:orie]; |
| 438 | } | 498 | } |
| 439 | 499 | ||
| @@ -442,9 +502,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -442,9 +502,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 442 | [_manager.kit rotateStreamTo:orie]; | 502 | [_manager.kit rotateStreamTo:orie]; |
| 443 | } | 503 | } |
| 444 | 504 | ||
| 445 | -#pragma mark - | ||
| 446 | #pragma mark - camera operation | 505 | #pragma mark - camera operation |
| 447 | - | ||
| 448 | - (BOOL)switchCamera { | 506 | - (BOOL)switchCamera { |
| 449 | return [_manager.kit switchCamera]; | 507 | return [_manager.kit switchCamera]; |
| 450 | } | 508 | } |
| @@ -467,7 +525,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -467,7 +525,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 467 | [_manager.kit toggleTorch]; | 525 | [_manager.kit toggleTorch]; |
| 468 | } | 526 | } |
| 469 | 527 | ||
| 470 | -#pragma mark - | ||
| 471 | #pragma mark - reconnect(由于开启会暴露推流地址,暂不开放) | 528 | #pragma mark - reconnect(由于开启会暴露推流地址,暂不开放) |
| 472 | @synthesize maxAutoRetry = _maxAutoRetry; | 529 | @synthesize maxAutoRetry = _maxAutoRetry; |
| 473 | - (void)setMaxAutoRetry:(int)maxAutoRetry { | 530 | - (void)setMaxAutoRetry:(int)maxAutoRetry { |
| @@ -491,9 +548,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -491,9 +548,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 491 | 548 | ||
| 492 | - (void)tryReconnect { | 549 | - (void)tryReconnect { |
| 493 | 550 | ||
| 494 | - // NSLog(@"tryReconnect---->autoRetryCnt:%d----initiativeRetry:%@----reteying:%@----retryFailed:%@", _autoRetryCnt, _initiativeRetry ? @"YES" : @"NO", _reteying?@"YES":@"NO", _retryFailed?@"YES":@"NO"); | ||
| 495 | - | ||
| 496 | - | ||
| 497 | if (_autoRetryCnt < 1) { | 551 | if (_autoRetryCnt < 1) { |
| 498 | return; | 552 | return; |
| 499 | } | 553 | } |
| @@ -504,12 +558,9 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -504,12 +558,9 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 504 | 558 | ||
| 505 | _reteying = YES; | 559 | _reteying = YES; |
| 506 | 560 | ||
| 507 | - // NSLog(@"tryReconnect---->autoRetryCnt:%d----initiativeRetry:%@----reteying:%@----retryFailed:%@", _autoRetryCnt, _initiativeRetry ? @"YES" : @"NO", _reteying?@"YES":@"NO", _retryFailed?@"YES":@"NO"); | ||
| 508 | - | ||
| 509 | - | ||
| 510 | if (_autoRetryCnt == _maxAutoRetry) { | 561 | if (_autoRetryCnt == _maxAutoRetry) { |
| 511 | _reconnectStatus = CNLiveReconnectStatusStart; | 562 | _reconnectStatus = CNLiveReconnectStatusStart; |
| 512 | - [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamReconnectStatusChangedNotification | 563 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerReconnectStatusChangedNotification |
| 513 | object:nil | 564 | object:nil |
| 514 | userInfo:nil]; | 565 | userInfo:nil]; |
| 515 | } | 566 | } |
| @@ -519,13 +570,12 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -519,13 +570,12 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 519 | dispatch_after(delay, dispatch_get_main_queue(), ^{ | 570 | dispatch_after(delay, dispatch_get_main_queue(), ^{ |
| 520 | 571 | ||
| 521 | if (!_manager.kit.streamerBase.isStreaming) { | 572 | if (!_manager.kit.streamerBase.isStreaming) { |
| 522 | - // if (!_streamerBase.isStreaming) { | ||
| 523 | 573 | ||
| 524 | if (_logPrintEnable) { | 574 | if (_logPrintEnable) { |
| 525 | NSLog(@"CNLiveGPUStreamerKit-->第(%d)次重连/(%d)", (_maxAutoRetry-_autoRetryCnt+1),_maxAutoRetry); | 575 | NSLog(@"CNLiveGPUStreamerKit-->第(%d)次重连/(%d)", (_maxAutoRetry-_autoRetryCnt+1),_maxAutoRetry); |
| 526 | } | 576 | } |
| 527 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 577 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 528 | -// [self requestStartStreamer:NULL failure:NULL timeString:timeString]; | 578 | + [self requestStartStreamer:NULL failure:NULL timeString:timeString]; |
| 529 | }]; | 579 | }]; |
| 530 | 580 | ||
| 531 | _autoRetryCnt--; | 581 | _autoRetryCnt--; |
| @@ -540,7 +590,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -540,7 +590,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 540 | _retryFailed = NO; | 590 | _retryFailed = NO; |
| 541 | } | 591 | } |
| 542 | 592 | ||
| 543 | -#pragma mark - | ||
| 544 | #pragma mark - KSYMethod | 593 | #pragma mark - KSYMethod |
| 545 | - (UIView *)preview { | 594 | - (UIView *)preview { |
| 546 | return (UIView *)_manager.kit.preview; | 595 | return (UIView *)_manager.kit.preview; |
| @@ -569,13 +618,13 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -569,13 +618,13 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 569 | _retryFailed = NO; | 618 | _retryFailed = NO; |
| 570 | 619 | ||
| 571 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 620 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 572 | -// [self requestStartStreamer:successBlock failure:failureBlock timeString:timeString]; | 621 | + [self requestStartStreamer:successBlock failure:failureBlock timeString:timeString]; |
| 573 | }]; | 622 | }]; |
| 574 | 623 | ||
| 575 | } else { | 624 | } else { |
| 576 | 625 | ||
| 577 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 626 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 578 | -// [self createActivityWithSuccess:successBlock failure:failureBlock timeString:timeString]; | 627 | + [self createActivityWithSuccess:successBlock failure:failureBlock timeString:timeString]; |
| 579 | }]; | 628 | }]; |
| 580 | 629 | ||
| 581 | } | 630 | } |
| @@ -595,7 +644,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -595,7 +644,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 595 | _hostURL = [NSURL URLWithString:url]; //推流地址 | 644 | _hostURL = [NSURL URLWithString:url]; //推流地址 |
| 596 | 645 | ||
| 597 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 646 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 598 | -// [self requestStartStreamer:successBlock failure:failureBlock timeString:timeString]; | 647 | + [self requestStartStreamer:successBlock failure:failureBlock timeString:timeString]; |
| 599 | }]; | 648 | }]; |
| 600 | } | 649 | } |
| 601 | 650 | ||
| @@ -603,7 +652,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -603,7 +652,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 603 | [_manager.kit.streamerBase stopStream]; | 652 | [_manager.kit.streamerBase stopStream]; |
| 604 | _isRecording = NO; | 653 | _isRecording = NO; |
| 605 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 654 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 606 | -// [self requestStopStreamerWithInfo:@"User Pause" timeString:timeString]; | 655 | + [self requestStopStreamerWithInfo:@"User Pause" timeString:timeString]; |
| 607 | }]; | 656 | }]; |
| 608 | } | 657 | } |
| 609 | 658 | ||
| @@ -616,7 +665,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -616,7 +665,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 616 | - (void)stopStream { | 665 | - (void)stopStream { |
| 617 | if (_activitySuccess) { | 666 | if (_activitySuccess) { |
| 618 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 667 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 619 | -// [self requestStopStreamerWithInfo:@"" timeString:timeString]; | 668 | + [self requestStopStreamerWithInfo:@"" timeString:timeString]; |
| 620 | }]; | 669 | }]; |
| 621 | _isRecording = NO; | 670 | _isRecording = NO; |
| 622 | [self.socket disconnect]; | 671 | [self.socket disconnect]; |
| @@ -640,8 +689,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -640,8 +689,6 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 640 | - (void)appEnterBackground { | 689 | - (void)appEnterBackground { |
| 641 | [_manager.kit appEnterBackground]; | 690 | [_manager.kit appEnterBackground]; |
| 642 | 691 | ||
| 643 | - // //进入后台停止采集,避免占用资源 | ||
| 644 | - // [_manager.kit.streamerBase stopStream]; | ||
| 645 | } | 692 | } |
| 646 | 693 | ||
| 647 | //回到前台 | 694 | //回到前台 |
| @@ -672,13 +719,11 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -672,13 +719,11 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 672 | _manager.kit.stabilizationMode = stabilizationMode; | 719 | _manager.kit.stabilizationMode = stabilizationMode; |
| 673 | } | 720 | } |
| 674 | 721 | ||
| 675 | -#pragma mark - | ||
| 676 | #pragma mark - filters | 722 | #pragma mark - filters |
| 677 | - (void)setupFilter:(GPUImageOutput<GPUImageInput> *)filter { | 723 | - (void)setupFilter:(GPUImageOutput<GPUImageInput> *)filter { |
| 678 | [_manager.kit setupFilter:filter]; | 724 | [_manager.kit setupFilter:filter]; |
| 679 | } | 725 | } |
| 680 | 726 | ||
| 681 | -#pragma mark - | ||
| 682 | #pragma mark - 设置接口参数 | 727 | #pragma mark - 设置接口参数 |
| 683 | - (void)setActivityId:(NSString *)activityId { | 728 | - (void)setActivityId:(NSString *)activityId { |
| 684 | _activityId = [NSString stringWithFormat:@"%@", activityId]; | 729 | _activityId = [NSString stringWithFormat:@"%@", activityId]; |
| @@ -736,11 +781,10 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -736,11 +781,10 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 736 | } | 781 | } |
| 737 | 782 | ||
| 738 | #pragma mark - GCDAsyncSocketDelegate | 783 | #pragma mark - GCDAsyncSocketDelegate |
| 739 | - | ||
| 740 | - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port { | 784 | - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port { |
| 741 | self.heartTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(checkLongConnectByServe) userInfo:nil repeats:YES]; | 785 | self.heartTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(checkLongConnectByServe) userInfo:nil repeats:YES]; |
| 742 | [self checkLongConnectByServe]; | 786 | [self checkLongConnectByServe]; |
| 743 | - // NSLog(@"socket -------- 已连接"); | 787 | + |
| 744 | } | 788 | } |
| 745 | 789 | ||
| 746 | - (void)checkLongConnectByServe { | 790 | - (void)checkLongConnectByServe { |
| @@ -751,32 +795,27 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -751,32 +795,27 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 751 | longConnect = [NSString stringWithFormat:@"%@#%@#",PLAYER_AppID,_activityId]; | 795 | longConnect = [NSString stringWithFormat:@"%@#%@#",PLAYER_AppID,_activityId]; |
| 752 | } | 796 | } |
| 753 | NSData *data = [longConnect dataUsingEncoding:NSUTF8StringEncoding]; | 797 | NSData *data = [longConnect dataUsingEncoding:NSUTF8StringEncoding]; |
| 754 | - // NSLog(@"socket-socket--socket---%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); | ||
| 755 | [self.socket writeData:data withTimeout:-1 tag:1]; | 798 | [self.socket writeData:data withTimeout:-1 tag:1]; |
| 799 | + | ||
| 756 | } | 800 | } |
| 757 | 801 | ||
| 758 | - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag { | 802 | - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag { |
| 759 | - // NSLog(@"socket:%p didWriteDataWithTag:%ld", sock, tag); | 803 | + |
| 760 | } | 804 | } |
| 761 | 805 | ||
| 762 | - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { | 806 | - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { |
| 763 | - // NSLog(@"socket:%p didReadData:withTag:%ld", sock, tag); | ||
| 764 | - | ||
| 765 | - // NSString *httpResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; | ||
| 766 | 807 | ||
| 767 | - // NSLog(@"HTTP Response:\n%@", httpResponse); | ||
| 768 | 808 | ||
| 769 | } | 809 | } |
| 770 | 810 | ||
| 771 | - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { | 811 | - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { |
| 772 | - // NSLog(@"socket-------- 断开连接 %@", err); | ||
| 773 | 812 | ||
| 774 | if (_isRecording) { | 813 | if (_isRecording) { |
| 775 | 814 | ||
| 776 | _isRecording = NO; | 815 | _isRecording = NO; |
| 777 | 816 | ||
| 778 | if (self.logPrintEnable) { | 817 | if (self.logPrintEnable) { |
| 779 | - NSLog(@"CNLiveGPUStreamerKit-->由于监听心跳未能正常运作而暂时断开推流,reason:%@",err?err.localizedDescription:@"nil"); | 818 | + NSLog(@"CNLiveStreamerKit-->由于监听心跳未能正常运作而暂时断开推流,reason:%@",err?err.localizedDescription:@"nil"); |
| 780 | } | 819 | } |
| 781 | 820 | ||
| 782 | [_manager.kit.streamerBase stopStream]; | 821 | [_manager.kit.streamerBase stopStream]; |
| @@ -784,29 +823,27 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -784,29 +823,27 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 784 | //如果socket异常断开,发送异常通知 | 823 | //如果socket异常断开,发送异常通知 |
| 785 | _streamErrorCode = CNLiveStreamErrorCode_ABNORMAL; | 824 | _streamErrorCode = CNLiveStreamErrorCode_ABNORMAL; |
| 786 | _streamState = CNLiveStreamStateError; | 825 | _streamState = CNLiveStreamStateError; |
| 787 | - [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamStateDidChangeNotification | 826 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerStateDidChangeNotification |
| 788 | object:nil | 827 | object:nil |
| 789 | userInfo:nil]; | 828 | userInfo:nil]; |
| 790 | 829 | ||
| 791 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 830 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 792 | -// [self requestStopStreamerWithInfo:@"CNLiveStreamErrorCode_ABNORMAL_1" timeString:timeString]; | 831 | + [self requestStopStreamerWithInfo:@"CNLiveStreamErrorCode_ABNORMAL_1" timeString:timeString]; |
| 793 | }]; | 832 | }]; |
| 794 | 833 | ||
| 795 | 834 | ||
| 796 | //重连失败通知开发者 | 835 | //重连失败通知开发者 |
| 797 | if (_retryFailed && _isCNLiveStreaming) { | 836 | if (_retryFailed && _isCNLiveStreaming) { |
| 798 | _reconnectStatus = CNLiveReconnectStatusFailed; | 837 | _reconnectStatus = CNLiveReconnectStatusFailed; |
| 799 | - [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamReconnectStatusChangedNotification | 838 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerReconnectStatusChangedNotification |
| 800 | object:nil | 839 | object:nil |
| 801 | userInfo:nil]; | 840 | userInfo:nil]; |
| 802 | [self recoverReconnectConfig]; | 841 | [self recoverReconnectConfig]; |
| 803 | } | 842 | } |
| 804 | 843 | ||
| 805 | - // NSLog(@"socketBreak---->autoRetryCnt:%d----initiativeRetry:%@----reteying:%@----retryFailed:%@", _autoRetryCnt, _initiativeRetry ? @"YES" : @"NO", _reteying?@"YES":@"NO", _retryFailed?@"YES":@"NO"); | ||
| 806 | - | ||
| 807 | if (_autoRetryCnt>0 && !_initiativeRetry) { | 844 | if (_autoRetryCnt>0 && !_initiativeRetry) { |
| 808 | [self tryReconnect]; | 845 | [self tryReconnect]; |
| 809 | - //NSLog(@"CNLiveStreamerKit-->reconnect ----- socketERROR"); | 846 | + |
| 810 | } | 847 | } |
| 811 | 848 | ||
| 812 | } | 849 | } |
| @@ -848,25 +885,20 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -848,25 +885,20 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 848 | 885 | ||
| 849 | _roomId = [NSString stringWithFormat:@"CNLiveAnchorStatus_%@",contentId]; | 886 | _roomId = [NSString stringWithFormat:@"CNLiveAnchorStatus_%@",contentId]; |
| 850 | 887 | ||
| 851 | - // NSLog(@"**********************----roomid %@",_roomId); | ||
| 852 | - | ||
| 853 | //加入聊天室 | 888 | //加入聊天室 |
| 854 | - [[CNLiveMsgManager sharedCNLiveMsgManager] gatherIfNullCreate:_roomId | ||
| 855 | - messageCount:1 | ||
| 856 | - success:^(NSString *targetId) { | ||
| 857 | - | ||
| 858 | - if (result) { | ||
| 859 | - result(YES); | ||
| 860 | - } | ||
| 861 | - | ||
| 862 | - } error:^(NSInteger errors, NSString *targetId) { | ||
| 863 | - | ||
| 864 | - // NSLog(@"***********--加入聊天室失败 ----errors %ld",(long)errors); | ||
| 865 | - | ||
| 866 | - if (result) { | ||
| 867 | - result(NO); | ||
| 868 | - } | ||
| 869 | - }]; | 889 | + [[CNLiveMsgManager sharedCNLiveMsgManager] gatherIfNullCreate:_roomId messageCount:1 success:^(NSString *targetId) { |
| 890 | + if (result) { | ||
| 891 | + result(YES); | ||
| 892 | + | ||
| 893 | + } | ||
| 894 | + | ||
| 895 | + } error:^(NSInteger errors, NSString *targetId) { | ||
| 896 | + if (result) { | ||
| 897 | + result(NO); | ||
| 898 | + | ||
| 899 | + } | ||
| 900 | + | ||
| 901 | + }]; | ||
| 870 | } | 902 | } |
| 871 | 903 | ||
| 872 | - (void)initRCloudNotificationObservers { | 904 | - (void)initRCloudNotificationObservers { |
| @@ -874,7 +906,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -874,7 +906,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 874 | if (_registerChatNoti) return; | 906 | if (_registerChatNoti) return; |
| 875 | 907 | ||
| 876 | //接收消息通知 | 908 | //接收消息通知 |
| 877 | - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveMessage:) name:MsgToolsStreamReceiveNotification object:nil]; | 909 | + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveMessage:) name:CNLiveStreamerMsgReceiveNotification object:nil]; |
| 878 | 910 | ||
| 879 | _registerChatNoti = YES; | 911 | _registerChatNoti = YES; |
| 880 | 912 | ||
| @@ -887,6 +919,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -887,6 +919,7 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 887 | int newValue = [noti.userInfo[@"message"] intValue]; | 919 | int newValue = [noti.userInfo[@"message"] intValue]; |
| 888 | 920 | ||
| 889 | if (_originalStatus == newValue) return; //如果新收到的状态与上一次状态一样不作处理 | 921 | if (_originalStatus == newValue) return; //如果新收到的状态与上一次状态一样不作处理 |
| 922 | + | ||
| 890 | if (!_originalStatus && newValue == 2) { | 923 | if (!_originalStatus && newValue == 2) { |
| 891 | return; | 924 | return; |
| 892 | } | 925 | } |
| @@ -907,20 +940,16 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -907,20 +940,16 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 907 | 940 | ||
| 908 | _registerChatNoti = NO; | 941 | _registerChatNoti = NO; |
| 909 | 942 | ||
| 910 | - [[NSNotificationCenter defaultCenter] removeObserver:self | ||
| 911 | - name:MsgToolsStreamReceiveNotification | ||
| 912 | - object:nil]; | 943 | + [[NSNotificationCenter defaultCenter] removeObserver:self name:CNLiveStreamerMsgReceiveNotification object:nil]; |
| 913 | 944 | ||
| 914 | - if ([CNLiveStreamerTools isEmptyString:_roomId]) { | ||
| 915 | - return; | 945 | + if (![CNLiveStreamerTools isEmptyString:_roomId]) { |
| 946 | + [[CNLiveMsgManager sharedCNLiveMsgManager] disperse:_roomId success:^(NSString *targetId) { | ||
| 947 | + | ||
| 948 | + } error:^(NSInteger errors, NSString *targetId) { | ||
| 949 | + | ||
| 950 | + }]; | ||
| 916 | } | 951 | } |
| 917 | 952 | ||
| 918 | - [[CNLiveMsgManager sharedCNLiveMsgManager] disperse:_roomId success:^(NSString *targetId) { | ||
| 919 | - | ||
| 920 | - } error:^(NSInteger errors, NSString *targetId) { | ||
| 921 | - | ||
| 922 | - }]; | ||
| 923 | - | ||
| 924 | } | 953 | } |
| 925 | 954 | ||
| 926 | #pragma mark - getter | 955 | #pragma mark - getter |
| @@ -961,30 +990,9 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -961,30 +990,9 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 961 | 990 | ||
| 962 | #pragma mark - dealloc | 991 | #pragma mark - dealloc |
| 963 | - (void)dealloc { | 992 | - (void)dealloc { |
| 964 | - | ||
| 965 | - [[NSNotificationCenter defaultCenter] removeObserver:self | ||
| 966 | - name:KSYCaptureStateDidChangeNotification | ||
| 967 | - object:nil]; | ||
| 968 | - | ||
| 969 | - [[NSNotificationCenter defaultCenter] removeObserver:self | ||
| 970 | - name:KSYStreamStateDidChangeNotification | ||
| 971 | - object:nil]; | ||
| 972 | - | ||
| 973 | - [[NSNotificationCenter defaultCenter] removeObserver:self | ||
| 974 | - name:UIApplicationDidEnterBackgroundNotification | ||
| 975 | - object:nil]; | ||
| 976 | - | ||
| 977 | - [[NSNotificationCenter defaultCenter] removeObserver:self | ||
| 978 | - name:UIApplicationWillEnterForegroundNotification | ||
| 979 | - object:nil]; | ||
| 980 | - | ||
| 981 | - [[NSNotificationCenter defaultCenter] removeObserver:self | ||
| 982 | - name:MsgToolsStreamReceiveNotification | ||
| 983 | - object:nil]; | ||
| 984 | - | 993 | + [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 985 | [UIApplication sharedApplication].idleTimerDisabled = NO; | 994 | [UIApplication sharedApplication].idleTimerDisabled = NO; |
| 986 | 995 | ||
| 987 | - | ||
| 988 | [_manager destroyStreamerManager]; | 996 | [_manager destroyStreamerManager]; |
| 989 | _manager = nil; | 997 | _manager = nil; |
| 990 | } | 998 | } |
| @@ -998,4 +1006,375 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | @@ -998,4 +1006,375 @@ NSString * const CNLiveServiceConnectBreakNotification = @"CNLiveServiceConnectB | ||
| 998 | return view; | 1006 | return view; |
| 999 | } | 1007 | } |
| 1000 | 1008 | ||
| 1009 | +#pragma mark - data | ||
| 1010 | +- (void)requestCreateActivityParameter:(NSDictionary *)param success:(void(^)(void))successBlock failure :(void (^)(NSDictionary *errorDic))failureBlock { | ||
| 1011 | + | ||
| 1012 | + [CNLivePlayerNetworkManager POST:StreamerURL parameters:param success:^(NSURLResponse * _Nullable response, id _Nullable responseObject) { | ||
| 1013 | + | ||
| 1014 | + if (![CNLiveStreamerTools isEmptyString:responseObject[@"errorCode"]] && [responseObject[@"errorCode"] intValue] == 0) { | ||
| 1015 | + | ||
| 1016 | + if (self.logPrintEnable) { | ||
| 1017 | + NSLog(@"CNLiveGPUStreamerKit-->创建活动成功"); | ||
| 1018 | + } | ||
| 1019 | + | ||
| 1020 | + //创建活动成功后,连接RM,获取主播状态 | ||
| 1021 | + // [self initRCloudWithAppId:SHARE_APPID appKey:SHARE_APPKEY connectResult:NULL]; | ||
| 1022 | + | ||
| 1023 | + _activitySuccess = YES; | ||
| 1024 | + | ||
| 1025 | + NSString *url = responseObject[@"data"][@"location"]; | ||
| 1026 | + _hostURL = [NSURL URLWithString:url]; | ||
| 1027 | + | ||
| 1028 | + [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | ||
| 1029 | + [self requestStartStreamer:successBlock failure:failureBlock timeString:timeString]; | ||
| 1030 | + }]; | ||
| 1031 | + | ||
| 1032 | + } else { | ||
| 1033 | + | ||
| 1034 | + if (self.logPrintEnable) { | ||
| 1035 | + NSLog(@"CNLiveGPUStreamerKit-->创建活动失败,失败原因:%@", responseObject); | ||
| 1036 | + } | ||
| 1037 | + | ||
| 1038 | + failureBlock ? failureBlock(responseObject) : nil; | ||
| 1039 | + | ||
| 1040 | + //用于探针 | ||
| 1041 | + | ||
| 1042 | + NSError *error = [CNLiveStreamerTools customErrorWithResponseObject:responseObject errorInfo:@"开启推流失败,请重试"]; | ||
| 1043 | + | ||
| 1044 | + [CNLiveStreamerTools errorStat:error.userInfo.description activityId:_activityId]; | ||
| 1045 | + } | ||
| 1046 | + | ||
| 1047 | + } failure:^(NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
| 1048 | + | ||
| 1049 | + NSDictionary *errorDic = @{@"errorCode": [NSString stringWithFormat:@"%ld", error.code], | ||
| 1050 | + @"errorMessage": error.localizedDescription}; | ||
| 1051 | + | ||
| 1052 | + failureBlock ? failureBlock(errorDic) : nil; | ||
| 1053 | + | ||
| 1054 | + if (self.logPrintEnable) { | ||
| 1055 | + NSLog(@"CNLiveGPUStreamerKit-->创建活动失败,失败原因:%@", errorDic); | ||
| 1056 | + } | ||
| 1057 | + | ||
| 1058 | + [CNLiveStreamerTools errorStat:error.userInfo.description activityId:_activityId]; | ||
| 1059 | + | ||
| 1060 | + }]; | ||
| 1061 | + | ||
| 1062 | +} | ||
| 1063 | + | ||
| 1064 | +//启动直播活动 | ||
| 1065 | +- (void)requestStartStreamer:(void (^)(void))successBlock failure:(void (^)(NSDictionary *))failureBlock timeString:(NSString *)timeString { | ||
| 1066 | + | ||
| 1067 | + _reteying = NO; | ||
| 1068 | + | ||
| 1069 | + // NSDate *date = [NSDate date]; | ||
| 1070 | + // NSInteger time = [date timeIntervalSince1970]; | ||
| 1071 | + // NSString *timeString = [NSString stringWithFormat:@"%ld", (long)time]; | ||
| 1072 | + | ||
| 1073 | + NSMutableDictionary *parameter = [@{@"appId": PLAYER_AppID, | ||
| 1074 | + @"activityId": _activityId, | ||
| 1075 | + @"timestamp":timeString, | ||
| 1076 | + @"platform_id":[NSBundle mainBundle].bundleIdentifier} copy] ; | ||
| 1077 | + | ||
| 1078 | + NSMutableDictionary *para = [CNLiveStreamerTools encryptionSignWithParameter:parameter]; | ||
| 1079 | + | ||
| 1080 | + [CNLivePlayerNetworkManager GET:StartStreamerURL parameters:para success:^(NSURLResponse * _Nullable response, id _Nullable responseObject) { | ||
| 1081 | + | ||
| 1082 | + if (responseObject[@"errorCode"] && [responseObject[@"errorCode"]isEqualToString:@"0"]) { //开始活动success | ||
| 1083 | + | ||
| 1084 | + _isRecording = YES; | ||
| 1085 | + BOOL linkResult; | ||
| 1086 | + | ||
| 1087 | + if (_socket.isDisconnected || !_socket) { | ||
| 1088 | + self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()]; | ||
| 1089 | + NSError *error; | ||
| 1090 | + linkResult = [self.socket connectToHost:Host onPort:Port withTimeout:5 error:&error]; | ||
| 1091 | + } else { | ||
| 1092 | + linkResult = YES; | ||
| 1093 | + } | ||
| 1094 | + | ||
| 1095 | + if (linkResult) { //连接聊天室success | ||
| 1096 | + | ||
| 1097 | + if (_manager.kit.streamerBase.isStreaming) { | ||
| 1098 | + _streamState = CNLiveStreamStateConnected; | ||
| 1099 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerStateDidChangeNotification | ||
| 1100 | + object:nil | ||
| 1101 | + userInfo:nil]; | ||
| 1102 | + } | ||
| 1103 | + | ||
| 1104 | + if (!_manager.kit.streamerBase.isStreaming) { | ||
| 1105 | + [_manager.kit.streamerBase startStream:_hostURL]; | ||
| 1106 | + } | ||
| 1107 | + | ||
| 1108 | + | ||
| 1109 | + if (successBlock) { | ||
| 1110 | + successBlock(); | ||
| 1111 | + } | ||
| 1112 | + | ||
| 1113 | + if (self.logPrintEnable) { | ||
| 1114 | + // D_NSLog(@"CNLiveGPUStreamerKit-->开启活动成功 -----连接状态%@", share.kit.streamerBase.isStreaming ? @"YES" : @"NO"); | ||
| 1115 | + NSLog(@"CNLiveGPUStreamerKit-->开启活动成功"); | ||
| 1116 | + } | ||
| 1117 | + | ||
| 1118 | + _initiativeRetry = NO; | ||
| 1119 | + | ||
| 1120 | + | ||
| 1121 | + } else { //连接聊天室fail | ||
| 1122 | + | ||
| 1123 | + _isRecording = NO; | ||
| 1124 | + | ||
| 1125 | + /** | ||
| 1126 | + * 开始活动成功但是聊天室连接失败应将活动状态置为“-2” | ||
| 1127 | + */ | ||
| 1128 | + [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | ||
| 1129 | + [self requestStopStreamerWithInfo:@"CNLiveStreamErrorCode_JoinRoomFailed" timeString:timeString]; | ||
| 1130 | + }]; | ||
| 1131 | + | ||
| 1132 | + /** | ||
| 1133 | + * 若返回前台,流没断,但是连接聊天室失败,需将流断开 | ||
| 1134 | + */ | ||
| 1135 | + if (_manager.kit.streamerBase.isStreaming) { | ||
| 1136 | + [_manager.kit.streamerBase stopStream]; | ||
| 1137 | + } | ||
| 1138 | + | ||
| 1139 | + //用于错误探针 | ||
| 1140 | + NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"socket连接失败"}]; | ||
| 1141 | + | ||
| 1142 | + [CNLiveStreamerTools errorStat:error.userInfo.description activityId:_activityId]; | ||
| 1143 | + | ||
| 1144 | + //用于回调 | ||
| 1145 | + NSDictionary *errorDic = @{@"errorCode": @"-1", | ||
| 1146 | + @"errorMessage": @"心跳连接失败,请重试"}; | ||
| 1147 | + | ||
| 1148 | + if (self.logPrintEnable) { | ||
| 1149 | + NSLog(@"CNLiveGPUStreamerKit-->开启活动失败,失败原因:%@", errorDic); | ||
| 1150 | + } | ||
| 1151 | + | ||
| 1152 | + //重连失败通知开发者 | ||
| 1153 | + if (_retryFailed && _isCNLiveStreaming) { | ||
| 1154 | + _reconnectStatus = CNLiveReconnectStatusFailed; | ||
| 1155 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerReconnectStatusChangedNotification | ||
| 1156 | + object:nil | ||
| 1157 | + userInfo:nil]; | ||
| 1158 | + [self recoverReconnectConfig]; | ||
| 1159 | + } | ||
| 1160 | + | ||
| 1161 | + // NSLog(@"socketConnectFailed---->autoRetryCnt:%d----initiativeRetry:%@----reteying:%@----retryFailed:%@", _autoRetryCnt, _initiativeRetry ? @"YES" : @"NO", _reteying?@"YES":@"NO", _retryFailed?@"YES":@"NO"); | ||
| 1162 | + | ||
| 1163 | + if (_autoRetryCnt>0 && !_initiativeRetry) { | ||
| 1164 | + [self tryReconnect]; | ||
| 1165 | + // D_NSLog(@"CNLiveGPUStreamerKit-->reconnect ----- socket连接失败"); | ||
| 1166 | + | ||
| 1167 | + } | ||
| 1168 | + | ||
| 1169 | + failureBlock ? failureBlock(errorDic) : nil; | ||
| 1170 | + | ||
| 1171 | + } | ||
| 1172 | + | ||
| 1173 | + } else { //开始活动失败 | ||
| 1174 | + | ||
| 1175 | + _isRecording = NO; | ||
| 1176 | + | ||
| 1177 | + if (_manager.kit.streamerBase.isStreaming) { | ||
| 1178 | + [_manager.kit.streamerBase stopStream]; | ||
| 1179 | + } | ||
| 1180 | + | ||
| 1181 | + //用于探针 | ||
| 1182 | + NSError *error = [CNLiveStreamerTools customErrorWithResponseObject:responseObject errorInfo:@"开启推流失败,请重试"]; | ||
| 1183 | + | ||
| 1184 | + [CNLiveStreamerTools errorStat:error.userInfo.description activityId:_activityId]; | ||
| 1185 | + | ||
| 1186 | + if (self.logPrintEnable) { | ||
| 1187 | + NSLog(@"CNLiveGPUStreamerKit-->开启活动失败,失败原因:%@", responseObject); | ||
| 1188 | + } | ||
| 1189 | + | ||
| 1190 | + //重连失败通知开发者 | ||
| 1191 | + if (_retryFailed && _isCNLiveStreaming) { | ||
| 1192 | + _reconnectStatus = CNLiveReconnectStatusFailed; | ||
| 1193 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerReconnectStatusChangedNotification | ||
| 1194 | + object:nil | ||
| 1195 | + userInfo:nil]; | ||
| 1196 | + [self recoverReconnectConfig]; | ||
| 1197 | + } | ||
| 1198 | + | ||
| 1199 | + // NSLog(@"startFailed---->autoRetryCnt:%d----initiativeRetry:%@----reteying:%@----retryFailed:%@", _autoRetryCnt, _initiativeRetry ? @"YES" : @"NO", _reteying?@"YES":@"NO", _retryFailed?@"YES":@"NO"); | ||
| 1200 | + | ||
| 1201 | + if (_autoRetryCnt>0 && !_initiativeRetry) { | ||
| 1202 | + [self tryReconnect]; | ||
| 1203 | + // D_NSLog(@"CNLiveGPUStreamerKit-->reconnect ----- 启动活动失败"); | ||
| 1204 | + } | ||
| 1205 | + | ||
| 1206 | + failureBlock ? failureBlock(responseObject) : nil; | ||
| 1207 | + | ||
| 1208 | + } | ||
| 1209 | + | ||
| 1210 | + } failure:^(NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
| 1211 | + | ||
| 1212 | + _isRecording = NO; | ||
| 1213 | + | ||
| 1214 | + if (_manager.kit.streamerBase.isStreaming) { | ||
| 1215 | + [_manager.kit.streamerBase stopStream]; | ||
| 1216 | + } | ||
| 1217 | + | ||
| 1218 | + NSDictionary *errorDic = @{@"errorCode": [NSString stringWithFormat:@"%ld",error.code], @"errorMessage": error.localizedDescription}; | ||
| 1219 | + | ||
| 1220 | + [CNLiveStreamerTools errorStat:error.userInfo.description activityId:_activityId]; | ||
| 1221 | + | ||
| 1222 | + | ||
| 1223 | + if (self.logPrintEnable) { | ||
| 1224 | + NSLog(@"CNLiveGPUStreamerKit-->开启活动失败,失败原因:%@", errorDic); | ||
| 1225 | + } | ||
| 1226 | + | ||
| 1227 | + //重连失败通知开发者 | ||
| 1228 | + if (_retryFailed && _isCNLiveStreaming) { | ||
| 1229 | + _reconnectStatus = CNLiveReconnectStatusFailed; | ||
| 1230 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerReconnectStatusChangedNotification | ||
| 1231 | + object:nil | ||
| 1232 | + userInfo:nil]; | ||
| 1233 | + [self recoverReconnectConfig]; | ||
| 1234 | + } | ||
| 1235 | + | ||
| 1236 | + // NSLog(@"no wlan---->autoRetryCnt:%d----initiativeRetry:%@----reteying:%@----retryFailed:%@", _autoRetryCnt, _initiativeRetry ? @"YES" : @"NO", _reteying?@"YES":@"NO", _retryFailed?@"YES":@"NO"); | ||
| 1237 | + | ||
| 1238 | + if (_autoRetryCnt>0 && !_initiativeRetry) { | ||
| 1239 | + [self tryReconnect]; | ||
| 1240 | + // D_NSLog(@"CNLiveGPUStreamerKit-->reconnect ----- 启动活动(((请求)))失败"); | ||
| 1241 | + } | ||
| 1242 | + | ||
| 1243 | + failureBlock ? failureBlock(errorDic) : nil; | ||
| 1244 | + | ||
| 1245 | + }]; | ||
| 1246 | +} | ||
| 1247 | + | ||
| 1248 | +//结束直播活动 | ||
| 1249 | +- (void)requestStopStreamerWithInfo:(NSString *)remark timeString:(NSString *)timeString { | ||
| 1250 | + // NSDate *date = [NSDate date]; | ||
| 1251 | + // NSInteger time = [date timeIntervalSince1970]; | ||
| 1252 | + // NSString *timeString = [NSString stringWithFormat:@"%ld", (long)time]; | ||
| 1253 | + | ||
| 1254 | + NSMutableDictionary *parameter = [@{@"appId": PLAYER_AppID, | ||
| 1255 | + @"activityId": _activityId, | ||
| 1256 | + @"platform_id":[NSBundle mainBundle].bundleIdentifier, | ||
| 1257 | + @"timestamp":timeString} mutableCopy]; | ||
| 1258 | + if (remark.length > 0) { | ||
| 1259 | + [parameter setObject:remark forKey:@"remark"]; | ||
| 1260 | + } | ||
| 1261 | + | ||
| 1262 | + NSMutableDictionary *para = [CNLiveStreamerTools encryptionSignWithParameter:parameter]; | ||
| 1263 | + | ||
| 1264 | + [CNLivePlayerNetworkManager GET:StopStreamerURL parameters:para success:^(NSURLResponse * _Nullable response, id _Nullable responseObject) { | ||
| 1265 | + | ||
| 1266 | + if ([[NSString stringWithFormat:@"%@", responseObject[@"errorCode"]] isEqualToString:@"0"]) { | ||
| 1267 | + | ||
| 1268 | + if (self.logPrintEnable) { | ||
| 1269 | + if (remark.length > 0) { | ||
| 1270 | + NSLog(@"CNLiveGPUStreamerKit-->异常结束推流error:%@,并成功通知后台", remark); | ||
| 1271 | + } else { | ||
| 1272 | + //结束推流成功通知 | ||
| 1273 | + _streamState = CNLiveStopStreamSuccess; | ||
| 1274 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerStateDidChangeNotification | ||
| 1275 | + object:nil | ||
| 1276 | + userInfo:nil]; | ||
| 1277 | + | ||
| 1278 | + NSLog(@"CNLiveGPUStreamerKit-->正常结束推流并成功通知后台"); | ||
| 1279 | + } | ||
| 1280 | + } | ||
| 1281 | + | ||
| 1282 | + | ||
| 1283 | + if ([CNLiveStreamerTools isEmptyString:remark]) { | ||
| 1284 | + NSString *duration = responseObject[@"data"][@"duration"]; | ||
| 1285 | + if ([duration isKindOfClass:[NSString class]] && duration.length > 0) { | ||
| 1286 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerGetDurationNotification object:duration ? duration : @"0"]; | ||
| 1287 | + } else { | ||
| 1288 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerGetDurationNotification object:@"0"]; | ||
| 1289 | + } | ||
| 1290 | + } | ||
| 1291 | + | ||
| 1292 | + | ||
| 1293 | + } else { | ||
| 1294 | + | ||
| 1295 | + if ([CNLiveStreamerTools isEmptyString:remark]) { | ||
| 1296 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerGetDurationNotification object:@"0"]; | ||
| 1297 | + | ||
| 1298 | + } | ||
| 1299 | + | ||
| 1300 | + if (self.logPrintEnable) { | ||
| 1301 | + if (remark.length > 0) { | ||
| 1302 | + NSLog(@"CNLiveGPUStreamerKit-->异常结束推流error:%@,未能通知后台 %@", remark,responseObject); | ||
| 1303 | + } else { | ||
| 1304 | + NSLog(@"CNLiveGPUStreamerKit-->正常结束推流,未能通知后台 %@",responseObject); | ||
| 1305 | + //结束推流失败通知 | ||
| 1306 | + _streamState = CNLiveStopStreamFailure; | ||
| 1307 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerStateDidChangeNotification | ||
| 1308 | + object:nil | ||
| 1309 | + userInfo:nil]; | ||
| 1310 | + } | ||
| 1311 | + } | ||
| 1312 | + | ||
| 1313 | + | ||
| 1314 | + NSError *error = [CNLiveStreamerTools customErrorWithResponseObject:responseObject errorInfo:@"结束推流失败"]; | ||
| 1315 | + | ||
| 1316 | + [CNLiveStreamerTools errorStat:error.userInfo.description activityId:_activityId]; | ||
| 1317 | + | ||
| 1318 | + } | ||
| 1319 | + | ||
| 1320 | + } failure:^(NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
| 1321 | + | ||
| 1322 | + if (self.logPrintEnable) { | ||
| 1323 | + if (remark.length > 0) { | ||
| 1324 | + NSLog(@"CNLiveGPUStreamerKit-->异常结束推流error:%@,未能通知后台", remark); | ||
| 1325 | + } else { | ||
| 1326 | + NSLog(@"CNLiveGPUStreamerKit-->正常结束推流,未能通知后台"); | ||
| 1327 | + } | ||
| 1328 | + } | ||
| 1329 | + | ||
| 1330 | + //结束推流失败通知 | ||
| 1331 | + _streamState = CNLiveStopStreamFailure; | ||
| 1332 | + [[NSNotificationCenter defaultCenter] postNotificationName:CNLiveStreamerStateDidChangeNotification | ||
| 1333 | + object:nil | ||
| 1334 | + userInfo:nil]; | ||
| 1335 | + | ||
| 1336 | + [CNLiveStreamerTools errorStat:error.userInfo.description activityId:_activityId]; | ||
| 1337 | + | ||
| 1338 | + }]; | ||
| 1339 | +} | ||
| 1340 | + | ||
| 1341 | +//创建直播活动 | ||
| 1342 | +- (void)createActivityWithSuccess:(void (^)(void))successBlock failure:(void (^)(NSDictionary *))failureBlock timeString:(NSString *)timeString { | ||
| 1343 | + //如果不是纯音频推流,先判断是否已开启采集状态,若未开启直接返回 | ||
| 1344 | + if (!_pureAudioMode) { | ||
| 1345 | + if (_manager.kit.captureState != KSYCaptureStateCapturing) { | ||
| 1346 | + | ||
| 1347 | + NSDictionary *errorDic = @{@"errorCode": @"-101", | ||
| 1348 | + @"errorMessage": @"未开启采集状态"}; | ||
| 1349 | + | ||
| 1350 | + failureBlock ? failureBlock(errorDic) : nil; | ||
| 1351 | + return; | ||
| 1352 | + } | ||
| 1353 | + } | ||
| 1354 | + | ||
| 1355 | + NSDate *date = [NSDate date]; | ||
| 1356 | +// NSInteger time = [date timeIntervalSince1970]; | ||
| 1357 | +// NSString *timeString = [NSString stringWithFormat:@"%ld", (long)time]; | ||
| 1358 | + | ||
| 1359 | + NSDictionary *params=@{@"platform_id":[NSBundle mainBundle].bundleIdentifier, | ||
| 1360 | + @"timestamp": timeString, | ||
| 1361 | + @"appId": PLAYER_AppID, | ||
| 1362 | + @"isHorizontalScreen":[NSString stringWithFormat:@"%d",_isHorizontalScreen], | ||
| 1363 | + @"uuid":[CNLiveStreamerTools getUidForStat:date]}; | ||
| 1364 | + | ||
| 1365 | + [_parameter addEntriesFromDictionary:params]; | ||
| 1366 | + | ||
| 1367 | + //避免创建活动失败,再次创建时字典中包含已加密sign | ||
| 1368 | + [_parameter removeObjectForKey:@"sign"]; | ||
| 1369 | + | ||
| 1370 | + //加密参数 | ||
| 1371 | + NSMutableDictionary *para = [CNLiveStreamerTools encryptionSignWithParameter:_parameter]; | ||
| 1372 | + | ||
| 1373 | + [self requestCreateActivityParameter:para success:successBlock failure:failureBlock]; | ||
| 1374 | + | ||
| 1375 | + [CNLiveStreamerTools statSDKWithDate:date activityId:_activityId]; | ||
| 1376 | + | ||
| 1377 | +} | ||
| 1378 | + | ||
| 1379 | + | ||
| 1001 | @end | 1380 | @end |
CNLivePlayer/Classes/Streamer/CNLiveStreamerTools.m
| @@ -13,7 +13,7 @@ | @@ -13,7 +13,7 @@ | ||
| 13 | #import "CNLivePlayerUrl.h" | 13 | #import "CNLivePlayerUrl.h" |
| 14 | 14 | ||
| 15 | @implementation CNLiveStreamerTools | 15 | @implementation CNLiveStreamerTools |
| 16 | - | 16 | +#pragma mark - 加密 |
| 17 | + (NSMutableDictionary *)encryptionSignWithParameter:(NSMutableDictionary *)parameter { | 17 | + (NSMutableDictionary *)encryptionSignWithParameter:(NSMutableDictionary *)parameter { |
| 18 | NSString *string = [NSString stringWithFormat:@"%@&key=%@",[self signvalue:parameter],PLAYER_AppKey]; | 18 | NSString *string = [NSString stringWithFormat:@"%@&key=%@",[self signvalue:parameter],PLAYER_AppKey]; |
| 19 | NSString *signString = [[self sha1:string] uppercaseString]; | 19 | NSString *signString = [[self sha1:string] uppercaseString]; |
| @@ -22,10 +22,7 @@ | @@ -22,10 +22,7 @@ | ||
| 22 | return startPara; | 22 | return startPara; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | -#pragma mark - | ||
| 26 | -#pragma mark - 加密 | ||
| 27 | -+ (NSString*)sha1:(NSString *)string | ||
| 28 | -{ | 25 | ++ (NSString*)sha1:(NSString *)string { |
| 29 | NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; | 26 | NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; |
| 30 | 27 | ||
| 31 | uint8_t digest[CC_SHA1_DIGEST_LENGTH]; | 28 | uint8_t digest[CC_SHA1_DIGEST_LENGTH]; |
| @@ -44,8 +41,7 @@ | @@ -44,8 +41,7 @@ | ||
| 44 | return output; | 41 | return output; |
| 45 | } | 42 | } |
| 46 | 43 | ||
| 47 | -+ (NSString *)signvalue:(NSDictionary*)parameter | ||
| 48 | -{ | 44 | ++ (NSString *)signvalue:(NSDictionary*)parameter { |
| 49 | //对所有传入参数按照字段名的 ASCII 码从小到大排序 | 45 | //对所有传入参数按照字段名的 ASCII 码从小到大排序 |
| 50 | NSArray *keyArr=[parameter allKeys]; | 46 | NSArray *keyArr=[parameter allKeys]; |
| 51 | NSArray *arr = [keyArr sortedArrayUsingSelector:@selector(compare:)]; | 47 | NSArray *arr = [keyArr sortedArrayUsingSelector:@selector(compare:)]; |
| @@ -66,10 +62,8 @@ | @@ -66,10 +62,8 @@ | ||
| 66 | return string1; | 62 | return string1; |
| 67 | } | 63 | } |
| 68 | 64 | ||
| 69 | -#pragma mark - | ||
| 70 | #pragma mark - 探针 | 65 | #pragma mark - 探针 |
| 71 | -+ (void)statSDKWithDate:(NSDate *)date activityId:(NSString *)activityId | ||
| 72 | -{ | 66 | ++ (void)statSDKWithDate:(NSDate *)date activityId:(NSString *)activityId { |
| 73 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 67 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 74 | NSString *stamp = [NSString stringWithFormat:@"%.3f", [timeString floatValue]]; | 68 | NSString *stamp = [NSString stringWithFormat:@"%.3f", [timeString floatValue]]; |
| 75 | stamp = [stamp stringByReplacingOccurrencesOfString:@"." withString:@""]; | 69 | stamp = [stamp stringByReplacingOccurrencesOfString:@"." withString:@""]; |
| @@ -79,8 +73,7 @@ | @@ -79,8 +73,7 @@ | ||
| 79 | 73 | ||
| 80 | } | 74 | } |
| 81 | 75 | ||
| 82 | -+ (void)errorStat:(NSString *)errorString activityId:(NSString *)activityId | ||
| 83 | -{ | 76 | ++ (void)errorStat:(NSString *)errorString activityId:(NSString *)activityId { |
| 84 | __block NSString *errorStr; | 77 | __block NSString *errorStr; |
| 85 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { | 78 | [CNLiveStreamerTools getRealTimeString:^(NSString *timeString) { |
| 86 | errorStr = [self urlEncodeUsingEncodingString:errorString]; | 79 | errorStr = [self urlEncodeUsingEncodingString:errorString]; |
| @@ -101,7 +94,6 @@ | @@ -101,7 +94,6 @@ | ||
| 101 | CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)); | 94 | CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)); |
| 102 | } | 95 | } |
| 103 | 96 | ||
| 104 | -#pragma mark - | ||
| 105 | #pragma mark - uuid | 97 | #pragma mark - uuid |
| 106 | + (NSString *)getUidForStat:(NSDate *)date { | 98 | + (NSString *)getUidForStat:(NSDate *)date { |
| 107 | NSString *uid = @""; | 99 | NSString *uid = @""; |
| @@ -138,10 +130,7 @@ | @@ -138,10 +130,7 @@ | ||
| 138 | uid = [[defauts objectForKey:@"kCNLiveUserDefaultsUIDKey"] copy]; | 130 | uid = [[defauts objectForKey:@"kCNLiveUserDefaultsUIDKey"] copy]; |
| 139 | return uid; | 131 | return uid; |
| 140 | } else { | 132 | } else { |
| 141 | - | ||
| 142 | - // NSString *stamp = [NSString stringWithFormat:@"%.3f", [date timeIntervalSince1970]]; | ||
| 143 | - // stamp = [stamp stringByReplacingOccurrencesOfString:@"." withString:@""]; | ||
| 144 | - | 133 | + |
| 145 | NSString *idfv = [[[[UIDevice currentDevice] identifierForVendor] UUIDString] stringByReplacingOccurrencesOfString:@"-" withString:@""]; | 134 | NSString *idfv = [[[[UIDevice currentDevice] identifierForVendor] UUIDString] stringByReplacingOccurrencesOfString:@"-" withString:@""]; |
| 146 | uid = [NSString stringWithFormat:@"%@_%@", idfv, date]; | 135 | uid = [NSString stringWithFormat:@"%@_%@", idfv, date]; |
| 147 | 136 | ||
| @@ -153,8 +142,7 @@ | @@ -153,8 +142,7 @@ | ||
| 153 | } | 142 | } |
| 154 | 143 | ||
| 155 | //错误信息 | 144 | //错误信息 |
| 156 | -+ (NSError *)customErrorWithResponseObject:(id)responseObject errorInfo:(NSString *) errorInfo | ||
| 157 | -{ | 145 | ++ (NSError *)customErrorWithResponseObject:(id)responseObject errorInfo:(NSString *) errorInfo { |
| 158 | //用于探针 | 146 | //用于探针 |
| 159 | NSString *defaultErrorInfo; | 147 | NSString *defaultErrorInfo; |
| 160 | NSInteger errorCode = -1; | 148 | NSInteger errorCode = -1; |
| @@ -170,50 +158,18 @@ | @@ -170,50 +158,18 @@ | ||
| 170 | } | 158 | } |
| 171 | 159 | ||
| 172 | 160 | ||
| 173 | -+ (BOOL)isEmptyString:(NSString *)string | ||
| 174 | -{ | 161 | ++ (BOOL)isEmptyString:(NSString *)string { |
| 175 | if (!string || ![string isKindOfClass:[NSString class]] || string.length == 0 || [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length == 0) { | 162 | if (!string || ![string isKindOfClass:[NSString class]] || string.length == 0 || [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length == 0) { |
| 176 | return YES; | 163 | return YES; |
| 177 | } | 164 | } |
| 178 | return NO; | 165 | return NO; |
| 179 | } | 166 | } |
| 180 | 167 | ||
| 181 | -#pragma mark - | ||
| 182 | #pragma mark - 真时时间 | 168 | #pragma mark - 真时时间 |
| 183 | -+ (void)getRealTimeString:(void (^)(NSString * __nullable))realTime | ||
| 184 | -{ | 169 | ++ (void)getRealTimeString:(void (^)(NSString * __nullable))realTime { |
| 185 | NSInteger time = [[NSDate date] timeIntervalSince1970]; | 170 | NSInteger time = [[NSDate date] timeIntervalSince1970]; |
| 186 | NSString *timeString = [NSString stringWithFormat:@"%ld", (long)time]; | 171 | NSString *timeString = [NSString stringWithFormat:@"%ld", (long)time]; |
| 187 | realTime(timeString); | 172 | realTime(timeString); |
| 188 | - | ||
| 189 | - // [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:HTTPorHTTPs@"api.cnlive.com/open/api2/timestamp"]] queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {// https://m.baidu.com | ||
| 190 | - // | ||
| 191 | - // if (!response) { | ||
| 192 | - // NSInteger time = [[NSDate date] timeIntervalSince1970]; | ||
| 193 | - // NSString *timeString = [NSString stringWithFormat:@"%ld", (long)time]; | ||
| 194 | - // dispatch_sync(dispatch_get_main_queue(), ^{ | ||
| 195 | - // realTime(timeString); | ||
| 196 | - // }); | ||
| 197 | - // return ; | ||
| 198 | - // } | ||
| 199 | - // | ||
| 200 | - // NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; | ||
| 201 | - // NSString *timestamp = [[httpResponse allHeaderFields] objectForKey:@"Date"]; | ||
| 202 | - // | ||
| 203 | - // NSString *timeStr = [timestamp substringWithRange:NSMakeRange(5, 20)]; | ||
| 204 | - // NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; | ||
| 205 | - // NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"GMT"]; | ||
| 206 | - // NSLocale *local = [[NSLocale alloc]initWithLocaleIdentifier:@"en_US_POSIX"]; | ||
| 207 | - // [formatter setLocale:local];//需要配置区域,不然会造成模拟器正常,真机日期为null的情况 | ||
| 208 | - // [formatter setTimeZone:timeZone]; | ||
| 209 | - // [formatter setDateFormat:@"dd MMM yyyy HH:mm:ss"];//设置源时间字符串的格式 | ||
| 210 | - // NSDate *date = [formatter dateFromString:timeStr];//将源时间字符串转化为NSDate | ||
| 211 | - // | ||
| 212 | - // NSString *timeString = [NSString stringWithFormat:@"%.0f", [date timeIntervalSince1970]]; | ||
| 213 | - // dispatch_sync(dispatch_get_main_queue(), ^{ | ||
| 214 | - // realTime(timeString); | ||
| 215 | - // }); | ||
| 216 | - // }]; | ||
| 217 | } | 173 | } |
| 218 | 174 | ||
| 219 | @end | 175 | @end |
CNLivePlayer/Classes/Streamer/CNLiveStreamerUrl.h
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveStreamerUrl.h | ||
| 3 | +// CNLivePlayer | ||
| 4 | +// | ||
| 5 | +// Created by CNLive-zxw on 2019/8/14. | ||
| 6 | +// Copyright © 2019 153993236@qq.com. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#ifndef CNLiveStreamerUrl_h | ||
| 10 | +#define CNLiveStreamerUrl_h | ||
| 11 | + | ||
| 12 | +#import "CNLivePlayerManager.h" | ||
| 13 | + | ||
| 14 | +#pragma mark - 推流器版本号 | ||
| 15 | +#define StreamerSDKVersion @"0.0.1" | ||
| 16 | + | ||
| 17 | +#pragma mark - 推流 | ||
| 18 | +//创建直播活动 | ||
| 19 | +#define StreamerURL [NSString stringWithFormat:@"%@/live_epg/createActivity", [CNLivePlayerManager manager].isTestEnvironment ? @"http://test.open.cnlive.com/openapi/api2" : @"http://api.cnlive.com/open/api2"] | ||
| 20 | + | ||
| 21 | +//启动直播活动 | ||
| 22 | +#define StartStreamerURL [NSString stringWithFormat:@"%@/live_epg/startActivity", [CNLivePlayerManager manager].isTestEnvironment ? @"http://test.open.cnlive.com/openapi/api2" : @"http://api.cnlive.com/open/api2"] | ||
| 23 | + | ||
| 24 | +//停止直播活动 | ||
| 25 | +#define StopStreamerURL [NSString stringWithFormat:@"%@/live_epg/stopActivity", [CNLivePlayerManager manager].isTestEnvironment ? @"http://test.open.cnlive.com/openapi/api2" : @"http://api.cnlive.com/open/api2"] | ||
| 26 | + | ||
| 27 | +#endif /* CNLiveStreamerUrl_h */ |
Example/CNLivePlayer.xcodeproj/project.pbxproj
| @@ -7,13 +7,23 @@ | @@ -7,13 +7,23 @@ | ||
| 7 | objects = { | 7 | objects = { |
| 8 | 8 | ||
| 9 | /* Begin PBXBuildFile section */ | 9 | /* Begin PBXBuildFile section */ |
| 10 | - 0807DF0E230799E000F409AC /* CNLivePlayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0807DF0D230799E000F409AC /* CNLivePlayerController.m */; }; | ||
| 11 | - 085FA988230D34890072B936 /* CNLiveStreamerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 085FA987230D34890072B936 /* CNLiveStreamerController.m */; }; | ||
| 12 | 086413BC22EAE229008713D3 /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 086413BB22EAE229008713D3 /* VideoToolbox.framework */; }; | 10 | 086413BC22EAE229008713D3 /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 086413BB22EAE229008713D3 /* VideoToolbox.framework */; }; |
| 13 | 086413BE22EAE23E008713D3 /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 086413BD22EAE23E008713D3 /* libbz2.tbd */; }; | 11 | 086413BE22EAE23E008713D3 /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 086413BD22EAE23E008713D3 /* libbz2.tbd */; }; |
| 14 | 086413C022EAE24F008713D3 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 086413BF22EAE24F008713D3 /* libz.tbd */; }; | 12 | 086413C022EAE24F008713D3 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 086413BF22EAE24F008713D3 /* libz.tbd */; }; |
| 15 | 086413C222EAE591008713D3 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 086413C122EAE591008713D3 /* OpenGLES.framework */; }; | 13 | 086413C222EAE591008713D3 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 086413C122EAE591008713D3 /* OpenGLES.framework */; }; |
| 16 | 086413C422EAEC11008713D3 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 086413C322EAEC11008713D3 /* libstdc++.tbd */; }; | 14 | 086413C422EAEC11008713D3 /* libstdc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 086413C322EAEC11008713D3 /* libstdc++.tbd */; }; |
| 15 | + 08740E51230E7DFB00B5D28D /* CNLiveStreamerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E3F230E7DFA00B5D28D /* CNLiveStreamerController.m */; }; | ||
| 16 | + 08740E52230E7DFB00B5D28D /* StreamerDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E40230E7DFA00B5D28D /* StreamerDetailViewController.m */; }; | ||
| 17 | + 08740E53230E7DFB00B5D28D /* FilterFunctionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E41230E7DFA00B5D28D /* FilterFunctionView.m */; }; | ||
| 18 | + 08740E54230E7DFB00B5D28D /* SliderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E44230E7DFA00B5D28D /* SliderView.m */; }; | ||
| 19 | + 08740E55230E7DFB00B5D28D /* FloatingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E45230E7DFA00B5D28D /* FloatingViewController.m */; }; | ||
| 20 | + 08740E56230E7DFB00B5D28D /* AudioStreamingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E46230E7DFA00B5D28D /* AudioStreamingViewController.m */; }; | ||
| 21 | + 08740E57230E7DFB00B5D28D /* MoreFunctionsView.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E47230E7DFA00B5D28D /* MoreFunctionsView.m */; }; | ||
| 22 | + 08740E58230E7DFB00B5D28D /* AudioCfgView.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E48230E7DFA00B5D28D /* AudioCfgView.m */; }; | ||
| 23 | + 08740E59230E7DFB00B5D28D /* BgmPlayerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E4D230E7DFA00B5D28D /* BgmPlayerView.m */; }; | ||
| 24 | + 08740E5C230E83B100B5D28D /* LoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E5B230E83B100B5D28D /* LoadingView.m */; }; | ||
| 25 | + 08740E5E230E8A0700B5D28D /* house.gif in Resources */ = {isa = PBXBuildFile; fileRef = 08740E5D230E8A0700B5D28D /* house.gif */; }; | ||
| 26 | + 08740E62230E8C6500B5D28D /* CNLivePlayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 08740E60230E8C6500B5D28D /* CNLivePlayerController.m */; }; | ||
| 17 | 1D258610626B544AFEEFD2F9 /* Pods_CNLivePlayer_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E14DC7AF4B1116AA5BC01855 /* Pods_CNLivePlayer_Example.framework */; }; | 27 | 1D258610626B544AFEEFD2F9 /* Pods_CNLivePlayer_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E14DC7AF4B1116AA5BC01855 /* Pods_CNLivePlayer_Example.framework */; }; |
| 18 | 2A57832D4B5A8EF9638641C3 /* Pods_CNLivePlayer_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDD4ACEE076815DE64A1FE2E /* Pods_CNLivePlayer_Tests.framework */; }; | 28 | 2A57832D4B5A8EF9638641C3 /* Pods_CNLivePlayer_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DDD4ACEE076815DE64A1FE2E /* Pods_CNLivePlayer_Tests.framework */; }; |
| 19 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; | 29 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; |
| @@ -44,15 +54,34 @@ | @@ -44,15 +54,34 @@ | ||
| 44 | /* End PBXContainerItemProxy section */ | 54 | /* End PBXContainerItemProxy section */ |
| 45 | 55 | ||
| 46 | /* Begin PBXFileReference section */ | 56 | /* Begin PBXFileReference section */ |
| 47 | - 0807DF0C230799E000F409AC /* CNLivePlayerController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNLivePlayerController.h; sourceTree = "<group>"; }; | ||
| 48 | - 0807DF0D230799E000F409AC /* CNLivePlayerController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CNLivePlayerController.m; sourceTree = "<group>"; }; | ||
| 49 | - 085FA986230D34890072B936 /* CNLiveStreamerController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNLiveStreamerController.h; sourceTree = "<group>"; }; | ||
| 50 | - 085FA987230D34890072B936 /* CNLiveStreamerController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CNLiveStreamerController.m; sourceTree = "<group>"; }; | ||
| 51 | 086413BB22EAE229008713D3 /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; }; | 57 | 086413BB22EAE229008713D3 /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; }; |
| 52 | 086413BD22EAE23E008713D3 /* libbz2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = usr/lib/libbz2.tbd; sourceTree = SDKROOT; }; | 58 | 086413BD22EAE23E008713D3 /* libbz2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = usr/lib/libbz2.tbd; sourceTree = SDKROOT; }; |
| 53 | 086413BF22EAE24F008713D3 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; | 59 | 086413BF22EAE24F008713D3 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; |
| 54 | 086413C122EAE591008713D3 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; | 60 | 086413C122EAE591008713D3 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; |
| 55 | 086413C322EAEC11008713D3 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; }; | 61 | 086413C322EAEC11008713D3 /* libstdc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libstdc++.tbd"; path = "usr/lib/libstdc++.tbd"; sourceTree = SDKROOT; }; |
| 62 | + 08740E3F230E7DFA00B5D28D /* CNLiveStreamerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNLiveStreamerController.m; sourceTree = "<group>"; }; | ||
| 63 | + 08740E40230E7DFA00B5D28D /* StreamerDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StreamerDetailViewController.m; sourceTree = "<group>"; }; | ||
| 64 | + 08740E41230E7DFA00B5D28D /* FilterFunctionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FilterFunctionView.m; sourceTree = "<group>"; }; | ||
| 65 | + 08740E42230E7DFA00B5D28D /* AudioCfgView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioCfgView.h; sourceTree = "<group>"; }; | ||
| 66 | + 08740E43230E7DFA00B5D28D /* BgmPlayerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BgmPlayerView.h; sourceTree = "<group>"; }; | ||
| 67 | + 08740E44230E7DFA00B5D28D /* SliderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SliderView.m; sourceTree = "<group>"; }; | ||
| 68 | + 08740E45230E7DFA00B5D28D /* FloatingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FloatingViewController.m; sourceTree = "<group>"; }; | ||
| 69 | + 08740E46230E7DFA00B5D28D /* AudioStreamingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioStreamingViewController.m; sourceTree = "<group>"; }; | ||
| 70 | + 08740E47230E7DFA00B5D28D /* MoreFunctionsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MoreFunctionsView.m; sourceTree = "<group>"; }; | ||
| 71 | + 08740E48230E7DFA00B5D28D /* AudioCfgView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioCfgView.m; sourceTree = "<group>"; }; | ||
| 72 | + 08740E49230E7DFA00B5D28D /* FilterFunctionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilterFunctionView.h; sourceTree = "<group>"; }; | ||
| 73 | + 08740E4A230E7DFA00B5D28D /* StreamerDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamerDetailViewController.h; sourceTree = "<group>"; }; | ||
| 74 | + 08740E4B230E7DFA00B5D28D /* CNLiveStreamerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNLiveStreamerController.h; sourceTree = "<group>"; }; | ||
| 75 | + 08740E4C230E7DFA00B5D28D /* SliderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SliderView.h; sourceTree = "<group>"; }; | ||
| 76 | + 08740E4D230E7DFA00B5D28D /* BgmPlayerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BgmPlayerView.m; sourceTree = "<group>"; }; | ||
| 77 | + 08740E4E230E7DFA00B5D28D /* FloatingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FloatingViewController.h; sourceTree = "<group>"; }; | ||
| 78 | + 08740E4F230E7DFA00B5D28D /* MoreFunctionsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MoreFunctionsView.h; sourceTree = "<group>"; }; | ||
| 79 | + 08740E50230E7DFA00B5D28D /* AudioStreamingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioStreamingViewController.h; sourceTree = "<group>"; }; | ||
| 80 | + 08740E5A230E83B100B5D28D /* LoadingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadingView.h; sourceTree = "<group>"; }; | ||
| 81 | + 08740E5B230E83B100B5D28D /* LoadingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LoadingView.m; sourceTree = "<group>"; }; | ||
| 82 | + 08740E5D230E8A0700B5D28D /* house.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = house.gif; sourceTree = "<group>"; }; | ||
| 83 | + 08740E60230E8C6500B5D28D /* CNLivePlayerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNLivePlayerController.m; sourceTree = "<group>"; }; | ||
| 84 | + 08740E61230E8C6500B5D28D /* CNLivePlayerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNLivePlayerController.h; sourceTree = "<group>"; }; | ||
| 56 | 17E088CE7F3FDB52D35B374B /* CNLivePlayer.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = CNLivePlayer.podspec; path = ../CNLivePlayer.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; | 85 | 17E088CE7F3FDB52D35B374B /* CNLivePlayer.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = CNLivePlayer.podspec; path = ../CNLivePlayer.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; |
| 57 | 26B97BD3DF7A4A551798F5CA /* Pods-CNLivePlayer_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLivePlayer_Tests.release.xcconfig"; path = "Target Support Files/Pods-CNLivePlayer_Tests/Pods-CNLivePlayer_Tests.release.xcconfig"; sourceTree = "<group>"; }; | 86 | 26B97BD3DF7A4A551798F5CA /* Pods-CNLivePlayer_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLivePlayer_Tests.release.xcconfig"; path = "Target Support Files/Pods-CNLivePlayer_Tests/Pods-CNLivePlayer_Tests.release.xcconfig"; sourceTree = "<group>"; }; |
| 58 | 32AFD179FF73966F488CAFA0 /* Pods-CNLivePlayer_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLivePlayer_Example.debug.xcconfig"; path = "Target Support Files/Pods-CNLivePlayer_Example/Pods-CNLivePlayer_Example.debug.xcconfig"; sourceTree = "<group>"; }; | 87 | 32AFD179FF73966F488CAFA0 /* Pods-CNLivePlayer_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLivePlayer_Example.debug.xcconfig"; path = "Target Support Files/Pods-CNLivePlayer_Example/Pods-CNLivePlayer_Example.debug.xcconfig"; sourceTree = "<group>"; }; |
| @@ -127,6 +156,43 @@ | @@ -127,6 +156,43 @@ | ||
| 127 | path = Pods; | 156 | path = Pods; |
| 128 | sourceTree = "<group>"; | 157 | sourceTree = "<group>"; |
| 129 | }; | 158 | }; |
| 159 | + 08740E3E230E7DFA00B5D28D /* Streamer */ = { | ||
| 160 | + isa = PBXGroup; | ||
| 161 | + children = ( | ||
| 162 | + 08740E5D230E8A0700B5D28D /* house.gif */, | ||
| 163 | + 08740E4B230E7DFA00B5D28D /* CNLiveStreamerController.h */, | ||
| 164 | + 08740E3F230E7DFA00B5D28D /* CNLiveStreamerController.m */, | ||
| 165 | + 08740E4A230E7DFA00B5D28D /* StreamerDetailViewController.h */, | ||
| 166 | + 08740E40230E7DFA00B5D28D /* StreamerDetailViewController.m */, | ||
| 167 | + 08740E5A230E83B100B5D28D /* LoadingView.h */, | ||
| 168 | + 08740E5B230E83B100B5D28D /* LoadingView.m */, | ||
| 169 | + 08740E50230E7DFA00B5D28D /* AudioStreamingViewController.h */, | ||
| 170 | + 08740E46230E7DFA00B5D28D /* AudioStreamingViewController.m */, | ||
| 171 | + 08740E4E230E7DFA00B5D28D /* FloatingViewController.h */, | ||
| 172 | + 08740E45230E7DFA00B5D28D /* FloatingViewController.m */, | ||
| 173 | + 08740E49230E7DFA00B5D28D /* FilterFunctionView.h */, | ||
| 174 | + 08740E41230E7DFA00B5D28D /* FilterFunctionView.m */, | ||
| 175 | + 08740E42230E7DFA00B5D28D /* AudioCfgView.h */, | ||
| 176 | + 08740E48230E7DFA00B5D28D /* AudioCfgView.m */, | ||
| 177 | + 08740E43230E7DFA00B5D28D /* BgmPlayerView.h */, | ||
| 178 | + 08740E4D230E7DFA00B5D28D /* BgmPlayerView.m */, | ||
| 179 | + 08740E4C230E7DFA00B5D28D /* SliderView.h */, | ||
| 180 | + 08740E44230E7DFA00B5D28D /* SliderView.m */, | ||
| 181 | + 08740E4F230E7DFA00B5D28D /* MoreFunctionsView.h */, | ||
| 182 | + 08740E47230E7DFA00B5D28D /* MoreFunctionsView.m */, | ||
| 183 | + ); | ||
| 184 | + path = Streamer; | ||
| 185 | + sourceTree = "<group>"; | ||
| 186 | + }; | ||
| 187 | + 08740E5F230E8C6500B5D28D /* Player */ = { | ||
| 188 | + isa = PBXGroup; | ||
| 189 | + children = ( | ||
| 190 | + 08740E60230E8C6500B5D28D /* CNLivePlayerController.m */, | ||
| 191 | + 08740E61230E8C6500B5D28D /* CNLivePlayerController.h */, | ||
| 192 | + ); | ||
| 193 | + path = Player; | ||
| 194 | + sourceTree = "<group>"; | ||
| 195 | + }; | ||
| 130 | 6003F581195388D10070C39A = { | 196 | 6003F581195388D10070C39A = { |
| 131 | isa = PBXGroup; | 197 | isa = PBXGroup; |
| 132 | children = ( | 198 | children = ( |
| @@ -171,10 +237,8 @@ | @@ -171,10 +237,8 @@ | ||
| 171 | children = ( | 237 | children = ( |
| 172 | 6003F59C195388D20070C39A /* CNLiveAppDelegate.h */, | 238 | 6003F59C195388D20070C39A /* CNLiveAppDelegate.h */, |
| 173 | 6003F59D195388D20070C39A /* CNLiveAppDelegate.m */, | 239 | 6003F59D195388D20070C39A /* CNLiveAppDelegate.m */, |
| 174 | - 0807DF0C230799E000F409AC /* CNLivePlayerController.h */, | ||
| 175 | - 0807DF0D230799E000F409AC /* CNLivePlayerController.m */, | ||
| 176 | - 085FA986230D34890072B936 /* CNLiveStreamerController.h */, | ||
| 177 | - 085FA987230D34890072B936 /* CNLiveStreamerController.m */, | 240 | + 08740E5F230E8C6500B5D28D /* Player */, |
| 241 | + 08740E3E230E7DFA00B5D28D /* Streamer */, | ||
| 178 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */, | 242 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */, |
| 179 | 6003F5A5195388D20070C39A /* CNLiveViewController.h */, | 243 | 6003F5A5195388D20070C39A /* CNLiveViewController.h */, |
| 180 | 6003F5A6195388D20070C39A /* CNLiveViewController.m */, | 244 | 6003F5A6195388D20070C39A /* CNLiveViewController.m */, |
| @@ -311,6 +375,7 @@ | @@ -311,6 +375,7 @@ | ||
| 311 | buildActionMask = 2147483647; | 375 | buildActionMask = 2147483647; |
| 312 | files = ( | 376 | files = ( |
| 313 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */, | 377 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */, |
| 378 | + 08740E5E230E8A0700B5D28D /* house.gif in Resources */, | ||
| 314 | 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */, | 379 | 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */, |
| 315 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */, | 380 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */, |
| 316 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */, | 381 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */, |
| @@ -381,6 +446,7 @@ | @@ -381,6 +446,7 @@ | ||
| 381 | "${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework", | 446 | "${BUILT_PRODUCTS_DIR}/CocoaLumberjack/CocoaLumberjack.framework", |
| 382 | "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework", | 447 | "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework", |
| 383 | "${BUILT_PRODUCTS_DIR}/GPUImage/GPUImage.framework", | 448 | "${BUILT_PRODUCTS_DIR}/GPUImage/GPUImage.framework", |
| 449 | + "${BUILT_PRODUCTS_DIR}/YYImage/YYImage.framework", | ||
| 384 | "${BUILT_PRODUCTS_DIR}/libksygpulive/libksygpulive.framework", | 450 | "${BUILT_PRODUCTS_DIR}/libksygpulive/libksygpulive.framework", |
| 385 | ); | 451 | ); |
| 386 | name = "[CP] Embed Pods Frameworks"; | 452 | name = "[CP] Embed Pods Frameworks"; |
| @@ -392,6 +458,7 @@ | @@ -392,6 +458,7 @@ | ||
| 392 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaLumberjack.framework", | 458 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaLumberjack.framework", |
| 393 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework", | 459 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework", |
| 394 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GPUImage.framework", | 460 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GPUImage.framework", |
| 461 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYImage.framework", | ||
| 395 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libksygpulive.framework", | 462 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libksygpulive.framework", |
| 396 | ); | 463 | ); |
| 397 | runOnlyForDeploymentPostprocessing = 0; | 464 | runOnlyForDeploymentPostprocessing = 0; |
| @@ -428,11 +495,20 @@ | @@ -428,11 +495,20 @@ | ||
| 428 | isa = PBXSourcesBuildPhase; | 495 | isa = PBXSourcesBuildPhase; |
| 429 | buildActionMask = 2147483647; | 496 | buildActionMask = 2147483647; |
| 430 | files = ( | 497 | files = ( |
| 498 | + 08740E58230E7DFB00B5D28D /* AudioCfgView.m in Sources */, | ||
| 499 | + 08740E5C230E83B100B5D28D /* LoadingView.m in Sources */, | ||
| 500 | + 08740E55230E7DFB00B5D28D /* FloatingViewController.m in Sources */, | ||
| 431 | 6003F59E195388D20070C39A /* CNLiveAppDelegate.m in Sources */, | 501 | 6003F59E195388D20070C39A /* CNLiveAppDelegate.m in Sources */, |
| 432 | - 0807DF0E230799E000F409AC /* CNLivePlayerController.m in Sources */, | 502 | + 08740E52230E7DFB00B5D28D /* StreamerDetailViewController.m in Sources */, |
| 433 | 6003F5A7195388D20070C39A /* CNLiveViewController.m in Sources */, | 503 | 6003F5A7195388D20070C39A /* CNLiveViewController.m in Sources */, |
| 504 | + 08740E56230E7DFB00B5D28D /* AudioStreamingViewController.m in Sources */, | ||
| 505 | + 08740E62230E8C6500B5D28D /* CNLivePlayerController.m in Sources */, | ||
| 506 | + 08740E54230E7DFB00B5D28D /* SliderView.m in Sources */, | ||
| 434 | 6003F59A195388D20070C39A /* main.m in Sources */, | 507 | 6003F59A195388D20070C39A /* main.m in Sources */, |
| 435 | - 085FA988230D34890072B936 /* CNLiveStreamerController.m in Sources */, | 508 | + 08740E59230E7DFB00B5D28D /* BgmPlayerView.m in Sources */, |
| 509 | + 08740E57230E7DFB00B5D28D /* MoreFunctionsView.m in Sources */, | ||
| 510 | + 08740E53230E7DFB00B5D28D /* FilterFunctionView.m in Sources */, | ||
| 511 | + 08740E51230E7DFB00B5D28D /* CNLiveStreamerController.m in Sources */, | ||
| 436 | ); | 512 | ); |
| 437 | runOnlyForDeploymentPostprocessing = 0; | 513 | runOnlyForDeploymentPostprocessing = 0; |
| 438 | }; | 514 | }; |
Example/CNLivePlayer/CNLiveStreamerController.m deleted
100644 → 0
| 1 | -// | ||
| 2 | -// CNLiveStreamerController.m | ||
| 3 | -// CNLivePlayer_Example | ||
| 4 | -// | ||
| 5 | -// Created by CNLive-zxw on 2019/8/21. | ||
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | ||
| 7 | -// | ||
| 8 | - | ||
| 9 | -#import "CNLiveStreamerController.h" | ||
| 10 | - | ||
| 11 | -@interface CNLiveStreamerController () | ||
| 12 | - | ||
| 13 | -@end | ||
| 14 | - | ||
| 15 | -@implementation CNLiveStreamerController | ||
| 16 | - | ||
| 17 | -- (void)viewDidLoad { | ||
| 18 | - [super viewDidLoad]; | ||
| 19 | - // Do any additional setup after loading the view. | ||
| 20 | - self.view.backgroundColor = [UIColor whiteColor]; | ||
| 21 | - UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeCustom]; | ||
| 22 | - btn2.frame = CGRectMake(0, 0, 100, 50); | ||
| 23 | - btn2.center = CGPointMake(self.view.center.x, self.view.center.y+50); | ||
| 24 | - btn2.backgroundColor = [UIColor redColor]; | ||
| 25 | - [btn2 setTitle:@"返回" forState:UIControlStateNormal]; | ||
| 26 | - [btn2 setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; | ||
| 27 | - [btn2 addTarget:self action:@selector(btnDidClicked2) forControlEvents:UIControlEventTouchUpInside]; | ||
| 28 | - [self.view addSubview:btn2]; | ||
| 29 | -} | ||
| 30 | - | ||
| 31 | - | ||
| 32 | -- (void)btnDidClicked2{ | ||
| 33 | - [self dismissViewControllerAnimated:YES completion:nil]; | ||
| 34 | - | ||
| 35 | -} | ||
| 36 | - | ||
| 37 | -/* | ||
| 38 | -#pragma mark - Navigation | ||
| 39 | - | ||
| 40 | -// In a storyboard-based application, you will often want to do a little preparation before navigation | ||
| 41 | -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { | ||
| 42 | - // Get the new view controller using [segue destinationViewController]. | ||
| 43 | - // Pass the selected object to the new view controller. | ||
| 44 | -} | ||
| 45 | -*/ | ||
| 46 | - | ||
| 47 | -@end |
Example/CNLivePlayer/Images.xcassets/Contents.json
0 → 100644
Example/CNLivePlayer/Images.xcassets/Streamer/Contents.json
0 → 100644
Example/CNLivePlayer/Images.xcassets/Streamer/back.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "back.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/back.imageset/back.png
0 → 100644
1.16 KB
Example/CNLivePlayer/Images.xcassets/Streamer/big_pause_button.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "big_pause_button.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/big_pause_button.imageset/big_pause_button.png
0 → 100644
3.7 KB
Example/CNLivePlayer/Images.xcassets/Streamer/big_play_button.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "big_play_button.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/big_play_button.imageset/big_play_button.png
0 → 100644
3.68 KB
Example/CNLivePlayer/Images.xcassets/Streamer/btn_dot.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "btn_dot.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/btn_dot.imageset/btn_dot.png
0 → 100644
627 Bytes
Example/CNLivePlayer/Images.xcassets/Streamer/cache setting.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "cache setting.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/cache setting.imageset/cache setting.png
0 → 100644
1.26 KB
Example/CNLivePlayer/Images.xcassets/Streamer/camera.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "camera.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/camera.imageset/camera.png
0 → 100644
1.4 KB
Example/CNLivePlayer/Images.xcassets/Streamer/cancel.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "cancel.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/cancel.imageset/cancel.png
0 → 100644
1.14 KB
Example/CNLivePlayer/Images.xcassets/Streamer/fanhui.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "fanhui.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/fanhui.imageset/fanhui.png
0 → 100644
983 Bytes
Example/CNLivePlayer/Images.xcassets/Streamer/filter.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "filter.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/filter.imageset/filter.png
0 → 100644
1.18 KB
Example/CNLivePlayer/Images.xcassets/Streamer/flash close.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "flash close.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/flash close.imageset/flash close.png
0 → 100644
1.13 KB
Example/CNLivePlayer/Images.xcassets/Streamer/flash open.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "flash open.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/flash open.imageset/flash open.png
0 → 100644
1.21 KB
Example/CNLivePlayer/Images.xcassets/Streamer/loop_all_icon.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "loop_all_icon.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/loop_all_icon.imageset/loop_all_icon.png
0 → 100644
840 Bytes
Example/CNLivePlayer/Images.xcassets/Streamer/loop_single_icon.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "loop_single_icon.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/loop_single_icon.imageset/loop_single_icon.png
0 → 100644
948 Bytes
Example/CNLivePlayer/Images.xcassets/Streamer/menu.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "menu.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/menu.imageset/menu.png
0 → 100644
296 Bytes
Example/CNLivePlayer/Images.xcassets/Streamer/music_slider_circle.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "music_slider_circle.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/music_slider_circle.imageset/music_slider_circle.png
0 → 100644
1.07 KB
Example/CNLivePlayer/Images.xcassets/Streamer/next_song.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "next_song.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/next_song.imageset/next_song.png
0 → 100644
814 Bytes
Example/CNLivePlayer/Images.xcassets/Streamer/pause.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "pause.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/pause.imageset/pause.png
0 → 100644
3.15 KB
Example/CNLivePlayer/Images.xcassets/Streamer/play.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "play.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/play.imageset/play.png
0 → 100644
6.41 KB
Example/CNLivePlayer/Images.xcassets/Streamer/prev_song.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "prev_song.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/prev_song.imageset/prev_song.png
0 → 100644
845 Bytes
Example/CNLivePlayer/Images.xcassets/Streamer/shuffle_icon.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "shuffle_icon.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/shuffle_icon.imageset/shuffle_icon.png
0 → 100644
802 Bytes
Example/CNLivePlayer/Images.xcassets/Streamer/voice.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "voice.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/voice.imageset/voice.png
0 → 100644
1.27 KB
Example/CNLivePlayer/Images.xcassets/Streamer/互动电视180x180.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "互动电视180x180.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/互动电视180x180.imageset/互动电视180x180.png
0 → 100644
21.2 KB
Example/CNLivePlayer/Images.xcassets/Streamer/更多.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "更多.png", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/更多.imageset/更多.png
0 → 100644
1.38 KB
Example/CNLivePlayer/Images.xcassets/Streamer/背景.imageset/Contents.json
0 → 100644
| 1 | +{ | ||
| 2 | + "images" : [ | ||
| 3 | + { | ||
| 4 | + "idiom" : "universal", | ||
| 5 | + "filename" : "背景.jpg", | ||
| 6 | + "scale" : "1x" | ||
| 7 | + }, | ||
| 8 | + { | ||
| 9 | + "idiom" : "universal", | ||
| 10 | + "scale" : "2x" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "idiom" : "universal", | ||
| 14 | + "scale" : "3x" | ||
| 15 | + } | ||
| 16 | + ], | ||
| 17 | + "info" : { | ||
| 18 | + "version" : 1, | ||
| 19 | + "author" : "xcode" | ||
| 20 | + } | ||
| 21 | +} | ||
| 0 | \ No newline at end of file | 22 | \ No newline at end of file |
Example/CNLivePlayer/Images.xcassets/Streamer/背景.imageset/背景.jpg
0 → 100644
17.1 KB
Example/CNLivePlayer/CNLivePlayerController.h renamed to Example/CNLivePlayer/Player/CNLivePlayerController.h
Example/CNLivePlayer/CNLivePlayerController.m renamed to Example/CNLivePlayer/Player/CNLivePlayerController.m
Example/CNLivePlayer/Streamer/AudioCfgView.h
0 → 100644
| 1 | +// | ||
| 2 | +// AudioCfgView.h | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 17/4/26. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import <UIKit/UIKit.h> | ||
| 10 | + | ||
| 11 | +typedef void(^AudioEffectBlock)(int type); //音效回调 | ||
| 12 | +typedef void(^ReverbTypeBlock)(int type); //混响回调 | ||
| 13 | +typedef void(^BPlayCapturedAudioBlock)(BOOL isOn); //是否开启耳返 | ||
| 14 | +typedef void(^MicVolumeBlock)(float micVolume); //麦克风音量 | ||
| 15 | +typedef void(^BPlayVolumeBlock)(float bPlayVolume); //耳返音量 | ||
| 16 | + | ||
| 17 | +@interface AudioCfgView : UIView | ||
| 18 | + | ||
| 19 | +@property (nonatomic, strong) UISwitch *bPlaySwitch; | ||
| 20 | + | ||
| 21 | +@property (nonatomic, copy) AudioEffectBlock audioEffectBlock; | ||
| 22 | +@property (nonatomic, copy) ReverbTypeBlock reverbTypeBlock; | ||
| 23 | +@property (nonatomic, copy) BPlayCapturedAudioBlock bPlayCapturedAudio; | ||
| 24 | +@property (nonatomic, copy) MicVolumeBlock micVolumeBlock; | ||
| 25 | +@property (nonatomic, copy) BPlayVolumeBlock bPlayVolumeBlock; | ||
| 26 | + | ||
| 27 | +@end |
Example/CNLivePlayer/Streamer/AudioCfgView.m
0 → 100644
| 1 | +// | ||
| 2 | +// AudioCfgView.m | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 17/4/26. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "AudioCfgView.h" | ||
| 10 | + | ||
| 11 | +@interface AudioCfgView () | ||
| 12 | + | ||
| 13 | +@property (nonatomic, strong) UISegmentedControl *audioEffectType; | ||
| 14 | +@property (nonatomic, strong) UISegmentedControl *reverbType; | ||
| 15 | +@property (nonatomic, strong) UISlider *micVolumeSlider; | ||
| 16 | +@property (nonatomic, strong) UISlider *bPlayVolumeSlider; | ||
| 17 | + | ||
| 18 | +@end | ||
| 19 | + | ||
| 20 | +@implementation AudioCfgView | ||
| 21 | + | ||
| 22 | +- (instancetype)initWithFrame:(CGRect)frame | ||
| 23 | +{ | ||
| 24 | + self = [super initWithFrame:frame]; | ||
| 25 | + if (self) { | ||
| 26 | + self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.1]; | ||
| 27 | + [self addSubview:self.audioEffectType]; | ||
| 28 | + [self addSubview:self.reverbType]; | ||
| 29 | + [self addSubview:self.bPlaySwitch]; | ||
| 30 | + [self addSubview:self.micVolumeSlider]; | ||
| 31 | + [self addSubview:self.bPlayVolumeSlider]; | ||
| 32 | + } | ||
| 33 | + return self; | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +#pragma mark - | ||
| 37 | +#pragma mark - action | ||
| 38 | +- (void)audioEffect:(UISegmentedControl *)sender { | ||
| 39 | + self.audioEffectBlock ? self.audioEffectBlock((int)sender.selectedSegmentIndex) : nil; | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +- (void)reverbType:(UISegmentedControl *)sender { | ||
| 43 | + self.reverbTypeBlock ? self.reverbTypeBlock((int)sender.selectedSegmentIndex) : nil; | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +-(void)switchAction:(id)sender { | ||
| 47 | + UISwitch *swi = (UISwitch *)sender; | ||
| 48 | + self.bPlayCapturedAudio ? self.bPlayCapturedAudio(swi.on) : nil; | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +- (void)micVolumeChanged:(UISlider *)slider { | ||
| 52 | + self.micVolumeBlock ? self.micVolumeBlock(slider.value) : nil; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +- (void)bPlayVolumeChanged:(UISlider *)slider { | ||
| 56 | + self.bPlayVolumeBlock ? self.bPlayVolumeBlock(slider.value) : nil; | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +#pragma mark - | ||
| 60 | +#pragma mark - getter | ||
| 61 | +- (UISegmentedControl *)audioEffectType | ||
| 62 | +{ | ||
| 63 | + if (!_audioEffectType) { | ||
| 64 | + NSArray *items = @[ @"关闭", | ||
| 65 | + @"大叔", | ||
| 66 | + @"萝莉", | ||
| 67 | + @"庄严", | ||
| 68 | + @"机器人"]; | ||
| 69 | + | ||
| 70 | + _audioEffectType = [[UISegmentedControl alloc] initWithItems:items]; | ||
| 71 | + _audioEffectType.frame = CGRectMake(60, 50, self.bounds.size.width-70, 30); | ||
| 72 | + _audioEffectType.tintColor= [UIColor blackColor]; | ||
| 73 | + _audioEffectType.selectedSegmentIndex = 0; | ||
| 74 | + _audioEffectType.layer.cornerRadius = 5; | ||
| 75 | + [_audioEffectType addTarget:self action:@selector(audioEffect:) forControlEvents:UIControlEventValueChanged]; | ||
| 76 | + | ||
| 77 | + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 55, 40, 20)]; | ||
| 78 | + label.text = @"变声"; | ||
| 79 | + [self addSubview:label]; | ||
| 80 | + } | ||
| 81 | + return _audioEffectType; | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +- (UISegmentedControl *)reverbType | ||
| 85 | +{ | ||
| 86 | + if (!_reverbType) { | ||
| 87 | + NSArray *items = @[ @"关闭", | ||
| 88 | + @"录音棚", | ||
| 89 | + @"演唱会", | ||
| 90 | + @"KTV", | ||
| 91 | + @"小舞台"]; | ||
| 92 | + | ||
| 93 | + _reverbType = [[UISegmentedControl alloc] initWithItems:items]; | ||
| 94 | + _reverbType.frame = CGRectMake(60, 90, self.bounds.size.width-70, 30); | ||
| 95 | + _reverbType.tintColor= [UIColor blackColor]; | ||
| 96 | + _reverbType.selectedSegmentIndex = 0; | ||
| 97 | + _reverbType.layer.cornerRadius = 5; | ||
| 98 | + [_reverbType addTarget:self action:@selector(reverbType:) forControlEvents:UIControlEventValueChanged]; | ||
| 99 | + | ||
| 100 | + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 95, 40, 20)]; | ||
| 101 | + label.text = @"混响"; | ||
| 102 | + [self addSubview:label]; | ||
| 103 | + } | ||
| 104 | + return _reverbType; | ||
| 105 | +} | ||
| 106 | + | ||
| 107 | +- (UISwitch *)bPlaySwitch | ||
| 108 | +{ | ||
| 109 | + if (!_bPlaySwitch) { | ||
| 110 | + _bPlaySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(60, 10, 100, 30)]; | ||
| 111 | + [_bPlaySwitch addTarget:self action:@selector(switchAction:) forControlEvents:UIControlEventValueChanged]; | ||
| 112 | + UILabel *modeLab = [[UILabel alloc] initWithFrame:CGRectMake(10, 15, 40, 20)]; | ||
| 113 | + modeLab.textColor = [UIColor blackColor]; | ||
| 114 | + modeLab.text = @"耳返"; | ||
| 115 | + [self addSubview:modeLab]; | ||
| 116 | + } | ||
| 117 | + return _bPlaySwitch; | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | +- (UISlider *)micVolumeSlider | ||
| 121 | +{ | ||
| 122 | + if (!_micVolumeSlider) { | ||
| 123 | + _micVolumeSlider = [[UISlider alloc] initWithFrame:CGRectMake(100, 135, self.bounds.size.width-110, 24)]; | ||
| 124 | + [_micVolumeSlider setMinimumTrackTintColor:[UIColor redColor]]; | ||
| 125 | + [_micVolumeSlider setMaximumTrackTintColor:[UIColor whiteColor]]; | ||
| 126 | + _micVolumeSlider.value = 1.0; | ||
| 127 | + [_micVolumeSlider addTarget:self action:@selector(micVolumeChanged:) forControlEvents:UIControlEventValueChanged]; | ||
| 128 | + [_micVolumeSlider setThumbImage:[UIImage imageNamed:@"btn_dot"] forState:UIControlStateNormal]; | ||
| 129 | + | ||
| 130 | + | ||
| 131 | + UILabel *micLab = [[UILabel alloc] initWithFrame:CGRectMake(10, 135, 90, 20)]; | ||
| 132 | + micLab.textColor = [UIColor blackColor]; | ||
| 133 | + micLab.text = @"麦克风音量"; | ||
| 134 | + [self addSubview:micLab]; | ||
| 135 | + } | ||
| 136 | + return _micVolumeSlider; | ||
| 137 | +} | ||
| 138 | + | ||
| 139 | +- (UISlider *)bPlayVolumeSlider | ||
| 140 | +{ | ||
| 141 | + if (!_bPlayVolumeSlider) { | ||
| 142 | + _bPlayVolumeSlider = [[UISlider alloc] initWithFrame:CGRectMake(100, 170, self.bounds.size.width-110, 24)]; | ||
| 143 | + _bPlayVolumeSlider.value = 1.0; | ||
| 144 | + [_bPlayVolumeSlider setMinimumTrackTintColor:[UIColor redColor]]; | ||
| 145 | + [_bPlayVolumeSlider setMaximumTrackTintColor:[UIColor whiteColor]]; | ||
| 146 | + [_bPlayVolumeSlider addTarget:self action:@selector(bPlayVolumeChanged:) forControlEvents:UIControlEventValueChanged]; | ||
| 147 | + [_bPlayVolumeSlider setThumbImage:[UIImage imageNamed:@"btn_dot"] forState:UIControlStateNormal]; | ||
| 148 | + | ||
| 149 | + UILabel *micLab = [[UILabel alloc] initWithFrame:CGRectMake(10, 170, 80, 20)]; | ||
| 150 | + micLab.textColor = [UIColor blackColor]; | ||
| 151 | + micLab.text = @"耳返音量"; | ||
| 152 | + [self addSubview:micLab]; | ||
| 153 | + } | ||
| 154 | + return _bPlayVolumeSlider; | ||
| 155 | +} | ||
| 156 | + | ||
| 157 | +/* | ||
| 158 | +// Only override drawRect: if you perform custom drawing. | ||
| 159 | +// An empty implementation adversely affects performance during animation. | ||
| 160 | +- (void)drawRect:(CGRect)rect { | ||
| 161 | + // Drawing code | ||
| 162 | +} | ||
| 163 | +*/ | ||
| 164 | + | ||
| 165 | +@end |
Example/CNLivePlayer/Streamer/AudioStreamingViewController.h
0 → 100644
| 1 | +// | ||
| 2 | +// AudioStreamingViewController.h | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 17/4/26. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import <UIKit/UIKit.h> | ||
| 10 | + | ||
| 11 | +@interface AudioStreamingViewController : UIViewController | ||
| 12 | + | ||
| 13 | +@property (nonatomic, assign) BOOL isAuthLive; | ||
| 14 | + | ||
| 15 | +@property (nonatomic, strong) NSURL *url; | ||
| 16 | + | ||
| 17 | +@end |
Example/CNLivePlayer/Streamer/AudioStreamingViewController.m
0 → 100644
| 1 | +// | ||
| 2 | +// AudioStreamingViewController.m | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 17/4/26. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "AudioStreamingViewController.h" | ||
| 10 | +#import "CNLiveStreamerManager.h" | ||
| 11 | +#import "CNLiveStreamerKit.h" | ||
| 12 | +#import "AudioCfgView.h" | ||
| 13 | +#import "BgmPlayerView.h" | ||
| 14 | +#import "CNLiveStreamerBase.h" | ||
| 15 | +#import "CNLiveWatermark.h" | ||
| 16 | +#import "CNLiveAudioCapture.h" | ||
| 17 | +#import "CNLiveBgmPlayer.h" | ||
| 18 | + | ||
| 19 | +#define Width [UIScreen mainScreen].bounds.size.width | ||
| 20 | +#define Height [UIScreen mainScreen].bounds.size.height | ||
| 21 | + | ||
| 22 | +@interface AudioStreamingViewController ()<BgmPlayerViewDelegate> | ||
| 23 | +{ | ||
| 24 | + UIButton *_startLiveBtn; | ||
| 25 | + NSArray *_listArr; | ||
| 26 | + NSInteger _currentIndex; | ||
| 27 | + NSTimer *_currentTimer; | ||
| 28 | + BOOL _playMode; //播放模式 | ||
| 29 | +} | ||
| 30 | + | ||
| 31 | +@property (nonatomic,strong) CNLiveStreamerKit *kitCN; //直播推流 | ||
| 32 | +@property (nonatomic,strong) UILabel *stateLab; | ||
| 33 | +@property (nonatomic,strong) AudioCfgView *audioCfgView; //声音相关设置 | ||
| 34 | +@property (nonatomic,strong) BgmPlayerView *bgmPlayerView; //背景音乐 | ||
| 35 | + | ||
| 36 | +@end | ||
| 37 | + | ||
| 38 | +@implementation AudioStreamingViewController | ||
| 39 | + | ||
| 40 | +- (void)viewDidLoad { | ||
| 41 | + [super viewDidLoad]; | ||
| 42 | + // Do any additional setup after loading the view. | ||
| 43 | + self.view.backgroundColor = [UIColor whiteColor]; | ||
| 44 | + [self.view addSubview:self.stateLab]; | ||
| 45 | + [self.view addSubview:self.audioCfgView]; | ||
| 46 | + [self.view addSubview:self.bgmPlayerView]; | ||
| 47 | + | ||
| 48 | + _currentTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timeChange) userInfo:nil repeats:YES]; | ||
| 49 | + | ||
| 50 | + | ||
| 51 | + if (_isAuthLive) { | ||
| 52 | + | ||
| 53 | + NSDate *date = [NSDate date]; | ||
| 54 | + NSInteger time = [date timeIntervalSince1970]; | ||
| 55 | + NSString *activityId = [NSString stringWithFormat:@"%ld", (long)time]; | ||
| 56 | + | ||
| 57 | + _kitCN = [[CNLiveStreamerKit alloc] initPureAudioStreamerWithDefaultConfig]; | ||
| 58 | + _kitCN.activityId = activityId; | ||
| 59 | + _kitCN.channelId = @"iostest"; | ||
| 60 | + | ||
| 61 | + [self setStreamerCfg]; | ||
| 62 | + [self addObservers]; | ||
| 63 | + | ||
| 64 | + }else{ | ||
| 65 | + | ||
| 66 | + _kitCN = [[CNLiveStreamerKit alloc] initWithDefaultConfig:YES]; | ||
| 67 | + | ||
| 68 | + [self setStreamerCfg]; | ||
| 69 | + [self addObservers]; | ||
| 70 | + | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + _startLiveBtn = [self addButton:@"开始直播" frame:CGRectMake(10, 40, 80, 40) action:@selector(startStreaming:)]; | ||
| 74 | + [_startLiveBtn setTitle:@"开始直播" forState:UIControlStateNormal]; | ||
| 75 | + [_startLiveBtn setTitle:@"停止直播" forState:UIControlStateSelected]; | ||
| 76 | + | ||
| 77 | + [self addButton:@"退出" frame:CGRectMake(100, 40, 80, 40) action:@selector(quit)]; | ||
| 78 | + [self addButton:@"背景音乐" frame:CGRectMake(10, 100, 80, 40) action:@selector(bgmPlayerBtnAction:)]; | ||
| 79 | + [self addButton:@"声音" frame:CGRectMake(100, 100, 80, 40) action:@selector(voiceBtnAction:)]; | ||
| 80 | + | ||
| 81 | + _listArr = @[@" See You Again ", | ||
| 82 | + @"Idina Menzel - Let It Go", | ||
| 83 | + @"Morrie - Lullaby", | ||
| 84 | + @"Zedd,Alessia Cara - Stay"]; | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +- (void)setStreamerCfg { | ||
| 88 | + _kitCN.streamerBase.audiokBPS = 48; | ||
| 89 | + | ||
| 90 | + //声音相关设置 | ||
| 91 | + __weak AudioStreamingViewController *weakself = self; | ||
| 92 | + | ||
| 93 | + _audioCfgView.audioEffectBlock = ^(int type) { //音效 | ||
| 94 | + weakself.kitCN.audioCapture.audioEffectType = type; | ||
| 95 | + }; | ||
| 96 | + | ||
| 97 | + _audioCfgView.reverbTypeBlock = ^(int type) { //混响 | ||
| 98 | + weakself.kitCN.audioCapture.reverbType = type; | ||
| 99 | + }; | ||
| 100 | + | ||
| 101 | + _audioCfgView.bPlayCapturedAudio = ^(BOOL isOn) { //耳返 | ||
| 102 | + if ([CNLiveAudioCapture isHeadsetPluggedIn]) { | ||
| 103 | + [weakself.kitCN.audioCapture setBPlayCapturedAudio:isOn]; | ||
| 104 | + } else { | ||
| 105 | + weakself.audioCfgView.bPlaySwitch.on = NO; | ||
| 106 | + [weakself toast:@"未检测到耳机"]; | ||
| 107 | + } | ||
| 108 | + }; | ||
| 109 | + | ||
| 110 | + _audioCfgView.micVolumeBlock = ^(float micVolume) { //麦克风音量 | ||
| 111 | + weakself.kitCN.audioCapture.micVolume = micVolume; | ||
| 112 | + }; | ||
| 113 | + | ||
| 114 | + _audioCfgView.bPlayVolumeBlock = ^(float bPlayVolume) { //耳返音量 | ||
| 115 | + weakself.kitCN.audioCapture.bPlayVolume = bPlayVolume; | ||
| 116 | + }; | ||
| 117 | + | ||
| 118 | + _kitCN.bgmPlayer.cnBgmFinishBlock = ^{ | ||
| 119 | + if (!_playMode) { | ||
| 120 | + if (_currentIndex != 3) { | ||
| 121 | + _currentIndex ++; | ||
| 122 | + [_kitCN.bgmPlayer stopPlayBgm]; | ||
| 123 | + [_kitCN.bgmPlayer startPlayBgm:[[NSBundle mainBundle] pathForResource:_listArr[_currentIndex] ofType:@"mp3"] isLoop:_playMode]; | ||
| 124 | + _bgmPlayerView.songTitleLab.text = _listArr[_currentIndex]; | ||
| 125 | + } | ||
| 126 | + } | ||
| 127 | + }; | ||
| 128 | + | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +- (UIButton *)addButton:(NSString*)title | ||
| 132 | + frame:(CGRect)frame | ||
| 133 | + action:(SEL)action { | ||
| 134 | + UIButton * button; | ||
| 135 | + button = [UIButton buttonWithType:UIButtonTypeCustom]; | ||
| 136 | + button.frame = frame; | ||
| 137 | + [button setTitle: title forState: UIControlStateNormal]; | ||
| 138 | + [button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside]; | ||
| 139 | + button.titleLabel.font = [UIFont systemFontOfSize:15]; | ||
| 140 | + [button setTitleColor:[UIColor colorWithRed:23/255.0 green:110/255.0 blue:254/255.0 alpha:1] forState:UIControlStateNormal]; | ||
| 141 | + button.layer.cornerRadius = 10; | ||
| 142 | + button.layer.masksToBounds = YES; | ||
| 143 | + button.layer.borderColor = [UIColor blackColor].CGColor; | ||
| 144 | + button.layer.borderWidth = 1; | ||
| 145 | + [self.view addSubview:button]; | ||
| 146 | + return button; | ||
| 147 | + | ||
| 148 | +} | ||
| 149 | + | ||
| 150 | +#pragma mark - | ||
| 151 | +#pragma mark - action | ||
| 152 | +- (void)startStreaming:(UIButton *)button { | ||
| 153 | + button.selected = !button.selected; | ||
| 154 | + | ||
| 155 | + if (button.selected) { | ||
| 156 | + | ||
| 157 | + if (_isAuthLive) { | ||
| 158 | + | ||
| 159 | + [_kitCN startStream:^{ | ||
| 160 | + NSLog(@"开启推流成功 ------- success"); | ||
| 161 | + } failure:^(NSDictionary *errorDic) { | ||
| 162 | + [self toast:errorDic[@"errorMessage"]]; | ||
| 163 | + _startLiveBtn.selected = NO; | ||
| 164 | + }]; | ||
| 165 | + | ||
| 166 | + }else{ | ||
| 167 | + [_kitCN startStream:self.url]; | ||
| 168 | + } | ||
| 169 | + }else{ | ||
| 170 | + _stateLab.text = nil; | ||
| 171 | + [_kitCN stopStream]; | ||
| 172 | + } | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +- (void)quit { | ||
| 176 | + if (_kitCN.streamState == CNLiveStreamStateConnected) { | ||
| 177 | + [_kitCN stopStream]; | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + if (_kitCN.bgmPlayer.isRunning) { | ||
| 181 | + [_kitCN.bgmPlayer stopPlayBgm]; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + if (_currentTimer) { | ||
| 185 | + [_currentTimer invalidate]; | ||
| 186 | + _currentTimer = nil; | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + [_kitCN quitStreaming]; | ||
| 190 | + self.kitCN = nil; | ||
| 191 | + [[NSNotificationCenter defaultCenter] removeObserver:self]; | ||
| 192 | + | ||
| 193 | + [self dismissViewControllerAnimated:YES completion:NULL]; | ||
| 194 | +} | ||
| 195 | + | ||
| 196 | +- (void)bgmPlayerBtnAction:(UIButton *)button { | ||
| 197 | + _audioCfgView.hidden = YES; | ||
| 198 | + _bgmPlayerView.hidden = button.selected; | ||
| 199 | + button.selected = !button.selected; | ||
| 200 | +} | ||
| 201 | + | ||
| 202 | +- (void)voiceBtnAction:(UIButton *)button { | ||
| 203 | + _bgmPlayerView.hidden = YES; | ||
| 204 | + _audioCfgView.hidden = button.selected; | ||
| 205 | + button.selected = !button.selected; | ||
| 206 | +} | ||
| 207 | + | ||
| 208 | +- (void)timeChange | ||
| 209 | +{ | ||
| 210 | + _bgmPlayerView.proSlider.value = _kitCN.bgmPlayer.bgmPlayTime/_kitCN.bgmPlayer.bgmDuration; | ||
| 211 | + _bgmPlayerView.currentTimeLab.text = [self getMMSSFromSS:[NSString stringWithFormat:@"%f",_kitCN.bgmPlayer.bgmPlayTime]]; | ||
| 212 | + _bgmPlayerView.duraTimeLab.text = [self getMMSSFromSS:[NSString stringWithFormat:@"%f",_kitCN.bgmPlayer.bgmDuration]]; | ||
| 213 | +} | ||
| 214 | + | ||
| 215 | +- (NSString *)getMMSSFromSS:(NSString *)totalTime { | ||
| 216 | + NSInteger seconds = [totalTime integerValue]; | ||
| 217 | + NSString *str_minute = [NSString stringWithFormat:@"%02ld",(seconds%3600)/60]; | ||
| 218 | + NSString *str_second = [NSString stringWithFormat:@"%02ld",seconds%60]; | ||
| 219 | + NSString *format_time = [NSString stringWithFormat:@"%@:%@",str_minute,str_second]; | ||
| 220 | + return format_time; | ||
| 221 | +} | ||
| 222 | + | ||
| 223 | +#pragma mark - | ||
| 224 | +#pragma mark - BgmPlayerViewDelegate | ||
| 225 | +- (void)valueType:(BOOL)isVolume value:(float)value { | ||
| 226 | + if (isVolume) { | ||
| 227 | + _kitCN.bgmPlayer.bgmVolume = value; | ||
| 228 | + } else { | ||
| 229 | + _kitCN.bgmPlayer.bgmPitch = value; | ||
| 230 | + } | ||
| 231 | +} | ||
| 232 | + | ||
| 233 | +- (void)bgmPlayerPlay:(UIButton *)button { | ||
| 234 | + if (_kitCN.bgmPlayer.isRunning) { | ||
| 235 | + [_kitCN.bgmPlayer stopPlayBgm]; | ||
| 236 | + } else { | ||
| 237 | + NSString *path = [[NSBundle mainBundle] pathForResource:_listArr[_currentIndex] ofType:@"mp3"]; | ||
| 238 | + _bgmPlayerView.songTitleLab.text = _listArr[_currentIndex]; | ||
| 239 | + [_kitCN.bgmPlayer startPlayBgm:path isLoop:_playMode]; | ||
| 240 | + } | ||
| 241 | +} | ||
| 242 | + | ||
| 243 | +- (void)bgmPlayerMode:(UIButton *)button { | ||
| 244 | + _kitCN.bgmPlayer.bLoop = button.selected; | ||
| 245 | + _playMode = _kitCN.bgmPlayer.bLoop; | ||
| 246 | +} | ||
| 247 | + | ||
| 248 | +- (void)bgmPlayerPauseOrResume:(UIButton *)button { | ||
| 249 | + if (button.selected) { | ||
| 250 | + [_kitCN.bgmPlayer pauseBgm]; | ||
| 251 | + } else { | ||
| 252 | + [_kitCN.bgmPlayer resumeBgm]; | ||
| 253 | + } | ||
| 254 | +} | ||
| 255 | + | ||
| 256 | +- (void)bgmPlayerLast:(UIButton *)button { | ||
| 257 | + /* | ||
| 258 | + if (_currentIndex == 0) { | ||
| 259 | + [self toast:@"已经是第一首"]; | ||
| 260 | + } else { | ||
| 261 | + _currentIndex --; | ||
| 262 | + [_kitCN.bgmPlayer stopPlayBgm]; | ||
| 263 | + [_kitCN.bgmPlayer startPlayBgm:[[NSBundle mainBundle] pathForResource:_listArr[_currentIndex] ofType:@"mp3"] isLoop:_playMode]; | ||
| 264 | + _bgmPlayerView.songTitleLab.text = _listArr[_currentIndex]; | ||
| 265 | + } | ||
| 266 | + */ | ||
| 267 | + | ||
| 268 | + [_kitCN.streamerBase muteStream:button.selected]; | ||
| 269 | +} | ||
| 270 | + | ||
| 271 | +- (void)bgmPlayerNext:(UIButton *)button; { | ||
| 272 | + if (_currentIndex == 3) { | ||
| 273 | + [self toast:@"已经是最后一首"]; | ||
| 274 | + } else { | ||
| 275 | + _currentIndex ++; | ||
| 276 | + [_kitCN.bgmPlayer stopPlayBgm]; | ||
| 277 | + [_kitCN.bgmPlayer startPlayBgm:[[NSBundle mainBundle] pathForResource:_listArr[_currentIndex] ofType:@"mp3"] isLoop:_playMode]; | ||
| 278 | + _bgmPlayerView.songTitleLab.text = _listArr[_currentIndex]; | ||
| 279 | + } | ||
| 280 | +} | ||
| 281 | + | ||
| 282 | +- (void)bgmPlayerProgressSlider:(UISlider *)slider { | ||
| 283 | + [_kitCN.bgmPlayer seekToProgress:slider.value]; | ||
| 284 | +} | ||
| 285 | + | ||
| 286 | +#pragma mark - | ||
| 287 | +#pragma mark - notification | ||
| 288 | +- (void)addObservers | ||
| 289 | +{ | ||
| 290 | + [[NSNotificationCenter defaultCenter] addObserver:self | ||
| 291 | + selector:@selector(streamStateChange) | ||
| 292 | + name:CNLiveStreamerStateDidChangeNotification | ||
| 293 | + object:nil]; | ||
| 294 | +} | ||
| 295 | + | ||
| 296 | +- (void)streamStateChange | ||
| 297 | +{ | ||
| 298 | + | ||
| 299 | + if (_kitCN.streamState == CNLiveStreamStateIdle) { | ||
| 300 | + NSLog(@"---------CNLiveStreamStateIdle"); | ||
| 301 | + _stateLab.text = @"CNLiveStreamStateIdle"; | ||
| 302 | + } | ||
| 303 | + | ||
| 304 | + if (_kitCN.streamState == CNLiveStreamStateConnected) { | ||
| 305 | + _startLiveBtn.selected = YES; | ||
| 306 | + NSLog(@"---------CNLiveStreamStateConnected"); | ||
| 307 | + _stateLab.text = [NSString stringWithFormat:@"CNLiveStreamStateConnected------%@",self.url]; | ||
| 308 | + } | ||
| 309 | + | ||
| 310 | + if (_kitCN.streamState == CNLiveStreamStateConnecting) { | ||
| 311 | + NSLog(@"---------CNLiveStreamStateConnecting"); | ||
| 312 | + _stateLab.text = @"CNLiveStreamStateConnecting"; | ||
| 313 | + } | ||
| 314 | + | ||
| 315 | + //推流出错 | ||
| 316 | + if (_kitCN.streamState == CNLiveStreamStateError) { | ||
| 317 | + NSLog(@"---------CNLiveStreamStateError"); | ||
| 318 | + [self onStreamError]; | ||
| 319 | + } | ||
| 320 | + | ||
| 321 | + //断开推流 | ||
| 322 | + if ( _kitCN.streamState == CNLiveStreamStateDisconnecting) { | ||
| 323 | + NSLog(@"---------CNLiveStreamStateDisconnecting"); | ||
| 324 | + _stateLab.text = @"CNLiveStreamStateDisconnecting"; | ||
| 325 | + | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + //结束推流成功 | ||
| 329 | + if ( _kitCN.streamState == CNLiveStopStreamSuccess) { | ||
| 330 | + NSLog(@"---------CNLiveStopStreamSuccess"); | ||
| 331 | + _stateLab.text = @"CNLiveStopStreamSuccess"; | ||
| 332 | + | ||
| 333 | + } | ||
| 334 | +} | ||
| 335 | + | ||
| 336 | +- (void)onStreamError { | ||
| 337 | + | ||
| 338 | + _startLiveBtn.selected = NO; | ||
| 339 | + CNLiveStreamErrorCode err = _kitCN.streamErrorCode; | ||
| 340 | + [self toast:[NSString stringWithFormat:@"error ------ %lu",(unsigned long)err]]; | ||
| 341 | + | ||
| 342 | + NSLog(@"onErr: %lu [%@]", (unsigned long) err, _stateLab.text); | ||
| 343 | + | ||
| 344 | + if ( CNLiveStreamErrorCode_CNLiveAUTHFAILED == err ) { | ||
| 345 | + _stateLab.text = @"SDK auth failed, \npls check ak/sk"; | ||
| 346 | + } | ||
| 347 | + else if ( CNLiveStreamErrorCode_CODEC_OPEN_FAILED == err) { | ||
| 348 | + _stateLab.text = @"Selected Codec not supported \n in this version"; | ||
| 349 | + } | ||
| 350 | + else if ( CNLiveStreamErrorCode_CONNECT_FAILED == err) { | ||
| 351 | + _stateLab.text = @"Connecting error, pls check host url \nor network"; | ||
| 352 | + } | ||
| 353 | + else if ( CNLiveStreamErrorCode_CONNECT_BREAK == err) { | ||
| 354 | + _stateLab.text = @"Connection break"; | ||
| 355 | + } | ||
| 356 | + else if ( CNLiveStreamErrorCode_ABNORMAL == err) { | ||
| 357 | + _stateLab.text = @"CNLiveStreamErrorCode_ABNORMAL"; | ||
| 358 | + [self toast:@"推流异常中断~~"]; | ||
| 359 | + | ||
| 360 | + } else if (err == CNLiveStreamErrorCode_CODEC_OPEN_FAILED) { | ||
| 361 | + NSLog(@"video codec open failed, try software codec"); | ||
| 362 | + _kitCN.streamerBase.videoCodec = CNLiveVideoCodec_VT264; | ||
| 363 | + [self tryReconnect]; | ||
| 364 | + } | ||
| 365 | + else { | ||
| 366 | + | ||
| 367 | + } | ||
| 368 | + | ||
| 369 | + // 断网重连 | ||
| 370 | + if (err == CNLiveStreamErrorCode_CONNECT_BREAK || err == CNLiveStreamErrorCode_AV_SYNC_ERROR) { | ||
| 371 | + [self tryReconnect]; | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | +} | ||
| 375 | + | ||
| 376 | +- (void) tryReconnect | ||
| 377 | +{ | ||
| 378 | + dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)); | ||
| 379 | + dispatch_after(delay, dispatch_get_main_queue(), ^{ | ||
| 380 | + | ||
| 381 | + NSLog(@"try again"); | ||
| 382 | + | ||
| 383 | + [_kitCN stopStream]; | ||
| 384 | + | ||
| 385 | + if (_isAuthLive) { | ||
| 386 | + | ||
| 387 | + [_kitCN startStream:^{ | ||
| 388 | + NSLog(@"开启推流成功 ------- success"); | ||
| 389 | + _startLiveBtn.selected = YES; | ||
| 390 | + | ||
| 391 | + } failure:^(NSDictionary *errorDic) { | ||
| 392 | + [self toast:errorDic[@"errorMessage"]]; | ||
| 393 | + _startLiveBtn.selected = NO; | ||
| 394 | + }]; | ||
| 395 | + | ||
| 396 | + }else{ | ||
| 397 | + [_kitCN startStream:self.url]; | ||
| 398 | + } | ||
| 399 | + }); | ||
| 400 | +} | ||
| 401 | + | ||
| 402 | +- (void)toast:(NSString*)message | ||
| 403 | +{ | ||
| 404 | + | ||
| 405 | + UIAlertView *toast = [[UIAlertView alloc] initWithTitle:nil | ||
| 406 | + message:message | ||
| 407 | + delegate:nil | ||
| 408 | + cancelButtonTitle:nil | ||
| 409 | + otherButtonTitles:nil, nil]; | ||
| 410 | + [toast show]; | ||
| 411 | + double duration = 2.5; | ||
| 412 | + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | ||
| 413 | + [toast dismissWithClickedButtonIndex:0 animated:NO]; | ||
| 414 | + }); | ||
| 415 | +} | ||
| 416 | + | ||
| 417 | +- (UILabel *)stateLab | ||
| 418 | +{ | ||
| 419 | + if (!_stateLab) { | ||
| 420 | + _stateLab = [[UILabel alloc] initWithFrame:CGRectMake(0, Height-100, Width, 100)]; | ||
| 421 | + _stateLab.backgroundColor = [UIColor colorWithWhite:0 alpha:0.1]; | ||
| 422 | + _stateLab.numberOfLines = 0; | ||
| 423 | + _stateLab.text = @"message"; | ||
| 424 | + _stateLab.textColor = [UIColor redColor]; | ||
| 425 | + } | ||
| 426 | + return _stateLab; | ||
| 427 | +} | ||
| 428 | + | ||
| 429 | +- (AudioCfgView *)audioCfgView | ||
| 430 | +{ | ||
| 431 | + if (!_audioCfgView) { | ||
| 432 | + _audioCfgView = [[AudioCfgView alloc] initWithFrame:CGRectMake(0, 160, Width, 200)]; | ||
| 433 | + _audioCfgView.hidden = YES; | ||
| 434 | + } | ||
| 435 | + return _audioCfgView; | ||
| 436 | +} | ||
| 437 | + | ||
| 438 | +- (BgmPlayerView *)bgmPlayerView | ||
| 439 | +{ | ||
| 440 | + if (!_bgmPlayerView) { | ||
| 441 | + _bgmPlayerView = [[BgmPlayerView alloc] initWithFrame:CGRectMake(0, 160, Width, 200)]; | ||
| 442 | + _bgmPlayerView.delegate = self; | ||
| 443 | + _bgmPlayerView.hidden = YES; | ||
| 444 | + } | ||
| 445 | + return _bgmPlayerView; | ||
| 446 | +} | ||
| 447 | + | ||
| 448 | +- (void)dealloc | ||
| 449 | +{ | ||
| 450 | + if (_currentTimer) { | ||
| 451 | + [_currentTimer invalidate]; | ||
| 452 | + _currentTimer = nil; | ||
| 453 | + } | ||
| 454 | + | ||
| 455 | + [_kitCN quitStreaming]; | ||
| 456 | + self.kitCN = nil; | ||
| 457 | + _bgmPlayerView.delegate = nil; | ||
| 458 | + [[NSNotificationCenter defaultCenter] removeObserver:self]; | ||
| 459 | +} | ||
| 460 | + | ||
| 461 | +- (void)didReceiveMemoryWarning { | ||
| 462 | + [super didReceiveMemoryWarning]; | ||
| 463 | + // Dispose of any resources that can be recreated. | ||
| 464 | +} | ||
| 465 | + | ||
| 466 | +/* | ||
| 467 | +#pragma mark - Navigation | ||
| 468 | + | ||
| 469 | +// In a storyboard-based application, you will often want to do a little preparation before navigation | ||
| 470 | +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { | ||
| 471 | + // Get the new view controller using [segue destinationViewController]. | ||
| 472 | + // Pass the selected object to the new view controller. | ||
| 473 | +} | ||
| 474 | +*/ | ||
| 475 | + | ||
| 476 | +@end |
Example/CNLivePlayer/Streamer/BgmPlayerView.h
0 → 100644
| 1 | +// | ||
| 2 | +// BgmPlayerView.h | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 17/4/19. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import <UIKit/UIKit.h> | ||
| 10 | + | ||
| 11 | +@protocol BgmPlayerViewDelegate <NSObject> | ||
| 12 | + | ||
| 13 | +- (void)valueType:(BOOL)isVolume value:(float)value; | ||
| 14 | +- (void)bgmPlayerPlay:(UIButton *)button; | ||
| 15 | +- (void)bgmPlayerMode:(UIButton *)button; | ||
| 16 | +- (void)bgmPlayerPauseOrResume:(UIButton *)button; | ||
| 17 | +- (void)bgmPlayerLast:(UIButton *)button; | ||
| 18 | +- (void)bgmPlayerNext:(UIButton *)button; | ||
| 19 | +- (void)bgmPlayerProgressSlider:(UISlider *)slider; | ||
| 20 | + | ||
| 21 | +@end | ||
| 22 | + | ||
| 23 | +@interface BgmPlayerView : UIView | ||
| 24 | + | ||
| 25 | +@property (nonatomic, strong) UILabel *currentTimeLab; | ||
| 26 | +@property (nonatomic, strong) UILabel *duraTimeLab; | ||
| 27 | +@property (nonatomic, strong) UISlider *proSlider; | ||
| 28 | +@property (nonatomic, strong) UILabel *songTitleLab; | ||
| 29 | +@property (nonatomic, strong) UIButton *playBtn; | ||
| 30 | +@property (nonatomic, strong) UIButton *nextBtn; | ||
| 31 | +@property (nonatomic, strong) UIButton *lastBtn; | ||
| 32 | +@property (nonatomic, strong) UIButton *pauseBtn; | ||
| 33 | +@property (nonatomic, strong) UIButton *playModeBtn; | ||
| 34 | +@property (nonatomic, assign) id<BgmPlayerViewDelegate> delegate; | ||
| 35 | + | ||
| 36 | +@end | ||
| 37 | + | ||
| 38 | +@interface MusicListView : UIView | ||
| 39 | + | ||
| 40 | +@end |
Example/CNLivePlayer/Streamer/BgmPlayerView.m
0 → 100644
| 1 | +// | ||
| 2 | +// BgmPlayerView.m | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 17/4/19. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "BgmPlayerView.h" | ||
| 10 | + | ||
| 11 | +#define COLOR(R, G, B, A) [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:A] | ||
| 12 | +#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0] | ||
| 13 | + | ||
| 14 | +#define BTN_WIDTH (CGRectGetWidth(self.bounds)-SPACE*6)/5 | ||
| 15 | +#define SPACE 7 | ||
| 16 | + | ||
| 17 | +@interface BgmPlayerView () | ||
| 18 | + | ||
| 19 | +@property (nonatomic, strong) UIView *playFuncView; | ||
| 20 | +@property (nonatomic, strong) UIView *volumeFuncView; | ||
| 21 | +@property (nonatomic, strong) UILabel *volumeValLab; | ||
| 22 | +@property (nonatomic, strong) UILabel *toneValLab; | ||
| 23 | + | ||
| 24 | +@end | ||
| 25 | + | ||
| 26 | +@implementation BgmPlayerView | ||
| 27 | + | ||
| 28 | +- (instancetype)initWithFrame:(CGRect)frame | ||
| 29 | +{ | ||
| 30 | + self = [super initWithFrame:frame]; | ||
| 31 | + if (self) { | ||
| 32 | + | ||
| 33 | + self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.1]; | ||
| 34 | + | ||
| 35 | + [self addSubview:self.playFuncView]; | ||
| 36 | + [self addSubview:self.volumeFuncView]; | ||
| 37 | + [self addSubview:self.currentTimeLab]; | ||
| 38 | + [self addSubview:self.duraTimeLab]; | ||
| 39 | + [self addSubview:self.proSlider]; | ||
| 40 | + [self addSubview:self.songTitleLab]; | ||
| 41 | + | ||
| 42 | + _playModeBtn = [self addButton:CGRectMake(SPACE, 0, BTN_WIDTH, 30) action:@selector(playModeBtnAction:) normalTitle:@"顺序播放" selectedTitle:@"循环播放"]; | ||
| 43 | + _lastBtn = [self addButton:CGRectMake(BTN_WIDTH+2*SPACE, 0, BTN_WIDTH, 30) action:@selector(lastBtnAction:) normalTitle:@"上一首" selectedTitle:@"上一首"]; | ||
| 44 | + _playBtn = [self addButton:CGRectMake(BTN_WIDTH*2+3*SPACE, 0, BTN_WIDTH, 30) action:@selector(playBtnAction:) normalTitle:@"播放" selectedTitle:@"停止"]; | ||
| 45 | + _pauseBtn = [self addButton:CGRectMake(BTN_WIDTH*3+4*SPACE, 0, BTN_WIDTH, 30) action:@selector(pauseBtnAction:) normalTitle:@"暂停" selectedTitle:@"继续"]; | ||
| 46 | + _nextBtn = [self addButton:CGRectMake(BTN_WIDTH*4+5*SPACE, 0, BTN_WIDTH, 30) action:@selector(nextBtnAction:) normalTitle:@"下一首" selectedTitle:@"下一首"]; | ||
| 47 | + | ||
| 48 | + [self.volumeFuncView addSubview:[self addVolumeView:CGRectMake(0, 0, CGRectGetWidth(self.bounds)/2, 40) action:@selector(volumeStepperAction:) type:YES]]; | ||
| 49 | + [self.volumeFuncView addSubview:[self addVolumeView:CGRectMake(CGRectGetWidth(self.bounds)/2, 0, CGRectGetWidth(self.bounds), 40) action:@selector(toneStepperAction:) type:NO]]; | ||
| 50 | + | ||
| 51 | + | ||
| 52 | + } | ||
| 53 | + return self; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +#pragma mark - | ||
| 57 | +#pragma mark - action | ||
| 58 | +- (void)playModeBtnAction:(UIButton *)button { | ||
| 59 | + button.selected = !button.selected; | ||
| 60 | + if (self.delegate && [self.delegate respondsToSelector:@selector(bgmPlayerMode:)]) { | ||
| 61 | + [self.delegate bgmPlayerMode:button]; | ||
| 62 | + } | ||
| 63 | +} | ||
| 64 | + | ||
| 65 | +- (void)lastBtnAction:(UIButton *)button { | ||
| 66 | + button.selected = !button.selected; | ||
| 67 | + if (self.delegate && [self.delegate respondsToSelector:@selector(bgmPlayerLast:)]) { | ||
| 68 | + [self.delegate bgmPlayerLast:button]; | ||
| 69 | + } | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +- (void)playBtnAction:(UIButton *)button { | ||
| 73 | + button.selected = !button.selected; | ||
| 74 | + if (self.delegate && [self.delegate respondsToSelector:@selector(bgmPlayerPlay:)]) { | ||
| 75 | + [self.delegate bgmPlayerPlay:button]; | ||
| 76 | + } | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +- (void)nextBtnAction:(UIButton *)button { | ||
| 80 | + button.selected = !button.selected; | ||
| 81 | + if (self.delegate && [self.delegate respondsToSelector:@selector(bgmPlayerNext:)]) { | ||
| 82 | + [self.delegate bgmPlayerNext:button]; | ||
| 83 | + } | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +- (void)pauseBtnAction:(UIButton *)button { | ||
| 87 | + button.selected = !button.selected; | ||
| 88 | + if (self.delegate && [self.delegate respondsToSelector:@selector(bgmPlayerPauseOrResume:)]) { | ||
| 89 | + [self.delegate bgmPlayerPauseOrResume:button]; | ||
| 90 | + } | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +- (void)beginScrubbing { | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | +- (void)endScrubbing:(UISlider *)slider { | ||
| 97 | + if (self.delegate && [self.delegate respondsToSelector:@selector(bgmPlayerProgressSlider:)]) { | ||
| 98 | + [self.delegate bgmPlayerProgressSlider:slider]; | ||
| 99 | + } | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | +- (void)volumeStepperAction:(UIStepper *)stepper { | ||
| 103 | + _volumeValLab.text = [NSString stringWithFormat:@"%.1f",stepper.value]; | ||
| 104 | + if (self.delegate && [self.delegate respondsToSelector:@selector(valueType:value:)]) { | ||
| 105 | + [self.delegate valueType:YES value:stepper.value]; | ||
| 106 | + } | ||
| 107 | +} | ||
| 108 | + | ||
| 109 | +- (void)toneStepperAction:(UIStepper *)stepper { | ||
| 110 | + _toneValLab.text = [NSString stringWithFormat:@"%.1f",stepper.value]; | ||
| 111 | + if (self.delegate && [self.delegate respondsToSelector:@selector(valueType:value:)]) { | ||
| 112 | + [self.delegate valueType:NO value:stepper.value]; | ||
| 113 | + } | ||
| 114 | +} | ||
| 115 | + | ||
| 116 | +#pragma mark - | ||
| 117 | +#pragma mark - | ||
| 118 | +- (UIButton *)addButton:(CGRect)rect action:(SEL)action normalTitle:(NSString *)normalTitle selectedTitle:(NSString *)selectedTitle{ | ||
| 119 | + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; | ||
| 120 | + button.frame = rect; | ||
| 121 | + [button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside]; | ||
| 122 | + [button setTitle:normalTitle forState:UIControlStateNormal]; | ||
| 123 | + [button setTitle:selectedTitle forState:UIControlStateSelected]; | ||
| 124 | + [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; | ||
| 125 | + button.titleLabel.font = [UIFont systemFontOfSize:14]; | ||
| 126 | + button.layer.cornerRadius = 5; | ||
| 127 | + button.layer.masksToBounds = YES; | ||
| 128 | + button.layer.borderColor = [UIColor blackColor].CGColor; | ||
| 129 | + button.layer.borderWidth = 1; | ||
| 130 | + [self.playFuncView addSubview:button]; | ||
| 131 | + return button; | ||
| 132 | +} | ||
| 133 | + | ||
| 134 | +- (UIView *)addVolumeView:(CGRect)rect action:(SEL)action type:(BOOL)volume { | ||
| 135 | + UIView *view = [[UIView alloc] initWithFrame:rect]; | ||
| 136 | + UILabel *titleLab = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, 40, 20)]; | ||
| 137 | + | ||
| 138 | + UILabel *valueLab = [[UILabel alloc] initWithFrame:CGRectMake(45, 10, 30, 20)]; | ||
| 139 | + valueLab.font = [UIFont systemFontOfSize:14]; | ||
| 140 | + | ||
| 141 | + UIStepper *step = [[UIStepper alloc] initWithFrame:CGRectMake(80, 5, 30, 30)]; | ||
| 142 | + step.tintColor = [UIColor blackColor]; | ||
| 143 | + [step addTarget:self action:action forControlEvents:UIControlEventValueChanged]; | ||
| 144 | + | ||
| 145 | + if (volume) { | ||
| 146 | + titleLab.text = @"音量: "; | ||
| 147 | + valueLab.text = @"1.0"; | ||
| 148 | + _volumeValLab = valueLab; | ||
| 149 | + step.maximumValue = 1; | ||
| 150 | + step.minimumValue = 0; | ||
| 151 | + step.stepValue = 0.1; | ||
| 152 | + step.value = 1.0; | ||
| 153 | + } else { | ||
| 154 | + titleLab.text = @"音调: "; | ||
| 155 | + valueLab.text = @"0.01"; | ||
| 156 | + _toneValLab = valueLab; | ||
| 157 | + step.maximumValue = 24.0; | ||
| 158 | + step.minimumValue = -24.0; | ||
| 159 | + step.stepValue = 1.0; | ||
| 160 | + step.value = 0.01; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + [view addSubview:titleLab]; | ||
| 164 | + [view addSubview:valueLab]; | ||
| 165 | + [view addSubview:step]; | ||
| 166 | + return view; | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +#pragma mark - | ||
| 170 | +#pragma mark - gatter | ||
| 171 | +- (UIView *)playFuncView { | ||
| 172 | + if (!_playFuncView) { | ||
| 173 | + _playFuncView = [[UIView alloc] initWithFrame:CGRectMake(0, 80, CGRectGetWidth(self.bounds), 40)]; | ||
| 174 | + } | ||
| 175 | + return _playFuncView; | ||
| 176 | +} | ||
| 177 | + | ||
| 178 | +- (UIView *)volumeFuncView { | ||
| 179 | + if (!_volumeFuncView) { | ||
| 180 | + _volumeFuncView = [[UIView alloc] initWithFrame:CGRectMake(0, 120, CGRectGetWidth(self.bounds), 40)]; | ||
| 181 | + } | ||
| 182 | + return _volumeFuncView; | ||
| 183 | +} | ||
| 184 | + | ||
| 185 | + | ||
| 186 | +- (UILabel *)songTitleLab | ||
| 187 | +{ | ||
| 188 | + if (!_songTitleLab) { | ||
| 189 | + _songTitleLab = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, CGRectGetWidth(self.bounds)-20, 20)]; | ||
| 190 | + _songTitleLab.textColor = [UIColor redColor]; | ||
| 191 | + _songTitleLab.font = [UIFont systemFontOfSize:14]; | ||
| 192 | + _songTitleLab.text = @"xxxx"; | ||
| 193 | + } | ||
| 194 | + return _songTitleLab; | ||
| 195 | +} | ||
| 196 | + | ||
| 197 | +- (UILabel *)currentTimeLab | ||
| 198 | +{ | ||
| 199 | + if (!_currentTimeLab) { | ||
| 200 | + _currentTimeLab = [[UILabel alloc] initWithFrame:CGRectMake(10, 40, 40, 20)]; | ||
| 201 | + _currentTimeLab.font = [UIFont systemFontOfSize:13]; | ||
| 202 | + _currentTimeLab.text = @"00:00"; | ||
| 203 | + } | ||
| 204 | + return _currentTimeLab; | ||
| 205 | +} | ||
| 206 | + | ||
| 207 | +- (UILabel *)duraTimeLab | ||
| 208 | +{ | ||
| 209 | + if (!_duraTimeLab) { | ||
| 210 | + _duraTimeLab = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.bounds)-50, 40, 40, 20)]; | ||
| 211 | + _duraTimeLab.font = [UIFont systemFontOfSize:13]; | ||
| 212 | + _duraTimeLab.text = @"00:00"; | ||
| 213 | + } | ||
| 214 | + return _duraTimeLab; | ||
| 215 | +} | ||
| 216 | + | ||
| 217 | +- (UISlider *)proSlider | ||
| 218 | +{ | ||
| 219 | + if (!_proSlider) { | ||
| 220 | + _proSlider = [[UISlider alloc] initWithFrame:CGRectMake(60, 35, CGRectGetWidth(self.bounds)-120, 30)]; | ||
| 221 | + [_proSlider setThumbImage:[UIImage imageNamed:@"btn_dot"] forState:UIControlStateNormal]; | ||
| 222 | + [_proSlider setMinimumTrackTintColor:[UIColor redColor]]; | ||
| 223 | + [_proSlider setMaximumTrackTintColor:[UIColor whiteColor]]; | ||
| 224 | + [_proSlider addTarget:self action:@selector(beginScrubbing) forControlEvents:UIControlEventTouchDown]; | ||
| 225 | + [_proSlider addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpInside]; | ||
| 226 | + [_proSlider addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpOutside]; | ||
| 227 | + } | ||
| 228 | + return _proSlider; | ||
| 229 | +} | ||
| 230 | +/* | ||
| 231 | +// Only override drawRect: if you perform custom drawing. | ||
| 232 | +// An empty implementation adversely affects performance during animation. | ||
| 233 | +- (void)drawRect:(CGRect)rect { | ||
| 234 | + // Drawing code | ||
| 235 | +} | ||
| 236 | +*/ | ||
| 237 | + | ||
| 238 | +@end | ||
| 239 | + | ||
| 240 | +#pragma mark - 音乐列表 | ||
| 241 | + | ||
| 242 | +@interface MusicListView ()<UITableViewDelegate,UITableViewDataSource> | ||
| 243 | +{ | ||
| 244 | + NSArray *_listArr; | ||
| 245 | +} | ||
| 246 | + | ||
| 247 | +@property (nonatomic, strong) UITableView *tableView; | ||
| 248 | + | ||
| 249 | +@end | ||
| 250 | + | ||
| 251 | +@implementation MusicListView | ||
| 252 | + | ||
| 253 | +- (instancetype)initWithFrame:(CGRect)frame | ||
| 254 | +{ | ||
| 255 | + self = [super initWithFrame:frame]; | ||
| 256 | + if (self) { | ||
| 257 | + _listArr = @[@"See You Again .mp3", | ||
| 258 | + @"Idina Menzel - Let It Go.mp3", | ||
| 259 | + @"Morrie - Lullaby.mp3", | ||
| 260 | + @"Zedd,Alessia Cara - Stay.mp3"]; | ||
| 261 | + } | ||
| 262 | + return self; | ||
| 263 | +} | ||
| 264 | + | ||
| 265 | +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { | ||
| 266 | + return _listArr.count; | ||
| 267 | +} | ||
| 268 | + | ||
| 269 | +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { | ||
| 270 | + static NSString *cellID = @"MusicListViewIdentify"; | ||
| 271 | + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID]; | ||
| 272 | + if (!cell) { | ||
| 273 | + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; | ||
| 274 | + } | ||
| 275 | + cell.textLabel.text = _listArr[indexPath.row]; | ||
| 276 | + cell.textLabel.textColor = UIColorFromRGB(515151); | ||
| 277 | + cell.backgroundColor = [UIColor whiteColor]; | ||
| 278 | + return cell; | ||
| 279 | +} | ||
| 280 | + | ||
| 281 | + | ||
| 282 | +- (UITableView *)tableView | ||
| 283 | +{ | ||
| 284 | + if (!_tableView) { | ||
| 285 | + _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 40, CGRectGetWidth(self.bounds), 100) style:UITableViewStylePlain]; | ||
| 286 | + _tableView.delegate = self; | ||
| 287 | + _tableView.dataSource = self; | ||
| 288 | + _tableView.backgroundColor = [UIColor whiteColor]; | ||
| 289 | + } | ||
| 290 | + return _tableView; | ||
| 291 | +} | ||
| 292 | + | ||
| 293 | + | ||
| 294 | +@end |
Example/CNLivePlayer/CNLiveStreamerController.h renamed to Example/CNLivePlayer/Streamer/CNLiveStreamerController.h
| 1 | // | 1 | // |
| 2 | -// CNLiveStreamerController.h | ||
| 3 | -// CNLivePlayer_Example | 2 | +// StreamerViewController.h |
| 3 | +// CNLivePlayerSDKTest | ||
| 4 | // | 4 | // |
| 5 | -// Created by CNLive-zxw on 2019/8/21. | ||
| 6 | -// Copyright © 2019 153993236@qq.com. All rights reserved. | 5 | +// Created by 雷浩杰 on 16/8/10. |
| 6 | +// Copyright © 2016年 雷浩杰. All rights reserved. | ||
| 7 | // | 7 | // |
| 8 | 8 | ||
| 9 | #import <UIKit/UIKit.h> | 9 | #import <UIKit/UIKit.h> |
| 10 | 10 | ||
| 11 | -NS_ASSUME_NONNULL_BEGIN | ||
| 12 | - | ||
| 13 | @interface CNLiveStreamerController : UIViewController | 11 | @interface CNLiveStreamerController : UIViewController |
| 14 | 12 | ||
| 15 | @end | 13 | @end |
| 16 | - | ||
| 17 | -NS_ASSUME_NONNULL_END |
Example/CNLivePlayer/Streamer/CNLiveStreamerController.m
0 → 100644
| 1 | +// | ||
| 2 | +// StreamerViewController.m | ||
| 3 | +// CNLivePlayerSDKTest | ||
| 4 | +// | ||
| 5 | +// Created by 雷浩杰 on 16/8/10. | ||
| 6 | +// Copyright © 2016年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "CNLiveStreamerController.h" | ||
| 10 | +#import "StreamerDetailViewController.h" | ||
| 11 | +#import "AudioStreamingViewController.h" | ||
| 12 | + | ||
| 13 | +#define KScreenWidth [UIScreen mainScreen].bounds.size.width | ||
| 14 | +#define KScreenHeight [UIScreen mainScreen].bounds.size.height | ||
| 15 | + | ||
| 16 | +@interface CNLiveStreamerController ()<UITextFieldDelegate> | ||
| 17 | +@property (nonatomic, strong) UITextField *urlTextField; | ||
| 18 | +@property (nonatomic, strong) UISwitch *pureAudioSwitch; | ||
| 19 | +@property (nonatomic, strong) UISegmentedControl *liveType; | ||
| 20 | + | ||
| 21 | +@end | ||
| 22 | + | ||
| 23 | +@implementation CNLiveStreamerController | ||
| 24 | + | ||
| 25 | +- (void)viewDidLoad { | ||
| 26 | + [super viewDidLoad]; | ||
| 27 | + self.view.backgroundColor = [UIColor whiteColor]; | ||
| 28 | + | ||
| 29 | + [self.view addSubview:self.urlTextField]; | ||
| 30 | + [self.view addSubview:self.pureAudioSwitch]; | ||
| 31 | + [self.view addSubview:self.liveType]; | ||
| 32 | + | ||
| 33 | + UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; | ||
| 34 | + btn.frame = CGRectMake(0, 0, 100, 50); | ||
| 35 | + btn.center = CGPointMake(self.view.center.x, self.view.center.y); | ||
| 36 | + btn.backgroundColor = [UIColor redColor]; | ||
| 37 | + [btn setTitle:@"返回" forState:UIControlStateNormal]; | ||
| 38 | + [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; | ||
| 39 | + [btn addTarget:self action:@selector(btnDidClicked) forControlEvents:UIControlEventTouchUpInside]; | ||
| 40 | + [self.view addSubview:btn]; | ||
| 41 | + | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +- (void)btnDidClicked{ | ||
| 45 | + [self dismissViewControllerAnimated:YES completion:nil]; | ||
| 46 | + | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +#pragma mark - Actioon | ||
| 50 | +- (void)onSegmentedControl:(UISegmentedControl *)sender { | ||
| 51 | + if (sender.selectedSegmentIndex == 0) { | ||
| 52 | + if (_urlTextField.text.length == 0) { | ||
| 53 | + [self toast:@"请输入推流地址"]; | ||
| 54 | + | ||
| 55 | + } | ||
| 56 | + else{ | ||
| 57 | + if (_pureAudioSwitch.on) { | ||
| 58 | + AudioStreamingViewController *vc = [[AudioStreamingViewController alloc] init]; | ||
| 59 | + vc.isAuthLive = NO; | ||
| 60 | + vc.url = [NSURL URLWithString:[NSString stringWithFormat:@"%@",self.urlTextField.text]]; | ||
| 61 | + [self presentViewController:vc animated:YES completion:NULL]; | ||
| 62 | + } | ||
| 63 | + else { | ||
| 64 | + StreamerDetailViewController *vc = [[StreamerDetailViewController alloc] init]; | ||
| 65 | + vc.isAuthLive = NO; | ||
| 66 | + vc.url = [NSURL URLWithString:[NSString stringWithFormat:@"%@",self.urlTextField.text]]; | ||
| 67 | + [self presentViewController:vc animated:YES completion:NULL]; | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + } | ||
| 72 | + else if (sender.selectedSegmentIndex == 1) { | ||
| 73 | + | ||
| 74 | + if (_pureAudioSwitch.on) { | ||
| 75 | + AudioStreamingViewController *vc = [[AudioStreamingViewController alloc] init]; | ||
| 76 | + vc.isAuthLive = YES; | ||
| 77 | + [self presentViewController:vc animated:YES completion:NULL]; | ||
| 78 | + } | ||
| 79 | + else { | ||
| 80 | + StreamerDetailViewController *vc = [[StreamerDetailViewController alloc] init]; | ||
| 81 | + vc.isAuthLive = YES; | ||
| 82 | + vc.url = [NSURL URLWithString:[NSString stringWithFormat:@"%@",self.urlTextField.text]]; | ||
| 83 | + [self presentViewController:vc animated:YES completion:NULL]; | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + } | ||
| 87 | + else if (sender.selectedSegmentIndex == 2) { | ||
| 88 | + StreamerDetailViewController *vc = [[StreamerDetailViewController alloc] init]; | ||
| 89 | + vc.isRecord = YES; | ||
| 90 | + [self presentViewController:vc animated:YES completion:NULL]; | ||
| 91 | + | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + _liveType.selectedSegmentIndex = -1; | ||
| 95 | + | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | + | ||
| 99 | +- (void)toast:(NSString*)message { | ||
| 100 | + UIAlertView *toast = [[UIAlertView alloc] initWithTitle:nil | ||
| 101 | + message:message | ||
| 102 | + delegate:nil | ||
| 103 | + cancelButtonTitle:nil | ||
| 104 | + otherButtonTitles:nil, nil]; | ||
| 105 | + [toast show]; | ||
| 106 | + double duration = 2.5; | ||
| 107 | + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ | ||
| 108 | + [toast dismissWithClickedButtonIndex:0 animated:NO]; | ||
| 109 | + }); | ||
| 110 | +} | ||
| 111 | + | ||
| 112 | +- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { | ||
| 113 | + if ([_urlTextField isFirstResponder]) { | ||
| 114 | + [_urlTextField resignFirstResponder]; | ||
| 115 | + } | ||
| 116 | +} | ||
| 117 | + | ||
| 118 | +- (BOOL)textFieldShouldReturn:(UITextField *)textField { | ||
| 119 | + [textField resignFirstResponder]; | ||
| 120 | + return YES; | ||
| 121 | +} | ||
| 122 | + | ||
| 123 | +#pragma mark - getter | ||
| 124 | +- (UITextField *)urlTextField { | ||
| 125 | + if (!_urlTextField) { | ||
| 126 | + _urlTextField = [[UITextField alloc] initWithFrame:CGRectMake(10, 170, KScreenWidth-20, 40)]; | ||
| 127 | + _urlTextField.placeholder = @"请输入推流地址"; | ||
| 128 | + _urlTextField.borderStyle = UITextBorderStyleRoundedRect; | ||
| 129 | + _urlTextField.returnKeyType = UIReturnKeyDone; | ||
| 130 | + _urlTextField.clearButtonMode = UITextFieldViewModeWhileEditing; | ||
| 131 | + _urlTextField.delegate = self; | ||
| 132 | + _urlTextField.text = @"rtmp://jsrtmp.up.cnlive.com/live/ceshi"; | ||
| 133 | + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, -30, 80, 30)]; | ||
| 134 | + label.text = @"推流地址:"; | ||
| 135 | + label.font = [UIFont systemFontOfSize:15]; | ||
| 136 | + [_urlTextField addSubview:label]; | ||
| 137 | + } | ||
| 138 | + return _urlTextField; | ||
| 139 | +} | ||
| 140 | + | ||
| 141 | +- (UISwitch *)pureAudioSwitch { | ||
| 142 | + if (!_pureAudioSwitch) { | ||
| 143 | + _pureAudioSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(110, 85, 100, 30)]; | ||
| 144 | + UILabel *modeLab = [[UILabel alloc] initWithFrame:CGRectMake(10, 90, 100, 20)]; | ||
| 145 | + modeLab.textColor = [UIColor blackColor]; | ||
| 146 | + modeLab.text = @"纯音频推流"; | ||
| 147 | + [self.view addSubview:modeLab]; | ||
| 148 | + } | ||
| 149 | + return _pureAudioSwitch; | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +- (UISegmentedControl *)liveType { | ||
| 153 | + if (!_liveType) { | ||
| 154 | + NSArray *items = @[ @"普通直播", | ||
| 155 | + @"鉴权直播", | ||
| 156 | + @"本地录制"]; | ||
| 157 | + | ||
| 158 | + _liveType = [[UISegmentedControl alloc] initWithItems:items]; | ||
| 159 | + _liveType.frame = CGRectMake(10, self.view.bounds.size.height-80, self.view.bounds.size.width-20, 40); | ||
| 160 | + _liveType.tintColor= [UIColor blackColor]; | ||
| 161 | + _liveType.selectedSegmentIndex = 0; | ||
| 162 | + _liveType.layer.cornerRadius = 5; | ||
| 163 | + _liveType.selectedSegmentIndex = -1; | ||
| 164 | + [_liveType addTarget:self action:@selector(onSegmentedControl:) forControlEvents:UIControlEventValueChanged]; | ||
| 165 | + } | ||
| 166 | + return _liveType; | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | + | ||
| 170 | +@end |
Example/CNLivePlayer/Streamer/FilterFunctionView.h
0 → 100644
| 1 | +// | ||
| 2 | +// FilterFunctionView.h | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 16/12/21. | ||
| 6 | +// Copyright © 2016年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import <UIKit/UIKit.h> | ||
| 10 | + | ||
| 11 | +typedef void(^FilterViewBlock)(float grindRatio , float whitenRatio, float intensity); | ||
| 12 | +typedef void(^FilterCurrentType)(NSInteger currentType); | ||
| 13 | +typedef void(^FilterCurrentIdx)(NSInteger currentIdx); | ||
| 14 | + | ||
| 15 | +@interface FilterFunctionView : UIView | ||
| 16 | + | ||
| 17 | +@property (nonatomic, copy) FilterViewBlock filterViewBlock; | ||
| 18 | +@property (nonatomic, copy) FilterCurrentType currentTypeBlock; | ||
| 19 | +@property (nonatomic, copy) FilterCurrentIdx currentIdxBlock; | ||
| 20 | + | ||
| 21 | +@end | ||
| 22 | + |
Example/CNLivePlayer/Streamer/FilterFunctionView.m
0 → 100644
| 1 | +// | ||
| 2 | +// FilterFunctionView.m | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 16/12/21. | ||
| 6 | +// Copyright © 2016年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "FilterFunctionView.h" | ||
| 10 | +#import "SliderView.h" | ||
| 11 | + | ||
| 12 | +@interface FilterFunctionView ()<SliderViewDelegate,UIPickerViewDelegate,UIPickerViewDataSource> | ||
| 13 | +{ | ||
| 14 | + NSArray *_dataArr; | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +@property (nonatomic, strong) SliderView *slider1; | ||
| 18 | +@property (nonatomic, strong) SliderView *slider2; | ||
| 19 | +@property (nonatomic, strong) SliderView *slider3; | ||
| 20 | +@property (nonatomic, strong) UISegmentedControl * filterGroupType; | ||
| 21 | +@property (nonatomic, strong) UIPickerView *effectPicker; | ||
| 22 | + | ||
| 23 | +@end | ||
| 24 | + | ||
| 25 | +@implementation FilterFunctionView | ||
| 26 | + | ||
| 27 | +- (instancetype)initWithFrame:(CGRect)frame | ||
| 28 | +{ | ||
| 29 | + self = [super initWithFrame:frame]; | ||
| 30 | + if (self) { | ||
| 31 | + [self addSubview:self.slider1]; | ||
| 32 | + [self addSubview:self.slider2]; | ||
| 33 | + [self addSubview:self.slider3]; | ||
| 34 | + [self addSubview:self.effectPicker]; | ||
| 35 | + [self addSubview:self.filterGroupType]; | ||
| 36 | + | ||
| 37 | + _dataArr = @[@"小清新",@"靓丽",@"甜美可人",@"怀旧",@"蓝调",@"老照片",@"樱花",@"樱花(光线较暗)",@"红润(光线较暗)",@"阳光(光线较暗)",@"红润",@"阳光",@"自然"]; | ||
| 38 | + | ||
| 39 | + } | ||
| 40 | + return self; | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +#pragma mark - | ||
| 44 | +#pragma mark - SliderViewDelegate | ||
| 45 | + | ||
| 46 | +- (void)sliderValueChenged | ||
| 47 | +{ | ||
| 48 | + if (_filterViewBlock) { | ||
| 49 | + _filterViewBlock(_slider1.currentValue, _slider2.currentValue, _slider3.currentValue); | ||
| 50 | + } | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +- (void)onSegCtrl:(UISegmentedControl *)sender | ||
| 54 | +{ | ||
| 55 | + | ||
| 56 | + if (sender.selectedSegmentIndex == 0) { | ||
| 57 | + _slider1.hidden = YES; | ||
| 58 | + _slider2.hidden = YES; | ||
| 59 | + _slider3.hidden = YES; | ||
| 60 | + _effectPicker.hidden = YES; | ||
| 61 | + | ||
| 62 | + } else if (sender.selectedSegmentIndex == 1) { | ||
| 63 | + _slider1.hidden = NO; | ||
| 64 | + _slider2.hidden = YES; | ||
| 65 | + _slider3.hidden = YES; | ||
| 66 | + _effectPicker.hidden = YES; | ||
| 67 | + } else if (sender.selectedSegmentIndex == 2) { | ||
| 68 | + _slider1.hidden = NO; | ||
| 69 | + _slider2.hidden = NO; | ||
| 70 | + _slider3.hidden = NO; | ||
| 71 | + _effectPicker.hidden = YES; | ||
| 72 | + } else { | ||
| 73 | + _slider1.hidden = NO; | ||
| 74 | + _slider2.hidden = NO; | ||
| 75 | + _slider3.hidden = NO; | ||
| 76 | + _effectPicker.hidden = NO; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + _currentTypeBlock ? _currentTypeBlock(sender.selectedSegmentIndex) : nil; | ||
| 80 | + | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +#pragma mark - | ||
| 84 | +#pragma mark - effectPicker | ||
| 85 | +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView | ||
| 86 | +{ | ||
| 87 | + return 1; | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component | ||
| 91 | +{ | ||
| 92 | + return _dataArr.count; | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component | ||
| 96 | +{ | ||
| 97 | + return _dataArr[row]; | ||
| 98 | +} | ||
| 99 | + | ||
| 100 | +- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component | ||
| 101 | +{ | ||
| 102 | + _currentIdxBlock ? _currentIdxBlock(row) : nil; | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +#pragma mark - | ||
| 106 | +#pragma mark - getter | ||
| 107 | + | ||
| 108 | +- (SliderView *)slider1 | ||
| 109 | +{ | ||
| 110 | + if (!_slider1) { | ||
| 111 | + _slider1 = [[SliderView alloc] initWithFrame:CGRectMake(8, 50, self.bounds.size.width-16, 24) title:@"磨皮"]; | ||
| 112 | + _slider1.delagate = self; | ||
| 113 | + } | ||
| 114 | + return _slider1; | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +- (SliderView *)slider2 | ||
| 118 | +{ | ||
| 119 | + if (!_slider2) { | ||
| 120 | + _slider2 = [[SliderView alloc] initWithFrame:CGRectMake(8, 80, self.bounds.size.width-16, 24) title:@"美白"]; | ||
| 121 | + _slider2.delagate = self; | ||
| 122 | + } | ||
| 123 | + return _slider2; | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +- (SliderView *)slider3 | ||
| 127 | +{ | ||
| 128 | + if (!_slider3) { | ||
| 129 | + _slider3 = [[SliderView alloc] initWithFrame:CGRectMake(8, 110, self.bounds.size.width-16, 24) title:@"特效"]; | ||
| 130 | + _slider3.delagate = self; | ||
| 131 | + } | ||
| 132 | + return _slider3; | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | +- (UIPickerView *)effectPicker | ||
| 136 | +{ | ||
| 137 | + if (!_effectPicker) { | ||
| 138 | + _effectPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(8, 130, self.bounds.size.width-16, 100)]; | ||
| 139 | + _effectPicker.showsSelectionIndicator=YES; | ||
| 140 | + _effectPicker.tintColor = [UIColor whiteColor]; | ||
| 141 | + _effectPicker.dataSource = self; | ||
| 142 | + _effectPicker.delegate = self; | ||
| 143 | + _effectPicker.hidden = YES; | ||
| 144 | + } | ||
| 145 | + return _effectPicker; | ||
| 146 | +} | ||
| 147 | + | ||
| 148 | +- (UISegmentedControl *)filterGroupType | ||
| 149 | +{ | ||
| 150 | + if (!_filterGroupType) { | ||
| 151 | + NSArray *items = @[ @"关", | ||
| 152 | + @"旧美颜", | ||
| 153 | + @"红润美颜", | ||
| 154 | + @"美颜特效", | ||
| 155 | + ]; | ||
| 156 | + | ||
| 157 | + _filterGroupType = [[UISegmentedControl alloc] initWithItems:items]; | ||
| 158 | + _filterGroupType.frame = CGRectMake(10, 0, self.bounds.size.width-20, 30); | ||
| 159 | + _filterGroupType.tintColor= [UIColor blackColor]; | ||
| 160 | + _filterGroupType.selectedSegmentIndex = 0; | ||
| 161 | + _filterGroupType.layer.cornerRadius = 5; | ||
| 162 | + _filterGroupType.selectedSegmentIndex = 1; | ||
| 163 | + [_filterGroupType addTarget:self action:@selector(onSegCtrl:) forControlEvents:UIControlEventValueChanged]; | ||
| 164 | + } | ||
| 165 | + return _filterGroupType; | ||
| 166 | +} | ||
| 167 | +@end |
Example/CNLivePlayer/Streamer/FloatingViewController.h
0 → 100644
| 1 | +// | ||
| 2 | +// FloatingViewController.h | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 2017/9/20. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import <UIKit/UIKit.h> | ||
| 10 | +#import "CNLiveStreamerKit.h" | ||
| 11 | + | ||
| 12 | +@interface FloatingViewController : UIViewController | ||
| 13 | + | ||
| 14 | +@property (nonatomic, strong) CNLiveStreamerKit *kit; | ||
| 15 | + | ||
| 16 | +@end |
Example/CNLivePlayer/Streamer/FloatingViewController.m
0 → 100644
| 1 | +// | ||
| 2 | +// FloatingViewController.m | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 2017/9/20. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "FloatingViewController.h" | ||
| 10 | + | ||
| 11 | +#define Width [UIScreen mainScreen].bounds.size.width | ||
| 12 | +#define Height [UIScreen mainScreen].bounds.size.height | ||
| 13 | + | ||
| 14 | +@interface FloatingViewController () | ||
| 15 | + | ||
| 16 | +@property (nonatomic, strong) UIView *preView; | ||
| 17 | +@property CGPoint loc_in; | ||
| 18 | + | ||
| 19 | +@end | ||
| 20 | + | ||
| 21 | +@implementation FloatingViewController | ||
| 22 | + | ||
| 23 | +- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { | ||
| 24 | + | ||
| 25 | + [self.preView removeFromSuperview]; | ||
| 26 | + self.preView = nil; | ||
| 27 | + | ||
| 28 | + self.preView = [self.kit floatingWindowFrame:CGRectMake(Width/3*2, Height/3*2, Width/3, Height/3)]; | ||
| 29 | + [self.view addSubview:self.preView]; | ||
| 30 | + UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; | ||
| 31 | + [_preView addGestureRecognizer:panGes]; | ||
| 32 | + | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +- (void)viewDidLoad { | ||
| 36 | + [super viewDidLoad]; | ||
| 37 | + | ||
| 38 | + self.view.backgroundColor = [UIColor whiteColor]; | ||
| 39 | + | ||
| 40 | + _preView = [self.kit floatingWindowFrame:CGRectMake(Width/3*2, Height/3*2, Width/3, Height/3)]; | ||
| 41 | + [self.view addSubview:self.preView]; | ||
| 42 | + UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)]; | ||
| 43 | + [_preView addGestureRecognizer:panGes]; | ||
| 44 | + | ||
| 45 | + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; | ||
| 46 | + button.frame = CGRectMake(10, 30, 25, 25); | ||
| 47 | + [button setImage:[UIImage imageNamed:@"back"] forState:UIControlStateNormal]; | ||
| 48 | + [button addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside]; | ||
| 49 | + [self.view addSubview:button]; | ||
| 50 | + | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +- (void)backAction { | ||
| 54 | + [self dismissViewControllerAnimated:YES completion:NULL]; | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +- (void)pan:(UIPanGestureRecognizer *)ges{ | ||
| 58 | + CGPoint loc = [ges locationInView:self.view]; | ||
| 59 | + if (ges.state == UIGestureRecognizerStateBegan) { | ||
| 60 | + _loc_in = [ges locationInView:_preView]; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + CGFloat x; | ||
| 64 | + CGFloat y; | ||
| 65 | + if (_preView.frame.size.width - _loc_in.x + loc.x >= Width){ | ||
| 66 | + x = Width - _preView.frame.size.width * 0.5; | ||
| 67 | + }else if (loc.x - _loc_in.x <= 0) { | ||
| 68 | + x = _preView.frame.size.width * 0.5; | ||
| 69 | + }else { | ||
| 70 | + x = _preView.frame.size.width * 0.5 - _loc_in.x + loc.x; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + if (_preView.frame.size.height - _loc_in.y + loc.y >= Height) { | ||
| 74 | + y = Height - _preView.frame.size.height * 0.5; | ||
| 75 | + }else if (loc.y - _loc_in.y <= 0){ | ||
| 76 | + y = _preView.frame.size.height * 0.5; | ||
| 77 | + }else { | ||
| 78 | + y = _preView.frame.size.height * 0.5 - _loc_in.y + loc.y; | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + [UIView animateWithDuration:0 animations:^{ | ||
| 82 | + _preView.center = CGPointMake(x, y); | ||
| 83 | + }]; | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | + | ||
| 87 | +- (void)didReceiveMemoryWarning { | ||
| 88 | + [super didReceiveMemoryWarning]; | ||
| 89 | + // Dispose of any resources that can be recreated. | ||
| 90 | +} | ||
| 91 | + | ||
| 92 | +/* | ||
| 93 | +#pragma mark - Navigation | ||
| 94 | + | ||
| 95 | +// In a storyboard-based application, you will often want to do a little preparation before navigation | ||
| 96 | +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { | ||
| 97 | + // Get the new view controller using [segue destinationViewController]. | ||
| 98 | + // Pass the selected object to the new view controller. | ||
| 99 | +} | ||
| 100 | +*/ | ||
| 101 | + | ||
| 102 | +@end |
Example/CNLivePlayer/Streamer/LoadingView.h
0 → 100644
| 1 | +// | ||
| 2 | +// LoadingView.h | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 17/3/8. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import <UIKit/UIKit.h> | ||
| 10 | + | ||
| 11 | +typedef NS_ENUM(NSUInteger, LoadingViewStyle) { | ||
| 12 | + LoadingViewStyleStartLoading = 0, | ||
| 13 | + LoadingViewStyleStopLoading, | ||
| 14 | + LoadingViewStyleRetry, | ||
| 15 | +}; | ||
| 16 | + | ||
| 17 | +@class LoadingView; | ||
| 18 | + | ||
| 19 | +@protocol LoadingViewDelegate <NSObject> | ||
| 20 | + | ||
| 21 | +- (void)loadingView:(LoadingView *)loadingViewRetryAction; | ||
| 22 | + | ||
| 23 | +@end | ||
| 24 | + | ||
| 25 | +@interface LoadingView : UIView | ||
| 26 | + | ||
| 27 | +@property (nonatomic, assign) id<LoadingViewDelegate> delegate; | ||
| 28 | + | ||
| 29 | +- (void)setLoadingViewStyle:(LoadingViewStyle)style; | ||
| 30 | + | ||
| 31 | +@end |
Example/CNLivePlayer/Streamer/LoadingView.m
0 → 100644
| 1 | +// | ||
| 2 | +// LoadingView.m | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 17/3/8. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "LoadingView.h" | ||
| 10 | + | ||
| 11 | +@interface LoadingView () | ||
| 12 | + | ||
| 13 | +@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator; | ||
| 14 | +@property (nonatomic, strong) UIButton *retryBtn; | ||
| 15 | + | ||
| 16 | +@end | ||
| 17 | + | ||
| 18 | +@implementation LoadingView | ||
| 19 | + | ||
| 20 | +- (instancetype)initWithFrame:(CGRect)frame | ||
| 21 | +{ | ||
| 22 | + self = [super initWithFrame:frame]; | ||
| 23 | + if (self) { | ||
| 24 | + [self addSubview:self.activityIndicator]; | ||
| 25 | + [self addSubview:self.retryBtn]; | ||
| 26 | + [self.activityIndicator startAnimating]; | ||
| 27 | + | ||
| 28 | + } | ||
| 29 | + return self; | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +#pragma mark - | ||
| 33 | +#pragma mark - action | ||
| 34 | +- (void)retryBtnAction { | ||
| 35 | + if (self.delegate && [self.delegate respondsToSelector:@selector(loadingView:)]) { | ||
| 36 | + [self.delegate loadingView:self]; | ||
| 37 | + [self setLoadingViewStyle:LoadingViewStyleStartLoading]; | ||
| 38 | + } | ||
| 39 | +} | ||
| 40 | + | ||
| 41 | +- (void)setLoadingViewStyle:(LoadingViewStyle)style { | ||
| 42 | + switch (style) { | ||
| 43 | + case LoadingViewStyleStartLoading: | ||
| 44 | + [_activityIndicator startAnimating]; | ||
| 45 | + _retryBtn.hidden = YES; | ||
| 46 | + break; | ||
| 47 | + | ||
| 48 | + case LoadingViewStyleStopLoading: | ||
| 49 | + [_activityIndicator stopAnimating]; | ||
| 50 | + _retryBtn.hidden = YES; | ||
| 51 | + break; | ||
| 52 | + | ||
| 53 | + case LoadingViewStyleRetry: | ||
| 54 | + [_activityIndicator stopAnimating]; | ||
| 55 | + _retryBtn.hidden = NO; | ||
| 56 | + break; | ||
| 57 | + | ||
| 58 | + default: | ||
| 59 | + break; | ||
| 60 | + } | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | + | ||
| 64 | + | ||
| 65 | +#pragma mark - | ||
| 66 | +#pragma mark - getter | ||
| 67 | +- (UIActivityIndicatorView *)activityIndicator { | ||
| 68 | + if (!_activityIndicator) { | ||
| 69 | + _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; | ||
| 70 | + _activityIndicator.center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2); | ||
| 71 | + } | ||
| 72 | + return _activityIndicator; | ||
| 73 | +} | ||
| 74 | + | ||
| 75 | +- (UIButton *)retryBtn { | ||
| 76 | + if (!_retryBtn) { | ||
| 77 | + _retryBtn = [UIButton buttonWithType:UIButtonTypeCustom]; | ||
| 78 | + _retryBtn.frame = CGRectMake(self.bounds.size.width/2-30, self.bounds.size.height/2-20, 60, 40); | ||
| 79 | + [_retryBtn setTitle:@"重试" forState:UIControlStateNormal]; | ||
| 80 | + [_retryBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; | ||
| 81 | + _retryBtn.hidden = YES; | ||
| 82 | + _retryBtn.layer.cornerRadius = 10; | ||
| 83 | + _retryBtn.layer.masksToBounds = YES; | ||
| 84 | + _retryBtn.layer.borderColor = [UIColor blackColor].CGColor; | ||
| 85 | + _retryBtn.layer.borderWidth = 1; | ||
| 86 | + [_retryBtn addTarget:self action:@selector(retryBtnAction) forControlEvents:UIControlEventTouchUpInside]; | ||
| 87 | + | ||
| 88 | + } | ||
| 89 | + return _retryBtn; | ||
| 90 | +} | ||
| 91 | + | ||
| 92 | +@end |
Example/CNLivePlayer/Streamer/MoreFunctionsView.h
0 → 100644
| 1 | +// | ||
| 2 | +// MoreFunctionsView.h | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 2017/9/19. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import <UIKit/UIKit.h> | ||
| 10 | + | ||
| 11 | +typedef NS_ENUM(NSUInteger, MoreFuncType) { | ||
| 12 | + MoreFuncTypeScreenshot = 0, | ||
| 13 | + MoreFuncTypeLiveScene, | ||
| 14 | + MoreFuncTypeRecordScene, | ||
| 15 | + MoreFuncTypeLogo | ||
| 16 | +}; | ||
| 17 | + | ||
| 18 | +typedef void(^MoreFuncBlock)(MoreFuncType type, NSInteger idx, UISegmentedControl *seg); | ||
| 19 | + | ||
| 20 | +@interface MoreFunctionsView : UIView | ||
| 21 | + | ||
| 22 | +@property (nonatomic, copy) MoreFuncBlock moreFuncBlock; | ||
| 23 | +@property (nonatomic, strong) UISwitch *bypassRecord; | ||
| 24 | +@property (nonatomic, strong) UIButton *floatingWindowBtn; | ||
| 25 | + | ||
| 26 | +@end |
Example/CNLivePlayer/Streamer/MoreFunctionsView.m
0 → 100644
| 1 | +// | ||
| 2 | +// MoreFunctionsView.m | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 2017/9/19. | ||
| 6 | +// Copyright © 2017年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "MoreFunctionsView.h" | ||
| 10 | + | ||
| 11 | +@interface MoreFunctionsView () | ||
| 12 | + | ||
| 13 | +@property (nonatomic, strong) UISegmentedControl *screenshotSeg; | ||
| 14 | +@property (nonatomic, strong) UISegmentedControl *liveSceneSeg; | ||
| 15 | +@property (nonatomic, strong) UISegmentedControl *recordSceneSeg; | ||
| 16 | +@property (nonatomic, strong) UISegmentedControl *logoSeg; | ||
| 17 | + | ||
| 18 | +@end | ||
| 19 | + | ||
| 20 | +@implementation MoreFunctionsView | ||
| 21 | + | ||
| 22 | +- (instancetype)initWithFrame:(CGRect)frame | ||
| 23 | +{ | ||
| 24 | + self = [super initWithFrame:frame]; | ||
| 25 | + if (self) { | ||
| 26 | + | ||
| 27 | + [self addSubview:self.screenshotSeg]; | ||
| 28 | + [self addSubview:self.liveSceneSeg]; | ||
| 29 | + [self addSubview:self.recordSceneSeg]; | ||
| 30 | + [self addSubview:self.logoSeg]; | ||
| 31 | + [self addSubview:self.bypassRecord]; | ||
| 32 | + [self addSubview:self.floatingWindowBtn]; | ||
| 33 | + | ||
| 34 | + } | ||
| 35 | + return self; | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +#pragma mark - | ||
| 39 | +#pragma mark - action | ||
| 40 | +- (void)onSegCtrl:(UISegmentedControl *)seg { | ||
| 41 | + if (self.moreFuncBlock) { | ||
| 42 | + self.moreFuncBlock(seg.tag, seg.selectedSegmentIndex, seg); | ||
| 43 | + } | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +#pragma mark - | ||
| 47 | +#pragma mark - getter | ||
| 48 | +- (UISegmentedControl *)screenshotSeg | ||
| 49 | +{ | ||
| 50 | + if (!_screenshotSeg) { | ||
| 51 | + NSArray *items = @[ @"截图为文件", | ||
| 52 | + @"截图为UIImage"]; | ||
| 53 | + | ||
| 54 | + _screenshotSeg = [[UISegmentedControl alloc] initWithItems:items]; | ||
| 55 | + _screenshotSeg.frame = CGRectMake(95, 0, self.bounds.size.width-105, 30); | ||
| 56 | + _screenshotSeg.tintColor= [UIColor blackColor]; | ||
| 57 | + _screenshotSeg.layer.cornerRadius = 5; | ||
| 58 | + _screenshotSeg.selectedSegmentIndex = -1; | ||
| 59 | + _screenshotSeg.tag = MoreFuncTypeScreenshot; | ||
| 60 | + [_screenshotSeg addTarget:self action:@selector(onSegCtrl:) forControlEvents:UIControlEventValueChanged]; | ||
| 61 | + | ||
| 62 | + UILabel *titleLab = [[UILabel alloc] initWithFrame:CGRectMake(-85, 0, 80, 30)]; | ||
| 63 | + titleLab.text = @"截图"; | ||
| 64 | + titleLab.textColor = [UIColor blackColor]; | ||
| 65 | + titleLab.font = [UIFont systemFontOfSize:15]; | ||
| 66 | + titleLab.textAlignment = NSTextAlignmentCenter; | ||
| 67 | + titleLab.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.2]; | ||
| 68 | + [_screenshotSeg addSubview:titleLab]; | ||
| 69 | + } | ||
| 70 | + return _screenshotSeg; | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | +- (UISegmentedControl *)liveSceneSeg | ||
| 74 | +{ | ||
| 75 | + if (!_liveSceneSeg) { | ||
| 76 | + NSArray *items = @[ @"默认", | ||
| 77 | + @"秀场", | ||
| 78 | + @"游戏", | ||
| 79 | + ]; | ||
| 80 | + | ||
| 81 | + _liveSceneSeg = [[UISegmentedControl alloc] initWithItems:items]; | ||
| 82 | + _liveSceneSeg.frame = CGRectMake(95, 40, self.bounds.size.width-105, 30); | ||
| 83 | + _liveSceneSeg.tintColor= [UIColor blackColor]; | ||
| 84 | + _liveSceneSeg.selectedSegmentIndex = 0; | ||
| 85 | + _liveSceneSeg.layer.cornerRadius = 5; | ||
| 86 | + _liveSceneSeg.selectedSegmentIndex = 1; | ||
| 87 | + _liveSceneSeg.tag = MoreFuncTypeLiveScene; | ||
| 88 | + [_liveSceneSeg addTarget:self action:@selector(onSegCtrl:) forControlEvents:UIControlEventValueChanged]; | ||
| 89 | + | ||
| 90 | + UILabel *titleLab = [[UILabel alloc] initWithFrame:CGRectMake(-85, 0, 80, 30)]; | ||
| 91 | + titleLab.text = @"直播场景"; | ||
| 92 | + titleLab.textColor = [UIColor blackColor]; | ||
| 93 | + titleLab.font = [UIFont systemFontOfSize:15]; | ||
| 94 | + titleLab.textAlignment = NSTextAlignmentCenter; | ||
| 95 | + titleLab.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.2]; | ||
| 96 | + [_liveSceneSeg addSubview:titleLab]; | ||
| 97 | + } | ||
| 98 | + return _liveSceneSeg; | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +- (UISegmentedControl *)recordSceneSeg | ||
| 102 | +{ | ||
| 103 | + if (!_recordSceneSeg) { | ||
| 104 | + NSArray *items = @[ @"恒定码率", | ||
| 105 | + @"恒定质量", | ||
| 106 | + ]; | ||
| 107 | + | ||
| 108 | + _recordSceneSeg = [[UISegmentedControl alloc] initWithItems:items]; | ||
| 109 | + _recordSceneSeg.frame = CGRectMake(95, 80, self.bounds.size.width-105, 30); | ||
| 110 | + _recordSceneSeg.tintColor= [UIColor blackColor]; | ||
| 111 | + _recordSceneSeg.selectedSegmentIndex = 0; | ||
| 112 | + _recordSceneSeg.layer.cornerRadius = 5; | ||
| 113 | + _recordSceneSeg.selectedSegmentIndex = 1; | ||
| 114 | + _recordSceneSeg.tag = MoreFuncTypeRecordScene; | ||
| 115 | + [_recordSceneSeg addTarget:self action:@selector(onSegCtrl:) forControlEvents:UIControlEventValueChanged]; | ||
| 116 | + | ||
| 117 | + UILabel *titleLab = [[UILabel alloc] initWithFrame:CGRectMake(-85, 0, 80, 30)]; | ||
| 118 | + titleLab.text = @"录制场景"; | ||
| 119 | + titleLab.textColor = [UIColor blackColor]; | ||
| 120 | + titleLab.font = [UIFont systemFontOfSize:15]; | ||
| 121 | + titleLab.textAlignment = NSTextAlignmentCenter; | ||
| 122 | + titleLab.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.2]; | ||
| 123 | + [_recordSceneSeg addSubview:titleLab]; | ||
| 124 | + } | ||
| 125 | + return _recordSceneSeg; | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +- (UISegmentedControl *)logoSeg | ||
| 129 | +{ | ||
| 130 | + if (!_logoSeg) { | ||
| 131 | + NSArray *items = @[ @"清除logo", | ||
| 132 | + @"图片logo", | ||
| 133 | + @"动态logo", | ||
| 134 | + ]; | ||
| 135 | + | ||
| 136 | + _logoSeg = [[UISegmentedControl alloc] initWithItems:items]; | ||
| 137 | + _logoSeg.frame = CGRectMake(95, 120, self.bounds.size.width-105, 30); | ||
| 138 | + _logoSeg.tintColor= [UIColor blackColor]; | ||
| 139 | + _logoSeg.selectedSegmentIndex = 0; | ||
| 140 | + _logoSeg.layer.cornerRadius = 5; | ||
| 141 | + _logoSeg.selectedSegmentIndex = 1; | ||
| 142 | + _logoSeg.tag = MoreFuncTypeLogo; | ||
| 143 | + [_logoSeg addTarget:self action:@selector(onSegCtrl:) forControlEvents:UIControlEventValueChanged]; | ||
| 144 | + | ||
| 145 | + UILabel *titleLab = [[UILabel alloc] initWithFrame:CGRectMake(-85, 0, 80, 30)]; | ||
| 146 | + titleLab.text = @"Logo设置"; | ||
| 147 | + titleLab.textColor = [UIColor blackColor]; | ||
| 148 | + titleLab.font = [UIFont systemFontOfSize:15]; | ||
| 149 | + titleLab.textAlignment = NSTextAlignmentCenter; | ||
| 150 | + titleLab.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.2]; | ||
| 151 | + [_logoSeg addSubview:titleLab]; | ||
| 152 | + } | ||
| 153 | + return _logoSeg; | ||
| 154 | +} | ||
| 155 | + | ||
| 156 | +- (UISwitch *)bypassRecord | ||
| 157 | +{ | ||
| 158 | + if (!_bypassRecord) { | ||
| 159 | + _bypassRecord = [[UISwitch alloc] initWithFrame:CGRectMake(95, 160, 100, 30)]; | ||
| 160 | + | ||
| 161 | + UILabel *titleLab = [[UILabel alloc] initWithFrame:CGRectMake(-85, 0, 80, 30)]; | ||
| 162 | + titleLab.textColor = [UIColor blackColor]; | ||
| 163 | + titleLab.text = @"旁路录制"; | ||
| 164 | + titleLab.font = [UIFont systemFontOfSize:15]; | ||
| 165 | + titleLab.textAlignment = NSTextAlignmentCenter; | ||
| 166 | + titleLab.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.2]; | ||
| 167 | + [_bypassRecord addSubview:titleLab]; | ||
| 168 | + } | ||
| 169 | + return _bypassRecord; | ||
| 170 | +} | ||
| 171 | + | ||
| 172 | +- (UIButton *)floatingWindowBtn | ||
| 173 | +{ | ||
| 174 | + if (!_floatingWindowBtn) { | ||
| 175 | + _floatingWindowBtn = [UIButton buttonWithType:UIButtonTypeCustom]; | ||
| 176 | + _floatingWindowBtn.frame = CGRectMake(220, 160, 80, 30); | ||
| 177 | + [_floatingWindowBtn setTitle:@"悬浮窗" forState: UIControlStateNormal]; | ||
| 178 | + _floatingWindowBtn.titleLabel.font = [UIFont systemFontOfSize:15]; | ||
| 179 | + [_floatingWindowBtn setTitleColor:[UIColor colorWithRed:23/255.0 green:110/255.0 blue:254/255.0 alpha:1] forState:UIControlStateNormal]; | ||
| 180 | + _floatingWindowBtn.layer.cornerRadius = 3; | ||
| 181 | + _floatingWindowBtn.layer.masksToBounds = YES; | ||
| 182 | + _floatingWindowBtn.layer.borderColor = [UIColor blackColor].CGColor; | ||
| 183 | + _floatingWindowBtn.layer.borderWidth = 1; | ||
| 184 | + | ||
| 185 | + } | ||
| 186 | + return _floatingWindowBtn; | ||
| 187 | +} | ||
| 188 | + | ||
| 189 | +/* | ||
| 190 | +// Only override drawRect: if you perform custom drawing. | ||
| 191 | +// An empty implementation adversely affects performance during animation. | ||
| 192 | +- (void)drawRect:(CGRect)rect { | ||
| 193 | + // Drawing code | ||
| 194 | +} | ||
| 195 | +*/ | ||
| 196 | + | ||
| 197 | +@end |
Example/CNLivePlayer/Streamer/SliderView.h
0 → 100644
| 1 | +// | ||
| 2 | +// SliderView.h | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 16/12/21. | ||
| 6 | +// Copyright © 2016年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import <UIKit/UIKit.h> | ||
| 10 | + | ||
| 11 | +@protocol SliderViewDelegate <NSObject> | ||
| 12 | + | ||
| 13 | +- (void)sliderValueChenged; | ||
| 14 | + | ||
| 15 | +@end | ||
| 16 | + | ||
| 17 | +@interface SliderView : UIView | ||
| 18 | + | ||
| 19 | +@property (nonatomic, strong) UILabel* nameL; // 滑块对应参数名称 | ||
| 20 | +@property (nonatomic, strong) UISlider* slider; // 滑块 | ||
| 21 | +@property (nonatomic, strong) UILabel* valueL; // 滑块当前的值 | ||
| 22 | +@property (nonatomic, assign, readonly) float currentValue; | ||
| 23 | +@property (nonatomic, assign) id<SliderViewDelegate> delagate; | ||
| 24 | + | ||
| 25 | +- (instancetype)initWithFrame:(CGRect)frame title:(NSString *)title; | ||
| 26 | + | ||
| 27 | +@end |
Example/CNLivePlayer/Streamer/SliderView.m
0 → 100644
| 1 | +// | ||
| 2 | +// SliderView.m | ||
| 3 | +// CNLivePlayerSDKDemo | ||
| 4 | +// | ||
| 5 | +// Created by iOS on 16/12/21. | ||
| 6 | +// Copyright © 2016年 雷浩杰. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "SliderView.h" | ||
| 10 | + | ||
| 11 | +@implementation SliderView | ||
| 12 | +{ | ||
| 13 | + NSString *_title; | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +- (instancetype)initWithFrame:(CGRect)frame title:(NSString *)title{ | ||
| 17 | + self = [super initWithFrame:frame]; | ||
| 18 | + if (self) { | ||
| 19 | + _title = title; | ||
| 20 | + [self addSubview:self.nameL]; | ||
| 21 | + [self addSubview:self.valueL]; | ||
| 22 | + [self addSubview:self.slider]; | ||
| 23 | + } | ||
| 24 | + return self; | ||
| 25 | +} | ||
| 26 | + | ||
| 27 | +- (float)currentValue | ||
| 28 | +{ | ||
| 29 | + return _slider.value; | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +#pragma mark - | ||
| 33 | +#pragma mark - action | ||
| 34 | + | ||
| 35 | +- (void)onSlider:(UISlider *)slider | ||
| 36 | +{ | ||
| 37 | + _valueL.text = [NSString stringWithFormat:@"%d",(int)(slider.value * 100)]; | ||
| 38 | + if (self.delagate && [self.delagate respondsToSelector:@selector(sliderValueChenged)]) { | ||
| 39 | + [self.delagate sliderValueChenged]; | ||
| 40 | + } | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +#pragma mark - | ||
| 44 | +#pragma mark - getter | ||
| 45 | + | ||
| 46 | +- (UILabel *)nameL | ||
| 47 | +{ | ||
| 48 | + if (!_nameL) { | ||
| 49 | + _nameL = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 24)]; | ||
| 50 | + _nameL.text = _title; | ||
| 51 | + _nameL.textAlignment = NSTextAlignmentCenter; | ||
| 52 | + _nameL.textColor = [UIColor blackColor]; | ||
| 53 | + _nameL.backgroundColor = [UIColor colorWithRed:192/255.0 green:192/255.0 blue:192/255.0 alpha:1]; | ||
| 54 | + _nameL.font = [UIFont systemFontOfSize:15]; | ||
| 55 | + _nameL.layer.cornerRadius = 5; | ||
| 56 | + _nameL.layer.masksToBounds = YES; | ||
| 57 | + } | ||
| 58 | + return _nameL; | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +- (UILabel *)valueL | ||
| 62 | +{ | ||
| 63 | + if (!_valueL) { | ||
| 64 | + _valueL = [[UILabel alloc] initWithFrame:CGRectMake(self.bounds.size.width-40, 0, 40, 24)]; | ||
| 65 | + _valueL.text = @"50"; | ||
| 66 | + _valueL.textAlignment = NSTextAlignmentCenter; | ||
| 67 | + _valueL.textColor = [UIColor blackColor]; | ||
| 68 | + _valueL.backgroundColor = [UIColor colorWithRed:192/255.0 green:192/255.0 blue:192/255.0 alpha:1]; | ||
| 69 | + _valueL.font = [UIFont systemFontOfSize:15]; | ||
| 70 | + _valueL.layer.cornerRadius = 5; | ||
| 71 | + _valueL.layer.masksToBounds = YES; | ||
| 72 | + | ||
| 73 | + } | ||
| 74 | + return _valueL; | ||
| 75 | +} | ||
| 76 | + | ||
| 77 | +- (UISlider *)slider | ||
| 78 | +{ | ||
| 79 | + if (!_slider) { | ||
| 80 | + _slider = [[UISlider alloc] initWithFrame:CGRectMake(40, 0, self.bounds.size.width-80, 24)]; | ||
| 81 | + [_slider setThumbImage:[UIImage imageNamed:@"btn_dot"] forState:UIControlStateNormal]; | ||
| 82 | + [_slider setMinimumTrackTintColor:[UIColor redColor]]; | ||
| 83 | + [_slider setMaximumTrackTintColor:[UIColor whiteColor]]; | ||
| 84 | + _slider.value = 0.5; | ||
| 85 | + | ||
| 86 | + [_slider addTarget:self action:@selector(onSlider:) forControlEvents:UIControlEventValueChanged]; | ||
| 87 | + } | ||
| 88 | + return _slider; | ||
| 89 | +} | ||
| 90 | +@end |
Example/CNLivePlayer/Streamer/StreamerDetailViewController.h
0 → 100644
| 1 | +// | ||
| 2 | +// LiveViewController.h | ||
| 3 | +// CNLiveLiveDemo | ||
| 4 | +// | ||
| 5 | +// Created by Android on 16/8/10. | ||
| 6 | +// Copyright © 2016年 Android. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import <UIKit/UIKit.h> | ||
| 10 | + | ||
| 11 | +@interface StreamerDetailViewController : UIViewController | ||
| 12 | + | ||
| 13 | +@property (nonatomic, assign) BOOL isAuthLive; | ||
| 14 | +@property (nonatomic, assign) BOOL isRecord; | ||
| 15 | + | ||
| 16 | +@property (nonatomic, strong) NSURL *url; | ||
| 17 | + | ||
| 18 | +@end |