PlayCloudVideoViewController.mm 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. //
  2. // PlayCloudVideoViewController.m
  3. // FunSDKDemo
  4. //
  5. // Created by XM on 2019/1/8.
  6. // Copyright © 2019年 XM. All rights reserved.
  7. //
  8. #import "PlayCloudVideoViewController.h"
  9. #import "PlayView.h"
  10. #import "PlayFunctionView.h"
  11. #import "PlayMenuView.h"
  12. #import "DateSelectView.h"
  13. #import "CloudVideoConfig.h"
  14. #import "MediaPlaybackControl.h"
  15. #import "NSDate+TimeCategory.h"
  16. #import "ProgressBackView.h"
  17. #import "FishPlayControl.h"
  18. #import "Header.h"
  19. @interface PlayCloudVideoViewController () <DateSelectViewDelegate,CloudVideoTimeDelegate,MediaplayerControlDelegate,basePlayFunctionViewDelegate,MediaPlayBackControlDelegate>
  20. {
  21. PlayView *pVIew; //播放画面
  22. PlayFunctionView *toolView; //工具栏
  23. PlayMenuView *playMenuView; //下方功能栏
  24. ChannelObject *channel; //选择播放的通道信息
  25. MediaPlaybackControl *mediaPlayer; //播放媒体工具
  26. DateSelectView *dateView; //时间选择器界面
  27. CloudVideoConfig *videoConfig; //云视频文件管理器
  28. ProgressBackView *pBackView; //时间轴所在的view
  29. FishPlayControl *feyeControl; //鱼眼控制器
  30. }
  31. //导航栏右边的时间按钮
  32. @property (nonatomic, strong) UIBarButtonItem *rightBarBtn;
  33. //导航栏左边的返回按钮
  34. @property (nonatomic, strong) UIBarButtonItem *leftBarBtn;
  35. @end
  36. @implementation PlayCloudVideoViewController
  37. - (void)viewDidLoad {
  38. [super viewDidLoad];
  39. //创建导航栏
  40. [self setNaviStyle];
  41. //创建预览界面
  42. [self createPlayView];
  43. //创建时间轴背景view
  44. [self createProgressBackView];
  45. //创建工具栏界面
  46. [self createToolView];
  47. //创建一个隐藏的时间选择器界面
  48. [self createDateView];
  49. //获取要播放的设备信息
  50. [self initDataSource];
  51. //开始搜索云视频文件
  52. [self startSearchFile];
  53. }
  54. #pragma mark - 开始播放视频
  55. - (void)startSearchFile {
  56. pBackView.date = dateView.date;
  57. [videoConfig searchCloudVideo:dateView.date];
  58. }
  59. #pragma mark - 预览对象初始化
  60. - (void)initDataSource {
  61. channel = [[[DeviceControl getInstance] getSelectChannelArray] firstObject];
  62. mediaPlayer = [[MediaPlaybackControl alloc] init];
  63. mediaPlayer.devID = channel.deviceMac;//设备序列号
  64. mediaPlayer.channel = channel.channelNumber;//当前通道号
  65. mediaPlayer.stream = 1;//辅码流
  66. mediaPlayer.renderWnd = pVIew;
  67. mediaPlayer.delegate = self;
  68. mediaPlayer.playbackDelegate = self;
  69. videoConfig = [[CloudVideoConfig alloc] init];
  70. videoConfig.timeDelegate = self;
  71. }
  72. -(FishPlayControl*)feyeControl{
  73. if (feyeControl == nil) {
  74. feyeControl = [[FishPlayControl alloc] init];
  75. }
  76. return feyeControl;
  77. }
  78. #pragma mark - 界面初始化
  79. - (void)createPlayView {
  80. pVIew = [[PlayView alloc] initWithFrame:CGRectMake(0, NavAndStatusHight, ScreenWidth, realPlayViewHeight)];
  81. [self.view addSubview:pVIew];
  82. [pVIew refreshView];
  83. }
  84. - (void)setNaviStyle {
  85. self.view.backgroundColor = [UIColor whiteColor];
  86. self.navigationItem.title = TS("Cloud_video");
  87. self.rightBarBtn = [[UIBarButtonItem alloc] initWithImage:nil style:UIBarButtonItemStylePlain target:self action:@selector(pushToNextViewController)];
  88. self.navigationItem.rightBarButtonItem = self.rightBarBtn;
  89. self.rightBarBtn.width = 15;
  90. [self setBtnRightTitle:[NSDate date]];
  91. self.leftBarBtn = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"new_back.png"] style:UIBarButtonItemStylePlain target:self action:@selector(popViewController)];
  92. self.navigationItem.leftBarButtonItem = self.leftBarBtn;
  93. }
  94. //设置当前选择的时间
  95. -(void)setBtnRightTitle:(NSDate*)selectDate
  96. {
  97. NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
  98. [dateFormat setDateFormat:@"MM-dd"];
  99. self.rightBarBtn.title = [dateFormat stringFromDate:selectDate];
  100. }
  101. #pragma mark - 创建工具栏
  102. -(void)createToolView{
  103. if (!toolView) {
  104. toolView = [[PlayFunctionView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ToolViewHeight)];
  105. toolView.Devicedelegate = self;
  106. }
  107. toolView.hidden = NO;
  108. toolView.playMode = REALPLAY_MODE;
  109. toolView.screenVertical = YES;
  110. [toolView showPlayFunctionView];
  111. toolView.frame = CGRectMake(0, NavAndStatusHight+ realPlayViewHeight, ScreenWidth, ToolViewHeight);
  112. [self.view addSubview:toolView];
  113. [toolView setPlayMode:PLAYBACK_MODE];
  114. }
  115. #pragma mark - 创建一个隐藏的时间选择器界面
  116. -(void)createDateView
  117. {
  118. dateView = [[DateSelectView alloc] initWithFrame:CGRectMake(0, NavHeight , ScreenWidth, ScreenHeight - NavHeight)];
  119. dateView.delegate = self;
  120. [self.view addSubview:dateView];
  121. }
  122. #pragma mark - 创建时间轴背景view
  123. -(void)createProgressBackView
  124. {
  125. pBackView = [[ProgressBackView alloc] initWithFrame:CGRectMake(0, NavHeight + realPlayViewHeight + 60, ScreenWidth, ScreenHeight - NavHeight - realPlayViewHeight - NavHeight)];
  126. [self.view addSubview:pBackView];
  127. //滑动时间轴之后的回调
  128. __weak typeof(self) weakSelf = self;
  129. pBackView.TouchSeektoTime = ^ (NSInteger _add){
  130. [weakSelf touchAndSeekToTime:_add];
  131. };
  132. }
  133. #pragma mark - buttonEvent
  134. #pragma mark 工具栏点击 - 暂停、音频、速度、抓图、录像
  135. - (void)basePlayFunctionViewBtnClickWithBtn:(int)tag {
  136. if ((CONTROL_TYPE)tag == CONTROL_REALPLAY_CloseChannle) {
  137. //点击暂停按钮,暂停预览
  138. if (mediaPlayer.status == MediaPlayerStatusPlaying) {
  139. [mediaPlayer pause];
  140. }else if (mediaPlayer.status == MediaPlayerStatusPause) {
  141. [mediaPlayer resumue];
  142. }
  143. }if ((CONTROL_TYPE)tag == CONTROL_REALPLAY_VOICE) {
  144. //点击音频按钮,打开音频
  145. if (mediaPlayer.voice == MediaVoiceTypeNone) {
  146. //音频没有回调,所以直接在这里刷新界面
  147. [self openSound];
  148. }else if (mediaPlayer.voice == MediaVoiceTypeVoice){
  149. [self closeSound];
  150. }
  151. }if ((CONTROL_TYPE)tag == CONTROL_TYPE_SPEED) {
  152. //点击速度切换按钮,1倍速度和2倍速度之间切换
  153. if(mediaPlayer.speed == MediaSpeedStateNormal){
  154. [mediaPlayer setPlaySpeed:1];
  155. }else{
  156. [mediaPlayer setPlaySpeed:0];
  157. }
  158. }if ((CONTROL_TYPE)tag == CONTROL_REALPLAY_SNAP) {
  159. //开始抓图
  160. [mediaPlayer snapImage];
  161. }if ((CONTROL_TYPE)tag == CONTROL_REALPLAY_VIDEO) {
  162. //开始和停止录像
  163. if (mediaPlayer.record == MediaRecordTypeNone) {
  164. [mediaPlayer startRecord];
  165. }else if (mediaPlayer.record == MediaRecordTypeRecording){
  166. [mediaPlayer stopRecord];
  167. }
  168. }
  169. }
  170. #pragma mark 停止播放音频
  171. - (void)closeSound {
  172. if (mediaPlayer.voice == MediaVoiceTypeVoice){
  173. [mediaPlayer closeSound];
  174. mediaPlayer.voice = MediaVoiceTypeNone;
  175. [toolView refreshFunctionView:CONTROL_REALPLAY_VOICE result:NO];
  176. }
  177. }
  178. #pragma mark 开始播放音频
  179. - (void)openSound {
  180. if (mediaPlayer.voice == MediaVoiceTypeNone){
  181. [mediaPlayer openSound:100];
  182. mediaPlayer.voice = MediaVoiceTypeVoice;
  183. [toolView refreshFunctionView:CONTROL_REALPLAY_VOICE result:YES];
  184. }
  185. }
  186. #pragma mark - 拖动时间轴切换播放时间,并且刷新播放状态
  187. -(void)touchAndSeekToTime:(NSInteger)addTime
  188. {
  189. pBackView.ifSliding = NO;
  190. [pVIew playViewBufferIng];
  191. //1、停止播放
  192. [mediaPlayer stop];
  193. //2、重新开始播放 addTime单位是秒
  194. int hour = (int)addTime/60/60;
  195. int minute = (int)(addTime/60)%60;
  196. int second = (int)addTime%60;
  197. int year = [NSDate getYearFormDate:dateView.date];
  198. int month = [NSDate getMonthFormDate:dateView.date];
  199. int day = [NSDate getDayFormDate:dateView.date];
  200. NSString *dateString = [NSString stringWithFormat:@"%04d-%0d-%02d %02d:%02d:%02d",year,month,day,hour,minute,second];
  201. NSDate *date = [NSDate dateFromString:dateString format:TimeFormatter];
  202. [mediaPlayer startPlayCloudVideo:date];
  203. }
  204. #pragma mark - 跳转到设备下一级界面
  205. - (void)pushToNextViewController {
  206. if (dateView && dateView.hidden == YES) {
  207. [dateView dateSelectVIewShow];
  208. [self.view bringSubviewToFront:dateView];
  209. }
  210. }
  211. #pragma mark - 选择日期之后的接口方法
  212. -(void)dateSelectedAction:(BOOL)Result
  213. {
  214. if (Result == NO) {
  215. return;
  216. }
  217. //重新选择日期之后,开始搜索和播放的流程
  218. if ([NSDate checkDate:pBackView.date WithDate:dateView.date]) {
  219. //判断是否为同一天
  220. return;
  221. }
  222. [self setBtnRightTitle:dateView.date];
  223. //停止当前回放
  224. [mediaPlayer stopRecord];
  225. [self closeSound];
  226. [mediaPlayer refresh];
  227. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  228. [mediaPlayer stop];
  229. [self startSearchFile];
  230. });
  231. }
  232. #pragma mark - 返回设备列表界面
  233. - (void)popViewController {
  234. [mediaPlayer stopRecord];
  235. [self closeSound];
  236. [mediaPlayer stop];
  237. [self.navigationController popViewControllerAnimated:YES];
  238. }
  239. #pragma mark - funsdk回调
  240. #pragma mark 云视频查询回调
  241. - (void)getCloudVideoTimeResult:(NSInteger)result {
  242. if (result >= 0) {
  243. [pBackView refreshProgressWithSearchResult:[videoConfig getVideoTimeArray]];
  244. [pVIew playViewBufferIng];
  245. //设置云视频时间并开始播放
  246. int hour = 0;
  247. int minute = 0;
  248. int second = 0;
  249. int year = [NSDate getYearFormDate:dateView.date];
  250. int month = [NSDate getMonthFormDate:dateView.date];
  251. int day = [NSDate getDayFormDate:dateView.date];
  252. NSString *dateString = [NSString stringWithFormat:@"%04d-%0d-%02d %02d:%02d:%02d",year,month,day,hour,minute,second];
  253. NSDate *date = [NSDate dateFromString:dateString format:TimeFormatter];
  254. [mediaPlayer startPlayCloudVideo:date];
  255. }
  256. else{
  257. [SVProgressHUD showErrorWithStatus:TS("Video_Not_Found")];
  258. }
  259. }
  260. #pragma mark 通过搜索录像返回的时间来刷新时间轴
  261. - (void)addTimeDelegate:(NSInteger)add{
  262. if (pBackView != nil) {
  263. [pBackView refreshWithAddTime:add];
  264. }
  265. }
  266. #pragma mark 录像回放时间帧回调,用来刷新label时间显示和时间轴
  267. -(void)mediaPlayer:(MediaplayerControl *)mediaPlayer timeInfo:(int)timeinfo{
  268. if (pBackView != nil && pBackView.ifSliding == NO) {
  269. [pBackView refreshTimeAndProgress:timeinfo];
  270. }
  271. }
  272. #pragma mark - 开始预览结果回调
  273. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer startResult:(int)result DSSResult:(int)dssResult {
  274. if (result < 0) {
  275. [MessageUI ShowErrorInt:result];
  276. }else {
  277. if (dssResult == 3) { //DSS 打开视频成功
  278. }else if (dssResult == 5){//RPS打开预览成功
  279. }
  280. [pVIew playViewBufferIng];
  281. }
  282. }
  283. #pragma mark - 视频缓冲中
  284. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer buffering:(BOOL)isBuffering {
  285. if (isBuffering == YES) {//开始缓冲
  286. [pVIew playViewBufferIng];
  287. }else{//缓冲完成
  288. [pVIew playViewBufferEnd];
  289. }
  290. }
  291. #pragma mark - 录像开始结果
  292. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer startRecordResult:(int)result path:(NSString*)path {
  293. if (result == EE_OK) { //开始录像成功
  294. mediaPlayer.record = MediaRecordTypeRecording;
  295. [toolView refreshFunctionView:CONTROL_REALPLAY_VIDEO result:YES];
  296. }else{
  297. [MessageUI ShowErrorInt:result];
  298. [toolView refreshFunctionView:CONTROL_REALPLAY_VIDEO result:NO];
  299. }
  300. }
  301. #pragma mark - 录像结束结果
  302. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer stopRecordResult:(int)result path:(NSString*)path {
  303. if (result == EE_OK) { //结束录像成功
  304. [SVProgressHUD showSuccessWithStatus:TS("Success") duration:2.0];
  305. }else{
  306. [MessageUI ShowErrorInt:result];
  307. }
  308. [toolView refreshFunctionView:CONTROL_REALPLAY_VIDEO result:NO];
  309. mediaPlayer.record = MediaRecordTypeNone;
  310. }
  311. #pragma mark 抓图结果
  312. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer snapImagePath:(NSString *)path result:(int)result {
  313. if (result == EE_OK) { //抓图成功
  314. [SVProgressHUD showSuccessWithStatus:TS("Success") duration:2.0];
  315. }else{
  316. [MessageUI ShowErrorInt:result];
  317. }
  318. }
  319. #pragma mark 设置速度结果
  320. -(void)setPlaySpeedResult:(int)result{
  321. if (result >= 0) {
  322. if(result == 0){
  323. mediaPlayer.speed = MediaSpeedStateNormal;
  324. [toolView refreshFunctionView:CONTROL_TYPE_SPEED result:NO];
  325. }else{
  326. mediaPlayer.speed = MediaSpeedStateAdd;
  327. [toolView refreshFunctionView:CONTROL_TYPE_SPEED result:YES];
  328. }
  329. }else{
  330. [MessageUI ShowErrorInt:result];
  331. }
  332. }
  333. #pragma mark 用户自定义信息帧回调,通过这个判断是什么模式在预览
  334. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer Hardandsoft:(int)Hardandsoft Hardmodel:(int)Hardmodel {
  335. if (Hardandsoft == 3 || Hardandsoft == 4 || Hardandsoft == 5) {
  336. //创建鱼眼预览界面
  337. [self createFeye:Hardandsoft Hardmodel:Hardmodel];
  338. }
  339. }
  340. #pragma mark YUV数据回调
  341. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer width:(int)width height:(int)height pYUV:(unsigned char *)pYUV {
  342. [self.feyeControl PushData:width height:height YUVData:pYUV];
  343. }
  344. #pragma mark - 设备时间(鱼眼)
  345. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer DevTime:(NSString *)time {
  346. [self.feyeControl setTimeLabelText:time];
  347. }
  348. #pragma mark 鱼眼软解坐标参数
  349. -(void)centerOffSetX:(MediaplayerControl*)mediaPlayer offSetx:(short)OffSetx offY:(short)OffSetY radius:(short)radius width:(short)width height:(short)height {
  350. [self.feyeControl centerOffSetX:OffSetx offY:OffSetY radius:radius width:width height:height];
  351. }
  352. #pragma mark 鱼眼画面智能分析报警自动旋转画面
  353. -(void)mediaPlayer:(MediaplayerControl*)mediaPlayer AnalyzelLength:(int)length site:(int)type Analyzel:(char*)area {
  354. }
  355. #pragma mark 初始化鱼眼播放界面
  356. -(void)createFeye:(int)Hardandsoft Hardmodel:(int)Hardmodel{
  357. [self.feyeControl createFeye:Hardandsoft frameSize:pVIew.frame];
  358. GLKViewController *glkVC= [self.feyeControl getFeyeViewController];
  359. [self addChildViewController:glkVC];
  360. [pVIew addSubview:glkVC.view];
  361. [self.feyeControl refreshSoftModel:(int)Hardandsoft model:Hardmodel];
  362. }
  363. @end