Commit b43edad08538b9bdab3acbb9611a3db50733f93f

Authored by 雷浩杰
1 parent f3efd1c5

no message

Showing 38 changed files with 3032 additions and 0 deletions
CNLivePlayer.pdf 0 → 100644
No preview for this file type
CNLivePlayerSDKTest/CNLivePlayerSDK.framework/CNLivePlayerSDK 0 → 100755
No preview for this file type
CNLivePlayerSDKTest/CNLivePlayerSDK.framework/Headers/CNLiveBarrageAnimationView.h 0 → 100644
  1 +//
  2 +// barrageAnimationView.h
  3 +//
  4 +// Created by CNLive on 16/8/3.
  5 +// Copyright © 2016年 CNLive. All rights reserved.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +
  10 +//承载弹幕动画的view
  11 +@interface CNLiveBarrageAnimationView : UIView
  12 +
  13 +/* 初始化 barrageAnimationView
  14 + *
  15 + * frame中height此时设置是无效的
  16 + * height将根据提供的行数和用来做弹幕动画的label的height决定
  17 + *
  18 + */
  19 +- (instancetype)initWithFrame:(CGRect)frame;
  20 +
  21 +/* 设置弹幕的行数
  22 + *
  23 + * 弹幕启动后设置无效
  24 + * 默认1行
  25 + *
  26 + */
  27 +- (void)setLinage:(NSInteger)linage;
  28 +
  29 +/* 设置弹幕文字到弹幕载体边缘的间隔
  30 + *
  31 + * 弹幕启动后设置无效
  32 + * 默认为0
  33 + *
  34 + */
  35 +- (void)setHorizontalSpace:(CGFloat)hSpace;
  36 +
  37 +/* 设置弹幕与弹幕之间上下的间隔
  38 + *
  39 + * 弹幕启动后设置无效
  40 + * 默认为0
  41 + *
  42 + */
  43 +- (void)setVerticalSpace:(CGFloat)vSpace;
  44 +
  45 +/* 设置弹幕动画的持续时间
  46 + *
  47 + * 弹幕启动后设置无效
  48 + * 默认5秒
  49 + *
  50 + */
  51 +- (void)setAnimationDuration:(CGFloat)duration;
  52 +
  53 +/* 设置弹幕的样式
  54 + *
  55 + * 弹幕启动后设置无效
  56 + *
  57 + * 通过传入label的属性来设置弹幕的样式
  58 + *
  59 + * 目前支持设置的属性有如下
  60 + * frame中的height
  61 + * backgroundColor
  62 + * font
  63 + * textColor
  64 + * layer.cornerRadius
  65 + * layer.masksToBounds
  66 + * layer.borderColor
  67 + * layer.borderWidth
  68 + *
  69 + */
  70 +- (void)setBarrageLabelStyle:(UILabel *)styleLabel;
  71 +
  72 +/* 启动弹幕
  73 + *
  74 + * 未启动时也会保留传入的弹幕内容
  75 + *
  76 + */
  77 +- (void)startAnimation;
  78 +
  79 +/* 关闭弹幕
  80 + *
  81 + * 调用时正在做动画的弹幕将立即消失
  82 + * 等待做动画的弹幕继续保留
  83 + * 再次调用startAnimation将继续展示
  84 + *
  85 + */
  86 +- (void)stopAnimation;
  87 +
  88 +// 传入需要展示的弹幕内容
  89 +- (void)showBarrageContent:(NSString *)content;
  90 +
  91 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDK.framework/Headers/CNLiveGPUStreamerKit.h 0 → 100644
  1 +//
  2 +// CNLiveGPUStreamerKit.h
  3 +// KSYLiveDemo
  4 +//
  5 +// Created by Android on 16/8/3.
  6 +// Copyright © 2016年 Android. All rights reserved.
  7 +//
  8 +
  9 +#import <Foundation/Foundation.h>
  10 +#import <AVFoundation/AVFoundation.h>
  11 +#import <UIKit/UIKit.h>
  12 +#import "CNLiveTypeDef.h"
  13 +
  14 +@interface CNLiveGPUStreamerKit : NSObject
  15 +
  16 +#pragma mark - 普通直播(可自行设置推流地址)
  17 +
  18 +/**
  19 + @abstract 初始化
  20 + @warning 要用全局变量进行初始化
  21 + */
  22 +-(instancetype)initWithDefaultConfig;
  23 +
  24 +/**
  25 + @abstract 视频分辨率
  26 + @discussion width x height ( 此处width始终大于高度,是否竖屏取决于videoOrientation的值 )
  27 + */
  28 +@property (nonatomic, assign) CNLiveVideoDimension videoDimension;
  29 +
  30 +/**
  31 + @abstract 视频编码器
  32 + @discussion video codec used for encode
  33 + */
  34 +@property (nonatomic, assign) CNLiveVideoCodec videoCodec;
  35 +
  36 +/**
  37 + @abstract 视频编码起始码率(单位:kbps)
  38 + @discussion 开始推流时的视频码率,开始推流后,根据网络情况在 [Min, Max]范围内调节
  39 + @discussion 视频码率上调则画面更清晰,下调则画面更模糊
  40 + */
  41 +@property (nonatomic, assign) int videoInitBitrate;
  42 +
  43 +/**
  44 + @abstract 视频编码最高码率(单位:kbps)
  45 + @discussion 视频码率自适应调整的上限, 为目标码率
  46 + */
  47 +@property (nonatomic, assign) int videoMaxBitrate;
  48 +
  49 +/**
  50 + @abstract 视频编码最低码率(单位:kbps)
  51 + @discussion 视频码率自适应调整的下限
  52 + */
  53 +@property (nonatomic, assign) int videoMinBitrate;
  54 +
  55 +/**
  56 + @abstract 最大关键帧间隔(单位:秒, 默认:2)
  57 + @discussion 即GOP长度 画面静止时,隔n秒插入一个关键帧
  58 + */
  59 +@property (nonatomic, assign) int maxKeyInterval;
  60 +
  61 +/**
  62 + @abstract 音频编码码率(单位:kbps)
  63 + @discussion 音频目标编码码率 (比如48,96,128等)
  64 + */
  65 +@property (nonatomic, assign) int audiokBPS;
  66 +
  67 +/**
  68 + @abstract 启用自动调整码率
  69 + @discussion 默认为关闭自动调整码率,开始预览前设置有效
  70 + */
  71 +@property (nonatomic, assign) BOOL enAutoApplyEstimateBW;
  72 +
  73 +/**
  74 + @abstract 视频帧率
  75 + @discussion video frame per seconds 有效范围[1~30], 超出会提示参数错误
  76 + */
  77 +@property (nonatomic, assign) int videoFPS;
  78 +
  79 +/**
  80 + @abstract 启用是否开启美颜
  81 + @discussion 默认为开启,开始预览前设置有效
  82 + */
  83 +@property (nonatomic, assign) BOOL isOpenImageFilter;
  84 +
  85 +/**
  86 + @abstract 摄像头位置
  87 + @discussion 前后摄像头 默认为前摄像头
  88 + */
  89 +@property (nonatomic, assign) AVCaptureDevicePosition cameraPosition;
  90 +
  91 +/**
  92 + @abstract 开关闪光灯
  93 + @discussion 切换闪光灯的开关状态 开 <--> 关
  94 + @warning 对后摄像头设置有效
  95 + */
  96 +- (void) toggleTorch;
  97 +- (void) setTorchMode:(AVCaptureTorchMode)mode;
  98 +
  99 +/**
  100 + @abstract 摄像头朝向
  101 + */
  102 +- (void) setVideoOrientationBy:(UIInterfaceOrientation)uiOrien;
  103 +
  104 +/**
  105 + @abstract 启动预览
  106 + @param view 预览画面作为subview,插入到 view 的最底层
  107 + @discussion 设置完成采集参数之后,按照设置值启动预览,启动后对采集参数修改不会生效
  108 + @discussion 需要访问摄像头和麦克风的权限,若授权失败,其他API都会拒绝服务
  109 + @warning: 开始推流前必须先启动预览
  110 + */
  111 +- (void) startPreview:(UIView*) view;
  112 +
  113 +/**
  114 + @abstract 停止预览,停止采集设备,并清理会话
  115 + @warning 若推流未结束,则先停止推流
  116 + */
  117 +- (void) stopPreview;
  118 +
  119 +/**
  120 + @abstract 启动推流
  121 + @param hostURL rtmp 服务器地址 “rtmp://xxx.xxx.xxx.xxx/appname/streamKey"
  122 + @discussion 设置完成推流参数之后,将媒体流推送到 publishURL 对应的地址
  123 + @discussion 推流参数主要是视频编码器,音视频码率的设置
  124 + @warning 不鉴权直接传入推流地址
  125 + */
  126 +- (void) startStream:(NSURL *)hostURL;
  127 +
  128 +/**
  129 + @abstract 停止推流
  130 + @discussion 断开网络连接,停止视频编码
  131 + */
  132 +- (void) stopStream;
  133 +
  134 +/**
  135 + @abstract 获取当前采集设备的指针
  136 + @return AVCaptureDevice* 预览开始前调用返回为nil,开始预览后,返回当前正在使用的摄像头
  137 + @warning 请勿修改摄像头的像素格式,帧率,分辨率等参数,修改后会导致推流工作异常或崩溃
  138 + */
  139 +- (AVCaptureDevice *) getCurrentCameraDevices;
  140 +
  141 +/**
  142 + @abstract 采集设备状态
  143 + */
  144 +@property (nonatomic, assign) CNLiveCaptureState captureState;
  145 +
  146 +FOUNDATION_EXPORT NSString *const CNLiveCaptureStateDidChangeNotification NS_AVAILABLE_IOS(7_0);
  147 +
  148 +/**
  149 + @abstract 推流状态
  150 + */
  151 +@property (nonatomic, assign) CNLiveStreamState streamState;
  152 +
  153 +FOUNDATION_EXPORT NSString *const CNLiveStreamStateDidChangeNotification NS_AVAILABLE_IOS(7_0);
  154 +
  155 +/**
  156 + * @abstract 推流错误码,用于指示推流失败的原因
  157 + */
  158 +@property (nonatomic, assign) CNLiveStreamErrorCode streamErrorCode;
  159 +
  160 +#pragma mark - 视讯云相关部分
  161 +
  162 +/**
  163 + @abstract 初始化
  164 + @warning 要用全局变量进行初始化
  165 + @param appId 应用ID
  166 + @param appKey 注册后的应用key
  167 + @param activityId 活动ID,确保SP下的唯一性
  168 + @param channelId 主播ID
  169 + @param isHorizontalScreen 屏幕方向,0:垂直即竖屏 /1:水平即横屏 ,默认为1
  170 + @param success 用于返回初始化状态(成功)
  171 + @param failure 用于返回初始化状态(失败)
  172 + @warning 必传参数
  173 + */
  174 +-(instancetype)initWithDefaultConfigWithAppId:(NSString *)appId
  175 + appKey:(NSString *)appKey
  176 + activityId:(NSString *)activityId
  177 + channelId:(NSString *)channelId
  178 + isHorizontalScreen:(NSString *)isHorizontalScreen;
  179 +
  180 +/**
  181 + @abstract 获取推流地址
  182 + @warning 请传入所需参数后调用 (若返回失败请重新调用此方法获取推流地址)
  183 + */
  184 +- (void)getStreamerURLWithSuccess:(void (^)(void))success
  185 + failure :(void (^)(NSError *error))failure;
  186 +
  187 +/**
  188 + @abstract 活动名称(非必传)
  189 + */
  190 +@property (nonatomic, strong) NSString *activityName;
  191 +
  192 +/**
  193 + @abstract 活动状态,0:未开始 /1:已开始 /3:已结束 /4 已下线,默认为0(非必传)
  194 + */
  195 +@property (nonatomic, strong) NSString *activityStatus;
  196 +
  197 +/**
  198 + @abstract 开始时间,格式yyyyMMddHHmmss(非必传)
  199 + */
  200 +@property (nonatomic, strong) NSString *startTime;
  201 +
  202 +/**
  203 + @abstract 结束时间,格式yyyyMMddHHmmss(非必传)
  204 + */
  205 +@property (nonatomic, strong) NSString *endTime;
  206 +
  207 +/**
  208 + @abstract 活动封面(非必传)
  209 + */
  210 +@property (nonatomic, strong) NSString *coverImgUrl;
  211 +
  212 +/**
  213 + @abstract 活动分类ID(非必传)
  214 + */
  215 +@property (nonatomic, strong) NSString *activityCategory;
  216 +
  217 +/**
  218 + @abstract 扩展字段,参数格式为Map对象的Json字符串(主播昵称、头像、)(非必传)
  219 + */
  220 +@property (nonatomic, strong) NSString *extensions;
  221 +
  222 +/**
  223 + @abstract 回调通知活动状态(错误,结束、心跳异常等状态),post 参数activityid、activitystatus值...(非必传)
  224 + */
  225 +@property (nonatomic, strong) NSString *callbackAcitvityStatushttpPostUrl;
  226 +
  227 +/**
  228 + @abstract 启动推流
  229 + @discussion 设置完成推流参数之后,将媒体流推送到 publishURL 对应的地址
  230 + @warning 鉴权成功后开启推流
  231 + */
  232 +- (void) startStream:(void (^)(void))success failure:(void (^)(NSError *error))failure;
  233 +
  234 +/**
  235 + @abstract 推流过程中异常通知
  236 + */
  237 +FOUNDATION_EXPORT NSString *const CNLiveStreamAbnormalNotification NS_AVAILABLE_IOS(7_0);
  238 +
  239 +/**
  240 + @abstract 结束推流成功
  241 + */
  242 +FOUNDATION_EXPORT NSString *const CNLiveStreamStopSuccessNotification NS_AVAILABLE_IOS(7_0);
  243 +
  244 +/**
  245 + @abstract 结束推流失败
  246 + */
  247 +FOUNDATION_EXPORT NSString *const CNLiveStreamStopFailedNotification NS_AVAILABLE_IOS(7_0);
  248 +
  249 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDK.framework/Headers/CNLiveMoviePlayerController.h 0 → 100644
  1 +//
  2 +// CNLiveMoviePlayerController.h
  3 +//
  4 +// Created by CNLive on 16/8/5.
  5 +// Copyright © 2016年 CNLive. All rights reserved.
  6 +//
  7 +
  8 +#import <UIKit/UIKit.h>
  9 +#import <MediaPlayer/MediaPlayer.h>
  10 +
  11 +@interface CNLiveMoviePlayerController : NSObject
  12 +
  13 +#pragma mark - 视讯云内容相关方法 直接通过节目id播放
  14 +/* 初始化点播播放器
  15 + *
  16 + * appId 在open.cnlive.com网站申请得到的appId
  17 + * appKey 在open.cnlive.com网站申请得到的app_key
  18 + * vId 点播Id
  19 + *
  20 + */
  21 +- (instancetype)initVodPlayWithAppId:(NSString *)appId
  22 + appKey:(NSString *)appKey
  23 + vId:(NSString *)vId;
  24 +
  25 +/* 初始化直播播放器 只有在completionBlock回调后才能对播放器进行操作
  26 + *
  27 + * appId 在open.cnlive.com网站申请得到的appId
  28 + * appKey 在open.cnlive.com网站申请得到的app_key
  29 + * channelId 直播Id
  30 + * completion 初始化完成
  31 + *
  32 + */
  33 +- (instancetype)initLivePlayWithAppId:(NSString *)appId
  34 + appKey:(NSString *)appKey
  35 + channelId:(NSString *)channelId
  36 + completion:(void(^)(void))completionBlock;
  37 +
  38 +/* 切换视角和码率
  39 + *
  40 + * channelId 直播Id
  41 + * rate 清晰度(1、2、3、4)
  42 + *
  43 + */
  44 +- (void)changeViewWithChannelId:(NSString *)channelId rate:(NSString *)rate;
  45 +
  46 +/* 切换视频源
  47 + *
  48 + * 当视频不够流畅时可调用此方法
  49 + *
  50 + */
  51 +- (void)retry;
  52 +
  53 +#pragma mark - 普通播放器方法
  54 +/*
  55 + * 初始化播放器并设置播放地址
  56 + */
  57 +- (instancetype)initWithContentURL:(NSURL *)url;
  58 +
  59 +/* 重新启动拉流
  60 + *
  61 + * url 视频播放地址,该地址可以是本地地址或者服务器地址.如果为nil,则使用前一次播放地址
  62 + *
  63 + */
  64 +- (void)reload:(NSURL *)aUrl;
  65 +
  66 +/*
  67 + * 播放视频时是否需要自动播放,默认值为YES
  68 + */
  69 +@property (nonatomic) BOOL shouldAutoplay;
  70 +
  71 +/* 准备视频播放
  72 + *
  73 + * MPMediaPlaybackIsPreparedToPlayDidChangeNotification, 播放器完成对视频文件的初始化时发送通知
  74 + *
  75 + */
  76 +- (void)prepareToPlay;
  77 +
  78 +/*
  79 + * 查询视频准备是否完成(只读)
  80 + */
  81 +@property(nonatomic, readonly) BOOL isPreparedToPlay;
  82 +
  83 +// Posted when the prepared state changes of an object conforming to the MPMediaPlayback protocol changes.
  84 +// This supersedes MPMoviePlayerContentPreloadDidFinishNotification.
  85 +MP_EXTERN NSString *const MPMediaPlaybackIsPreparedToPlayDidChangeNotification NS_DEPRECATED_IOS(3_2, 9_0);
  86 +
  87 +/*
  88 + * 播放当前视频
  89 + */
  90 +- (void)play;
  91 +
  92 +/* 暂停播放当前视频
  93 + *
  94 + * 播放器内部监听了UIApplicationWillEnterForegroundNotification通知,该通知发生时如果视频仍然在播放,将自动调用pause暂停当前视频播放
  95 + *
  96 + * 需要APP有后台执行权限,在工程Info.plist中添加后台运行模式,设置为audio。具体是添加UIBackgroundModes项,值为audio
  97 + * 当用户点击home按钮后,播放器进入后台继续读取数据并播放音频
  98 + * 当APP回到前台后,音频继续播放。图像渲染内容保持和音频同步
  99 + * 如果在开启后台运行模式后,需要切换后台暂停,需要监听相关事件并主动调用pause操作
  100 + *
  101 + */
  102 +- (void)pause;
  103 +
  104 +/* 结束当前视频的播放
  105 + *
  106 + * 重复多次调用将会导致崩溃
  107 + * 调用stop结束当前播放,如果需要重新播放该视频,需要调用[prepareToPlay]([KSYMediaPlayback prepareToPlay])方法
  108 + * 调用stop方法后,播放器开始进入关闭当前播放的操作,操作完成将发送MPMoviePlayerPlaybackDidFinishNotification通知
  109 + *
  110 + * MPMoviePlayerPlaybackDidFinishNotification, 当播放完成将发送该通知
  111 + *
  112 + */
  113 +- (void)stop;
  114 +
  115 +/*
  116 + * 当前播放器是否在播放
  117 + */
  118 +- (BOOL)isPlaying;
  119 +
  120 +/* 播放视频的当前时刻,单位为秒
  121 + *
  122 + * 视频正常播放时,如果改变currentPlaybackTime的值,将导致播放行为跳转到新的currentPlaybackTime位置播放
  123 + * 如果在视频未播放前设置currentPlaybackTime的值,将导致播放时刻从currentPlaybackTime位置播放
  124 + *
  125 + */
  126 +@property(nonatomic) NSTimeInterval currentPlaybackTime;
  127 +
  128 +/*
  129 + * 当前视频总时长(只读)
  130 + */
  131 +@property (nonatomic, readonly) NSTimeInterval duration;
  132 +
  133 +/* 当前视频可播放长度(只读)
  134 + *
  135 + * currentPlaybackTime 标记的是播放器当前已播放的时长。
  136 + * playableDuration 标记的是播放器缓冲的时间,会稍大于currentPlaybackTime,与currentPlaybackTime的差值则是缓冲长度。
  137 + *
  138 + */
  139 +@property (nonatomic, readonly) NSTimeInterval playableDuration;
  140 +
  141 +/* 包含视频播放内容的VIEW(只读)
  142 + *
  143 + * 可以通过frame设置view大大小
  144 + * 使用[scalingMode]可以更改视频内容在VIEW中的显示情况
  145 + *
  146 + */
  147 +@property (nonatomic, readonly) UIView *view;
  148 +
  149 +/* 当前播放器的播放状态(只读)
  150 + *
  151 + * MPMoviePlaybackStateStopped, // 播放停止
  152 + * MPMoviePlaybackStatePlaying, // 正在播放
  153 + * MPMoviePlaybackStatePaused, // 播放暂停
  154 + * MPMoviePlaybackStateInterrupted, // 播放被打断
  155 + * MPMoviePlaybackStateSeekingForward, // 向前seeking中
  156 + * MPMoviePlaybackStateSeekingBackward // 向后seeking中
  157 + *
  158 + * MPMoviePlayerPlaybackDidFinishNotification,当播放完成时提供通知
  159 + * MPMoviePlayerPlaybackStateDidChangeNotification,当播放状态变化时提供通知
  160 + *
  161 + */
  162 +@property (nonatomic, readonly) MPMoviePlaybackState playbackState;
  163 +
  164 +/* 当前网络加载情况(只读)
  165 + *
  166 + * MPMovieLoadStateUnknown = 0, // 加载情况未知
  167 + * MPMovieLoadStatePlayable = 1 << 0, // 加载完成,可以播放
  168 + * MPMovieLoadStatePlaythroughOK = 1 << 1, // 加载完成,如果shouldAutoplay为YES,将自动开始播放
  169 + * MPMovieLoadStateStalled = 1 << 2, // 如果视频正在加载中
  170 + *
  171 + * MPMoviePlayerLoadStateDidChangeNotification,当加载状态变化时提供通知
  172 + *
  173 + */
  174 +@property (nonatomic, readonly) MPMovieLoadState loadState;
  175 +
  176 +/* 当前缩放显示模式
  177 + *
  178 + * MPMovieScalingModeNone, // 无缩放
  179 + * MPMovieScalingModeAspectFit, // 同比适配,某个方向会有黑边
  180 + * MPMovieScalingModeAspectFill, // 同比填充,某个方向的显示内容可能被裁剪
  181 + * MPMovieScalingModeFill // 满屏填充,与原始视频比例不一致
  182 + *
  183 + */
  184 +@property (nonatomic) MPMovieScalingMode scalingMode;
  185 +
  186 +/* 当前视频宽高(只读)
  187 + *
  188 + * 监听MPMovieNaturalSizeAvailableNotification
  189 + * 播放过程中,宽高信息可能会产生更改
  190 + *
  191 + */
  192 +@property (nonatomic, readonly) CGSize naturalSize;
  193 +
  194 +// Posted when the playback state changes, either programatically or by the user.
  195 +MP_EXTERN NSString * const MPMoviePlayerPlaybackStateDidChangeNotification;
  196 +
  197 +// Posted when movie playback ends or a user exits playback.
  198 +MP_EXTERN NSString * const MPMoviePlayerPlaybackDidFinishNotification;
  199 +
  200 +MP_EXTERN NSString * const MPMoviePlayerPlaybackDidFinishReasonUserInfoKey; // NSNumber (MPMovieFinishReason)
  201 +
  202 +// Posted when the network load state changes.
  203 +MP_EXTERN NSString * const MPMoviePlayerLoadStateDidChangeNotification;
  204 +
  205 +MP_EXTERN NSString * const MPMovieNaturalSizeAvailableNotification;
  206 +
  207 +MP_EXTERN NSString * const MPMoviePlayerFirstVideoFrameRenderedNotification;
  208 +
  209 +MP_EXTERN NSString * const MPMoviePlayerFirstAudioFrameRenderedNotification;
  210 +
  211 +/* bufferTimeMax指定直播流播放时的最大缓冲时长,单位为秒
  212 + *
  213 + * 当buffer为负数时,关闭直播追赶
  214 + * 该属性仅对直播流有效
  215 + * 默认值为2秒
  216 + *
  217 + */
  218 +@property NSTimeInterval bufferTimeMax;
  219 +
  220 +/* 已经加载的数据大小(只读)
  221 + *
  222 + * 已经加载的数据大小,单位是兆
  223 + * 已经加载的全部数据大小,包括音频和视频
  224 + * 数据包括已经播放的,和当前的cache数据
  225 + *
  226 + */
  227 +@property (nonatomic, readonly) double readSize;
  228 +
  229 +/* buffer为空时,拉取数据所耗的时长(只读)
  230 + *
  231 + * 当buffer为空时,开始统计。单位为秒
  232 + *
  233 + * 当MPMoviePlayerLoadStateDidChangeNotification 通知发起
  234 + * MPMovieLoadState状态为MPMovieLoadStateStalled 开始计时
  235 + * MPMovieLoadState状态为MPMovieLoadStatePlayable 或者 MPMovieLoadStatePlaythroughOK时,结束计时
  236 + *
  237 + */
  238 +@property (nonatomic, readonly) NSTimeInterval bufferEmptyDuration;
  239 +
  240 +/* 发起cache的次数(只读)
  241 + *
  242 + * 当buffer为空时,统计一次,统计的条件为
  243 + *
  244 + * 当MPMoviePlayerLoadStateDidChangeNotification 通知发起
  245 + * MPMovieLoadState 状态为MPMovieLoadStateStalled
  246 + *
  247 + */
  248 +@property (nonatomic, readonly) NSInteger bufferEmptyCount;
  249 +
  250 +/* 截图
  251 + *
  252 + * 当前时刻的视频UIImage 图像
  253 + *
  254 + */
  255 +- (UIImage *)thumbnailImageAtCurrentTime;
  256 +
  257 +/* 是否开启硬件解码
  258 + *
  259 + * 默认是关闭
  260 + * 只在[prepareToPlay]调用前设置生效
  261 + *
  262 + */
  263 +@property(nonatomic) BOOL shouldUseHWCodec;
  264 +
  265 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDK.framework/Headers/CNLiveTypeDef.h 0 → 100644
  1 +//
  2 +// CNLiveTypeDef.h
  3 +// CNLiveLiveDemo
  4 +//
  5 +// Created by Android on 16/8/3.
  6 +// Copyright © 2016年 Android. All rights reserved.
  7 +//
  8 +
  9 +#ifndef CNLiveTypeDef_h
  10 +#define CNLiveTypeDef_h
  11 +
  12 +#pragma mark - Video Dimension
  13 +
  14 +/// 采集分辨率
  15 +typedef NS_ENUM(NSUInteger, CNLiveVideoDimension) {
  16 + /// 16 : 9 宽高比,1280 x 720 分辨率
  17 + CNLiveVideoDimension_16_9__1280x720 = 0,
  18 + /// 16 : 9 宽高比,960 x 540 分辨率
  19 + CNLiveVideoDimension_16_9__960x540,
  20 + /// 4 : 3 宽高比,640 x 480 分辨率
  21 + CNLiveVideoDimension_4_3__640x480,
  22 + /// 16 : 9 宽高比,640 x 360 分辨率
  23 + CNLiveVideoDimension_16_9__640x360,
  24 + /// 4 : 3 宽高比,320 x 240 分辨率
  25 + CNLiveVideoDimension_5_4__352x288,
  26 +
  27 + /// 缩放自定义分辨率 从设备支持的最近分辨率缩放获得, 若设备没有对应宽高比的分辨率,则裁剪后进行缩放
  28 + CNLiveVideoDimension_UserDefine_Scale,
  29 + /// 裁剪自定义分辨率 从设备支持的最近分辨率裁剪获得
  30 + CNLiveVideoDimension_UserDefine_Crop,
  31 + /// 注意: 选择缩放自定义分辨率时可能会有额外CPU代价
  32 +
  33 + /// 默认分辨率,默认为 4 : 3 宽高比,640 x 480 分辨率
  34 + CNLiveVideoDimension_Default = CNLiveVideoDimension_4_3__640x480,
  35 +};
  36 +
  37 +
  38 +#pragma mark - Video Codec ID
  39 +/*!
  40 + * @abstract 视频编码器类型
  41 + */
  42 +typedef NS_ENUM(NSUInteger, CNLiveVideoCodec) {
  43 + /// 视频编码器 - h264 软件编码器
  44 + CNLiveVideoCodec_X264 = 0,
  45 + /// 视频编码器 - 仟壹265 软件编码器
  46 + CNLiveVideoCodec_QY265,
  47 + /// 视频编码器 - iOS VT264硬件编码器 (iOS 8.0以上支持)
  48 + CNLiveVideoCodec_VT264,
  49 +};
  50 +
  51 +#pragma mark - QYPublisher State
  52 +
  53 +/*!
  54 + * @abstract 采集设备状态
  55 + */
  56 +typedef NS_ENUM(NSUInteger, CNLiveCaptureState) {
  57 + /// 设备空闲中
  58 + CNLiveCaptureStateIdle,
  59 + /// 设备工作中
  60 + CNLiveCaptureStateCapturing,
  61 + /// 设备授权被拒绝
  62 + CNLiveCaptureStateDevAuthDenied,
  63 + /// 关闭采集设备中
  64 + CNLiveCaptureStateClosingCapture,
  65 + /// 参数错误,无法打开(比如设置的分辨率,码率当前设备不支持)
  66 + CNLiveCaptureStateParameterError,
  67 + /// 设备正忙,请稍后尝试 ( 该状态在发出通知0.5秒后被清除 )
  68 + CNLiveCaptureStateDevBusy,
  69 +};
  70 +
  71 +/*!
  72 + * @abstract 推流状态
  73 + */
  74 +typedef NS_ENUM(NSUInteger, CNLiveStreamState) {
  75 + /// 初始化时状态为空闲
  76 + CNLiveStreamStateIdle = 0,
  77 + /// 连接中
  78 + CNLiveStreamStateConnecting,
  79 + /// 已连接
  80 + CNLiveStreamStateConnected,
  81 + /// 断开连接中
  82 + CNLiveStreamStateDisconnecting,
  83 + /// 推流出错
  84 + CNLiveStreamStateError,
  85 +};
  86 +
  87 +/*!
  88 + * @abstract 推流错误码,用于指示推流失败的原因
  89 + */
  90 +typedef NS_ENUM(NSUInteger, CNLiveStreamErrorCode) {
  91 + /// 正常无错误
  92 + CNLiveStreamErrorCode_NONE = 0,
  93 + /// SDK 鉴权失败 (暂时正常推流5~8分钟后终止推流)
  94 + CNLiveStreamErrorCode_CNLiveAUTHFAILED,
  95 + /// 当前帧编码失败
  96 + CNLiveStreamErrorCode_ENCODE_FRAMES_FAILED,
  97 + /// 无法打开配置指示的CODEC
  98 + CNLiveStreamErrorCode_CODEC_OPEN_FAILED,
  99 + /// 连接出错,检查地址
  100 + CNLiveStreamErrorCode_CONNECT_FAILED,
  101 + /// 网络连接中断
  102 + CNLiveStreamErrorCode_CONNECT_BREAK,
  103 + /// rtmp 推流域名不存在 (CNLive 自定义)
  104 + CNLiveStreamErrorCode_RTMP_NonExistDomain,
  105 + /// rtmp 应用名不存在(CNLive 自定义)
  106 + CNLiveStreamErrorCode_RTMP_NonExistApplication,
  107 + /// rtmp 流名已存在(CNLive 自定义)
  108 + CNLiveStreamErrorCode_RTMP_AlreadyExistStreamName,
  109 + /// rtmp 被黑名单拒绝(CNLive 自定义)
  110 + CNLiveStreamErrorCode_RTMP_ForbiddenByBlacklist,
  111 + /// rtmp 内部错误(CNLive 自定义)
  112 + CNLiveStreamErrorCode_RTMP_InternalError,
  113 + /// rtmp URL 地址已过期(CNLive 自定义)
  114 + CNLiveStreamErrorCode_RTMP_URLExpired,
  115 + /// rtmp URL 地址签名错误(CNLive 自定义)
  116 + CNLiveStreamErrorCode_RTMP_SignatureDoesNotMatch,
  117 + /// rtmp URL 中AccessKeyId非法(CNLive 自定义)
  118 + CNLiveStreamErrorCode_RTMP_InvalidAccessKeyId,
  119 + /// rtmp URL 中参数错误(CNLive 自定义)
  120 + CNLiveStreamErrorCode_RTMP_BadParams,
  121 + /// rtmp URL 中的推流不在发布点内(CNLive 自定义)
  122 + CNLiveStreamErrorCode_RTMP_ForbiddenByRegion,
  123 + /// SDK 因为鉴权失败停止推流
  124 + CNLiveStreamErrorCode_FRAMES_THRESHOLD,
  125 + /// 没有输入的数据,无法开始推流
  126 + CNLiveStreamErrorCode_NO_INPUT_SAMPLE,
  127 +};
  128 +
  129 +#endif /* CNLiveTypeDef_h */
... ...
CNLivePlayerSDKTest/CNLivePlayerSDK.framework/Info.plist 0 → 100644
No preview for this file type
CNLivePlayerSDKTest/CNLivePlayerSDKTest.xcodeproj/project.pbxproj 0 → 100644
  1 +// !$*UTF8*$!
  2 +{
  3 + archiveVersion = 1;
  4 + classes = {
  5 + };
  6 + objectVersion = 46;
  7 + objects = {
  8 +
  9 +/* Begin PBXBuildFile section */
  10 + 32E6CA2B1D5B0AF400B58EBC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E6CA2A1D5B0AF400B58EBC /* main.m */; };
  11 + 32E6CA2E1D5B0AF400B58EBC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E6CA2D1D5B0AF400B58EBC /* AppDelegate.m */; };
  12 + 32E6CA311D5B0AF400B58EBC /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E6CA301D5B0AF400B58EBC /* ViewController.m */; };
  13 + 32E6CA341D5B0AF400B58EBC /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32E6CA321D5B0AF400B58EBC /* Main.storyboard */; };
  14 + 32E6CA361D5B0AF400B58EBC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 32E6CA351D5B0AF400B58EBC /* Assets.xcassets */; };
  15 + 32E6CA391D5B0AF400B58EBC /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32E6CA371D5B0AF400B58EBC /* LaunchScreen.storyboard */; };
  16 + 32E6CA901D5B2AF700B58EBC /* BarrageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E6CA831D5B2AF700B58EBC /* BarrageViewController.m */; };
  17 + 32E6CA911D5B2AF700B58EBC /* CNLiveViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E6CA861D5B2AF700B58EBC /* CNLiveViewController.m */; };
  18 + 32E6CA921D5B2AF700B58EBC /* NormalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E6CA881D5B2AF700B58EBC /* NormalViewController.m */; };
  19 + 32E6CA931D5B2AF700B58EBC /* PlayerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E6CA8A1D5B2AF700B58EBC /* PlayerViewController.m */; };
  20 + 32E6CA941D5B2AF700B58EBC /* StreamerDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E6CA8D1D5B2AF700B58EBC /* StreamerDetailViewController.m */; };
  21 + 32E6CA951D5B2AF700B58EBC /* StreamerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E6CA8F1D5B2AF700B58EBC /* StreamerViewController.m */; };
  22 + 32F57CB01D93CFFA00A6D031 /* CNLivePlayerSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32F57CAE1D93CFF500A6D031 /* CNLivePlayerSDK.framework */; };
  23 + 32F57CB11D93CFFA00A6D031 /* CNLivePlayerSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 32F57CAE1D93CFF500A6D031 /* CNLivePlayerSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
  24 +/* End PBXBuildFile section */
  25 +
  26 +/* Begin PBXCopyFilesBuildPhase section */
  27 + 32E6CA7A1D5B280B00B58EBC /* Embed Frameworks */ = {
  28 + isa = PBXCopyFilesBuildPhase;
  29 + buildActionMask = 2147483647;
  30 + dstPath = "";
  31 + dstSubfolderSpec = 10;
  32 + files = (
  33 + 32F57CB11D93CFFA00A6D031 /* CNLivePlayerSDK.framework in Embed Frameworks */,
  34 + );
  35 + name = "Embed Frameworks";
  36 + runOnlyForDeploymentPostprocessing = 0;
  37 + };
  38 +/* End PBXCopyFilesBuildPhase section */
  39 +
  40 +/* Begin PBXFileReference section */
  41 + 32E6CA261D5B0AF400B58EBC /* CNLivePlayerSDKTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CNLivePlayerSDKTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
  42 + 32E6CA2A1D5B0AF400B58EBC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
  43 + 32E6CA2C1D5B0AF400B58EBC /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
  44 + 32E6CA2D1D5B0AF400B58EBC /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
  45 + 32E6CA2F1D5B0AF400B58EBC /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
  46 + 32E6CA301D5B0AF400B58EBC /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
  47 + 32E6CA331D5B0AF400B58EBC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
  48 + 32E6CA351D5B0AF400B58EBC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
  49 + 32E6CA381D5B0AF400B58EBC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
  50 + 32E6CA3A1D5B0AF400B58EBC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
  51 + 32E6CA821D5B2AF700B58EBC /* BarrageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BarrageViewController.h; sourceTree = "<group>"; };
  52 + 32E6CA831D5B2AF700B58EBC /* BarrageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BarrageViewController.m; sourceTree = "<group>"; };
  53 + 32E6CA851D5B2AF700B58EBC /* CNLiveViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CNLiveViewController.h; sourceTree = "<group>"; };
  54 + 32E6CA861D5B2AF700B58EBC /* CNLiveViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CNLiveViewController.m; sourceTree = "<group>"; };
  55 + 32E6CA871D5B2AF700B58EBC /* NormalViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NormalViewController.h; sourceTree = "<group>"; };
  56 + 32E6CA881D5B2AF700B58EBC /* NormalViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NormalViewController.m; sourceTree = "<group>"; };
  57 + 32E6CA891D5B2AF700B58EBC /* PlayerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayerViewController.h; sourceTree = "<group>"; };
  58 + 32E6CA8A1D5B2AF700B58EBC /* PlayerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlayerViewController.m; sourceTree = "<group>"; };
  59 + 32E6CA8C1D5B2AF700B58EBC /* StreamerDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamerDetailViewController.h; sourceTree = "<group>"; };
  60 + 32E6CA8D1D5B2AF700B58EBC /* StreamerDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StreamerDetailViewController.m; sourceTree = "<group>"; };
  61 + 32E6CA8E1D5B2AF700B58EBC /* StreamerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamerViewController.h; sourceTree = "<group>"; };
  62 + 32E6CA8F1D5B2AF700B58EBC /* StreamerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StreamerViewController.m; sourceTree = "<group>"; };
  63 + 32F57CAE1D93CFF500A6D031 /* CNLivePlayerSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CNLivePlayerSDK.framework; sourceTree = "<group>"; };
  64 +/* End PBXFileReference section */
  65 +
  66 +/* Begin PBXFrameworksBuildPhase section */
  67 + 32E6CA231D5B0AF400B58EBC /* Frameworks */ = {
  68 + isa = PBXFrameworksBuildPhase;
  69 + buildActionMask = 2147483647;
  70 + files = (
  71 + 32F57CB01D93CFFA00A6D031 /* CNLivePlayerSDK.framework in Frameworks */,
  72 + );
  73 + runOnlyForDeploymentPostprocessing = 0;
  74 + };
  75 +/* End PBXFrameworksBuildPhase section */
  76 +
  77 +/* Begin PBXGroup section */
  78 + 32E6CA1D1D5B0AF400B58EBC = {
  79 + isa = PBXGroup;
  80 + children = (
  81 + 32F57CAE1D93CFF500A6D031 /* CNLivePlayerSDK.framework */,
  82 + 32E6CA281D5B0AF400B58EBC /* CNLivePlayerSDKTest */,
  83 + 32E6CA271D5B0AF400B58EBC /* Products */,
  84 + );
  85 + sourceTree = "<group>";
  86 + };
  87 + 32E6CA271D5B0AF400B58EBC /* Products */ = {
  88 + isa = PBXGroup;
  89 + children = (
  90 + 32E6CA261D5B0AF400B58EBC /* CNLivePlayerSDKTest.app */,
  91 + );
  92 + name = Products;
  93 + sourceTree = "<group>";
  94 + };
  95 + 32E6CA281D5B0AF400B58EBC /* CNLivePlayerSDKTest */ = {
  96 + isa = PBXGroup;
  97 + children = (
  98 + 32E6CA811D5B2AF700B58EBC /* Barrage */,
  99 + 32E6CA841D5B2AF700B58EBC /* Player */,
  100 + 32E6CA8B1D5B2AF700B58EBC /* Streamer */,
  101 + 32E6CA2C1D5B0AF400B58EBC /* AppDelegate.h */,
  102 + 32E6CA2D1D5B0AF400B58EBC /* AppDelegate.m */,
  103 + 32E6CA2F1D5B0AF400B58EBC /* ViewController.h */,
  104 + 32E6CA301D5B0AF400B58EBC /* ViewController.m */,
  105 + 32E6CA321D5B0AF400B58EBC /* Main.storyboard */,
  106 + 32E6CA351D5B0AF400B58EBC /* Assets.xcassets */,
  107 + 32E6CA371D5B0AF400B58EBC /* LaunchScreen.storyboard */,
  108 + 32E6CA3A1D5B0AF400B58EBC /* Info.plist */,
  109 + 32E6CA291D5B0AF400B58EBC /* Supporting Files */,
  110 + );
  111 + path = CNLivePlayerSDKTest;
  112 + sourceTree = "<group>";
  113 + };
  114 + 32E6CA291D5B0AF400B58EBC /* Supporting Files */ = {
  115 + isa = PBXGroup;
  116 + children = (
  117 + 32E6CA2A1D5B0AF400B58EBC /* main.m */,
  118 + );
  119 + name = "Supporting Files";
  120 + sourceTree = "<group>";
  121 + };
  122 + 32E6CA811D5B2AF700B58EBC /* Barrage */ = {
  123 + isa = PBXGroup;
  124 + children = (
  125 + 32E6CA821D5B2AF700B58EBC /* BarrageViewController.h */,
  126 + 32E6CA831D5B2AF700B58EBC /* BarrageViewController.m */,
  127 + );
  128 + path = Barrage;
  129 + sourceTree = "<group>";
  130 + };
  131 + 32E6CA841D5B2AF700B58EBC /* Player */ = {
  132 + isa = PBXGroup;
  133 + children = (
  134 + 32E6CA851D5B2AF700B58EBC /* CNLiveViewController.h */,
  135 + 32E6CA861D5B2AF700B58EBC /* CNLiveViewController.m */,
  136 + 32E6CA871D5B2AF700B58EBC /* NormalViewController.h */,
  137 + 32E6CA881D5B2AF700B58EBC /* NormalViewController.m */,
  138 + 32E6CA891D5B2AF700B58EBC /* PlayerViewController.h */,
  139 + 32E6CA8A1D5B2AF700B58EBC /* PlayerViewController.m */,
  140 + );
  141 + path = Player;
  142 + sourceTree = "<group>";
  143 + };
  144 + 32E6CA8B1D5B2AF700B58EBC /* Streamer */ = {
  145 + isa = PBXGroup;
  146 + children = (
  147 + 32E6CA8C1D5B2AF700B58EBC /* StreamerDetailViewController.h */,
  148 + 32E6CA8D1D5B2AF700B58EBC /* StreamerDetailViewController.m */,
  149 + 32E6CA8E1D5B2AF700B58EBC /* StreamerViewController.h */,
  150 + 32E6CA8F1D5B2AF700B58EBC /* StreamerViewController.m */,
  151 + );
  152 + path = Streamer;
  153 + sourceTree = "<group>";
  154 + };
  155 +/* End PBXGroup section */
  156 +
  157 +/* Begin PBXNativeTarget section */
  158 + 32E6CA251D5B0AF400B58EBC /* CNLivePlayerSDKTest */ = {
  159 + isa = PBXNativeTarget;
  160 + buildConfigurationList = 32E6CA3D1D5B0AF400B58EBC /* Build configuration list for PBXNativeTarget "CNLivePlayerSDKTest" */;
  161 + buildPhases = (
  162 + 32E6CA221D5B0AF400B58EBC /* Sources */,
  163 + 32E6CA231D5B0AF400B58EBC /* Frameworks */,
  164 + 32E6CA241D5B0AF400B58EBC /* Resources */,
  165 + 32E6CA7A1D5B280B00B58EBC /* Embed Frameworks */,
  166 + );
  167 + buildRules = (
  168 + );
  169 + dependencies = (
  170 + );
  171 + name = CNLivePlayerSDKTest;
  172 + productName = CNLivePlayerSDKTest;
  173 + productReference = 32E6CA261D5B0AF400B58EBC /* CNLivePlayerSDKTest.app */;
  174 + productType = "com.apple.product-type.application";
  175 + };
  176 +/* End PBXNativeTarget section */
  177 +
  178 +/* Begin PBXProject section */
  179 + 32E6CA1E1D5B0AF400B58EBC /* Project object */ = {
  180 + isa = PBXProject;
  181 + attributes = {
  182 + LastUpgradeCheck = 0730;
  183 + ORGANIZATIONNAME = "雷浩杰";
  184 + TargetAttributes = {
  185 + 32E6CA251D5B0AF400B58EBC = {
  186 + CreatedOnToolsVersion = 7.3.1;
  187 + DevelopmentTeam = 94X49GG3ZW;
  188 + };
  189 + };
  190 + };
  191 + buildConfigurationList = 32E6CA211D5B0AF400B58EBC /* Build configuration list for PBXProject "CNLivePlayerSDKTest" */;
  192 + compatibilityVersion = "Xcode 3.2";
  193 + developmentRegion = English;
  194 + hasScannedForEncodings = 0;
  195 + knownRegions = (
  196 + en,
  197 + Base,
  198 + );
  199 + mainGroup = 32E6CA1D1D5B0AF400B58EBC;
  200 + productRefGroup = 32E6CA271D5B0AF400B58EBC /* Products */;
  201 + projectDirPath = "";
  202 + projectRoot = "";
  203 + targets = (
  204 + 32E6CA251D5B0AF400B58EBC /* CNLivePlayerSDKTest */,
  205 + );
  206 + };
  207 +/* End PBXProject section */
  208 +
  209 +/* Begin PBXResourcesBuildPhase section */
  210 + 32E6CA241D5B0AF400B58EBC /* Resources */ = {
  211 + isa = PBXResourcesBuildPhase;
  212 + buildActionMask = 2147483647;
  213 + files = (
  214 + 32E6CA391D5B0AF400B58EBC /* LaunchScreen.storyboard in Resources */,
  215 + 32E6CA361D5B0AF400B58EBC /* Assets.xcassets in Resources */,
  216 + 32E6CA341D5B0AF400B58EBC /* Main.storyboard in Resources */,
  217 + );
  218 + runOnlyForDeploymentPostprocessing = 0;
  219 + };
  220 +/* End PBXResourcesBuildPhase section */
  221 +
  222 +/* Begin PBXSourcesBuildPhase section */
  223 + 32E6CA221D5B0AF400B58EBC /* Sources */ = {
  224 + isa = PBXSourcesBuildPhase;
  225 + buildActionMask = 2147483647;
  226 + files = (
  227 + 32E6CA931D5B2AF700B58EBC /* PlayerViewController.m in Sources */,
  228 + 32E6CA311D5B0AF400B58EBC /* ViewController.m in Sources */,
  229 + 32E6CA951D5B2AF700B58EBC /* StreamerViewController.m in Sources */,
  230 + 32E6CA911D5B2AF700B58EBC /* CNLiveViewController.m in Sources */,
  231 + 32E6CA901D5B2AF700B58EBC /* BarrageViewController.m in Sources */,
  232 + 32E6CA2E1D5B0AF400B58EBC /* AppDelegate.m in Sources */,
  233 + 32E6CA2B1D5B0AF400B58EBC /* main.m in Sources */,
  234 + 32E6CA941D5B2AF700B58EBC /* StreamerDetailViewController.m in Sources */,
  235 + 32E6CA921D5B2AF700B58EBC /* NormalViewController.m in Sources */,
  236 + );
  237 + runOnlyForDeploymentPostprocessing = 0;
  238 + };
  239 +/* End PBXSourcesBuildPhase section */
  240 +
  241 +/* Begin PBXVariantGroup section */
  242 + 32E6CA321D5B0AF400B58EBC /* Main.storyboard */ = {
  243 + isa = PBXVariantGroup;
  244 + children = (
  245 + 32E6CA331D5B0AF400B58EBC /* Base */,
  246 + );
  247 + name = Main.storyboard;
  248 + sourceTree = "<group>";
  249 + };
  250 + 32E6CA371D5B0AF400B58EBC /* LaunchScreen.storyboard */ = {
  251 + isa = PBXVariantGroup;
  252 + children = (
  253 + 32E6CA381D5B0AF400B58EBC /* Base */,
  254 + );
  255 + name = LaunchScreen.storyboard;
  256 + sourceTree = "<group>";
  257 + };
  258 +/* End PBXVariantGroup section */
  259 +
  260 +/* Begin XCBuildConfiguration section */
  261 + 32E6CA3B1D5B0AF400B58EBC /* Debug */ = {
  262 + isa = XCBuildConfiguration;
  263 + buildSettings = {
  264 + ALWAYS_SEARCH_USER_PATHS = NO;
  265 + CLANG_ANALYZER_NONNULL = YES;
  266 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  267 + CLANG_CXX_LIBRARY = "libc++";
  268 + CLANG_ENABLE_MODULES = YES;
  269 + CLANG_ENABLE_OBJC_ARC = YES;
  270 + CLANG_WARN_BOOL_CONVERSION = YES;
  271 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  272 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  273 + CLANG_WARN_EMPTY_BODY = YES;
  274 + CLANG_WARN_ENUM_CONVERSION = YES;
  275 + CLANG_WARN_INT_CONVERSION = YES;
  276 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  277 + CLANG_WARN_UNREACHABLE_CODE = YES;
  278 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  279 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  280 + COPY_PHASE_STRIP = NO;
  281 + DEBUG_INFORMATION_FORMAT = dwarf;
  282 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  283 + ENABLE_TESTABILITY = YES;
  284 + GCC_C_LANGUAGE_STANDARD = gnu99;
  285 + GCC_DYNAMIC_NO_PIC = NO;
  286 + GCC_NO_COMMON_BLOCKS = YES;
  287 + GCC_OPTIMIZATION_LEVEL = 0;
  288 + GCC_PREPROCESSOR_DEFINITIONS = (
  289 + "DEBUG=1",
  290 + "$(inherited)",
  291 + );
  292 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  293 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  294 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  295 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  296 + GCC_WARN_UNUSED_FUNCTION = YES;
  297 + GCC_WARN_UNUSED_VARIABLE = YES;
  298 + IPHONEOS_DEPLOYMENT_TARGET = 9.3;
  299 + MTL_ENABLE_DEBUG_INFO = YES;
  300 + ONLY_ACTIVE_ARCH = YES;
  301 + SDKROOT = iphoneos;
  302 + };
  303 + name = Debug;
  304 + };
  305 + 32E6CA3C1D5B0AF400B58EBC /* Release */ = {
  306 + isa = XCBuildConfiguration;
  307 + buildSettings = {
  308 + ALWAYS_SEARCH_USER_PATHS = NO;
  309 + CLANG_ANALYZER_NONNULL = YES;
  310 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  311 + CLANG_CXX_LIBRARY = "libc++";
  312 + CLANG_ENABLE_MODULES = YES;
  313 + CLANG_ENABLE_OBJC_ARC = YES;
  314 + CLANG_WARN_BOOL_CONVERSION = YES;
  315 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  316 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  317 + CLANG_WARN_EMPTY_BODY = YES;
  318 + CLANG_WARN_ENUM_CONVERSION = YES;
  319 + CLANG_WARN_INT_CONVERSION = YES;
  320 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  321 + CLANG_WARN_UNREACHABLE_CODE = YES;
  322 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  323 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  324 + COPY_PHASE_STRIP = NO;
  325 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
  326 + ENABLE_NS_ASSERTIONS = NO;
  327 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  328 + GCC_C_LANGUAGE_STANDARD = gnu99;
  329 + GCC_NO_COMMON_BLOCKS = YES;
  330 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  331 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  332 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  333 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  334 + GCC_WARN_UNUSED_FUNCTION = YES;
  335 + GCC_WARN_UNUSED_VARIABLE = YES;
  336 + IPHONEOS_DEPLOYMENT_TARGET = 9.3;
  337 + MTL_ENABLE_DEBUG_INFO = NO;
  338 + SDKROOT = iphoneos;
  339 + VALIDATE_PRODUCT = YES;
  340 + };
  341 + name = Release;
  342 + };
  343 + 32E6CA3E1D5B0AF400B58EBC /* Debug */ = {
  344 + isa = XCBuildConfiguration;
  345 + buildSettings = {
  346 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  347 + DEVELOPMENT_TEAM = 94X49GG3ZW;
  348 + ENABLE_BITCODE = NO;
  349 + FRAMEWORK_SEARCH_PATHS = (
  350 + "$(inherited)",
  351 + "$(PROJECT_DIR)/CNLivePlayerSDKTest",
  352 + "$(PROJECT_DIR)",
  353 + );
  354 + INFOPLIST_FILE = CNLivePlayerSDKTest/Info.plist;
  355 + IPHONEOS_DEPLOYMENT_TARGET = 8.0;
  356 + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
  357 + PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.libs;
  358 + PRODUCT_NAME = "$(TARGET_NAME)";
  359 + };
  360 + name = Debug;
  361 + };
  362 + 32E6CA3F1D5B0AF400B58EBC /* Release */ = {
  363 + isa = XCBuildConfiguration;
  364 + buildSettings = {
  365 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  366 + DEVELOPMENT_TEAM = 94X49GG3ZW;
  367 + ENABLE_BITCODE = NO;
  368 + FRAMEWORK_SEARCH_PATHS = (
  369 + "$(inherited)",
  370 + "$(PROJECT_DIR)/CNLivePlayerSDKTest",
  371 + "$(PROJECT_DIR)",
  372 + );
  373 + INFOPLIST_FILE = CNLivePlayerSDKTest/Info.plist;
  374 + IPHONEOS_DEPLOYMENT_TARGET = 8.0;
  375 + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
  376 + PRODUCT_BUNDLE_IDENTIFIER = com.cnlive.libs;
  377 + PRODUCT_NAME = "$(TARGET_NAME)";
  378 + };
  379 + name = Release;
  380 + };
  381 +/* End XCBuildConfiguration section */
  382 +
  383 +/* Begin XCConfigurationList section */
  384 + 32E6CA211D5B0AF400B58EBC /* Build configuration list for PBXProject "CNLivePlayerSDKTest" */ = {
  385 + isa = XCConfigurationList;
  386 + buildConfigurations = (
  387 + 32E6CA3B1D5B0AF400B58EBC /* Debug */,
  388 + 32E6CA3C1D5B0AF400B58EBC /* Release */,
  389 + );
  390 + defaultConfigurationIsVisible = 0;
  391 + defaultConfigurationName = Release;
  392 + };
  393 + 32E6CA3D1D5B0AF400B58EBC /* Build configuration list for PBXNativeTarget "CNLivePlayerSDKTest" */ = {
  394 + isa = XCConfigurationList;
  395 + buildConfigurations = (
  396 + 32E6CA3E1D5B0AF400B58EBC /* Debug */,
  397 + 32E6CA3F1D5B0AF400B58EBC /* Release */,
  398 + );
  399 + defaultConfigurationIsVisible = 0;
  400 + defaultConfigurationName = Release;
  401 + };
  402 +/* End XCConfigurationList section */
  403 + };
  404 + rootObject = 32E6CA1E1D5B0AF400B58EBC /* Project object */;
  405 +}
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Workspace
  3 + version = "1.0">
  4 + <FileRef
  5 + location = "self:CNLivePlayerSDKTest.xcodeproj">
  6 + </FileRef>
  7 +</Workspace>
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest.xcodeproj/xcuserdata/leihaojie.xcuserdatad/xcschemes/CNLivePlayerSDKTest.xcscheme 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Scheme
  3 + LastUpgradeVersion = "0730"
  4 + version = "1.3">
  5 + <BuildAction
  6 + parallelizeBuildables = "YES"
  7 + buildImplicitDependencies = "YES">
  8 + <BuildActionEntries>
  9 + <BuildActionEntry
  10 + buildForTesting = "YES"
  11 + buildForRunning = "YES"
  12 + buildForProfiling = "YES"
  13 + buildForArchiving = "YES"
  14 + buildForAnalyzing = "YES">
  15 + <BuildableReference
  16 + BuildableIdentifier = "primary"
  17 + BlueprintIdentifier = "32E6CA251D5B0AF400B58EBC"
  18 + BuildableName = "CNLivePlayerSDKTest.app"
  19 + BlueprintName = "CNLivePlayerSDKTest"
  20 + ReferencedContainer = "container:CNLivePlayerSDKTest.xcodeproj">
  21 + </BuildableReference>
  22 + </BuildActionEntry>
  23 + </BuildActionEntries>
  24 + </BuildAction>
  25 + <TestAction
  26 + buildConfiguration = "Debug"
  27 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  28 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  29 + shouldUseLaunchSchemeArgsEnv = "YES">
  30 + <Testables>
  31 + </Testables>
  32 + <MacroExpansion>
  33 + <BuildableReference
  34 + BuildableIdentifier = "primary"
  35 + BlueprintIdentifier = "32E6CA251D5B0AF400B58EBC"
  36 + BuildableName = "CNLivePlayerSDKTest.app"
  37 + BlueprintName = "CNLivePlayerSDKTest"
  38 + ReferencedContainer = "container:CNLivePlayerSDKTest.xcodeproj">
  39 + </BuildableReference>
  40 + </MacroExpansion>
  41 + <AdditionalOptions>
  42 + </AdditionalOptions>
  43 + </TestAction>
  44 + <LaunchAction
  45 + buildConfiguration = "Debug"
  46 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  47 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  48 + launchStyle = "0"
  49 + useCustomWorkingDirectory = "NO"
  50 + ignoresPersistentStateOnLaunch = "NO"
  51 + debugDocumentVersioning = "YES"
  52 + debugServiceExtension = "internal"
  53 + allowLocationSimulation = "YES">
  54 + <BuildableProductRunnable
  55 + runnableDebuggingMode = "0">
  56 + <BuildableReference
  57 + BuildableIdentifier = "primary"
  58 + BlueprintIdentifier = "32E6CA251D5B0AF400B58EBC"
  59 + BuildableName = "CNLivePlayerSDKTest.app"
  60 + BlueprintName = "CNLivePlayerSDKTest"
  61 + ReferencedContainer = "container:CNLivePlayerSDKTest.xcodeproj">
  62 + </BuildableReference>
  63 + </BuildableProductRunnable>
  64 + <AdditionalOptions>
  65 + </AdditionalOptions>
  66 + </LaunchAction>
  67 + <ProfileAction
  68 + buildConfiguration = "Release"
  69 + shouldUseLaunchSchemeArgsEnv = "YES"
  70 + savedToolIdentifier = ""
  71 + useCustomWorkingDirectory = "NO"
  72 + debugDocumentVersioning = "YES">
  73 + <BuildableProductRunnable
  74 + runnableDebuggingMode = "0">
  75 + <BuildableReference
  76 + BuildableIdentifier = "primary"
  77 + BlueprintIdentifier = "32E6CA251D5B0AF400B58EBC"
  78 + BuildableName = "CNLivePlayerSDKTest.app"
  79 + BlueprintName = "CNLivePlayerSDKTest"
  80 + ReferencedContainer = "container:CNLivePlayerSDKTest.xcodeproj">
  81 + </BuildableReference>
  82 + </BuildableProductRunnable>
  83 + </ProfileAction>
  84 + <AnalyzeAction
  85 + buildConfiguration = "Debug">
  86 + </AnalyzeAction>
  87 + <ArchiveAction
  88 + buildConfiguration = "Release"
  89 + revealArchiveInOrganizer = "YES">
  90 + </ArchiveAction>
  91 +</Scheme>
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest.xcodeproj/xcuserdata/leihaojie.xcuserdatad/xcschemes/xcschememanagement.plist 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>SchemeUserState</key>
  6 + <dict>
  7 + <key>CNLivePlayerSDKTest.xcscheme</key>
  8 + <dict>
  9 + <key>orderHint</key>
  10 + <integer>0</integer>
  11 + </dict>
  12 + </dict>
  13 + <key>SuppressBuildableAutocreation</key>
  14 + <dict>
  15 + <key>32E6CA251D5B0AF400B58EBC</key>
  16 + <dict>
  17 + <key>primary</key>
  18 + <true/>
  19 + </dict>
  20 + </dict>
  21 +</dict>
  22 +</plist>
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/AppDelegate.h 0 → 100644
  1 +//
  2 +// AppDelegate.h
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +
  11 +@interface AppDelegate : UIResponder <UIApplicationDelegate>
  12 +
  13 +@property (strong, nonatomic) UIWindow *window;
  14 +
  15 +
  16 +@end
  17 +
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/AppDelegate.m 0 → 100644
  1 +//
  2 +// AppDelegate.m
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import "AppDelegate.h"
  10 +
  11 +@interface AppDelegate ()
  12 +
  13 +@end
  14 +
  15 +@implementation AppDelegate
  16 +
  17 +
  18 +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  19 + // Override point for customization after application launch.
  20 + return YES;
  21 +}
  22 +
  23 +- (void)applicationWillResignActive:(UIApplication *)application {
  24 + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
  25 + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
  26 +}
  27 +
  28 +- (void)applicationDidEnterBackground:(UIApplication *)application {
  29 + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
  30 + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
  31 +}
  32 +
  33 +- (void)applicationWillEnterForeground:(UIApplication *)application {
  34 + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
  35 +}
  36 +
  37 +- (void)applicationDidBecomeActive:(UIApplication *)application {
  38 + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
  39 +}
  40 +
  41 +- (void)applicationWillTerminate:(UIApplication *)application {
  42 + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
  43 +}
  44 +
  45 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Assets.xcassets/AppIcon.appiconset/Contents.json 0 → 100644
  1 +{
  2 + "images" : [
  3 + {
  4 + "idiom" : "iphone",
  5 + "size" : "29x29",
  6 + "scale" : "2x"
  7 + },
  8 + {
  9 + "idiom" : "iphone",
  10 + "size" : "29x29",
  11 + "scale" : "3x"
  12 + },
  13 + {
  14 + "idiom" : "iphone",
  15 + "size" : "40x40",
  16 + "scale" : "2x"
  17 + },
  18 + {
  19 + "idiom" : "iphone",
  20 + "size" : "40x40",
  21 + "scale" : "3x"
  22 + },
  23 + {
  24 + "idiom" : "iphone",
  25 + "size" : "60x60",
  26 + "scale" : "2x"
  27 + },
  28 + {
  29 + "idiom" : "iphone",
  30 + "size" : "60x60",
  31 + "scale" : "3x"
  32 + }
  33 + ],
  34 + "info" : {
  35 + "version" : 1,
  36 + "author" : "xcode"
  37 + }
  38 +}
0 39 \ No newline at end of file
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Assets.xcassets/Contents.json 0 → 100644
  1 +{
  2 + "info" : {
  3 + "version" : 1,
  4 + "author" : "xcode"
  5 + }
  6 +}
0 7 \ No newline at end of file
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Assets.xcassets/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 22 \ No newline at end of file
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Assets.xcassets/pause.imageset/pause.png 0 → 100644

3.15 KB

CNLivePlayerSDKTest/CNLivePlayerSDKTest/Assets.xcassets/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 22 \ No newline at end of file
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Assets.xcassets/play.imageset/play.png 0 → 100644

6.41 KB

CNLivePlayerSDKTest/CNLivePlayerSDKTest/Barrage/BarrageViewController.h 0 → 100644
  1 +//
  2 +// BarrageViewController.h
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +
  11 +@interface BarrageViewController : UIViewController
  12 +
  13 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Barrage/BarrageViewController.m 0 → 100644
  1 +//
  2 +// BarrageViewController.m
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import "BarrageViewController.h"
  10 +#import <CNLivePlayerSDK/CNLiveBarrageAnimationView.h>
  11 +
  12 +@interface BarrageViewController ()<UITextFieldDelegate>
  13 +{
  14 + CNLiveBarrageAnimationView *_barrage;
  15 +}
  16 +
  17 +@end
  18 +
  19 +@implementation BarrageViewController
  20 +
  21 +- (void)viewDidLoad {
  22 + [super viewDidLoad];
  23 +
  24 + self.view.backgroundColor = [UIColor whiteColor];
  25 +
  26 + _barrage = [[CNLiveBarrageAnimationView alloc] initWithFrame:CGRectMake(0, 130, self.view.frame.size.width, 0)];
  27 + _barrage.backgroundColor = [UIColor grayColor];
  28 + [_barrage setLinage:6];
  29 + [_barrage setAnimationDuration:4];
  30 + [_barrage setHorizontalSpace:10];
  31 + [_barrage setVerticalSpace:5];
  32 + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 20)];
  33 + label.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.5];
  34 + label.font = [UIFont systemFontOfSize:13];
  35 + label.textColor = [UIColor whiteColor];
  36 + label.layer.cornerRadius = 10;
  37 + label.layer.masksToBounds = YES;
  38 + label.layer.borderColor = [UIColor redColor].CGColor;
  39 + label.layer.borderWidth = 0.5;
  40 + [_barrage setBarrageLabelStyle:label];
  41 + [self.view addSubview:_barrage];
  42 +
  43 + UIButton *startbutton = [UIButton buttonWithType:UIButtonTypeSystem];
  44 + [startbutton setTitle:@"开始" forState:UIControlStateNormal];
  45 + startbutton.frame = CGRectMake(0, 20, 50, 50);
  46 + [self.view addSubview:startbutton];
  47 + [startbutton addTarget:self action:@selector(startbutton) forControlEvents:UIControlEventTouchUpInside];
  48 +
  49 + UIButton *stopbutton = [UIButton buttonWithType:UIButtonTypeSystem];
  50 + [stopbutton setTitle:@"停止" forState:UIControlStateNormal];
  51 + stopbutton.frame = CGRectMake(100, 20, 50, 50);
  52 + [self.view addSubview:stopbutton];
  53 + [stopbutton addTarget:self action:@selector(stopbutton) forControlEvents:UIControlEventTouchUpInside];
  54 +
  55 + UIButton *exitbutton = [UIButton buttonWithType:UIButtonTypeSystem];
  56 + [exitbutton setTitle:@"退出" forState:UIControlStateNormal];
  57 + exitbutton.frame = CGRectMake(200, 20, 50, 50);
  58 + [self.view addSubview:exitbutton];
  59 + [exitbutton addTarget:self action:@selector(exitbutton) forControlEvents:UIControlEventTouchUpInside];
  60 +
  61 + UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 80, 300, 30)];
  62 + textField.backgroundColor = [UIColor grayColor];
  63 + [self.view addSubview:textField];
  64 + textField.delegate = self;
  65 +
  66 +}
  67 +
  68 +- (void)startbutton
  69 +{
  70 + [_barrage startAnimation];
  71 +}
  72 +
  73 +- (void)stopbutton
  74 +{
  75 + [_barrage stopAnimation];
  76 +}
  77 +
  78 +- (void)exitbutton
  79 +{
  80 + [_barrage stopAnimation];
  81 + [self dismissViewControllerAnimated:YES completion:NULL];
  82 +}
  83 +
  84 +- (BOOL)textFieldShouldReturn:(UITextField *)textField
  85 +{
  86 + [_barrage showBarrageContent:textField.text];
  87 + return YES;
  88 +}
  89 +
  90 +- (void)didReceiveMemoryWarning {
  91 + [super didReceiveMemoryWarning];
  92 + // Dispose of any resources that can be recreated.
  93 +}
  94 +
  95 +/*
  96 +#pragma mark - Navigation
  97 +
  98 +// In a storyboard-based application, you will often want to do a little preparation before navigation
  99 +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  100 + // Get the new view controller using [segue destinationViewController].
  101 + // Pass the selected object to the new view controller.
  102 +}
  103 +*/
  104 +
  105 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Base.lproj/LaunchScreen.storyboard 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8150" systemVersion="15A204g" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
  3 + <dependencies>
  4 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8122"/>
  5 + </dependencies>
  6 + <scenes>
  7 + <!--View Controller-->
  8 + <scene sceneID="EHf-IW-A2E">
  9 + <objects>
  10 + <viewController id="01J-lp-oVM" sceneMemberID="viewController">
  11 + <layoutGuides>
  12 + <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
  13 + <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
  14 + </layoutGuides>
  15 + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
  16 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
  17 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  18 + <animations/>
  19 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
  20 + </view>
  21 + </viewController>
  22 + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
  23 + </objects>
  24 + <point key="canvasLocation" x="53" y="375"/>
  25 + </scene>
  26 + </scenes>
  27 +</document>
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Base.lproj/Main.storyboard 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
  3 + <dependencies>
  4 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/>
  5 + </dependencies>
  6 + <scenes>
  7 + <!--View Controller-->
  8 + <scene sceneID="tne-QT-ifu">
  9 + <objects>
  10 + <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
  11 + <layoutGuides>
  12 + <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
  13 + <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
  14 + </layoutGuides>
  15 + <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
  16 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
  17 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  18 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
  19 + </view>
  20 + </viewController>
  21 + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
  22 + </objects>
  23 + </scene>
  24 + </scenes>
  25 +</document>
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Info.plist 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>NSMicrophoneUsageDescription</key>
  6 + <string></string>
  7 + <key>NSCameraUsageDescription</key>
  8 + <string></string>
  9 + <key>CFBundleDevelopmentRegion</key>
  10 + <string>en</string>
  11 + <key>CFBundleExecutable</key>
  12 + <string>$(EXECUTABLE_NAME)</string>
  13 + <key>CFBundleIdentifier</key>
  14 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  15 + <key>CFBundleInfoDictionaryVersion</key>
  16 + <string>6.0</string>
  17 + <key>CFBundleName</key>
  18 + <string>$(PRODUCT_NAME)</string>
  19 + <key>CFBundlePackageType</key>
  20 + <string>APPL</string>
  21 + <key>CFBundleShortVersionString</key>
  22 + <string>1.0</string>
  23 + <key>CFBundleSignature</key>
  24 + <string>????</string>
  25 + <key>CFBundleVersion</key>
  26 + <string>1</string>
  27 + <key>LSRequiresIPhoneOS</key>
  28 + <true/>
  29 + <key>NSAppTransportSecurity</key>
  30 + <dict>
  31 + <key>NSAllowsArbitraryLoads</key>
  32 + <true/>
  33 + </dict>
  34 + <key>UILaunchStoryboardName</key>
  35 + <string>LaunchScreen</string>
  36 + <key>UIMainStoryboardFile</key>
  37 + <string>Main</string>
  38 + <key>UIRequiredDeviceCapabilities</key>
  39 + <array>
  40 + <string>armv7</string>
  41 + </array>
  42 + <key>UISupportedInterfaceOrientations</key>
  43 + <array>
  44 + <string>UIInterfaceOrientationPortrait</string>
  45 + <string>UIInterfaceOrientationLandscapeLeft</string>
  46 + <string>UIInterfaceOrientationLandscapeRight</string>
  47 + </array>
  48 +</dict>
  49 +</plist>
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Player/CNLiveViewController.h 0 → 100644
  1 +//
  2 +// CNLiveViewController.h
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +
  11 +@interface CNLiveViewController : UIViewController
  12 +
  13 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Player/CNLiveViewController.m 0 → 100644
  1 +//
  2 +// CNLiveViewController.m
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import "CNLiveViewController.h"
  10 +#import <CNLivePlayerSDK/CNLiveMoviePlayerController.h>
  11 +
  12 +@interface CNLiveViewController ()
  13 +{
  14 + CNLiveMoviePlayerController *_player;
  15 + UIButton *_playOrPauseBtn;
  16 + UISlider *_timeSlide;
  17 + UIProgressView *_bufferProgress;
  18 + UILabel *_currentTimeLabel;
  19 + UILabel *_durationLabel;
  20 + NSTimer *_currentTimer;
  21 +}
  22 +
  23 +@end
  24 +
  25 +@implementation CNLiveViewController
  26 +
  27 +- (void)viewDidLoad {
  28 + [super viewDidLoad];
  29 +
  30 + self.view.backgroundColor = [UIColor grayColor];
  31 +
  32 + _currentTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
  33 +
  34 + [self installMovieNotificationObservers];
  35 + //直播播放
  36 + _player = [[CNLiveMoviePlayerController alloc] initLivePlayWithAppId:@"60_irg1rhs308" appKey:@"4e7a37b27a717a9e9b0a7aea4620ee55ea61fbf923bf46" channelId:@"d849bb4277be42799df3ffc21654d949" completion:^{
  37 + _player.shouldUseHWCodec = YES;
  38 + _player.view.frame = CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.width*9/16);
  39 + _player.shouldAutoplay = YES;
  40 + [_player prepareToPlay];
  41 + [self.view addSubview:_player.view];
  42 + }];
  43 +
  44 + /* 点播播放
  45 + _player = [[CNLiveMoviePlayerController alloc] initVodPlayWithAppId:@"60_irg1rhs308" appKey:@"4e7a37b27a717a9e9b0a7aea4620ee55ea61fbf923bf46" vId:@"aaa123"];
  46 + _player.shouldUseHWCodec = YES;
  47 + _player.view.frame = CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.width*9/16);
  48 + _player.shouldAutoplay = YES;
  49 + [_player prepareToPlay];
  50 + [self.view addSubview:_player.view];
  51 + */
  52 +
  53 + _playOrPauseBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  54 + _playOrPauseBtn.frame = CGRectMake(10, self.view.frame.size.width*9/16+20+50, 50, 50);
  55 + [_playOrPauseBtn setImage:[UIImage imageNamed:@"play"] forState:UIControlStateNormal];
  56 + [_playOrPauseBtn addTarget:self action:@selector(playOrPauseBtnAction) forControlEvents:UIControlEventTouchUpInside];
  57 + [self.view addSubview:_playOrPauseBtn];
  58 +
  59 + _currentTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(70, self.view.frame.size.width*9/16+20+50, 60, 50)];
  60 + _currentTimeLabel.textColor = [UIColor blackColor];
  61 + _currentTimeLabel.font = [UIFont systemFontOfSize:13];
  62 + [_currentTimeLabel setText:[NSString stringWithFormat:@"00:00:00"]];
  63 + [self.view addSubview:_currentTimeLabel];
  64 +
  65 + _bufferProgress = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
  66 + _bufferProgress.frame = CGRectMake(130+2, self.view.frame.size.width*9/16+20+50+24, self.view.frame.size.width-130-80-4, 1);
  67 + _bufferProgress.trackTintColor = [UIColor darkGrayColor];
  68 + _bufferProgress.progressTintColor = [UIColor blackColor];
  69 + _bufferProgress.progress = 0;
  70 + [self.view addSubview:_bufferProgress];
  71 +
  72 + _timeSlide = [[UISlider alloc] initWithFrame:CGRectMake(130, self.view.frame.size.width*9/16+20+50, self.view.frame.size.width-130-80, 50)];
  73 + [_timeSlide setMinimumTrackTintColor:[UIColor redColor]];
  74 + [_timeSlide setMaximumTrackTintColor:[UIColor clearColor]];
  75 + [_timeSlide addTarget:self action:@selector(beginScrubbing) forControlEvents:UIControlEventTouchDown];
  76 + [_timeSlide addTarget:self action:@selector(endScrubbing) forControlEvents:UIControlEventTouchUpInside];
  77 + [_timeSlide addTarget:self action:@selector(endScrubbing) forControlEvents:UIControlEventTouchUpOutside];
  78 + [self.view addSubview:_timeSlide];
  79 +
  80 + _durationLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.view.frame.size.width-60-10, self.view.frame.size.width*9/16+20+50, 60, 50)];
  81 + _durationLabel.textColor = [UIColor blackColor];
  82 + _durationLabel.font = [UIFont systemFontOfSize:13];
  83 + [_durationLabel setText:[NSString stringWithFormat:@"00:00:00"]];
  84 + [self.view addSubview:_durationLabel];
  85 +
  86 + UIButton *exitBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  87 + exitBtn.frame = CGRectMake(0, 350, self.view.frame.size.width, 50);
  88 + [exitBtn setTitle:@"退出" forState:UIControlStateNormal];
  89 + [exitBtn addTarget:self action:@selector(exitBtnAction) forControlEvents:UIControlEventTouchUpInside];
  90 + [self.view addSubview:exitBtn];
  91 +}
  92 +
  93 +- (void)exitBtnAction
  94 +{
  95 + [_player stop];
  96 + [_currentTimer invalidate];
  97 + _currentTimer = nil;
  98 + [self removeMovieNotificationObservers];
  99 + [self dismissViewControllerAnimated:YES completion:NULL];
  100 +}
  101 +
  102 +- (void)prepareToPlay
  103 +{
  104 + _player.shouldUseHWCodec = YES;
  105 + _player.view.frame = CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.width*9/16);
  106 + _player.shouldAutoplay = YES;
  107 + [_player prepareToPlay];
  108 + [self.view addSubview:_player.view];
  109 +}
  110 +
  111 +- (void)changePlayBtnStatus:(BOOL)playing
  112 +{
  113 + if (playing) {
  114 + [_playOrPauseBtn setImage:[UIImage imageNamed:@"pause"] forState:UIControlStateNormal];
  115 + } else {
  116 + [_playOrPauseBtn setImage:[UIImage imageNamed:@"play"] forState:UIControlStateNormal];
  117 + }
  118 +}
  119 +
  120 +- (void)playOrPauseBtnAction
  121 +{
  122 + if (_player.isPlaying) {
  123 + [_player pause];
  124 + } else {
  125 + [_player play];
  126 + }
  127 +}
  128 +
  129 +- (void)beginScrubbing //currentSlide
  130 +{
  131 + [_player pause];
  132 +}
  133 +
  134 +- (void)endScrubbing //currentSlide
  135 +{
  136 + [_player setCurrentPlaybackTime:_timeSlide.value];
  137 + [_player play];
  138 +}
  139 +
  140 +-(void)installMovieNotificationObservers //添加视频播放通知
  141 +{
  142 + [[NSNotificationCenter defaultCenter] addObserver:self
  143 + selector:@selector(loadStateDidChange:)
  144 + name:MPMoviePlayerLoadStateDidChangeNotification
  145 + object:nil];
  146 +
  147 + [[NSNotificationCenter defaultCenter] addObserver:self
  148 + selector:@selector(moviePlayBackDidFinish:)
  149 + name:MPMoviePlayerPlaybackDidFinishNotification
  150 + object:nil];
  151 +
  152 + [[NSNotificationCenter defaultCenter] addObserver:self
  153 + selector:@selector(mediaIsPreparedToPlayDidChange:)
  154 + name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification
  155 + object:nil];
  156 +
  157 + [[NSNotificationCenter defaultCenter] addObserver:self
  158 + selector:@selector(moviePlayBackStateDidChange:)
  159 + name:MPMoviePlayerPlaybackStateDidChangeNotification
  160 + object:nil];
  161 +}
  162 +
  163 +- (void)removeMovieNotificationObservers
  164 +{
  165 + [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
  166 + [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
  167 + [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification object:nil];
  168 + [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
  169 +}
  170 +
  171 +- (void)timeChange
  172 +{
  173 + _bufferProgress.progress = _player.playableDuration/_player.duration;
  174 + if (!_player.isPreparedToPlay) {
  175 + return;
  176 + }
  177 +
  178 + _timeSlide.value = _player.currentPlaybackTime;
  179 + _timeSlide.maximumValue = _player.duration;
  180 +
  181 + NSInteger currentSeconds = (NSInteger)_player.currentPlaybackTime;
  182 + NSInteger seconds = currentSeconds % 60;
  183 + NSInteger minutes = currentSeconds / 60;
  184 + NSInteger hours = minutes / 60;
  185 +
  186 + NSInteger durationall = (NSInteger)_player.duration;
  187 + NSInteger durationSeconds = durationall % 60;
  188 + NSInteger durationMinutes = durationall / 60;
  189 + NSInteger durationHours = durationMinutes / 60;
  190 +
  191 + _currentTimeLabel.text = [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)hours, (long)minutes%60, (long)seconds];
  192 + _durationLabel.text = [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)durationHours, (long)durationMinutes%60, (long)durationSeconds];
  193 +}
  194 +
  195 +- (void)loadStateDidChange:(NSNotification *)notification
  196 +{
  197 + if (_player) {
  198 + MPMovieLoadState loadState = _player.loadState;
  199 + if ((loadState & MPMovieLoadStatePlaythroughOK) != 0) {
  200 + NSLog(@"loadStateDidChange: MPMovieLoadStatePlaythroughOK: %d\n", (int)loadState);
  201 +
  202 + } else if ((loadState & MPMovieLoadStateStalled) != 0) {
  203 + NSLog(@"loadStateDidChange: MPMovieLoadStateStalled: %d\n", (int)loadState);
  204 +
  205 + } else {
  206 + NSLog(@"loadStateDidChange: ???: %d\n", (int)loadState);
  207 + }
  208 + }
  209 +}
  210 +
  211 +- (void)moviePlayBackDidFinish:(NSNotification *)notification
  212 +{
  213 + if (_player) {
  214 + int reason = [[[notification userInfo] valueForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
  215 + switch (reason)
  216 + {
  217 + case MPMovieFinishReasonPlaybackEnded:
  218 + NSLog(@"playbackStateDidChange: MPMovieFinishReasonPlaybackEnded: %d\n", reason);
  219 + break;
  220 +
  221 + case MPMovieFinishReasonUserExited:
  222 + NSLog(@"playbackStateDidChange: MPMovieFinishReasonUserExited: %d\n", reason);
  223 + break;
  224 +
  225 + case MPMovieFinishReasonPlaybackError:
  226 + NSLog(@"playbackStateDidChange: MPMovieFinishReasonPlaybackError: %d\n", reason);
  227 + break;
  228 +
  229 + default:
  230 + NSLog(@"playbackPlayBackDidFinish: ???: %d\n", reason);
  231 + break;
  232 + }
  233 + }
  234 +}
  235 +
  236 +- (void)mediaIsPreparedToPlayDidChange:(NSNotification *)notification
  237 +{
  238 + if (_player) {
  239 + NSLog(@"isPreparedToPlay");
  240 + }
  241 +}
  242 +
  243 +- (void)moviePlayBackStateDidChange:(NSNotification *)notification
  244 +{
  245 + if (_player) {
  246 +
  247 + switch (_player.playbackState) {
  248 + case MPMoviePlaybackStateStopped: {
  249 + [self changePlayBtnStatus:NO];
  250 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStateStopped");
  251 + break;
  252 + }
  253 + case MPMoviePlaybackStatePlaying: {
  254 + [self changePlayBtnStatus:YES];
  255 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStatePlaying");
  256 + break;
  257 + }
  258 + case MPMoviePlaybackStatePaused:
  259 + [self changePlayBtnStatus:NO];
  260 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStatePaused");
  261 + break;
  262 + case MPMoviePlaybackStateInterrupted:
  263 + [self changePlayBtnStatus:NO];
  264 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStateInterrupted");
  265 + break;
  266 + case MPMoviePlaybackStateSeekingForward:
  267 + [self changePlayBtnStatus:NO];
  268 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStateSeekingForward");
  269 + break;
  270 + case MPMoviePlaybackStateSeekingBackward:
  271 + [self changePlayBtnStatus:NO];
  272 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStateSeekingBackward");
  273 + break;
  274 + default:
  275 + [self changePlayBtnStatus:NO];
  276 + NSLog(@"moviePlayBackStateDidChange : %ld", _player.playbackState);
  277 + break;
  278 + }
  279 + }
  280 +}
  281 +
  282 +- (void)didReceiveMemoryWarning {
  283 + [super didReceiveMemoryWarning];
  284 + // Dispose of any resources that can be recreated.
  285 +}
  286 +
  287 +/*
  288 +#pragma mark - Navigation
  289 +
  290 +// In a storyboard-based application, you will often want to do a little preparation before navigation
  291 +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  292 + // Get the new view controller using [segue destinationViewController].
  293 + // Pass the selected object to the new view controller.
  294 +}
  295 +*/
  296 +
  297 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Player/NormalViewController.h 0 → 100644
  1 +//
  2 +// NormalViewController.h
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +
  11 +@interface NormalViewController : UIViewController
  12 +
  13 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Player/NormalViewController.m 0 → 100644
  1 +//
  2 +// NormalViewController.m
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import "NormalViewController.h"
  10 +#import <CNLivePlayerSDK/CNLiveMoviePlayerController.h>
  11 +
  12 +@interface NormalViewController ()
  13 +{
  14 + CNLiveMoviePlayerController *_player;
  15 + UIButton *_playOrPauseBtn;
  16 + UISlider *_timeSlide;
  17 + UIProgressView *_bufferProgress;
  18 + UILabel *_currentTimeLabel;
  19 + UILabel *_durationLabel;
  20 + NSTimer *_currentTimer;
  21 +}
  22 +
  23 +@end
  24 +
  25 +@implementation NormalViewController
  26 +
  27 +- (void)viewDidLoad {
  28 + [super viewDidLoad];
  29 + self.view.backgroundColor = [UIColor grayColor];
  30 +
  31 + _currentTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];
  32 +
  33 + [self installMovieNotificationObservers];
  34 +
  35 + _player = [[CNLiveMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:@"http://wideo00.cnlive.com/video/data1/2016/0808/140935/800/e3554e4c5de34a8d9a03c534849cd2e4_140935_800.m3u8"]];
  36 + _player.shouldUseHWCodec = YES;
  37 + _player.view.frame = CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.width*9/16);
  38 + _player.shouldAutoplay = YES;
  39 + [_player prepareToPlay];
  40 + [self.view addSubview:_player.view];
  41 +
  42 + _playOrPauseBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  43 + _playOrPauseBtn.frame = CGRectMake(10, self.view.frame.size.width*9/16+20+50, 50, 50);
  44 + [_playOrPauseBtn setImage:[UIImage imageNamed:@"play"] forState:UIControlStateNormal];
  45 + [_playOrPauseBtn addTarget:self action:@selector(playOrPauseBtnAction) forControlEvents:UIControlEventTouchUpInside];
  46 + [self.view addSubview:_playOrPauseBtn];
  47 +
  48 + _currentTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(70, self.view.frame.size.width*9/16+20+50, 60, 50)];
  49 + _currentTimeLabel.textColor = [UIColor blackColor];
  50 + _currentTimeLabel.font = [UIFont systemFontOfSize:13];
  51 + [_currentTimeLabel setText:[NSString stringWithFormat:@"00:00:00"]];
  52 + [self.view addSubview:_currentTimeLabel];
  53 +
  54 + _bufferProgress = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
  55 + _bufferProgress.frame = CGRectMake(130+2, self.view.frame.size.width*9/16+20+50+24, self.view.frame.size.width-130-80-4, 1);
  56 + _bufferProgress.trackTintColor = [UIColor darkGrayColor];
  57 + _bufferProgress.progressTintColor = [UIColor blackColor];
  58 + _bufferProgress.progress = 0;
  59 + [self.view addSubview:_bufferProgress];
  60 +
  61 + _timeSlide = [[UISlider alloc] initWithFrame:CGRectMake(130, self.view.frame.size.width*9/16+20+50, self.view.frame.size.width-130-80, 50)];
  62 + [_timeSlide setMinimumTrackTintColor:[UIColor redColor]];
  63 + [_timeSlide setMaximumTrackTintColor:[UIColor clearColor]];
  64 + [_timeSlide addTarget:self action:@selector(beginScrubbing) forControlEvents:UIControlEventTouchDown];
  65 + [_timeSlide addTarget:self action:@selector(endScrubbing) forControlEvents:UIControlEventTouchUpInside];
  66 + [_timeSlide addTarget:self action:@selector(endScrubbing) forControlEvents:UIControlEventTouchUpOutside];
  67 + [self.view addSubview:_timeSlide];
  68 +
  69 + _durationLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.view.frame.size.width-60-10, self.view.frame.size.width*9/16+20+50, 60, 50)];
  70 + _durationLabel.textColor = [UIColor blackColor];
  71 + _durationLabel.font = [UIFont systemFontOfSize:13];
  72 + [_durationLabel setText:[NSString stringWithFormat:@"00:00:00"]];
  73 + [self.view addSubview:_durationLabel];
  74 +
  75 + UIButton *exitBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  76 + exitBtn.frame = CGRectMake(0, 350, self.view.frame.size.width, 50);
  77 + [exitBtn setTitle:@"退出" forState:UIControlStateNormal];
  78 + [exitBtn addTarget:self action:@selector(exitBtnAction) forControlEvents:UIControlEventTouchUpInside];
  79 + [self.view addSubview:exitBtn];
  80 +}
  81 +
  82 +- (void)exitBtnAction
  83 +{
  84 + [_player stop];
  85 + [_currentTimer invalidate];
  86 + _currentTimer = nil;
  87 + [self removeMovieNotificationObservers];
  88 + [self dismissViewControllerAnimated:YES completion:NULL];
  89 +}
  90 +
  91 +- (void)changePlayBtnStatus:(BOOL)playing
  92 +{
  93 + if (playing) {
  94 + [_playOrPauseBtn setImage:[UIImage imageNamed:@"pause"] forState:UIControlStateNormal];
  95 + } else {
  96 + [_playOrPauseBtn setImage:[UIImage imageNamed:@"play"] forState:UIControlStateNormal];
  97 + }
  98 +}
  99 +
  100 +- (void)playOrPauseBtnAction
  101 +{
  102 + if (_player.isPlaying) {
  103 + [_player pause];
  104 + } else {
  105 + [_player play];
  106 + }
  107 +}
  108 +
  109 +- (void)beginScrubbing //currentSlide
  110 +{
  111 + [_player pause];
  112 +}
  113 +
  114 +- (void)endScrubbing //currentSlide
  115 +{
  116 + [_player setCurrentPlaybackTime:_timeSlide.value];
  117 + [_player play];
  118 +}
  119 +
  120 +-(void)installMovieNotificationObservers //添加视频播放通知
  121 +{
  122 + [[NSNotificationCenter defaultCenter] addObserver:self
  123 + selector:@selector(loadStateDidChange:)
  124 + name:MPMoviePlayerLoadStateDidChangeNotification
  125 + object:nil];
  126 +
  127 + [[NSNotificationCenter defaultCenter] addObserver:self
  128 + selector:@selector(moviePlayBackDidFinish:)
  129 + name:MPMoviePlayerPlaybackDidFinishNotification
  130 + object:nil];
  131 +
  132 + [[NSNotificationCenter defaultCenter] addObserver:self
  133 + selector:@selector(mediaIsPreparedToPlayDidChange:)
  134 + name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification
  135 + object:nil];
  136 +
  137 + [[NSNotificationCenter defaultCenter] addObserver:self
  138 + selector:@selector(moviePlayBackStateDidChange:)
  139 + name:MPMoviePlayerPlaybackStateDidChangeNotification
  140 + object:nil];
  141 +}
  142 +
  143 +- (void)removeMovieNotificationObservers
  144 +{
  145 + [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
  146 + [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
  147 + [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification object:nil];
  148 + [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
  149 +}
  150 +
  151 +- (void)timeChange
  152 +{
  153 + _bufferProgress.progress = _player.playableDuration/_player.duration;
  154 + if (!_player.isPreparedToPlay) {
  155 + return;
  156 + }
  157 +
  158 + _timeSlide.value = _player.currentPlaybackTime;
  159 + _timeSlide.maximumValue = _player.duration;
  160 +
  161 + NSInteger currentSeconds = (NSInteger)_player.currentPlaybackTime;
  162 + NSInteger seconds = currentSeconds % 60;
  163 + NSInteger minutes = currentSeconds / 60;
  164 + NSInteger hours = minutes / 60;
  165 +
  166 + NSInteger durationall = (NSInteger)_player.duration;
  167 + NSInteger durationSeconds = durationall % 60;
  168 + NSInteger durationMinutes = durationall / 60;
  169 + NSInteger durationHours = durationMinutes / 60;
  170 +
  171 + _currentTimeLabel.text = [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)hours, (long)minutes%60, (long)seconds];
  172 + _durationLabel.text = [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)durationHours, (long)durationMinutes%60, (long)durationSeconds];
  173 +}
  174 +
  175 +- (void)loadStateDidChange:(NSNotification *)notification
  176 +{
  177 + if (_player) {
  178 + MPMovieLoadState loadState = _player.loadState;
  179 + if ((loadState & MPMovieLoadStatePlaythroughOK) != 0) {
  180 + NSLog(@"loadStateDidChange: MPMovieLoadStatePlaythroughOK: %d\n", (int)loadState);
  181 +
  182 + } else if ((loadState & MPMovieLoadStateStalled) != 0) {
  183 + NSLog(@"loadStateDidChange: MPMovieLoadStateStalled: %d\n", (int)loadState);
  184 +
  185 + } else {
  186 + NSLog(@"loadStateDidChange: ???: %d\n", (int)loadState);
  187 + }
  188 + }
  189 +}
  190 +
  191 +- (void)moviePlayBackDidFinish:(NSNotification *)notification
  192 +{
  193 + if (_player) {
  194 + int reason = [[[notification userInfo] valueForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
  195 + switch (reason)
  196 + {
  197 + case MPMovieFinishReasonPlaybackEnded:
  198 + NSLog(@"playbackStateDidChange: MPMovieFinishReasonPlaybackEnded: %d\n", reason);
  199 + break;
  200 +
  201 + case MPMovieFinishReasonUserExited:
  202 + NSLog(@"playbackStateDidChange: MPMovieFinishReasonUserExited: %d\n", reason);
  203 + break;
  204 +
  205 + case MPMovieFinishReasonPlaybackError:
  206 + NSLog(@"playbackStateDidChange: MPMovieFinishReasonPlaybackError: %d\n", reason);
  207 + break;
  208 +
  209 + default:
  210 + NSLog(@"playbackPlayBackDidFinish: ???: %d\n", reason);
  211 + break;
  212 + }
  213 + }
  214 +}
  215 +
  216 +- (void)mediaIsPreparedToPlayDidChange:(NSNotification *)notification
  217 +{
  218 + if (_player) {
  219 + NSLog(@"isPreparedToPlay");
  220 + }
  221 +}
  222 +
  223 +- (void)moviePlayBackStateDidChange:(NSNotification *)notification
  224 +{
  225 + if (_player) {
  226 +
  227 + switch (_player.playbackState) {
  228 + case MPMoviePlaybackStateStopped: {
  229 + [self changePlayBtnStatus:NO];
  230 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStateStopped");
  231 + break;
  232 + }
  233 + case MPMoviePlaybackStatePlaying: {
  234 + [self changePlayBtnStatus:YES];
  235 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStatePlaying");
  236 + break;
  237 + }
  238 + case MPMoviePlaybackStatePaused:
  239 + [self changePlayBtnStatus:NO];
  240 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStatePaused");
  241 + break;
  242 + case MPMoviePlaybackStateInterrupted:
  243 + [self changePlayBtnStatus:NO];
  244 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStateInterrupted");
  245 + break;
  246 + case MPMoviePlaybackStateSeekingForward:
  247 + [self changePlayBtnStatus:NO];
  248 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStateSeekingForward");
  249 + break;
  250 + case MPMoviePlaybackStateSeekingBackward:
  251 + [self changePlayBtnStatus:NO];
  252 + NSLog(@"moviePlayBackStateDidChange : MPMoviePlaybackStateSeekingBackward");
  253 + break;
  254 + default:
  255 + [self changePlayBtnStatus:NO];
  256 + NSLog(@"moviePlayBackStateDidChange : %ld", _player.playbackState);
  257 + break;
  258 + }
  259 + }
  260 +}
  261 +
  262 +- (void)didReceiveMemoryWarning {
  263 + [super didReceiveMemoryWarning];
  264 + // Dispose of any resources that can be recreated.
  265 +}
  266 +
  267 +/*
  268 +#pragma mark - Navigation
  269 +
  270 +// In a storyboard-based application, you will often want to do a little preparation before navigation
  271 +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  272 + // Get the new view controller using [segue destinationViewController].
  273 + // Pass the selected object to the new view controller.
  274 +}
  275 +*/
  276 +
  277 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Player/PlayerViewController.h 0 → 100644
  1 +//
  2 +// PlayerViewController.h
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +
  11 +@interface PlayerViewController : UIViewController
  12 +
  13 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Player/PlayerViewController.m 0 → 100644
  1 +//
  2 +// PlayerViewController.m
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import "PlayerViewController.h"
  10 +#import "CNLiveViewController.h"
  11 +#import "NormalViewController.h"
  12 +
  13 +@interface PlayerViewController ()
  14 +
  15 +@end
  16 +
  17 +@implementation PlayerViewController
  18 +
  19 +- (void)viewDidLoad {
  20 + [super viewDidLoad];
  21 +
  22 + self.view.backgroundColor = [UIColor whiteColor];
  23 +
  24 + UIButton *cnlivePlayerBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  25 + cnlivePlayerBtn.frame = CGRectMake(0, 50, self.view.frame.size.width, 50);
  26 + [cnlivePlayerBtn setTitle:@"视讯云内容播放" forState:UIControlStateNormal];
  27 + [cnlivePlayerBtn addTarget:self action:@selector(cnlivePlayerBtnAction) forControlEvents:UIControlEventTouchUpInside];
  28 + [self.view addSubview:cnlivePlayerBtn];
  29 +
  30 + UIButton *normalPlayerBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  31 + normalPlayerBtn.frame = CGRectMake(0, 150, self.view.frame.size.width, 50);
  32 + [normalPlayerBtn setTitle:@"普通播放" forState:UIControlStateNormal];
  33 + [normalPlayerBtn addTarget:self action:@selector(normalPlayerBtnAction) forControlEvents:UIControlEventTouchUpInside];
  34 + [self.view addSubview:normalPlayerBtn];
  35 +
  36 + UIButton *exitBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  37 + exitBtn.frame = CGRectMake(0, 250, self.view.frame.size.width, 50);
  38 + [exitBtn setTitle:@"退出" forState:UIControlStateNormal];
  39 + [exitBtn addTarget:self action:@selector(exitBtnAction) forControlEvents:UIControlEventTouchUpInside];
  40 + [self.view addSubview:exitBtn];
  41 +}
  42 +
  43 +- (void)exitBtnAction
  44 +{
  45 + [self dismissViewControllerAnimated:YES completion:NULL];
  46 +}
  47 +
  48 +- (void)cnlivePlayerBtnAction
  49 +{
  50 + CNLiveViewController *cnlive = [[CNLiveViewController alloc] init];
  51 + [self presentViewController:cnlive animated:YES completion:NULL];
  52 +}
  53 +
  54 +- (void)normalPlayerBtnAction
  55 +{
  56 + NormalViewController *cnlive = [[NormalViewController alloc] init];
  57 + [self presentViewController:cnlive animated:YES completion:NULL];
  58 +}
  59 +
  60 +- (void)didReceiveMemoryWarning {
  61 + [super didReceiveMemoryWarning];
  62 + // Dispose of any resources that can be recreated.
  63 +}
  64 +
  65 +/*
  66 +#pragma mark - Navigation
  67 +
  68 +// In a storyboard-based application, you will often want to do a little preparation before navigation
  69 +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  70 + // Get the new view controller using [segue destinationViewController].
  71 + // Pass the selected object to the new view controller.
  72 +}
  73 +*/
  74 +
  75 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/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 +
  15 +@property (nonatomic, strong) NSURL *url;
  16 +
  17 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Streamer/StreamerDetailViewController.m 0 → 100644
  1 +//
  2 +// LiveViewController.m
  3 +// CNLiveLiveDemo
  4 +//
  5 +// Created by Android on 16/8/10.
  6 +// Copyright © 2016年 Android. All rights reserved.
  7 +//
  8 +
  9 +#import "StreamerDetailViewController.h"
  10 +#import <CNLivePlayerSDK/CNLiveGPUStreamerKit.h>
  11 +
  12 +#define Width [UIScreen mainScreen].bounds.size.width
  13 +#define Height [UIScreen mainScreen].bounds.size.height
  14 +
  15 +@interface StreamerDetailViewController ()<UIGestureRecognizerDelegate>
  16 +{
  17 + UILabel *_stateLab;
  18 + UIButton *_startLiveBtn;
  19 +}
  20 +
  21 +@property (nonatomic,strong) UIView *captureView;
  22 +@property (nonatomic,strong) NSURL *hostURL;
  23 +
  24 +@property (nonatomic,strong) CNLiveGPUStreamerKit *kitCN; //直播推流
  25 +
  26 +@end
  27 +
  28 +@implementation StreamerDetailViewController
  29 +
  30 +- (void)viewDidLoad {
  31 + [super viewDidLoad];
  32 +
  33 + [self.view addSubview:self.captureView];
  34 +
  35 + if (_isAuthLive) {
  36 +
  37 + NSString *activityId = [NSString stringWithFormat:@"%d%d%d%d%d",arc4random()%9,arc4random()%9,arc4random()%9,arc4random()%9,arc4random()%9];
  38 + _kitCN = [[CNLiveGPUStreamerKit alloc] initWithDefaultConfigWithAppId:@"60_irg1rhs308" appKey:@"4e7a37b27a717a9e9b0a7aea4620ee55ea61fbf923bf46" activityId:activityId channelId:activityId isHorizontalScreen:@"0"];
  39 + _kitCN.activityName = @"中国网+测试";
  40 +
  41 + [_kitCN getStreamerURLWithSuccess:^{
  42 +
  43 + [self setStreamerCfg];
  44 + [self addObservers];
  45 +
  46 + } failure:^(NSError *error) {
  47 +
  48 + [self toast:[NSString stringWithFormat:@"初始化失败:%@",error.localizedDescription]];
  49 +
  50 + }];
  51 +
  52 + }else{
  53 + _kitCN = [[CNLiveGPUStreamerKit alloc] initWithDefaultConfig];
  54 + _hostURL = _url;
  55 +
  56 + [self setStreamerCfg];
  57 + [self addObservers];
  58 +
  59 + }
  60 +
  61 + _startLiveBtn = [self addButton:@"开始直播" frame:CGRectMake(80, 40, 60, 40) action:@selector(startCapture:)];
  62 +
  63 + [self addButton:@"开启预览" frame:CGRectMake(10, 40, 60, 40) action:@selector(startPreview:)];
  64 +
  65 + [self addButton:@"退出" frame:CGRectMake(150, 40, 60, 40) action:@selector(quit)];
  66 +
  67 + [self addButton:@"美颜" frame:CGRectMake(10, 100, 60, 40) action:@selector(openFilter:)];
  68 +
  69 + [self addButton:@"摄像头" frame:CGRectMake(80, 100, 60, 40) action:@selector(changeCamera:)];
  70 +
  71 + [self addButton:@"闪光灯" frame:CGRectMake(150, 100, 60, 40) action:@selector(openFlash)];
  72 +
  73 + _stateLab = [[UILabel alloc] initWithFrame:CGRectMake(0, 160, Width, 200)];
  74 + _stateLab.backgroundColor = [UIColor clearColor];
  75 + _stateLab.numberOfLines = 0;
  76 + _stateLab.textColor = [UIColor redColor];
  77 + [self.view addSubview:_stateLab];
  78 +
  79 + UITapGestureRecognizer * singleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTap:)];
  80 + singleRecognizer.delegate = self;
  81 + [self.captureView addGestureRecognizer:singleRecognizer];
  82 +
  83 +}
  84 +
  85 +- (UIButton *)addButton:(NSString*)title
  86 + frame:(CGRect)frame
  87 + action:(SEL)action {
  88 + UIButton * button;
  89 + button = [UIButton buttonWithType:UIButtonTypeCustom];
  90 + button.frame = frame;
  91 + [button setTitle: title forState: UIControlStateNormal];
  92 + button.backgroundColor = [UIColor lightGrayColor];
  93 + [button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
  94 + button.titleLabel.font = [UIFont systemFontOfSize:15];
  95 + [self.captureView addSubview:button];
  96 + return button;
  97 +}
  98 +#pragma mark - initialization
  99 +
  100 +- (void)setStreamerCfg
  101 +{
  102 + _kitCN.videoInitBitrate = 900;
  103 + _kitCN.videoMaxBitrate = 900;
  104 + _kitCN.videoMinBitrate = 300;
  105 + _kitCN.maxKeyInterval = 2;
  106 + _kitCN.audiokBPS = 48;
  107 + _kitCN.videoFPS = 15;
  108 + _kitCN.enAutoApplyEstimateBW = YES;
  109 + _kitCN.isOpenImageFilter = YES;
  110 + [_kitCN setVideoOrientationBy:UIInterfaceOrientationPortrait];
  111 +}
  112 +
  113 +#pragma mark - Action
  114 +
  115 +- (void)startPreview:(UIButton *)button
  116 +{
  117 + button.selected = !button.selected;
  118 + if (button.selected) {
  119 + [_kitCN startPreview:self.captureView];
  120 + [button setTitle:@"关闭预览" forState:UIControlStateNormal];
  121 + }else{
  122 + [button setTitle:@"开启预览" forState:UIControlStateNormal];
  123 + if (_startLiveBtn.selected) {
  124 + [_kitCN stopStream];
  125 + [_startLiveBtn setTitle:@"开始直播" forState:UIControlStateNormal];
  126 + _startLiveBtn.selected = NO;
  127 + }
  128 + [_kitCN stopPreview];
  129 + }
  130 +}
  131 +
  132 +- (void)startCapture:(UIButton *)button
  133 +{
  134 + button.selected = !button.selected;
  135 +
  136 + if (button.selected) {
  137 + [button setTitle:@"停止直播" forState:UIControlStateNormal];
  138 + if (_isAuthLive) {
  139 + [_kitCN startStream:^{
  140 + NSLog(@"开始推流");
  141 + } failure:^(NSError *error) {
  142 + [self toast:error.localizedDescription];
  143 + }];
  144 + }else{
  145 + [_kitCN startStream:_hostURL];
  146 + }
  147 + }else{
  148 + _stateLab.text = nil;
  149 + [_kitCN stopStream];
  150 + [button setTitle:@"开始直播" forState:UIControlStateNormal];
  151 + }
  152 +}
  153 +
  154 +- (void)openFilter:(UIButton *)button
  155 +{
  156 + _kitCN.isOpenImageFilter = button.selected;
  157 + button.selected = !button.selected;
  158 +}
  159 +
  160 +- (void)changeCamera:(UIButton *)button
  161 +{
  162 + button.selected = !button.selected;
  163 + if (button.selected) {
  164 + _kitCN.cameraPosition = AVCaptureDevicePositionBack;
  165 + }else{
  166 + _kitCN.cameraPosition = AVCaptureDevicePositionFront;
  167 + }
  168 +}
  169 +
  170 +- (void)openFlash
  171 +{
  172 + [_kitCN toggleTorch];
  173 +}
  174 +
  175 +- (void)quit
  176 +{
  177 + [_kitCN stopStream];
  178 + [_kitCN stopPreview];
  179 + [[NSNotificationCenter defaultCenter] removeObserver:self];
  180 + [self dismissViewControllerAnimated:YES completion:NULL];
  181 +}
  182 +
  183 +- (void)addObservers
  184 +{
  185 + [[NSNotificationCenter defaultCenter] addObserver:self
  186 + selector:@selector(captureStateChange)
  187 + name:CNLiveCaptureStateDidChangeNotification
  188 + object:nil];
  189 +
  190 + [[NSNotificationCenter defaultCenter] addObserver:self
  191 + selector:@selector(streamStateChange)
  192 + name:CNLiveStreamStateDidChangeNotification
  193 + object:nil];
  194 +}
  195 +
  196 +#pragma mark - notification
  197 +
  198 +- (void)captureStateChange
  199 +{
  200 +
  201 + if ( _kitCN.captureState == CNLiveCaptureStateIdle){
  202 + //初始化时状态为空闲
  203 + NSLog(@"---------CNLiveCaptureStateIdle");
  204 + _stateLab.text = @"idle";
  205 +
  206 + return;
  207 + }
  208 + else if (_kitCN.captureState == CNLiveCaptureStateCapturing ) {
  209 + //设备工作中
  210 + NSLog(@"---------CNLiveCaptureStateCapturing");
  211 + _stateLab.text = @"capturing";
  212 +
  213 + return;
  214 + }
  215 + else if (_kitCN.captureState == CNLiveCaptureStateClosingCapture ) {
  216 + //关闭采集设备中
  217 + NSLog(@"---------CNLiveCaptureStateClosingCapture");
  218 + _stateLab.text = @"closing capture";
  219 +
  220 + return;
  221 + }
  222 + else if (_kitCN.captureState == CNLiveCaptureStateDevAuthDenied ) {
  223 + //设备授权被拒绝
  224 + NSLog(@"---------CNLiveCaptureStateDevAuthDenied");
  225 + _stateLab.text = @"camera/mic Authorization Denied";
  226 +
  227 + return;
  228 + }
  229 + else if (_kitCN.captureState == CNLiveCaptureStateParameterError ) {
  230 + // 参数错误,无法打开
  231 + NSLog(@"---------CNLiveCaptureStateParameterError");
  232 + _stateLab.text = @"capture devices ParameterError";
  233 +
  234 + return;
  235 + }
  236 + else if (_kitCN.captureState == CNLiveCaptureStateDevBusy ) {
  237 + //设备正忙,请稍后尝试
  238 + NSLog(@"---------CNLiveCaptureStateDevBusy");
  239 + _stateLab.text = @"device busy, try later";
  240 +
  241 + }
  242 +}
  243 +
  244 +- (void)streamStateChange
  245 +{
  246 + if (_kitCN.streamState == CNLiveStreamStateIdle) {
  247 + NSLog(@"---------CNLiveStreamStateIdle");
  248 + _stateLab.text = @"idle";
  249 + }
  250 +
  251 + if (_kitCN.streamState == CNLiveStreamStateConnected) {
  252 + NSLog(@"---------CNLiveStreamStateConnected");
  253 + _stateLab.text = [NSString stringWithFormat:@"connected------%@",_hostURL];
  254 + }
  255 +
  256 + if (_kitCN.streamState == CNLiveStreamStateConnecting) {
  257 + NSLog(@"---------CNLiveStreamStateConnecting");
  258 + _stateLab.text = @"kit connecting";
  259 + }
  260 +
  261 + //推流出错
  262 + if (_kitCN.streamState == CNLiveStreamStateError) {
  263 + NSLog(@"---------CNLiveStreamStateError");
  264 + [self onStreamError];
  265 + }
  266 +
  267 + //断开推流
  268 + if ( _kitCN.streamState == CNLiveStreamStateDisconnecting) {
  269 + NSLog(@"---------CNLiveStreamStateDisconnecting");
  270 + _stateLab.text = @"disconnecting";
  271 +
  272 + }
  273 +}
  274 +
  275 +- (void) onStreamError {
  276 + CNLiveStreamErrorCode err = _kitCN.streamErrorCode;
  277 +
  278 + if ( CNLiveStreamErrorCode_CNLiveAUTHFAILED == err ) {
  279 + _stateLab.text = @"SDK auth failed, \npls check ak/sk";
  280 + }
  281 + else if ( CNLiveStreamErrorCode_CODEC_OPEN_FAILED == err) {
  282 + _stateLab.text = @"Selected Codec not supported \n in this version";
  283 + }
  284 + else if ( CNLiveStreamErrorCode_CONNECT_FAILED == err) {
  285 + _stateLab.text = @"Connecting error, pls check host url \nor network";
  286 + }
  287 + else if ( CNLiveStreamErrorCode_CONNECT_BREAK == err) {
  288 + _stateLab.text = @"Connection break";
  289 + }
  290 + else {
  291 +
  292 + }
  293 + NSLog(@"onErr: %lu [%@]", (unsigned long) err, _stateLab.text);
  294 + // 断网重连
  295 + if ( CNLiveStreamErrorCode_CONNECT_BREAK == err) {
  296 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  297 +
  298 + [_kitCN stopStream];
  299 +
  300 + if (_isAuthLive) {
  301 + [_kitCN startStream:^{
  302 + NSLog(@"开始推流");
  303 + } failure:^(NSError *error) {
  304 + [self toast:error.localizedDescription];
  305 + }];
  306 + }else{
  307 + [_kitCN startStream:_hostURL];
  308 + }
  309 + });
  310 + }
  311 +}
  312 +
  313 +//对焦
  314 +- (void)onTap:(UIGestureRecognizer *)sender
  315 +{
  316 + CGPoint point = [sender locationInView:self.view];
  317 + CGPoint tap;
  318 + tap.x = (point.x/Width);
  319 + tap.y = (point.y/Height);
  320 +
  321 + NSError __autoreleasing *error;
  322 + [self focusAtPoint:tap error:&error];
  323 +}
  324 +
  325 +- (BOOL)focusAtPoint:(CGPoint )point error:(NSError *__autoreleasing* )error
  326 +{
  327 + AVCaptureDevice *dev = [_kitCN getCurrentCameraDevices];
  328 + if ([dev isFocusPointOfInterestSupported] && [dev isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
  329 + if ([dev lockForConfiguration:error]) {
  330 + [dev setFocusPointOfInterest:point];
  331 + [dev setFocusMode:AVCaptureFocusModeAutoFocus];
  332 + [dev unlockForConfiguration];
  333 + return YES;
  334 + }
  335 + }
  336 + return NO;
  337 +}
  338 +
  339 +- (void)toast:(NSString*)message
  340 +{
  341 + UIAlertView *toast = [[UIAlertView alloc] initWithTitle:nil
  342 + message:message
  343 + delegate:nil
  344 + cancelButtonTitle:nil
  345 + otherButtonTitles:nil, nil];
  346 + [toast show];
  347 + double duration = 2.5;
  348 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  349 + [toast dismissWithClickedButtonIndex:0 animated:NO];
  350 + });
  351 +}
  352 +
  353 +#pragma mark - GetMethod
  354 +
  355 +- (UIView *)captureView
  356 +{
  357 + if (!_captureView) {
  358 + _captureView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, Width, Height)];
  359 + _captureView.backgroundColor = [UIColor blackColor];
  360 + }
  361 + return _captureView;
  362 +}
  363 +
  364 +
  365 +- (void)didReceiveMemoryWarning {
  366 + [super didReceiveMemoryWarning];
  367 + // Dispose of any resources that can be recreated.
  368 +}
  369 +
  370 +/*
  371 +#pragma mark - Navigation
  372 +
  373 +// In a storyboard-based application, you will often want to do a little preparation before navigation
  374 +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  375 + // Get the new view controller using [segue destinationViewController].
  376 + // Pass the selected object to the new view controller.
  377 +}
  378 +*/
  379 +
  380 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Streamer/StreamerViewController.h 0 → 100644
  1 +//
  2 +// StreamerViewController.h
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +
  11 +@interface StreamerViewController : UIViewController
  12 +
  13 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/Streamer/StreamerViewController.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 "StreamerViewController.h"
  10 +#import "StreamerDetailViewController.h"
  11 +
  12 +#define dataKey @"dataKey"
  13 +
  14 +#define KScreenWidth [UIScreen mainScreen].bounds.size.width
  15 +#define KScreenHeight [UIScreen mainScreen].bounds.size.height
  16 +
  17 +@interface StreamerViewController ()<UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>
  18 +{
  19 + NSMutableArray *_dataArray;
  20 +}
  21 +
  22 +@property (nonatomic,strong) UITableView *tableView;
  23 +@property (nonatomic,strong) UITextField *urlTextField;
  24 +@property (nonatomic,strong) UIButton *liveBtn;
  25 +@property (nonatomic,strong) UIButton *authLiveBtn;
  26 +
  27 +@end
  28 +
  29 +@implementation StreamerViewController
  30 +
  31 +- (void)viewDidLoad {
  32 + [super viewDidLoad];
  33 +
  34 + self.view.backgroundColor = [UIColor whiteColor];
  35 +
  36 + _dataArray = [[NSMutableArray alloc] initWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:dataKey]];
  37 +
  38 + [self.view addSubview:self.liveBtn];
  39 + [self.view addSubview:self.authLiveBtn];
  40 + [self.view addSubview:self.urlTextField];
  41 + [self.view addSubview:self.tableView];
  42 +
  43 + UIButton *exitBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  44 + exitBtn.frame = CGRectMake(KScreenWidth/2-40, KScreenHeight-100, 80, 30);
  45 + [exitBtn setTitle:@"退出" forState:UIControlStateNormal];
  46 + [exitBtn addTarget:self action:@selector(exitBtnAction) forControlEvents:UIControlEventTouchUpInside];
  47 + [self.view addSubview:exitBtn];
  48 +}
  49 +
  50 +- (void)exitBtnAction
  51 +{
  52 + [self dismissViewControllerAnimated:YES completion:NULL];
  53 +}
  54 +
  55 +#pragma mark - Actioon
  56 +
  57 +- (void)nextViewController:(UIButton *)button
  58 +{
  59 + StreamerDetailViewController *vc = [[StreamerDetailViewController alloc] init];
  60 +
  61 + if (button.tag == 100000) {
  62 + vc.isAuthLive = NO;
  63 +
  64 + if (_urlTextField.text.length == 0) {
  65 +
  66 + [self toast:@"请输入推流地址"];
  67 +
  68 + }else{
  69 +
  70 + vc.url = [NSURL URLWithString:[NSString stringWithFormat:@"%@",self.urlTextField.text]];
  71 +
  72 + if (![_dataArray containsObject:_urlTextField.text]) {
  73 + if (_dataArray.count > 4) {
  74 + [_dataArray removeObjectAtIndex:0];
  75 + [_dataArray addObject:_urlTextField.text];
  76 + }else{
  77 + [_dataArray addObject:_urlTextField.text];
  78 + }
  79 +
  80 + [self.tableView reloadData];
  81 + }
  82 +
  83 + NSArray *arr = [NSArray arrayWithArray:_dataArray];
  84 + [[NSUserDefaults standardUserDefaults] setObject:arr forKey:dataKey];
  85 + [[NSUserDefaults standardUserDefaults] synchronize];
  86 +
  87 + [self presentViewController:vc animated:YES completion:NULL];
  88 + }
  89 +
  90 + }else{
  91 + vc.isAuthLive = YES;
  92 + [self presentViewController:vc animated:YES completion:NULL];
  93 + }
  94 +
  95 +}
  96 +
  97 +- (void)toast:(NSString*)message
  98 +{
  99 + UIAlertView *toast = [[UIAlertView alloc] initWithTitle:nil
  100 + message:message
  101 + delegate:nil
  102 + cancelButtonTitle:nil
  103 + otherButtonTitles:nil, nil];
  104 + [toast show];
  105 + double duration = 2.5;
  106 + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  107 + [toast dismissWithClickedButtonIndex:0 animated:NO];
  108 + });
  109 +}
  110 +
  111 +#pragma mark - tableView
  112 +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  113 +{
  114 + return _dataArray.count;
  115 +}
  116 +
  117 +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  118 +{
  119 + static NSString *cellID = @"cellID";
  120 + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
  121 + if (!cell) {
  122 + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
  123 + }
  124 + cell.textLabel.text = _dataArray[indexPath.row];
  125 + return cell;
  126 +}
  127 +
  128 +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  129 +{
  130 + self.urlTextField.text = _dataArray[indexPath.row];
  131 +}
  132 +
  133 +- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  134 +{
  135 + if ([_urlTextField isFirstResponder]) {
  136 + [_urlTextField resignFirstResponder];
  137 + }
  138 +}
  139 +
  140 +-(BOOL)textFieldShouldReturn:(UITextField *)textField
  141 +{
  142 + [textField resignFirstResponder];
  143 + return YES;
  144 +}
  145 +
  146 +#pragma mark - getMethod
  147 +
  148 +- (UIButton *)liveBtn
  149 +{
  150 + if (!_liveBtn) {
  151 + _liveBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  152 + _liveBtn.frame = CGRectMake(KScreenWidth/2-40, 80, 80, 30);
  153 + _liveBtn.tag = 100000;
  154 + [_liveBtn setTitle:@"开始直播" forState:UIControlStateNormal];
  155 + [_liveBtn addTarget:self action:@selector(nextViewController:) forControlEvents:UIControlEventTouchUpInside];
  156 + }
  157 + return _liveBtn;
  158 +}
  159 +
  160 +- (UIButton *)authLiveBtn
  161 +{
  162 + if (!_authLiveBtn) {
  163 + _authLiveBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  164 + _authLiveBtn.frame = CGRectMake(KScreenWidth/2-40, KScreenHeight-150, 80, 30);
  165 + _authLiveBtn.tag = 100001;
  166 + [_authLiveBtn setTitle:@"鉴权直播" forState:UIControlStateNormal];
  167 + [_authLiveBtn addTarget:self action:@selector(nextViewController:) forControlEvents:UIControlEventTouchUpInside];
  168 + }
  169 + return _authLiveBtn;
  170 +}
  171 +
  172 +- (UITableView *)tableView
  173 +{
  174 + if (!_tableView) {
  175 + _tableView = [[UITableView alloc] initWithFrame:CGRectMake(10, 190, KScreenWidth-20, 220) style:UITableViewStylePlain];
  176 + _tableView.backgroundColor = [UIColor clearColor];
  177 + _tableView.delegate = self;
  178 + _tableView.dataSource = self;
  179 + }
  180 + return _tableView;
  181 +}
  182 +
  183 +- (UITextField *)urlTextField
  184 +{
  185 + if (!_urlTextField) {
  186 + _urlTextField = [[UITextField alloc] initWithFrame:CGRectMake(10, 130, KScreenWidth-20, 40)];
  187 + _urlTextField.placeholder = @"请输入推流地址";
  188 + _urlTextField.borderStyle = UITextBorderStyleRoundedRect;
  189 + _urlTextField.returnKeyType = UIReturnKeyDone;
  190 + _urlTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
  191 + _urlTextField.delegate = self;
  192 + _urlTextField.text = @"rtmp://jsrtmp.up.cnlive.com/live/ceshi";
  193 + }
  194 + return _urlTextField;
  195 +}
  196 +
  197 +- (void)didReceiveMemoryWarning {
  198 + [super didReceiveMemoryWarning];
  199 + // Dispose of any resources that can be recreated.
  200 +}
  201 +
  202 +/*
  203 +#pragma mark - Navigation
  204 +
  205 +// In a storyboard-based application, you will often want to do a little preparation before navigation
  206 +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  207 + // Get the new view controller using [segue destinationViewController].
  208 + // Pass the selected object to the new view controller.
  209 +}
  210 +*/
  211 +
  212 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/ViewController.h 0 → 100644
  1 +//
  2 +// ViewController.h
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +
  11 +@interface ViewController : UIViewController
  12 +
  13 +
  14 +@end
  15 +
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/ViewController.m 0 → 100644
  1 +//
  2 +// ViewController.m
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import "ViewController.h"
  10 +#import "PlayerViewController.h"
  11 +#import "BarrageViewController.h"
  12 +#import "StreamerViewController.h"
  13 +
  14 +@interface ViewController ()
  15 +
  16 +@end
  17 +
  18 +@implementation ViewController
  19 +
  20 +- (void)viewDidLoad {
  21 + [super viewDidLoad];
  22 +
  23 + UIButton *playerBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  24 + playerBtn.frame = CGRectMake(0, 50, self.view.frame.size.width, 50);
  25 + [playerBtn setTitle:@"播放demo" forState:UIControlStateNormal];
  26 + [playerBtn addTarget:self action:@selector(playerBtnAction) forControlEvents:UIControlEventTouchUpInside];
  27 + [self.view addSubview:playerBtn];
  28 +
  29 + UIButton *barrageBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  30 + barrageBtn.frame = CGRectMake(0, 150, self.view.frame.size.width, 50);
  31 + [barrageBtn setTitle:@"弹幕demo" forState:UIControlStateNormal];
  32 + [barrageBtn addTarget:self action:@selector(barrageBtnAction) forControlEvents:UIControlEventTouchUpInside];
  33 + [self.view addSubview:barrageBtn];
  34 +
  35 + UIButton *streamerBtn = [UIButton buttonWithType:UIButtonTypeSystem];
  36 + streamerBtn.frame = CGRectMake(0, 250, self.view.frame.size.width, 50);
  37 + [streamerBtn setTitle:@"推流demo" forState:UIControlStateNormal];
  38 + [streamerBtn addTarget:self action:@selector(streamerBtnAction) forControlEvents:UIControlEventTouchUpInside];
  39 + [self.view addSubview:streamerBtn];
  40 +}
  41 +
  42 +- (void)playerBtnAction
  43 +{
  44 + PlayerViewController *player = [[PlayerViewController alloc] init];
  45 + [self presentViewController:player animated:YES completion:NULL];
  46 +}
  47 +
  48 +- (void)barrageBtnAction
  49 +{
  50 + BarrageViewController *player = [[BarrageViewController alloc] init];
  51 + [self presentViewController:player animated:YES completion:NULL];
  52 +}
  53 +
  54 +- (void)streamerBtnAction
  55 +{
  56 + StreamerViewController *streamer = [[StreamerViewController alloc] init];
  57 + [self presentViewController:streamer animated:YES completion:NULL];
  58 +}
  59 +
  60 +- (void)didReceiveMemoryWarning {
  61 + [super didReceiveMemoryWarning];
  62 + // Dispose of any resources that can be recreated.
  63 +}
  64 +
  65 +@end
... ...
CNLivePlayerSDKTest/CNLivePlayerSDKTest/main.m 0 → 100644
  1 +//
  2 +// main.m
  3 +// CNLivePlayerSDKTest
  4 +//
  5 +// Created by 雷浩杰 on 16/8/10.
  6 +// Copyright © 2016年 雷浩杰. All rights reserved.
  7 +//
  8 +
  9 +#import <UIKit/UIKit.h>
  10 +#import "AppDelegate.h"
  11 +
  12 +int main(int argc, char * argv[]) {
  13 + @autoreleasepool {
  14 + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  15 + }
  16 +}
... ...
CNLiveStreamer.pdf 0 → 100644
No preview for this file type