BGKSYAgoraStreamerBaseController.m 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. //
  2. // BGKSYAgoraStreamerBaseController.m
  3. // FanweLive
  4. //
  5. // Created by yiqian on 10/15/15.
  6. // Copyright (c) 2015 ksyun. All rights reserved.
  7. //
  8. #import "BGKSYAgoraStreamerBaseController.h"
  9. /////////////////// TiFaceSDK 添加 开始 ///////////////////
  10. //#import "TiUIView.h"
  11. #import "TiSDKInterface.h"
  12. /////////////////// TiFaceSDK 添加 结束 ///////////////////
  13. // 为防止将手机存储写满,限制录像时长为30s
  14. #define REC_MAX_TIME 30 //录制视频的最大时间,单位s
  15. @interface BGKSYAgoraStreamerBaseController ()
  16. //<TiUIViewDelegate>
  17. {
  18. CGFloat _currentPinchZoomFactor; // 当前触摸缩放因子
  19. UIImageView *_foucsCursorImgView; // 对焦框
  20. GlobalVariables *_fanweApp;
  21. NSMutableDictionary *_obsDict;
  22. float _cfgTimes; // 连麦参数相对于推流参数的倍数
  23. }
  24. ///////////// TiSDK 添加 开始 /////////////
  25. //@property(nonatomic, strong) TiUIView *tiUIView;
  26. @property(nonatomic, strong) TiSDKManager *tiSDKManager;
  27. ///////////// TiSDK 添加 结束 /////////////
  28. @end
  29. @implementation BGKSYAgoraStreamerBaseController
  30. - (void)viewDidLoad
  31. {
  32. [super viewDidLoad];
  33. if (_isApplicant)
  34. {
  35. _cfgTimes = 0.25;
  36. }
  37. else
  38. {
  39. _cfgTimes = 1;
  40. }
  41. ///////////// TiSDK 添加 开始 ////////////
  42. //#error TiSDK Key, 与包名对应,请联系商务获取
  43. NSString* key = [GlobalVariables sharedInstance].appModel.bogo_beauty_key;
  44. if([BGUtils isBlankString:key])
  45. {
  46. [[BGHUDHelper sharedInstance] tipMessage:ASLocalizedString(@"美颜key为空,请尝试重新打开app获取!")];
  47. }
  48. if(key != nil)
  49. {
  50. // [TiSDK init:key];
  51. [TiSDK init:key CallBack:^(InitStatus initStatus) {
  52. [[NSNotificationCenter defaultCenter] postNotificationName:@"TiSDKInitStatusNotification" object:nil];
  53. }];
  54. }
  55. else
  56. {
  57. }
  58. //
  59. // self.tiSDKManager = [[TiSDKManager alloc]init];
  60. //
  61. // self.tiUIView = [[TiUIView alloc]initTiUIViewWith:self.tiSDKManager delegate:self superView:self.view];
  62. // self.tiUIView.isClearOldUI = NO;
  63. // [self.tiUIView createTiUIView];
  64. if([[GlobalVariables sharedInstance].appModel.spear_live isEqualToString:@"1"])
  65. {
  66. ///////////// TiSDK 添加 开始 ////////////
  67. self.tiSDKManager = [[TiSDKManager alloc]init];
  68. // self.tiUIView = [[TiUIView alloc]initTiUIViewWith:self.tiSDKManager delegate:self superView:kCurrentWindow];
  69. // self.tiUIView.isClearOldUI = NO;
  70. // [self.tiUIView createTiUIView];
  71. }
  72. ///////////// TiSDK 添加 结束 /////////////
  73. // 添加视频容器视图
  74. _videoContrainerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenW, kScreenH)];
  75. _videoContrainerView.backgroundColor = [UIColor whiteColor];
  76. [self.view addSubview:_videoContrainerView];
  77. _fanweApp = [GlobalVariables sharedInstance];
  78. // 初始化监听
  79. [self initObservers];
  80. // 添加监听
  81. [self addObservers];
  82. #if TARGET_IPHONE_SIMULATOR
  83. _gPUStreamerKit = [[KSYGPUStreamerKit alloc] initWithDefaultCfg];
  84. #define SIMULATOR_TEST
  85. #else
  86. _gPUStreamerKit = [[KSYAgoraStreamerKit alloc] initWithDefaultCfg];
  87. #endif
  88. NSLog(ASLocalizedString(@"=====当前金山SDK版本号:%@"),[_gPUStreamerKit.streamerBase getKSYVersion]);
  89. // 采集相关设置初始化
  90. [self setCaptureCfg];
  91. // 推流相关设置初始化
  92. [self setStreamerCfg];
  93. // 设置rtc参数
  94. [self setAgoraStreamerKitCfg];
  95. dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC));
  96. dispatch_after(delay, dispatch_get_main_queue(), ^{
  97. _gPUStreamerKit.videoOrientation = [[UIApplication sharedApplication] statusBarOrientation];
  98. [_gPUStreamerKit startPreview:_videoContrainerView];
  99. });
  100. // 添加对焦框
  101. [self addfoucsCursorImgView];
  102. // 添加手势
  103. [self addPinchGestureRecognizer];
  104. self.view.backgroundColor = kClearColor;
  105. NSLog(ASLocalizedString(@"=====当前金山SDK版本为: %@"), [_gPUStreamerKit getKSYVersion]);
  106. }
  107. #pragma mark 对焦框
  108. - (void)addfoucsCursorImgView
  109. {
  110. _foucsCursorImgView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"lr_camera_focus_red"]];
  111. _foucsCursorImgView.frame = CGRectMake(80, 80, 80, 80);
  112. [self.view addSubview:_foucsCursorImgView];
  113. _foucsCursorImgView.alpha = 0;
  114. }
  115. #pragma mark - ----------------------- 推流 -----------------------
  116. /*
  117. * 开始连麦
  118. * applicantId:申请连麦者ID
  119. * responderId:接收连麦者ID
  120. * roomId:房间ID
  121. */
  122. - (void)startLinkMic:(NSString *)applicantId andResponderId:(NSString *)responderId roomId:(NSString *)roomId
  123. {
  124. _applicantId = applicantId;
  125. // [_gPUStreamerKit rtc];
  126. #if TARGET_IPHONE_SIMULATOR
  127. #else
  128. _videoContrainerView.hidden = NO;
  129. _gPUStreamerKit.winRect = CGRectMake(kLinkMickXRate, kLinkMickYRate, kLinkMickWRate, kLinkMickHRate);//设置小窗口属性
  130. [_gPUStreamerKit startPreview:_videoContrainerView];
  131. [_gPUStreamerKit joinChannel:roomId];
  132. #endif
  133. }
  134. /*
  135. * 停止连麦
  136. * applicantId:申请连麦者ID
  137. */
  138. - (void)stopLinkMic:(NSString *)applicantId
  139. {
  140. #if TARGET_IPHONE_SIMULATOR
  141. #else
  142. if (_gPUStreamerKit.callstarted)
  143. {
  144. // [_gPUStreamerKit stopPreview];
  145. [_gPUStreamerKit leaveChannel];
  146. if (_isApplicant)
  147. {
  148. _videoContrainerView.hidden = YES;
  149. }
  150. }
  151. #endif
  152. #if TARGET_IPHONE_SIMULATOR
  153. #else
  154. if (_isApplicant && !_gPUStreamerKit.callstarted)
  155. {
  156. [_gPUStreamerKit stopPreview];
  157. _gPUStreamerKit = nil;
  158. }
  159. #endif
  160. }
  161. -(void)PkWithRoomId:(NSString *)roomid
  162. {
  163. #if TARGET_IPHONE_SIMULATOR
  164. #else
  165. [_gPUStreamerKit joinChannel:roomid];
  166. #endif
  167. }
  168. #pragma mark 开始推流
  169. - (void)startRtmp
  170. {
  171. dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC));
  172. dispatch_after(delay, dispatch_get_main_queue(), ^{
  173. [_gPUStreamerKit.streamerBase startStream:self.pushUrl];
  174. NSLog(@"pushrtmp :%@",self.pushUrl);
  175. });
  176. }
  177. -(void)reloadRtmp
  178. {
  179. [_gPUStreamerKit.streamerBase stopStream];
  180. [self setCaptureCfg];
  181. [_gPUStreamerKit.streamerBase startStream:self.pushUrl];
  182. //
  183. // [self stopRtmp];
  184. //
  185. // // 添加视频容器视图
  186. // _videoContrainerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenW, kScreenH)];
  187. // _videoContrainerView.backgroundColor = [UIColor whiteColor];
  188. // [self.view addSubview:_videoContrainerView];
  189. //
  190. // _fanweApp = [GlobalVariables sharedInstance];
  191. //
  192. // // 初始化监听
  193. // [self initObservers];
  194. // // 添加监听
  195. // [self addObservers];
  196. //
  197. // _gPUStreamerKit = [[KSYAgoraStreamerKit alloc] initWithDefaultCfg];
  198. // NSLog(ASLocalizedString(@"=====当前金山SDK版本号:%@"),[_gPUStreamerKit.streamerBase getKSYVersion]);
  199. //
  200. // // 采集相关设置初始化
  201. // [self setCaptureCfg];
  202. // // 推流相关设置初始化
  203. // [self setStreamerCfg];
  204. // // 设置rtc参数
  205. // [self setAgoraStreamerKitCfg];
  206. // dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC));
  207. // dispatch_after(delay, dispatch_get_main_queue(), ^{
  208. // _gPUStreamerKit.videoOrientation = [[UIApplication sharedApplication] statusBarOrientation];
  209. // [_gPUStreamerKit startPreview:_videoContrainerView];
  210. // [self startRtmp];
  211. // });
  212. }
  213. #pragma mark 停止推流
  214. - (void)stopRtmp
  215. {
  216. if (_gPUStreamerKit)
  217. {
  218. #if TARGET_IPHONE_SIMULATOR
  219. #else
  220. [_gPUStreamerKit leaveChannel];
  221. #endif
  222. [_gPUStreamerKit.streamerBase stopStream];
  223. [_gPUStreamerKit stopPreview];
  224. _gPUStreamerKit = nil;
  225. }
  226. [[NSNotificationCenter defaultCenter] removeObserver:self];
  227. }
  228. #pragma mark 尝试重连
  229. - (void)tryReconnect
  230. {
  231. if (_gPUStreamerKit.maxAutoRetry > 0)
  232. {
  233. return;
  234. }
  235. [self startRtmp];
  236. }
  237. #pragma mark - ----------------------- 配置 -----------------------
  238. #pragma mark 采集相关设置初始化
  239. - (void)setCaptureCfg
  240. {
  241. // 采集分辨率 (仅在开始采集前设置有效)
  242. _gPUStreamerKit.capPreset = AVCaptureSessionPreset640x480;
  243. _gPUStreamerKit.previewDimension = CGSizeMake(640, 480);
  244. _gPUStreamerKit.streamDimension = CGSizeMake(640, 480);
  245. //配置profile 0:标清(360*640) 1:高清(540*960) 2:超清(720*1280)
  246. if (_fanweApp.appModel.video_resolution_type == 0)
  247. {
  248. [_gPUStreamerKit setStreamerProfile:KSYStreamerProfile_360p_auto];
  249. }
  250. else if (_fanweApp.appModel.video_resolution_type == 1)
  251. {
  252. [_gPUStreamerKit setStreamerProfile:KSYStreamerProfile_540p_auto];
  253. }
  254. else if (_fanweApp.appModel.video_resolution_type == 2)
  255. {
  256. [_gPUStreamerKit setStreamerProfile:KSYStreamerProfile_720p_auto];
  257. }
  258. // 视频帧率 默认:15
  259. _gPUStreamerKit.videoFPS = 15;
  260. // 摄像头位置 (仅在开始采集前设置有效)
  261. _gPUStreamerKit.cameraPosition = AVCaptureDevicePositionFront;
  262. // gpu output pixel format (默认:kCVPixelFormatType_32BGRA) (仅在开始采集前设置有效)
  263. // _gPUStreamerKit.gpuOutputPixelFormat = kCVPixelFormatType_32BGRA;
  264. // 视频处理回调接口
  265. // _gPUStreamerKit.videoProcessingCallback = ^(CMSampleBufferRef buf){
  266. // // 在此处添加自定义图像处理, 直接修改buf中的图像数据会传递到观众端
  267. // // 或复制图像数据之后再做其他处理, 则观众端仍然看到处理前的图像
  268. // };
  269. // 采集模块输出的像素格式 (默认:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) (仅在开始采集前设置有效)
  270. // _gPUStreamerKit.capturePixelFormat = kCVPixelFormatType_32BGRA;
  271. // 音频处理回调接口
  272. // _gPUStreamerKit.audioProcessingCallback = ^(CMSampleBufferRef buf){
  273. // // 在此处添加自定义音频处理, 直接修改buf中的pcm数据会传递到观众端
  274. // // 或复制音频数据之后再做其他处理, 则观众端仍然听到原始声音
  275. // };
  276. // 摄像头采集被打断的消息通知
  277. // _gPUStreamerKit.interruptCallback = ^(BOOL bInterrupt){
  278. // // 在此处添加自定义图像采集被打断的处理 (比如接听电话等)
  279. // };
  280. }
  281. #pragma mark 推流相关设置初始化
  282. - (void)setStreamerCfg
  283. {
  284. if (_gPUStreamerKit.streamerBase == nil)
  285. {
  286. return;
  287. }
  288. // must set after capture
  289. // stream default settings
  290. // 视频编码器 默认为 自动选择
  291. _gPUStreamerKit.streamerBase.videoCodec = KSYVideoCodec_X264;
  292. if (_fanweApp.appModel.video_resolution_type == 0)
  293. {
  294. // 视频编码最高码率(单位:kbps, 默认:800)
  295. _gPUStreamerKit.streamerBase.videoMaxBitrate = 800 * _cfgTimes;
  296. // 视频编码最低码率(单位:kbps, 默认:200)
  297. _gPUStreamerKit.streamerBase.videoMinBitrate = 200 * _cfgTimes;
  298. }
  299. else if (_fanweApp.appModel.video_resolution_type == 1)
  300. {
  301. // 视频编码最高码率(单位:kbps, 默认:800)
  302. _gPUStreamerKit.streamerBase.videoMaxBitrate = 1000 * _cfgTimes;
  303. // 视频编码最低码率(单位:kbps, 默认:200)
  304. _gPUStreamerKit.streamerBase.videoMinBitrate = 400 * _cfgTimes;
  305. }
  306. else if (_fanweApp.appModel.video_resolution_type == 2)
  307. {
  308. // 视频编码最高码率(单位:kbps, 默认:800)
  309. _gPUStreamerKit.streamerBase.videoMaxBitrate = 1000 * _cfgTimes;
  310. // 视频编码最低码率(单位:kbps, 默认:200)
  311. _gPUStreamerKit.streamerBase.videoMinBitrate = 600 * _cfgTimes;
  312. }
  313. // 视频编码起始码率(单位:kbps, 默认:500)
  314. _gPUStreamerKit.streamerBase.videoInitBitrate = _gPUStreamerKit.streamerBase.videoMaxBitrate * 0.6;
  315. // 音频编码码率(单位:kbps)
  316. _gPUStreamerKit.streamerBase.audiokBPS = 48;
  317. #ifdef DEBUG
  318. // // 收集网络相关状态的日志,默认开启
  319. _gPUStreamerKit.streamerBase.shouldEnableKSYStatModule = YES;
  320. // 获取Streamer中与网络相关的日志
  321. _gPUStreamerKit.streamerBase.logBlock = ^(NSString* str){
  322. NSLog(ASLocalizedString(@"====获取Streamer中与网络相关的日志:%@"), str);
  323. };
  324. #endif
  325. // // 直播场景 (KSY内部会根据场景的特征进行参数调优)
  326. // _gPUStreamerKit.streamerBase.liveScene = KSYLiveScene_Showself;
  327. // // 视频编码性能档次 (视频质量 和 设备资源之间的权衡)
  328. // _gPUStreamerKit.streamerBase.videoEncodePerf = KSYVideoEncodePer_Balance;
  329. // // 是否处理视频的图像数据 (默认YES)
  330. // _gPUStreamerKit.streamerBase.bWithVideo = YES;
  331. // //是否冻结图像(主动提供重复图像) 比如:视频采集被打断时, bAutoRepeat为NO,则停止提供图像; 为YES, 则主动提供最后一帧图像
  332. // _gPUStreamerKit.gpuToStr.bAutoRepeat = YES;
  333. // // 自动重连次数 关闭(0), 开启(>0), 默认为0
  334. // _gPUStreamerKit.maxAutoRetry = 3;
  335. }
  336. - (UIView *)createUIView
  337. {
  338. UIView * view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
  339. view.layer.borderWidth = 10;
  340. view.layer.borderColor = [kClearColor CGColor];
  341. return view;
  342. }
  343. #pragma mark 设置rtc参数
  344. - (void)setAgoraStreamerKitCfg
  345. {
  346. #if TARGET_IPHONE_SIMULATOR
  347. #else
  348. if (_isApplicant)
  349. {
  350. // 主播、辅播窗口位置调换
  351. _gPUStreamerKit.selfInFront = YES;
  352. }
  353. //设置小窗口属性
  354. _gPUStreamerKit.winRect = CGRectMake(0.6, 0.6, 0.3, 0.3);
  355. _gPUStreamerKit.winRect = CGRectMake(kLinkMickXRate, kLinkMickYRate, kLinkMickWRate, kLinkMickHRate);//设置小窗口属性
  356. _gPUStreamerKit.rtcLayer = 4;//设置小窗口图层,因为主版本占用了1~3,建议设置为4
  357. //特性1:悬浮图层,用户可以在小窗口叠加自己的view,注意customViewLayer >rtcLayer,(option)
  358. // _gPUStreamerKit.customViewRect = CGRectMake(0.6, 0.6, 0.3, 0.3);
  359. // _gPUStreamerKit.customViewLayer = 5;
  360. //
  361. // UIView * customView = [self createUIView];
  362. // [_gPUStreamerKit.contentView addSubview:customView];
  363. //特性2:圆角小窗口
  364. // _gPUStreamerKit.maskPicture = [[GPUImagePicture alloc] initWithImage:[UIImage imageNamed:@"mask.png"]];
  365. //rtcClient的回调,(option)
  366. __weak typeof(self) ws = self;
  367. // start call的回调函数
  368. _gPUStreamerKit.onCallStart =^(int status){
  369. NSLog(@"oncallstart:%d",status);
  370. if(status == 200) // 建立连接
  371. {
  372. if([UIApplication sharedApplication].applicationState != UIApplicationStateBackground)
  373. {
  374. if (ws.delegate && [ws.delegate respondsToSelector:@selector(linkOrBreakMick:applicantId:)])
  375. {
  376. [ws.delegate linkOrBreakMick:YES applicantId:ws.applicantId];
  377. }
  378. }
  379. }
  380. else if(status == 408 || status == 404) // 408:对方无应答 404:呼叫未注册号码,主动停止
  381. {
  382. [ws stopLinkMic:ws.applicantId];
  383. if (ws.delegate && [ws.delegate respondsToSelector:@selector(linkOrBreakMick:applicantId:)])
  384. {
  385. [ws.delegate linkOrBreakMick:NO applicantId:ws.applicantId];
  386. }
  387. }
  388. if(ws.onMyCallStart)
  389. {
  390. ws.onMyCallStart(status);
  391. }
  392. };
  393. // stop call的回调函数
  394. _gPUStreamerKit.onCallStop = ^(int status){
  395. NSLog(@"oncallstop:%d",status);
  396. if(status == 200)
  397. {
  398. if([UIApplication sharedApplication].applicationState != UIApplicationStateBackground)
  399. {
  400. NSLog(ASLocalizedString(@"断开连接"));
  401. }
  402. }
  403. else if(status == 408)
  404. {
  405. NSLog(ASLocalizedString(@"408超时"));
  406. }
  407. [ws stopLinkMic:ws.applicantId];
  408. if (ws.delegate && [ws.delegate respondsToSelector:@selector(linkOrBreakMick:applicantId:)])
  409. {
  410. [ws.delegate linkOrBreakMick:NO applicantId:ws.applicantId];
  411. }
  412. if(ws.onMyCallStop)
  413. {
  414. ws.onMyCallStop(status);
  415. }
  416. };
  417. _gPUStreamerKit.onChannelJoin = ^(int status){
  418. NSLog(@"onChannelJoin:%d",status);
  419. if(status == 200) // 成功加入
  420. {
  421. if([UIApplication sharedApplication].applicationState !=UIApplicationStateBackground)
  422. {
  423. }
  424. }
  425. if(ws.onMyChannelJoin)
  426. {
  427. ws.onMyChannelJoin(status);
  428. }
  429. };
  430. _gPUStreamerKit.videoProcessingCallback = ^(CMSampleBufferRef buf){
  431. // 在此处添加自定义图像处理, 直接修改buf中的图像数据会传递到观众端
  432. // 或复制图像数据之后再做其他处理, 则观众端仍然看到处理前的图像
  433. // _kit.videopts
  434. _gPUStreamerKit.videoPts= CMSampleBufferGetPresentationTimeStamp(buf);
  435. /////////////////// TiFaceSDK 添加 开始 ///////////////////
  436. CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(buf);
  437. BOOL isMirror = NO;
  438. CVPixelBufferLockBaseAddress(pixelBuffer, 0);
  439. unsigned char *baseAddress = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
  440. UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
  441. UIInterfaceOrientation orie;
  442. TiRotationEnum rotation;
  443. switch (orientation) {
  444. case UIDeviceOrientationPortrait:
  445. rotation = CLOCKWISE_90;
  446. orie = UIInterfaceOrientationPortrait;
  447. break;
  448. case UIDeviceOrientationLandscapeLeft:
  449. rotation = isMirror ? CLOCKWISE_180 : CLOCKWISE_0;
  450. orie = UIInterfaceOrientationLandscapeRight;
  451. break;
  452. case UIDeviceOrientationLandscapeRight:
  453. rotation = isMirror ? CLOCKWISE_0 : CLOCKWISE_180;
  454. orie = UIInterfaceOrientationLandscapeLeft;
  455. break;
  456. case UIDeviceOrientationPortraitUpsideDown:
  457. rotation = CLOCKWISE_270;
  458. orie = UIInterfaceOrientationPortraitUpsideDown;
  459. break;
  460. default:
  461. rotation = CLOCKWISE_90;
  462. orie = UIInterfaceOrientationPortrait;
  463. break;
  464. }
  465. // 视频帧格式
  466. TiImageFormatEnum format;
  467. switch (CVPixelBufferGetPixelFormatType(pixelBuffer)) {
  468. case kCVPixelFormatType_32BGRA:
  469. format = BGRA;
  470. break;
  471. case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
  472. format = NV12;
  473. break;
  474. case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange:
  475. format = NV12;
  476. break;
  477. default:
  478. NSLog(ASLocalizedString(@"错误的视频帧格式!"));
  479. format = BGRA;
  480. break;
  481. }
  482. int imageWidth, imageHeight;
  483. if (format == BGRA) {
  484. imageWidth = (int)CVPixelBufferGetBytesPerRow(pixelBuffer) / 4;
  485. imageHeight = (int)CVPixelBufferGetHeight(pixelBuffer);
  486. } else {
  487. imageWidth = (int)CVPixelBufferGetWidthOfPlane(pixelBuffer , 0);
  488. imageHeight = (int)CVPixelBufferGetHeightOfPlane(pixelBuffer , 0);
  489. }
  490. if(self.tiSDKManager!=nil){
  491. [self.tiSDKManager renderPixels:baseAddress Format:format Width:imageWidth Height:imageHeight Rotation:CLOCKWISE_0 Mirror:isMirror];
  492. }
  493. CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
  494. /////////////////// TiFaceSDK 添加 结束 ///////////////////
  495. };
  496. #endif
  497. }
  498. #pragma mark - ----------------------- 监听 -----------------------
  499. - (void)initObservers
  500. {
  501. _obsDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  502. SEL_VALUE(onCaptureStateChange:) , KSYCaptureStateDidChangeNotification,
  503. SEL_VALUE(onStreamStateChange:) , KSYStreamStateDidChangeNotification,
  504. SEL_VALUE(onBgmPlayerStateChange:) ,KSYAudioStateDidChangeNotification,
  505. nil];
  506. }
  507. - (void)addObservers
  508. {
  509. //KSYStreamer state changes
  510. NSNotificationCenter* dc = [NSNotificationCenter defaultCenter];
  511. for (NSString* key in _obsDict)
  512. {
  513. SEL aSel = [[_obsDict objectForKey:key] pointerValue];
  514. [dc addObserver:self
  515. selector:aSel
  516. name:key
  517. object:nil];
  518. }
  519. }
  520. #pragma mark state change
  521. - (void)onCaptureStateChange:(NSNotification *)notification
  522. {
  523. if (_gPUStreamerKit.captureState == KSYCaptureStateIdle)
  524. {
  525. // self.view.backgroundColor = [UIColor darkGrayColor];
  526. }
  527. else if(_gPUStreamerKit.captureState == KSYCaptureStateCapturing)
  528. {
  529. // self.view.backgroundColor = [UIColor lightGrayColor];
  530. }
  531. }
  532. #pragma mark 推流状态监听
  533. - (void)onStreamStateChange:(NSNotification *)notification
  534. {
  535. if (_gPUStreamerKit.streamerBase)
  536. {
  537. NSLog(@"stream State %@", [_gPUStreamerKit.streamerBase getCurStreamStateName]);
  538. }
  539. if(_gPUStreamerKit.streamerBase.streamState == KSYStreamStateError)
  540. {
  541. [self onStreamError:_gPUStreamerKit.streamerBase.streamErrorCode];
  542. }
  543. else if (_gPUStreamerKit.streamerBase.streamState == KSYStreamStateConnecting)
  544. {
  545. }
  546. else if (_gPUStreamerKit.streamerBase.streamState == KSYStreamStateConnected)
  547. {
  548. // self.view.backgroundColor = [UIColor lightGrayColor];
  549. if (_delegate && [_delegate respondsToSelector:@selector(firstFrame:)])
  550. {
  551. [_delegate firstAgoraFrame:self];
  552. }
  553. }
  554. else if (_gPUStreamerKit.streamerBase.streamState == KSYStreamStateIdle)
  555. {
  556. // self.view.backgroundColor = [UIColor darkGrayColor];
  557. }
  558. //状态为KSYStreamStateIdle且_bRecord为ture时,录制视频
  559. if (_gPUStreamerKit.streamerBase.streamState == KSYStreamStateIdle && _liveType == FW_LIVE_TYPE_RECORD)
  560. {
  561. // [self saveVideoToAlbum:[_presetCfgView hostUrl]];
  562. }
  563. }
  564. #pragma mark 推流错误处理
  565. - (void)onStreamError:(KSYStreamErrorCode) errCode
  566. {
  567. if (errCode == KSYStreamErrorCode_CONNECT_BREAK)
  568. {
  569. [self tryReconnect];
  570. }
  571. else if (errCode == KSYStreamErrorCode_AV_SYNC_ERROR)
  572. {
  573. NSLog(@"audio video is not synced, please check timestamp");
  574. [self tryReconnect];
  575. }
  576. else if (errCode == KSYStreamErrorCode_CODEC_OPEN_FAILED)
  577. {
  578. NSLog(@"video codec open failed, try software codec");
  579. _gPUStreamerKit.streamerBase.videoCodec = KSYVideoCodec_X264;
  580. [self tryReconnect];
  581. }
  582. }
  583. - (void)onBgmPlayerStateChange:(NSNotification *)notification
  584. {
  585. NSString *st = [_gPUStreamerKit.bgmPlayer getCurBgmStateName];
  586. NSLog(@"=====bgmStatus:%@",[st substringFromIndex:17]);
  587. }
  588. #pragma mark - ----------------------- 手势 -----------------------
  589. #pragma mark 将UI的坐标转换成相机坐标
  590. - (CGPoint)convertToPointOfInterestFromViewCoordinates:(CGPoint)viewCoordinates
  591. {
  592. CGPoint pointOfInterest = CGPointMake(.5f, .5f);
  593. CGSize frameSize = self.view.frame.size;
  594. CGSize apertureSize = [_gPUStreamerKit captureDimension];
  595. CGPoint point = viewCoordinates;
  596. CGFloat apertureRatio = apertureSize.height / apertureSize.width;
  597. CGFloat viewRatio = frameSize.width / frameSize.height;
  598. CGFloat xc = .5f;
  599. CGFloat yc = .5f;
  600. if (viewRatio > apertureRatio)
  601. {
  602. CGFloat y2 = frameSize.height;
  603. CGFloat x2 = frameSize.height * apertureRatio;
  604. CGFloat x1 = frameSize.width;
  605. CGFloat blackBar = (x1 - x2) / 2;
  606. if (point.x >= blackBar && point.x <= blackBar + x2)
  607. {
  608. xc = point.y / y2;
  609. yc = 1.f - ((point.x - blackBar) / x2);
  610. }
  611. }
  612. else
  613. {
  614. CGFloat y2 = frameSize.width / apertureRatio;
  615. CGFloat y1 = frameSize.height;
  616. CGFloat x2 = frameSize.width;
  617. CGFloat blackBar = (y1 - y2) / 2;
  618. if (point.y >= blackBar && point.y <= blackBar + y2)
  619. {
  620. xc = ((point.y - blackBar) / y2);
  621. yc = 1.f - (point.x / x2);
  622. }
  623. }
  624. pointOfInterest = CGPointMake(xc, yc);
  625. return pointOfInterest;
  626. }
  627. //设置摄像头对焦位置
  628. - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
  629. {
  630. UITouch *touch = [touches anyObject];
  631. CGPoint current = [touch locationInView:self.view];
  632. CGPoint point = [self convertToPointOfInterestFromViewCoordinates:current];
  633. [_gPUStreamerKit exposureAtPoint:point];
  634. [_gPUStreamerKit focusAtPoint:point];
  635. _foucsCursorImgView.center = current;
  636. _foucsCursorImgView.transform = CGAffineTransformMakeScale(1.5, 1.5);
  637. _foucsCursorImgView.alpha=1.0;
  638. [UIView animateWithDuration:1.0 animations:^{
  639. _foucsCursorImgView.transform=CGAffineTransformIdentity;
  640. } completion:^(BOOL finished) {
  641. _foucsCursorImgView.alpha=0;
  642. }];
  643. }
  644. #pragma mark 添加缩放手势,缩放时镜头放大或缩小
  645. - (void)addPinchGestureRecognizer
  646. {
  647. UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchDetected:)];
  648. [self.view addGestureRecognizer:pinch];
  649. }
  650. - (void)pinchDetected:(UIPinchGestureRecognizer *)recognizer
  651. {
  652. if (recognizer.state == UIGestureRecognizerStateBegan)
  653. {
  654. _currentPinchZoomFactor = _gPUStreamerKit.pinchZoomFactor;
  655. }
  656. CGFloat zoomFactor = _currentPinchZoomFactor * recognizer.scale;//当前触摸缩放因子*坐标比例
  657. [_gPUStreamerKit setPinchZoomFactor:zoomFactor];
  658. }
  659. -(void)viewDidDisappear:(BOOL)animated
  660. {
  661. [super viewDidDisappear:animated];
  662. if (!_gPUStreamerKit) {
  663. [GlobalVariables sharedInstance].appModel.spear_live = @"0";
  664. if (self.tiSDKManager) {
  665. [self.tiSDKManager destroy];
  666. self.tiSDKManager = nil;
  667. // if(_tiUIView.viewArr != nil)
  668. // for (UIView *sview in _tiUIView.viewArr) {
  669. // [sview removeFromSuperview];
  670. // }
  671. }
  672. }
  673. }
  674. -(void)dealloc
  675. {
  676. [_tiSDKManager destroy];
  677. }
  678. @end