PlayViewController.mm 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. //
  2. // PlayViewController.m
  3. // FunSDKDemo
  4. //
  5. // Created by XM on 2018/5/23.
  6. // Copyright © 2018年 XM. All rights reserved.
  7. //
  8. #import "PlayViewController.h"
  9. #import "DeviceConfigViewController.h"
  10. #import "PlayBackViewController.h"
  11. #import "MediaplayerControl.h"
  12. #import "PlayView.h"
  13. #import "PlayFunctionView.h"
  14. #import "PlayMenuView.h"
  15. #import "TalkView.h"
  16. #import "PTZView.h"
  17. #import "TalkBackControl.h"
  18. #import "FishPlayControl.h"
  19. #import "VRGLViewController.h"
  20. #import "HardVRViewController.h"
  21. #import "UILabelOutLined.h"
  22. #import "DeviceManager.h"
  23. #import "Header.h"
  24. @interface PlayViewController () <MediaplayerControlDelegate,basePlayFunctionViewDelegate,PlayMenuViewDelegate,TalKViewDelegate,PTZViewDelegate>
  25. {
  26. PlayView *pVIew; //播放画面
  27. VRGLViewController *softV;//鱼眼软解播放画面,(绝大部分设备都是软解)
  28. HardVRViewController *hardV; //鱼眼硬解播放画面
  29. PlayFunctionView *toolView; // 工具栏
  30. PlayMenuView *playMenuView;//下方功能栏
  31. TalkView *talkView;//对讲功能界面
  32. PTZView *ptzView; //云台控制界面
  33. ChannelObject *channel; //选择播放的通道信息
  34. MediaplayerControl *mediaPlayer;//播放媒体工具
  35. TalkBackControl *talkControl;//对讲工具
  36. FishPlayControl *feyeControl;
  37. int Hardandsofts;//鱼眼解码模式 4:软解 3:硬解
  38. int Hardmodels;//鱼眼画面模式
  39. int shapeType; //吸顶模式还是壁挂模式
  40. BOOL isFeyeYuv;//是否是鱼眼预览
  41. short centerOffsetX; //鱼眼偏移量参数
  42. short centerOffsetY;
  43. short imageWidth; //语言宽高参数
  44. short imageHeight;
  45. short imgradius; //鱼眼半径参数
  46. UILabelOutLined *timeLab;
  47. UILabelOutLined *nameLab;
  48. }
  49. //导航栏右边的设置按钮
  50. @property (nonatomic, strong) UIBarButtonItem *rightBarBtn;
  51. //导航栏左边的返回按钮
  52. @property (nonatomic, strong) UIBarButtonItem *leftBarBtn;
  53. @end
  54. @implementation PlayViewController
  55. - (void)viewDidLoad {
  56. [super viewDidLoad];
  57. //创建导航栏;
  58. [self setNaviStyle];
  59. //创建预览界面
  60. [self createPlayView];
  61. //获取要播放的设备信息
  62. [self initDataSource];
  63. //创建工具栏界面
  64. [self createToolView];
  65. //创建下方功能栏
  66. [self createPlayMenuView];
  67. //开始播放视频
  68. [self startRealPlay];
  69. }
  70. #pragma mark - 开始播放视频
  71. - (void)startRealPlay {
  72. [pVIew playViewBufferIng];
  73. [mediaPlayer start];
  74. }
  75. #pragma mark 切换码流
  76. -(void)changeStreamType {
  77. //如果正在录像、对讲、播放音频,需要先停止这几项操作
  78. [self stopRecord];
  79. [self closeSound];
  80. [self stopTalk];
  81. //先停止预览
  82. [mediaPlayer stop];
  83. //切换主辅码流
  84. if (mediaPlayer.stream == 0) {
  85. mediaPlayer.stream = 1;
  86. }else if (mediaPlayer.stream == 1) {
  87. mediaPlayer.stream = 0;
  88. }
  89. //重新播放预览
  90. [mediaPlayer start];
  91. //刷新主辅码流显示
  92. [playMenuView setStreamType:mediaPlayer.stream];
  93. }
  94. #pragma mark - 工具栏点击 - 暂停、音频、抓图、录像
  95. - (void)basePlayFunctionViewBtnClickWithBtn:(int)tag {
  96. if ((CONTROL_TYPE)tag == CONTROL_FULLREALPLAY_PAUSE) {
  97. //点击暂停按钮,暂停预览
  98. if (mediaPlayer.status == MediaPlayerStatusPlaying) {
  99. [mediaPlayer pause];
  100. }else if (mediaPlayer.status == MediaPlayerStatusPause) {
  101. [mediaPlayer resumue];
  102. }
  103. }if ((CONTROL_TYPE)tag == CONTROL_REALPLAY_VOICE) {
  104. //点击音频按钮,打开音频
  105. if (mediaPlayer.voice == MediaVoiceTypeNone) {
  106. //音频没有回调,所以直接在这里刷新界面
  107. [self openSound];
  108. }else if (mediaPlayer.voice == MediaVoiceTypeVoice){
  109. [self closeSound];
  110. }
  111. }if ((CONTROL_TYPE)tag == CONTROL_REALPLAY_TALK) {
  112. //点击对讲按钮,打开对讲
  113. [self presentTalkView];
  114. }if ((CONTROL_TYPE)tag == CONTROL_REALPLAY_SNAP) {
  115. //开始抓图
  116. [mediaPlayer snapImage];
  117. }if ((CONTROL_TYPE)tag == CONTROL_REALPLAY_VIDEO) {
  118. //开始和停止录像
  119. if (mediaPlayer.record == MediaRecordTypeNone) {
  120. [mediaPlayer startRecord];
  121. }else if (mediaPlayer.record == MediaRecordTypeRecording){
  122. [mediaPlayer stopRecord];
  123. }
  124. }
  125. }
  126. #pragma mark 停止录像
  127. - (void)stopRecord {
  128. if (mediaPlayer.record == MediaRecordTypeNone) {
  129. [mediaPlayer stopRecord];
  130. }
  131. }
  132. #pragma mark 停止播放音频
  133. - (void)closeSound {
  134. if (mediaPlayer.voice == MediaVoiceTypeVoice){
  135. [mediaPlayer closeSound];
  136. mediaPlayer.voice = MediaVoiceTypeNone;
  137. [toolView refreshFunctionView:CONTROL_REALPLAY_VOICE result:NO];
  138. }
  139. }
  140. #pragma mark 开始播放音频
  141. - (void)openSound {
  142. if (mediaPlayer.voice == MediaVoiceTypeNone){
  143. [mediaPlayer openSound:100];
  144. mediaPlayer.voice = MediaVoiceTypeVoice;
  145. [toolView refreshFunctionView:CONTROL_REALPLAY_VOICE result:YES];
  146. }
  147. }
  148. #pragma mark 停止对讲
  149. - (void)stopTalk {
  150. //停止对讲
  151. [talkControl closeTalk];
  152. if (talkView) {
  153. [talkView cannelTheView];
  154. }
  155. }
  156. #pragma mark - 开始预览结果回调
  157. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer startResult:(int)result DSSResult:(int)dssResult {
  158. if (result < 0) {
  159. if(result == EE_DVR_PASSWORD_NOT_VALID)//密码错误,弹出密码修改框
  160. {
  161. [SVProgressHUD dismiss];
  162. ChannelObject *channel = [[DeviceControl getInstance] getSelectChannel];
  163. DeviceObject *device = [[DeviceControl getInstance] GetDeviceObjectBySN:channel.deviceMac];
  164. UIAlertController *alert = [UIAlertController alertControllerWithTitle:TS("EE_DVR_PASSWORD_NOT_VALID") message:channel.deviceMac preferredStyle:UIAlertControllerStyleAlert];
  165. [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
  166. textField.placeholder = TS("set_new_psd");
  167. }];
  168. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:TS("Cancel") style:UIAlertActionStyleCancel handler:nil];
  169. UIAlertAction *okAction = [UIAlertAction actionWithTitle:TS("OK") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  170. UITextField *passWordTextField = alert.textFields.firstObject;
  171. DeviceManager *manager = [DeviceManager getInstance];
  172. //点击确定修改密码
  173. [manager changeDevicePsw:channel.deviceMac loginName:device.loginName password:passWordTextField.text];
  174. //开始播放视频
  175. [self startRealPlay];
  176. }];
  177. [alert addAction:cancelAction];
  178. [alert addAction:okAction];
  179. [self presentViewController:alert animated:YES completion:nil];
  180. return;
  181. }
  182. [MessageUI ShowErrorInt:result];
  183. }else {
  184. if (dssResult == 3) { //DSS 打开视频成功
  185. }else if (dssResult == 5){//RPS打开预览成功
  186. }
  187. [pVIew playViewBufferIng];
  188. }
  189. }
  190. #pragma mark - 视频缓冲中
  191. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer buffering:(BOOL)isBuffering {
  192. if (isBuffering == YES) {//开始缓冲
  193. [pVIew playViewBufferIng];
  194. }else{//缓冲完成
  195. [pVIew playViewBufferEnd];
  196. }
  197. }
  198. #pragma mark 收到暂停播放结果消息
  199. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer pauseOrResumeResult:(int)result {
  200. if (result == 2) { //暂停预览
  201. mediaPlayer.status = MediaPlayerStatusPause;
  202. [toolView refreshFunctionView:CONTROL_FULLREALPLAY_PAUSE result:YES];
  203. }else if (result == 1){ //恢复预览
  204. mediaPlayer.status = MediaPlayerStatusPlaying;
  205. [toolView refreshFunctionView:CONTROL_FULLREALPLAY_PAUSE result:NO];
  206. }
  207. }
  208. #pragma mark - 录像开始结果
  209. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer startRecordResult:(int)result path:(NSString*)path {
  210. if (result == EE_OK) { //开始录像成功
  211. mediaPlayer.record = MediaRecordTypeRecording;
  212. [toolView refreshFunctionView:CONTROL_REALPLAY_VIDEO result:YES];
  213. }else{
  214. [MessageUI ShowErrorInt:result];
  215. [toolView refreshFunctionView:CONTROL_REALPLAY_VIDEO result:NO];
  216. }
  217. }
  218. #pragma mark - 录像结束结果
  219. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer stopRecordResult:(int)result path:(NSString*)path {
  220. if (result == EE_OK) { //结束录像成功
  221. [SVProgressHUD showSuccessWithStatus:TS("Success") duration:2.0];
  222. }else{
  223. [MessageUI ShowErrorInt:result];
  224. }
  225. [toolView refreshFunctionView:CONTROL_REALPLAY_VIDEO result:NO];
  226. mediaPlayer.record = MediaRecordTypeNone;
  227. }
  228. #pragma mark 抓图结果
  229. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer snapImagePath:(NSString *)path result:(int)result {
  230. if (result == EE_OK) { //抓图成功
  231. [SVProgressHUD showSuccessWithStatus:TS("Success") duration:2.0];
  232. }else{
  233. [MessageUI ShowErrorInt:result];
  234. }
  235. }
  236. #pragma mark 收到视频宽高比信息
  237. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer width:(int)width htight:(int)height {
  238. }
  239. #pragma mark -鱼眼视频预览相关处理 (非鱼眼设备可以不用考虑下列几个方法)
  240. UIPinchGestureRecognizer *twoFingerPinch;//硬解码捏合手势
  241. #pragma mark 用户自定义信息帧回调,通过这个判断是什么模式在预览
  242. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer Hardandsoft:(int)Hardandsoft Hardmodel:(int)Hardmodel {
  243. if (Hardandsoft == 3 || Hardandsoft == 4 || Hardandsoft == 5) {
  244. //创建鱼眼预览界面
  245. [self createFeye:Hardandsoft Hardmodel:Hardmodel];
  246. }
  247. }
  248. #pragma mark YUV数据回调
  249. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer width:(int)width height:(int)height pYUV:(unsigned char *)pYUV {
  250. [self.feyeControl PushData:width height:height YUVData:pYUV];
  251. }
  252. #pragma mark - 设备时间(鱼眼)
  253. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer DevTime:(NSString *)time {
  254. [self.feyeControl setTimeLabelText:time];
  255. }
  256. #pragma mark 鱼眼软解坐标参数
  257. -(void)centerOffSetX:(MediaplayerControl*)mediaPlayer offSetx:(short)OffSetx offY:(short)OffSetY radius:(short)radius width:(short)width height:(short)height {
  258. [self.feyeControl centerOffSetX:OffSetx offY:OffSetY radius:radius width:width height:height];
  259. }
  260. #pragma mark 鱼眼画面智能分析报警自动旋转画面
  261. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer AnalyzelLength:(int)length site:(int)type Analyzel:(char*)area {
  262. }
  263. #pragma mark - 预览对象初始化
  264. - (void)initDataSource {
  265. channel = [[[DeviceControl getInstance] getSelectChannelArray] firstObject];
  266. mediaPlayer = [[MediaplayerControl alloc] init];
  267. mediaPlayer.devID = channel.deviceMac;//设备序列号
  268. mediaPlayer.channel = channel.channelNumber;//当前通道号
  269. mediaPlayer.stream = 1;//辅码流
  270. mediaPlayer.renderWnd = pVIew;
  271. mediaPlayer.delegate = self;
  272. //初始化对讲工具,这个可以放在对讲开始前初始化
  273. talkControl = [[TalkBackControl alloc] init];
  274. talkControl.deviceMac = mediaPlayer.devID;
  275. talkControl.channel = mediaPlayer.channel;
  276. }
  277. -(FishPlayControl*)feyeControl{
  278. if (feyeControl == nil) {
  279. feyeControl = [[FishPlayControl alloc] init];
  280. }
  281. return feyeControl;
  282. }
  283. #pragma mark - 界面初始化
  284. - (void)createPlayView {
  285. pVIew = [[PlayView alloc] initWithFrame:CGRectMake(0, NavAndStatusHight, ScreenWidth, realPlayViewHeight)];
  286. [self.view addSubview:pVIew];
  287. [pVIew refreshView];
  288. }
  289. - (void)setNaviStyle {
  290. self.view.backgroundColor = [UIColor whiteColor];
  291. self.navigationItem.title = TS("Real_Time_Video");
  292. self.rightBarBtn = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Local_Settings.png"] style:UIBarButtonItemStylePlain target:self action:@selector(pushToDeviceConfigViewController)];
  293. self.navigationItem.rightBarButtonItem = self.rightBarBtn;
  294. self.rightBarBtn.width = 15;
  295. self.leftBarBtn = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"new_back.png"] style:UIBarButtonItemStylePlain target:self action:@selector(popViewController)];
  296. self.navigationItem.leftBarButtonItem = self.leftBarBtn;
  297. }
  298. #pragma mark - 创建工具栏
  299. -(void)createToolView{
  300. if (!toolView) {
  301. toolView = [[PlayFunctionView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ToolViewHeight)];
  302. toolView.Devicedelegate = self;
  303. }
  304. toolView.hidden = NO;
  305. toolView.playMode = REALPLAY_MODE;
  306. toolView.screenVertical = YES;
  307. [toolView showPlayFunctionView];
  308. toolView.frame = CGRectMake(0, NavAndStatusHight+ realPlayViewHeight, ScreenWidth, ToolViewHeight);
  309. [self.view addSubview:toolView];
  310. [toolView setPlayMode:REALPLAY_MODE];
  311. }
  312. -(void)createPlayMenuView {
  313. if (!playMenuView) {
  314. playMenuView = [[PlayMenuView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ToolViewHeight)];
  315. playMenuView.delegate = self;
  316. }
  317. float height = (ScreenHeight - NavHeight - realPlayViewHeight - ToolViewHeight);
  318. playMenuView.frame = CGRectMake(0, NavAndStatusHight+ realPlayViewHeight+ToolViewHeight, ScreenWidth, height);
  319. [self.view addSubview:playMenuView];
  320. }
  321. #pragma mark 初始化鱼眼播放界面
  322. -(void)createFeye:(int)Hardandsoft Hardmodel:(int)Hardmodel{
  323. [self.feyeControl createFeye:Hardandsoft frameSize:pVIew.frame];
  324. GLKViewController *glkVC= [self.feyeControl getFeyeViewController];
  325. [self addChildViewController:glkVC];
  326. [pVIew addSubview:glkVC.view];
  327. [self.feyeControl refreshSoftModel:(int)Hardandsoft model:Hardmodel];
  328. }
  329. ////初始化鱼眼播放界面
  330. //-(void)createFeye:(int)type {
  331. // if (timeLab == nil) {
  332. // timeLab = [[UILabelOutLined alloc] initWithFrame:CGRectMake(ScreenWidth-160 , 0, 150, 30)];
  333. // timeLab.textAlignment = NSTextAlignmentRight;
  334. // [pVIew addSubview:timeLab];
  335. // }
  336. // if (nameLab == nil) {
  337. // nameLab = [[UILabelOutLined alloc] initWithFrame:CGRectMake(10 , 0, 150, 30)];
  338. // nameLab.textAlignment = NSTextAlignmentLeft;
  339. // [pVIew addSubview:nameLab];
  340. // [pVIew insertSubview:nameLab belowSubview:timeLab];
  341. // }
  342. // if (type == 3) {
  343. // if (hardV == nil) {
  344. // hardV = [[HardVRViewController alloc] init];
  345. // [self addChildViewController:hardV];
  346. // hardV.view.hidden = YES;
  347. // [pVIew addSubview:hardV.view];
  348. // }
  349. // [pVIew insertSubview:hardV.view belowSubview:timeLab];
  350. // }
  351. // else if (type == 4 || type == 5) {
  352. // if (softV == nil) {
  353. // softV = [[VRGLViewController alloc] init];
  354. // [self addChildViewController:softV];
  355. // softV.view.hidden = YES;
  356. // [pVIew addSubview:softV.view];
  357. // }
  358. //
  359. // [pVIew insertSubview:softV.view belowSubview:timeLab];
  360. // }
  361. // CGRect rect = pVIew.frame;
  362. // rect.origin.x=0;
  363. // rect.origin.y=0;
  364. // softV.view.frame = rect;
  365. // hardV.view.frame = rect;
  366. //}
  367. #pragma mark - 跳转到设备配置界面
  368. - (void)pushToDeviceConfigViewController {
  369. DeviceConfigViewController *devConfigVC = [[DeviceConfigViewController alloc] initWithNibName:nil bundle:nil];
  370. [self.navigationController pushViewController:devConfigVC animated:YES];
  371. }
  372. #pragma mark - 显示云台控制器
  373. -(void)showPTZControl{
  374. if (ptzView == nil) {
  375. ptzView = [[PTZView alloc] initWithFrame:CGRectMake(0, ScreenHeight-150, ScreenWidth, 150)];
  376. ptzView.PTZdelegate = self;
  377. ptzView.speedDelegate = self;
  378. }
  379. [self.view addSubview:ptzView];
  380. }
  381. #pragma mark 显示对讲画面
  382. -(void)presentTalkView{
  383. if (talkView == nil) {
  384. talkView = [[TalkView alloc]init];
  385. talkView.frame = CGRectMake(0, ScreenHeight - 150 , ScreenWidth, 150);
  386. talkView.delegate = self;
  387. [self.view addSubview:talkView];
  388. [talkView showTheView];
  389. [toolView refreshFunctionView:CONTROL_REALPLAY_TALK result:YES];
  390. }else{
  391. [talkView cannelTheView];
  392. [self closeTalkView];
  393. }
  394. }
  395. #pragma mark - 云台控制按钮的代理 云台控制方法没有回调
  396. //方向控制点击
  397. -(void)controlPTZBtnTouchDownAction:(int)sender{
  398. [mediaPlayer controZStartlPTAction:(PTZ_ControlType)sender];
  399. }
  400. //方向控制抬起
  401. -(void)controlPTZBtnTouchUpInsideAction:(int)sender{
  402. [mediaPlayer controZStopIPTAction:(PTZ_ControlType)sender];
  403. }
  404. //点击控制的按钮(变倍,变焦,光圈)
  405. -(void)controladdSpeedTouchDownAction:(int)sender{
  406. [mediaPlayer controZStartlPTAction:(PTZ_ControlType)sender];
  407. }
  408. //抬起控制的按钮(变倍,变焦,光圈)
  409. -(void)controladdSpeedTouchUpInsideAction:(int)sender{
  410. [mediaPlayer controZStopIPTAction:(PTZ_ControlType)sender];
  411. }
  412. #pragma - mark - 语音对讲按钮代理
  413. - (void)openTalk {
  414. talkControl.handle = mediaPlayer.msgHandle;
  415. [talkControl startTalk];
  416. [toolView refreshFunctionView:CONTROL_REALPLAY_VOICE result:NO];
  417. }
  418. - (void)closeTalk {
  419. talkControl.handle = mediaPlayer.msgHandle;
  420. [talkControl pauseTalk];
  421. [toolView refreshFunctionView:CONTROL_REALPLAY_VOICE result:YES];
  422. }
  423. #pragma mark 隐藏对讲画面
  424. -(void)closeTalkView {
  425. //停止对讲
  426. talkControl.handle = mediaPlayer.msgHandle;
  427. [talkControl closeTalk];
  428. [toolView refreshFunctionView:CONTROL_REALPLAY_TALK result:NO];
  429. [toolView refreshFunctionView:CONTROL_REALPLAY_VOICE result:NO];
  430. talkView = nil;
  431. }
  432. #pragma mark - 跳转到视频回放界面
  433. -(void)presentPlayBackViewController {
  434. PlayBackViewController *playBack = [[PlayBackViewController alloc] init];
  435. [self.navigationController pushViewController:playBack animated:YES];
  436. }
  437. #pragma mark - 返回设备列表界面
  438. - (void)popViewController {
  439. [talkControl closeTalk]; //停止对讲
  440. [mediaPlayer closeSound]; //停止音频
  441. [mediaPlayer stop];
  442. [[DeviceControl getInstance] cleanSelectChannel];
  443. [self.navigationController popViewControllerAnimated:YES];
  444. }
  445. @end