KSYStreamerBase.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. //
  2. // KSYStreamerBase.h
  3. // KSYStreamer
  4. //
  5. // Created by pengbin on 10/15/15.
  6. // Copyright © 2015 ksyun. All rights reserved.
  7. //
  8. #import <AVFoundation/AVFoundation.h>
  9. #import <UIKit/UIKit.h>
  10. #import "KSYTypeDef.h"
  11. @class KSYReachability;
  12. /**
  13. 金山云直播推流SDK iOS版提供了iOS移动设备上的推流功能
  14. * 音频编码采用AAC编码,码率可配置;
  15. * 视频频编码采用H.264编码,码率可配置;
  16. * 支持 RTMP 协议直播推流;
  17. * 支持写入本地flv和mp4文件;
  18. * 支持推流同时旁路录像功能;
  19. __Found__: 2015-10-15
  20. */
  21. @interface KSYStreamerBase : NSObject
  22. /**
  23. @abstract 获取SDK版本号
  24. */
  25. - (NSString*) getKSYVersion;
  26. #pragma mark - configures
  27. /**
  28. @abstract 直播推流时为rtmp主机地址; 本地文件录制时,为输出文件路径
  29. @discussion 直播时将音视频流推向该主机或写入本地文件
  30. eg: rtmp://xxx.xxx.xxx.xxx/appname/streamKey
  31. eg: /var/xxxxx/xxx.mp4 /var/xxxxx/xxx.flv
  32. */
  33. @property (nonatomic, readonly) NSURL* hostURL;
  34. /**
  35. @abstract 视频帧率 默认:15
  36. @discussion 请保持调用 processVideoSampleBuffer 或 processVideoPixelBuffer 的频率与此设置的帧率一致
  37. @discussion 当实际送入的视频帧率过高时会主动丢帧
  38. @discussion video frame per seconds 有效范围[1~30], 超出会提示参数错误
  39. */
  40. @property (nonatomic, assign) int videoFPS;
  41. /**
  42. @abstract 视频帧率最小值,默认与videoFPS相同
  43. @discussion video frame per seconds 有效范围[1~30], 超出会提示参数错误
  44. @discussion 不设置该值时表示网络自适应不使用动态帧率
  45. */
  46. @property (nonatomic, assign) int videoMinFPS;
  47. /**
  48. @abstract 视频帧率最大值,默认与videoFPS相同
  49. @discussion video frame per seconds 有效范围[1~30], 超出会提示参数错误
  50. @discussion 不设置该值时表示网络自适应不使用动态帧率
  51. */
  52. @property (nonatomic, assign) int videoMaxFPS;
  53. /**
  54. @abstract 视频编码器 默认为 自动选择
  55. @discussion video codec used for encode
  56. @discussion 修改此选项会导致videoEncodePerf值变化
  57. @discussion 如果需要定制编码档次, 请在修改videoCodec之后再测设置
  58. @see KSYVideoCodec,videoEncodePerf
  59. */
  60. @property (nonatomic, assign) KSYVideoCodec videoCodec;
  61. /**
  62. @abstract 音频编码器 (默认为AAC-HE)
  63. @discussion audio codec used for encode
  64. @see KSYAudioCodec
  65. */
  66. @property (nonatomic, assign) KSYAudioCodec audioCodec;
  67. /**
  68. @abstract 视频编码起始码率(单位:kbps, 默认:500)
  69. @discussion 开始推流时的视频码率,开始推流后,根据网络情况在Min~Max范围内调节
  70. @discussion 视频码率上调则画面更清晰,下调则画面更模糊
  71. @see videoMaxBitrate, videoMinBitrate
  72. */
  73. @property (nonatomic, assign) int videoInitBitrate; // kbit/s of video
  74. /**
  75. @abstract 视频编码最高码率(单位:kbps, 默认:800)
  76. @discussion 视频码率自适应调整的上限, 为目标码率
  77. @see videoInitBitrate, videoMinBitrate
  78. */
  79. @property (nonatomic, assign) int videoMaxBitrate; // kbit/s of video
  80. /**
  81. @abstract 视频编码最低码率(单位:kbps, 默认:200)
  82. @discussion 视频码率自适应调整的下限
  83. @see videoInitBitrate, videoMaxBitrate
  84. */
  85. @property (nonatomic, assign) int videoMinBitrate; // kbit/s of video
  86. /**
  87. @abstract 推流全局附带的metadata (默认为nil)
  88. @discussion key 一定要是 NSString* 类型的
  89. */
  90. @property(atomic, copy) NSDictionary * streamMetaData;
  91. /**
  92. @abstract 视频流附带的metadata (默认为nil)
  93. @discussion key 一定要是 NSString* 类型的; 目前有效
  94. */
  95. @property(atomic, copy) NSDictionary * videoMetaData;
  96. /**
  97. @abstract 最大关键帧间隔(单位:秒, 默认:3)
  98. @discussion 即GOP长度 画面静止时,隔n秒插入一个关键帧
  99. */
  100. @property (nonatomic, assign) float maxKeyInterval; // seconds
  101. /**
  102. @abstract 音频编码码率(单位:kbps)
  103. @discussion 音频目标编码码率 (比如48,96,128等)
  104. */
  105. @property (nonatomic, assign) int audiokBPS; // kbit/s of audio
  106. /**
  107. @abstract 带宽估计模式
  108. @discussion 带宽估计的策略选择 (开始推流前设置有效)
  109. */
  110. @property (nonatomic, assign) KSYBWEstimateMode bwEstimateMode;
  111. /**
  112. @abstract 本次直播的目标场景 (默认为KSYLiveScene_Default)
  113. @discussion KSY内部会根据场景的特征进行参数调优,开始推流前设置有效
  114. */
  115. @property (nonatomic, assign) KSYLiveScene liveScene;
  116. /**
  117. @abstract 本次录制的目标场景 (默认为KSYRecScene_ConstantBitRate)
  118. @discussion 用于指定录制时, 视频编码器码率控制的优先目标
  119. @discussion 恒定码率: 最后视频文件的码率更平稳,但复杂场景质量可能差一些
  120. @discussion 恒定质量: 最后视频文件的质量更平稳写, 但码率波动要大一些
  121. @discussion 开始录制前设置有效, 录制本地文件时有效, 直播不建议修改
  122. */
  123. @property (nonatomic, assign) KSYRecScene recScene;
  124. /**
  125. @abstract 质量等级(默认:20)
  126. @discussion 视频恒定质量等级,范围0~51,值越小,质量越好
  127. @discussion 当 recScene 为 KSYRecScene_ConstantQuality, 且选择软编码器时有效
  128. */
  129. @property (nonatomic, assign) int videoCrf;
  130. /**
  131. @abstract 视频编码性能档次
  132. @discussion 视频质量和设备资源之间的权衡,开始推流前, videoCodec设置之后,修改有效
  133. @discussion 选择软编码的默认为KSYVideoEncodePer_LowPower
  134. @discussion 选择Auto或硬编码的默认为KSYVideoEncodePer_HighPerformance
  135. */
  136. @property (nonatomic, assign) KSYVideoEncodePerformance videoEncodePerf;
  137. /**
  138. @abstract 是否处理视频的图像数据 (默认YES)
  139. @warning 如果在推流前设置为NO, 则在推流过程中无法再开启图像
  140. @discussion 启动推流前设置为NO, 推流过程中修改本属性无效
  141. */
  142. @property (nonatomic, assign) BOOL bWithVideo;
  143. /**
  144. @abstract 是否处理音频数据 (默认YES)
  145. */
  146. @property (nonatomic, assign) BOOL bWithAudio;
  147. /**
  148. @abstract 是否处理Message (默认YES)
  149. */
  150. @property (nonatomic, assign)BOOL bWithMessage;
  151. /**
  152. @abstract cpu缩放比率,设置>0为按比例缩放,默认为0
  153. @warning 请在推流之前进行设置
  154. */
  155. @property (nonatomic, assign) float scaleRatio;
  156. #pragma mark - Status Notification
  157. /**
  158. @abstract 当前推流状况
  159. @discussion 可以通过该属性获取推流会话的工作状况
  160. @discussion 通知:
  161. * KSYStreamStateDidChangeNotification 当推流工作状态发生变化时提供通知
  162. * 收到通知后,通过本属性查询新的状态,并作出相应的动作
  163. */
  164. @property (nonatomic, readonly) KSYStreamState streamState;
  165. /**
  166. @abstract 获取推流状态对应的字符串
  167. @param stat 状态码
  168. @return 状态名称
  169. */
  170. - (NSString*) getStreamStateName : (KSYStreamState) stat;
  171. /**
  172. @abstract 获取当前推流状态对应的字符串
  173. @return 当前状态名称
  174. */
  175. - (NSString*) getCurStreamStateName;
  176. /**
  177. @abstract 当前推流的错误码
  178. @discussion 可以通过该属性获取推流失败的原因
  179. @discussion 当streamState 为KSYStreamStateError时可查询
  180. @discussion KSYStreamErrorCode_KSYAUTHFAILED 除外
  181. @discussion 在streamState 为KSYStreamStateConnected 时查询到
  182. @discussion 状态变化后清0
  183. @see streamState
  184. */
  185. @property (nonatomic, readonly) KSYStreamErrorCode streamErrorCode;
  186. /**
  187. @abstract 发生推流状态变化时的回调函数
  188. @discussion 参数为新状态
  189. */
  190. @property (nonatomic, copy)void (^streamStateChange)(KSYStreamState newState);
  191. /**
  192. @abstract 获取错误码对应的字符串
  193. @param code 错误码
  194. */
  195. - (NSString*) getKSYStreamErrorCodeName:(KSYStreamErrorCode)code;
  196. /**
  197. @abstract 获取当前错误码对应的字符串
  198. */
  199. - (NSString*) getCurKSYStreamErrorCodeName;
  200. /**
  201. @abstract 当前推流的网络事件
  202. @discussion 可以通过该属性查询网络状况
  203. @discussion 通知:
  204. * KSYNetStateEventNotification 当检测到网络发生特定事件时SDK发出通知
  205. * 收到通知后,通过本属性查询具体事件类型
  206. @discussion KSYNetStateEventNotification
  207. */
  208. @property (nonatomic, readonly) KSYNetStateCode netStateCode;
  209. /**
  210. @abstract 帧率应发生变化时的回调函数
  211. @discussion 参数为建议设定的fps
  212. */
  213. @property (nonatomic, copy)void (^videoFPSChange)(int32_t newVideoFPS);
  214. // Posted when stream state changes
  215. FOUNDATION_EXPORT NSString *const KSYStreamStateDidChangeNotification NS_AVAILABLE_IOS(7_0);
  216. // Posted when there is an net state event
  217. FOUNDATION_EXPORT NSString *const KSYNetStateEventNotification NS_AVAILABLE_IOS(7_0);
  218. #pragma mark - methods
  219. /**
  220. @abstract 初始化方法 (step1)
  221. @discussion 初始化,将下列属性设置为默认值
  222. * _videoFPS = 15;
  223. * _videoCodec = KSYVideoCodec_AUTO;
  224. * _audiokBPS = 32;
  225. * _videoInitBitrate = 500;
  226. * _videoMaxBitrate = 800;
  227. * _videoMinBitrate = 200;
  228. @warning KSYStreamerBase只支持单实例推流,构造多个实例会出现异常
  229. */
  230. - (instancetype) initWithDefaultCfg;
  231. /**
  232. @abstract 启动推流 (step2)
  233. @param url 目标地址
  234. @discussion 实现直播功能时, url为 rtmp 服务器地址 “rtmp://xxx.xx/appname/streamKey"
  235. @discussion 设置完成推流参数之后,将媒体流推送到 publishURL 对应的地址
  236. @discussion 实现本地录制功能时, url为本地文件地址 "/var/xxx/xx.mp4"
  237. @discussion 本地录制支持mp4和flv两种输出格式, 通过url的文件后缀指定
  238. @discussion 推流参数主要是视频编码器,音视频码率的设置
  239. @see hostURL, videoCodec,videokBPS,audiokBPS
  240. */
  241. - (void) startStream: (NSURL*) url;
  242. /**
  243. @abstract 停止推流 (step3)
  244. @discussion 断开网络连接 或停止文件写入
  245. */
  246. - (void) stopStream;
  247. /**
  248. @abstract 静音推流 (仍然有音频输出发送, 只是音量为0)
  249. @param bMute YES / ON
  250. */
  251. - (void) muteStream:(BOOL) bMute;
  252. /**
  253. @abstract 处理一个视频帧(只支持编码前的原始图像数据)
  254. @param sampleBuffer Buffer to process
  255. @discussion 应当在开始推流前定期调用此接口,比如按照采集帧率调用
  256. @discussion 支持的图像格式包括: BGR0,NV12,YUVA444P,YUV420P
  257. */
  258. - (void)processVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer;
  259. /**
  260. @abstract 处理一个视频帧(只支持编码前的原始图像数据)
  261. @param sampleBuffer Buffer to process
  262. @param completion 当前视频帧处理完成的回调
  263. */
  264. - (void)processVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer
  265. onComplete:(void (^)(BOOL))completion;
  266. /**
  267. @abstract 处理一个视频帧(只支持编码前的原始图像数据)
  268. @param pixelBuffer 待编码的像素数据
  269. @param timeStamp 待编码的时间戳
  270. @discussion 应当在开始推流前定期调用此接口,比如按照采集帧率调用
  271. @discussion 支持的图像格式包括: BGR0,NV12,YUVA444P,YUV420P
  272. */
  273. - (void)processVideoPixelBuffer:(CVPixelBufferRef)pixelBuffer
  274. timeInfo:(CMTime)timeStamp;
  275. /**
  276. @abstract 处理一个视频帧(只支持编码前的原始图像数据)
  277. @param pixelBuffer 待编码的像素数据
  278. @param timeStamp 待编码的时间戳
  279. @param completion 当前视频帧处理完成的回调
  280. */
  281. - (void)processVideoPixelBuffer:(CVPixelBufferRef)pixelBuffer
  282. timeInfo:(CMTime)timeStamp
  283. onComplete:(void (^)(BOOL))completion;
  284. /**
  285. @abstract 处理一段音频数据
  286. @param sampleBuffer Buffer to process
  287. @discussion 应当在开始推流前定期调用此接口,与processVideoSampleBuffer 交错进行
  288. @warning 目前只支持 S16 格式的PCM数据
  289. */
  290. - (void)processAudioSampleBuffer:(CMSampleBufferRef)sampleBuffer;
  291. /**
  292. @abstract 处理一段音频数据
  293. @param pData 原始数据指针数组
  294. @param len 数据的长度,单位为字节
  295. @param fmt 原始数据的格式 (必须保证一次推流过程中数据格式不变)
  296. @param pts 原始数据的时间戳
  297. */
  298. - (void)processAudioData:(uint8_t**)pData
  299. nbSample:(int)len
  300. withFormat:(const AudioStreamBasicDescription*)fmt
  301. timeinfo:(CMTime*)pts;
  302. /**
  303. @abstract 处理一个消息
  304. @param message message to process
  305. @discussion 开始推流后发生相应事件时调用此接口
  306. @warning
  307. */
  308. - (void)processMessageData:(NSDictionary *)messageData;
  309. #pragma mark - Status property
  310. /**
  311. @abstract 获取当前用户的ak
  312. @warnning 默认是空的,只有在需要鉴权时,才能获取到
  313. */
  314. @property (nonatomic, assign) NSString *clientAk;
  315. /**
  316. @abstract 获取当前SDK过期时间
  317. @discussion 为nil时,可以永久使用不会过期
  318. @warnning sdk自行解析得到, 外部赋值无效
  319. */
  320. @property (nonatomic, assign) NSDate *expireDate;
  321. /**
  322. @abstract 查询当前推流的事件ID
  323. @discussion md5(hostURL+timestamp) 对本次推流活动的标识
  324. @discussion timestamp 为建立连接时的事件戳
  325. @see hostURL
  326. */
  327. @property (nonatomic, readonly) NSString *streamID;
  328. /**
  329. @abstract 查询当前是否处于推流状态 (建立连接中, 或连接中)
  330. */
  331. - (BOOL) isStreaming;
  332. /**
  333. @abstract 查询当前编码的视频码率大小(每秒更新)
  334. @discussion 该码率为编码器产生的视频码率大小,单位为kbps
  335. @see videoMaxBitrate
  336. */
  337. @property (nonatomic, readonly) double encodeVKbps;
  338. /**
  339. @abstract 查询当前编码的音频码率大小(每秒更新)
  340. @discussion 该码率为编码器产生的音频码率大小,单位为kbps
  341. @see audiokBPS
  342. */
  343. @property (nonatomic, readonly) double encodeAKbps;
  344. /**
  345. @abstract 查询本次推流发送的流量大小 (仅推流时有效)
  346. @discussion 从开始推流到现在,发送出去的数据字节数,单位为KByte
  347. */
  348. @property (nonatomic, readonly) int uploadedKByte;
  349. /**
  350. @abstract 查询当前上传的码率大小 (每秒更新)
  351. @discussion 该码率为实际上传的速度, 也就是每秒上传的字节数,单位为kbps
  352. */
  353. @property (nonatomic, readonly) double currentUploadingKbps;
  354. /**
  355. @abstract 查询当前编码的平均视频帧率
  356. @discussion 采集设备的输出帧率为videoFPS,约等于编码的目标帧率
  357. @discussion 编码的视频帧率不会高于采集帧率,但是当CPU资源不足时,编码帧率会低于采集帧率
  358. @see videoFPS
  359. */
  360. @property (nonatomic, readonly) double encodingFPS;
  361. /**
  362. @abstract 查询本次推流编码的视频总帧数
  363. @discussion 从开始推流到现在,编码过的视频总帧数
  364. */
  365. @property (nonatomic, readonly) int encodedFrames;
  366. /**
  367. @abstract 查询本次推流发送的丢帧数量
  368. @discussion 这里是指编码后,由于网络发送阻塞导致丢弃的帧数
  369. */
  370. @property (nonatomic, readonly) int droppedVideoFrames;
  371. /**
  372. @abstract 推流的qos信息
  373. @discussion 在推流过程中,查询当前推流qos信息
  374. */
  375. @property (nonatomic, readonly) KSYStreamerQosInfo *qosInfo;
  376. /**
  377. @abstract 查询当前推流的rtmp服务器的主机IP
  378. @discussion 开始推流之后获取才为有效IP, 之前为空字符串
  379. */
  380. @property (atomic, readonly) NSString* rtmpHostIP;
  381. #pragma mark - logblock
  382. /**
  383. @abstract 收集网络相关状态的日志,默认开启
  384. @discussion 可开关
  385. */
  386. @property (nonatomic, assign) BOOL shouldEnableKSYStatModule;
  387. /**
  388. @abstract 获取Streamer中与网络相关的日志
  389. @discussion 相关字段说明请联系金山云技术支持
  390. */
  391. @property (nonatomic, copy)void (^logBlock)(NSString *logJson);
  392. #pragma mark - snapshot
  393. /**
  394. @abstract 截图功能,目前只支持jpg格式
  395. @param jpegCompressionQuality 设置图像的压缩比例
  396. @param filename 图片的文件名
  397. */
  398. - (void) takePhotoWithQuality:(CGFloat)jpegCompressionQuality
  399. fileName:(NSString *)filename;
  400. /**
  401. @abstract 获取当前编码的截图
  402. @param completion 通过完成代码块获取到截图完成的图像
  403. */
  404. - (void) getSnapshotWithCompletion:(void (^)(UIImage*))completion;
  405. #pragma mark - record
  406. /**
  407. @abstract 旁路录像地址
  408. @discussion 开始录像后, 将直播的内容同步存储一份到本地文件
  409. eg: /private/var/mobile/Containers/Data/Application/APPID/tmp/test.mp4
  410. @discussion 如果只要存储本地文件,请继续使用原来的startStream接口
  411. @see hostURL, startStream
  412. */
  413. @property (nonatomic, readonly) NSURL* bypassRecordURL;
  414. /**
  415. @abstract mp4文件允许快速启动 (默认NO)
  416. @discussion mp4格式的文件中将moov等index信息放到文件开头
  417. @discussion 开始录制前设置有效
  418. @warning 启用此开关会在结束是对文件进行处理, 如果要长时间录制,请关闭本选项
  419. */
  420. @property (nonatomic, assign) BOOL bypassMp4FastStart;
  421. /**
  422. @abstract 启动旁路录像
  423. @param url 本地录像文件地址:/private/var/..../test.mp4
  424. @return 是否能尝试启动写入, 不能表明真正开始录像了,真正开始请确认bypassRecordState的值
  425. @discussion 启动推流后才能开始写入文件
  426. @discussion 文件中的内容和直播内容完全一致
  427. @see bypassRecordURL,stopBypassRecord, bypassRecordState
  428. */
  429. - (BOOL) startBypassRecord: (NSURL*) url;
  430. /**
  431. @abstract 停止旁路录像
  432. */
  433. - (void) stopBypassRecord;
  434. /** 旁路录像的文件时长 */
  435. @property (nonatomic, readonly) double bypassRecordDuration;
  436. /** 旁路录像的状态 */
  437. @property (nonatomic, readonly) KSYRecordState bypassRecordState;
  438. /** 旁路录像的错误码 */
  439. @property (nonatomic, readonly) KSYRecordError bypassRecordErrorCode;
  440. /** 旁路录像的错误名称 */
  441. @property (nonatomic, readonly) NSString* bypassRecordErrorName;
  442. /**
  443. @abstract 当旁路录制的状态变化时
  444. @discussion 只有设置 loop为NO时才有效, 在开始播放前设置有效
  445. */
  446. @property(nonatomic, copy) void(^bypassRecordStateChange)(KSYRecordState recordState);
  447. /**
  448. @abstract 是否允许编码前丢帧,默认开启
  449. @warnning 请勿在直播时使用,否则可能出现音视频不同步,仅在离线转码需要输出所有帧的情况下开启
  450. */
  451. @property (nonatomic, assign) BOOL shouldEnableKSYDropModule;
  452. //// 网络状态监控 (当SDK内部发现网络不可用时主动发出connet_break的错误码)
  453. @property (nonatomic, readonly) KSYReachability* netReachability;
  454. /**
  455. @abstract 是否能连通外网
  456. @discussion networkDetectURL为nil或未探测到结果前,该值为KSYNetReachState_Unknown
  457. */
  458. @property (nonatomic, readonly) KSYNetReachState netReachState;
  459. /**
  460. @abstract 用于检测网络连通性的地址,默认使用地址为“www.baidu.com”
  461. @discussion 用户可自定义地址,但不可设置无效地址,如果不清楚规则,建议使用默认值
  462. @discussion 设置为nil时,则关闭网络连通性的检测, netReachability为nil,netReachState为KSYNetReachState_Unknown
  463. @since Available in KSYLive_iOS 2.1.1 and later
  464. */
  465. @property (nonatomic, readwrite) NSString* reachabilityDetectURL;
  466. @end