| | |
| | | #import "UIViewController+EZBackPop.h" |
| | | #import "DDCollectionViewFlowLayout.h" |
| | | #import "MJRefresh.h" |
| | | #import "EZRecordDownloader.h" |
| | | #import "EZDeviceRecordDownloadTask.h" |
| | | #import "EZCloudRecordDownloadTask.h" |
| | | #import <EZOpenSDKFramework/EZRecordDownloader.h> |
| | | #import <EZOpenSDKFramework/EZDeviceRecordDownloadTask.h> |
| | | #import <EZOpenSDKFramework/EZCloudRecordDownloadTask.h> |
| | | #import "EZRecordCell.h" |
| | | #import "DDKit.h" |
| | | #import "EZCloudRecordFile.h" |
| | | #import "EZDeviceRecordFile.h" |
| | | #import "EZPlayer.h" |
| | | #import <EZOpenSDKFramework/EZCloudRecordFile.h> |
| | | #import <EZOpenSDKFramework/EZDeviceRecordFile.h> |
| | | #import <EZOpenSDKFramework/EZPlayer.h> |
| | | #import "HIKLoadView.h" |
| | | #import "Masonry.h" |
| | | #import "EZCameraInfo.h" |
| | | #import <EZOpenSDKFramework/EZCameraInfo.h> |
| | | #import "MBProgressHUD.h" |
| | | #import "Toast+UIView.h" |
| | | #import "EZCustomTableView.h" |
| | | #import "EZStreamPlayer.h" |
| | | #import <EZOpenSDKFramework/EZStreamPlayer.h> |
| | | #import <Photos/Photos.h> |
| | | #import "FCFileManager.h" |
| | | #import <EZOpenSDKFramework/EZVideoTransformer.h> |
| | | |
| | | |
| | | @interface EZPlaybackViewController ()<DDCollectionViewDelegateFlowLayout, UICollectionViewDataSource,EZPlayerDelegate, UIAlertViewDelegate, EZRecordCellDelegate, EZCustomTableViewDelegate,EZStreamPlayerDelegate> |
| | | { |
| | | BOOL _isOpenSound; |
| | | BOOL _isPlaying; |
| | | BOOL _landscape; // 是否旋转 |
| | | |
| | | NSTimeInterval _playSeconds; //播放秒数 |
| | | NSTimeInterval _duringSeconds; //录像时长 |
| | |
| | | NSArray *sdCardRate; |
| | | NSArray *cloudRateStr; |
| | | NSArray *sdCardRateStr; |
| | | |
| | | // BOOL _isDoBack; |
| | | |
| | | // BOOL _isDoBack; |
| | | } |
| | | |
| | | @property (nonatomic, strong) NSIndexPath *selectedIndexPath; |
| | |
| | | @property (nonatomic, strong) HIKLoadView *loadingView; |
| | | @property (nonatomic) BOOL isSelectedDevice; |
| | | @property (nonatomic, weak) IBOutlet UIView *playerView; |
| | | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *playViewWHScale; |
| | | @property (nonatomic, weak) IBOutlet UILabel *largeTitleLabel; |
| | | @property (nonatomic, weak) IBOutlet UIDatePicker *datePicker; |
| | | @property (nonatomic, weak) IBOutlet UITextField *dateTextField; |
| | |
| | | [EZOPENSDK releasePlayer:_player]; |
| | | } |
| | | |
| | | - (void)viewWillAppear:(BOOL)animated |
| | | { |
| | | [super viewWillAppear:animated]; |
| | | self.navigationController.navigationBar.hidden = NO;//2021-02-01 |
| | | |
| | | } |
| | | |
| | | - (void)viewDidLoad { |
| | | [super viewDidLoad]; |
| | | // Do any additional setup after loading the view. |
| | | self.isAutorotate = YES; |
| | | self.largeTitleLabel.text = self.deviceInfo.deviceName; |
| | | self.largeTitleLabel.hidden = YES; |
| | | _landscape = NO; |
| | | |
| | | if(!_records) |
| | | _records = [NSMutableArray new]; |
| | |
| | | |
| | | [self.duringSlider setThumbImage:[UIImage imageNamed:@"slider"] forState:UIControlStateNormal]; |
| | | [self.duringSlider setThumbImage:[UIImage imageNamed:@"slider_sel"] forState:UIControlStateHighlighted]; |
| | | |
| | | |
| | | self.cloudButton.selected = YES; |
| | | self.largeBackButton.hidden = YES; |
| | | |
| | |
| | | [self.dateButton setTitle:[dateFormatter stringFromDate:self.datePicker.date] forState:UIControlStateNormal]; |
| | | dateFormatter.dateFormat = @"MM-dd △"; |
| | | [self.dateButton setTitle:[dateFormatter stringFromDate:self.datePicker.date] forState:UIControlStateSelected]; |
| | | |
| | | |
| | | _isShowToolbox = YES; |
| | | |
| | | cloudRate = @[@(EZOPENSDK_PLAY_RATE_1), |
| | |
| | | |
| | | cloudRateStr = @[@"x1",@"x4",@"x8",@"x16",@"x32"]; |
| | | sdCardRateStr = @[@"x1",@"x4",@"x8",@"x16"]; |
| | | |
| | | //2021-07-21 隐藏streamPlayBtn和rateBtn |
| | | [self.streamPlayBtn setHidden:YES]; |
| | | [self.rateBtn setHidden:YES]; |
| | | |
| | | } |
| | | |
| | | - (void)viewWillDisappear:(BOOL)animated { |
| | |
| | | } |
| | | |
| | | /* |
| | | #pragma mark - Navigation |
| | | |
| | | // In a storyboard-based application, you will often want to do a little preparation before navigation |
| | | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { |
| | | // Get the new view controller using [segue destinationViewController]. |
| | | // Pass the selected object to the new view controller. |
| | | } |
| | | */ |
| | | #pragma mark - Navigation |
| | | |
| | | // In a storyboard-based application, you will often want to do a little preparation before navigation |
| | | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { |
| | | // Get the new view controller using [segue destinationViewController]. |
| | | // Pass the selected object to the new view controller. |
| | | } |
| | | */ |
| | | |
| | | - (UIInterfaceOrientationMask)supportedInterfaceOrientations |
| | | { |
| | | return UIInterfaceOrientationMaskAllButUpsideDown; |
| | | if (@available(iOS 16.0, *)) { |
| | | if (_landscape) { |
| | | //横屏 |
| | | return UIInterfaceOrientationMaskLandscape; |
| | | } else { |
| | | //竖屏 |
| | | return UIInterfaceOrientationMaskPortrait; |
| | | } |
| | | } else { |
| | | return UIInterfaceOrientationMaskAllButUpsideDown; |
| | | } |
| | | } |
| | | |
| | | - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation |
| | |
| | | self.largeButton.hidden = NO; |
| | | self.voiceButton.hidden = NO; |
| | | self.playButton.hidden = NO; |
| | | [self.playerView setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| | | [NSLayoutConstraint deactivateConstraints:@[self.playViewWHScale]]; |
| | | self.playViewWHScale = [NSLayoutConstraint constraintWithItem:self.playerView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.playerView attribute:NSLayoutAttributeHeight multiplier:16/9. constant:0]; |
| | | [NSLayoutConstraint activateConstraints:@[self.playViewWHScale]]; |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [self.playerView layoutIfNeeded]; |
| | | }); |
| | | if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || |
| | | toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) |
| | | { |
| | |
| | | self.playbackList.hidden = YES; |
| | | self.largeBackButton.hidden = NO; |
| | | self.navigationController.navigationBarHidden = YES; |
| | | |
| | | CGFloat tureScreenW = HDLEZ_APP_SCREEN_WIDTH > HDLEZ_APP_SCREEN_HEIGHT ? HDLEZ_APP_SCREEN_HEIGHT : HDLEZ_APP_SCREEN_WIDTH; |
| | | CGFloat tureScreenH = HDLEZ_APP_SCREEN_WIDTH < HDLEZ_APP_SCREEN_HEIGHT ? HDLEZ_APP_SCREEN_HEIGHT : HDLEZ_APP_SCREEN_WIDTH; |
| | | |
| | | |
| | | [self.playerView setTranslatesAutoresizingMaskIntoConstraints:NO]; |
| | | [NSLayoutConstraint deactivateConstraints:@[self.playViewWHScale]]; |
| | | self.playViewWHScale = [NSLayoutConstraint constraintWithItem:self.playerView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.playerView attribute:NSLayoutAttributeHeight multiplier:tureScreenH/(tureScreenW) constant:0]; |
| | | [NSLayoutConstraint activateConstraints:@[self.playViewWHScale]]; |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [self.playerView layoutIfNeeded]; |
| | | }); |
| | | } |
| | | } |
| | | |
| | |
| | | cell.deviceSerial = _cameraInfo.deviceSerial; |
| | | cell.isSelectedDevice = _isSelectedDevice; |
| | | cell.delegate = self; |
| | | //2021-07-21 隐藏下载按钮 |
| | | [cell.downloadBtn setHidden:NO]; |
| | | |
| | | if(_isSelectedDevice) |
| | | { |
| | |
| | | |
| | | [self invalidateTimer]; |
| | | |
| | | // [_player stopPlayback]; |
| | | // [_player stopPlayback]; |
| | | |
| | | if(_isSelectedDevice) |
| | | { |
| | |
| | | #pragma mark - ValidateCode Methods |
| | | |
| | | - (void)repeatDelay{ |
| | | |
| | | |
| | | self.selectedCell = NO; |
| | | } |
| | | |
| | |
| | | |
| | | EZDeviceRecordFile *deviceFile = (EZDeviceRecordFile *)recordFile; |
| | | |
| | | NSString *path = [NSString stringWithFormat:@"%@/ezopensdk/DeviceRecord/%@.ps",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject], [dateformatter stringFromDate:deviceFile.startTime]]; |
| | | NSString *path = [NSString stringWithFormat:@"%@/ezopensdk/DeviceRecord/%@.ps",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], [dateformatter stringFromDate:deviceFile.startTime]]; |
| | | NSLog(@"path: %@ ", path); |
| | | [self startDeviceRecordDownload:path deviceFile:deviceFile]; |
| | | __weak __typeof(self)weakSelf = self; |
| | | [self authPhotoLibraries:^(BOOL isAblity) { |
| | | if (isAblity) { |
| | | [weakSelf startDeviceRecordDownload:path deviceFile:deviceFile]; |
| | | } else { |
| | | [weakSelf guideUserOpenAuth]; |
| | | } |
| | | }]; |
| | | } |
| | | else { |
| | | |
| | |
| | | verifyCode:self.verifyCode |
| | | savePath:path |
| | | completion:^(EZDeviceRecordDownloadTask * _Nonnull task) { |
| | | |
| | | |
| | | //设置回调函数 |
| | | __weak typeof(task) weakTask = task; |
| | | [task setDownloadCallBackWithFinshed:^(EZRecordDownloaderStatus statusCode) { |
| | |
| | | NSLog(@"statuCode:%ld", (long)statusCode); |
| | | |
| | | switch (statusCode) { |
| | | case EZRecordDownloaderStatusFinish: |
| | | |
| | | [self.navigationController.view makeToast:[NSString stringWithFormat:@"SDD Task:%lu-下载成功", (unsigned long)strongTask.taskID]]; |
| | | |
| | | case EZRecordDownloaderStatusFinish:{ |
| | | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ |
| | | NSLog(@"#########开始保存视频!!!!%@", path); |
| | | |
| | | NSDateFormatter *dateformatter = [[NSDateFormatter alloc] init]; |
| | | dateformatter.dateFormat = @"yyyyMMddHHmmss"; |
| | | |
| | | NSString *mp4Path = [NSString stringWithFormat:@"%@/ezopensdk/DeviceRecord/%@.mp4", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], [dateformatter stringFromDate:deviceFile.startTime]]; |
| | | [self videoFormatConvertAndSave2Album:path mp4Path:mp4Path]; |
| | | }); |
| | | } |
| | | break; |
| | | case EZRecordDownloaderStatusMoreToken: |
| | | |
| | |
| | | }]; |
| | | } |
| | | |
| | | /** 如果需要把回放视频保存到相册,一定要先把.ps文件转成.mp4文件 |
| | | 注意:下载录像过程中因为网络原因导致.ps文件未下载完,也可以调用此方法将已下载的录像片段解码成.mp4文件。 |
| | | */ |
| | | - (void)videoFormatConvertAndSave2Album:(NSString *)psPath mp4Path:(NSString *)mp4Path { |
| | | [FCFileManager createFileAtPath:mp4Path overwrite:YES]; |
| | | __weak typeof(self) weakSelf = self; |
| | | [EZVideoTransformer videoTransFormerPSPath:psPath toPath:mp4Path type:EZVideoTransformerTypeMP4 withKey:_verifyCode succBlock:^{ |
| | | NSLog(@"转换成功"); |
| | | // 将.mp4文件保存到相册 |
| | | PHPhotoLibrary *photoLibrary = [PHPhotoLibrary sharedPhotoLibrary]; |
| | | [photoLibrary performChanges:^{ |
| | | [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:[NSURL fileURLWithPath:mp4Path]]; |
| | | } completionHandler:^(BOOL success, NSError * _Nullable error) { |
| | | if (success) { |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [weakSelf.navigationController.view makeToast:HDLEZLocallizedString(@"device_save_gallery")]; |
| | | }); |
| | | NSLog(@"########保存成功!!!"); |
| | | // 下载完成后删除.ps和.mp4文件 |
| | | [FCFileManager removeItemAtPath:psPath]; |
| | | [FCFileManager removeItemAtPath:mp4Path]; |
| | | } else { |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [weakSelf.navigationController.view makeToast:HDLEZLocallizedString(@"device_save_gallery_failure")]; |
| | | }); |
| | | } |
| | | }]; |
| | | } processBlock:^(int rate) { |
| | | // 转换进度 |
| | | } failBlock:^(int errCode) { |
| | | NSLog(@"转换失败"); |
| | | }]; |
| | | } |
| | | |
| | | - (void) startCloudRecordDownload:(NSString*)path cloudFile:(EZCloudRecordFile *)cloudFile { |
| | | |
| | | EZCloudRecordDownloadTask *task = [[EZCloudRecordDownloadTask alloc] initTaskWithID:_selectedIndexPath.row cloudRecordFile:cloudFile verifyCode:self.verifyCode savePath:path]; |
| | |
| | | NSLog(@"statuCode:%ld", (long)statusCode); |
| | | |
| | | switch (statusCode) { |
| | | case EZRecordDownloaderStatusFinish: |
| | | |
| | | [self.navigationController.view makeToast:[NSString stringWithFormat:@"CD Task:%lu-下载成功", (unsigned long)strongTask.taskID]]; |
| | | case EZRecordDownloaderStatusFinish: { |
| | | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ |
| | | NSLog(@"#########开始保存视频!!!!%@", path); |
| | | |
| | | NSDateFormatter *dateformatter = [[NSDateFormatter alloc] init]; |
| | | dateformatter.dateFormat = @"yyyyMMddHHmmss"; |
| | | |
| | | NSString *mp4Path = [NSString stringWithFormat:@"%@/ezopensdk/DeviceRecord/%@.mp4", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], [dateformatter stringFromDate:cloudFile.startTime]]; |
| | | [self videoFormatConvertAndSave2Album:path mp4Path:mp4Path]; |
| | | }); |
| | | } |
| | | |
| | | break; |
| | | case EZRecordDownloaderStatusMoreToken: |
| | |
| | | [self.navigationController.view makeToast:[NSString stringWithFormat:@"CD Task:%lu-任务已在下载中", (unsigned long)task.taskID]]; |
| | | } |
| | | } |
| | | } |
| | | |
| | | #pragma mark 视频保存完毕的回调 |
| | | - (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{ |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | if (error) { |
| | | [self.navigationController.view makeToast:HDLEZLocallizedString(@"device_save_gallery_failure")]; |
| | | NSLog(@"保存视频过程中发生错误,错误信息:%@",error.localizedDescription); |
| | | NSLog(@"保存视频过程中发生错误,错误信息:%@",error); |
| | | }else{ |
| | | [self.navigationController.view makeToast:HDLEZLocallizedString(@"device_save_gallery")]; |
| | | NSLog(@"视频保存成功."); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /*访问相册权限 |
| | | */ |
| | | -(void)authPhotoLibraries:(void(^)(BOOL isAblity))result { |
| | | PHAuthorizationStatus author =[PHPhotoLibrary authorizationStatus]; |
| | | if (author == PHAuthorizationStatusRestricted || author ==PHAuthorizationStatusDenied){ |
| | | if (result) { |
| | | result(NO); |
| | | } |
| | | } else if (author == PHAuthorizationStatusNotDetermined) { // 首次授权 |
| | | dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); |
| | | dispatch_async(queue, ^{ |
| | | [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) { |
| | | if (status != PHAuthorizationStatusAuthorized) { |
| | | if (result) { |
| | | result(NO); |
| | | } |
| | | } else { |
| | | if (result) { |
| | | result(YES); |
| | | } |
| | | } |
| | | }]; |
| | | }); |
| | | } else { |
| | | if (result) { |
| | | result(YES); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /*引导用户授权获取图片 |
| | | */ |
| | | - (void)guideUserOpenAuth{ |
| | | UIAlertController *alertC = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"hdl_ez_download_tip", @"温馨提示") message:NSLocalizedString(@"hdl_ez_download_auth", @"请打开访问权限") preferredStyle:(UIAlertControllerStyleAlert)]; |
| | | UIAlertAction *alertA = [UIAlertAction actionWithTitle:NSLocalizedString(@"hdl_ez_download_cancle", @"取消") style:(UIAlertActionStyleDefault) handler:nil]; |
| | | UIAlertAction *act = [UIAlertAction actionWithTitle:NSLocalizedString(@"hdl_ez_download_toSet", @"去设置") style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { |
| | | // 引导用户设置 |
| | | NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; |
| | | |
| | | if ([[UIApplication sharedApplication] canOpenURL:url]) { |
| | | |
| | | [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil]; |
| | | } |
| | | }]; |
| | | [alertC addAction:alertA]; |
| | | [alertC addAction:act]; |
| | | [self presentViewController:alertC animated:YES completion:nil]; |
| | | } |
| | | |
| | | #pragma mark - PlayerDelegate Methods |
| | |
| | | |
| | | NSLog(@"GetStreamFetchType:%d", [self.player getStreamFetchType]); |
| | | |
| | | [self showStreamFetchType]; |
| | | // [self showStreamFetchType]; |
| | | } |
| | | else if (messageCode == PLAYER_PLAYBACK_STOP) |
| | | { |
| | |
| | | } |
| | | |
| | | - (void) invalidateTimer { |
| | | |
| | | |
| | | if(self.playbackTimer) |
| | | { |
| | | [self.playbackTimer invalidate]; |
| | |
| | | |
| | | - (IBAction)hiddenPlayerToolbox:(id)sender |
| | | { |
| | | // [UIView animateWithDuration:0.3 |
| | | // animations:^{ |
| | | // self.playerToolbox.alpha = 0.0f; |
| | | // } |
| | | // completion:^(BOOL finished) { |
| | | // _isShowToolbox = NO; |
| | | // }]; |
| | | // [UIView animateWithDuration:0.3 |
| | | // animations:^{ |
| | | // self.playerToolbox.alpha = 0.0f; |
| | | // } |
| | | // completion:^(BOOL finished) { |
| | | // _isShowToolbox = NO; |
| | | // }]; |
| | | } |
| | | |
| | | #pragma mark - MJRefresh Methods |
| | |
| | | [self.operation cancel]; |
| | | [self.playbackList.header endRefreshing]; |
| | | __weak __typeof(self) weakSelf = self; |
| | | |
| | | |
| | | self.playbackList.header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ |
| | | weakSelf.noVideoImageView.hidden = YES; |
| | | weakSelf.noVideoLabel.hidden = YES; |
| | |
| | | beginTime:weakSelf.beginTime |
| | | endTime:weakSelf.endTime |
| | | completion:^(NSArray *deviceRecords, NSError *error) { |
| | | NSLog(@"deviceRecords is %@, error is %@", deviceRecords, error); |
| | | if (!error) |
| | | { |
| | | [weakSelf.records removeAllObjects]; |
| | | if(deviceRecords.count == 0) |
| | | { |
| | | weakSelf.noVideoLabel.hidden = NO; |
| | | weakSelf.noVideoImageView.hidden = NO; |
| | | [weakSelf.playbackList reloadData]; |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | return; |
| | | } |
| | | if (deviceRecords.count > 0) |
| | | { |
| | | [weakSelf.records addObjectsFromArray:deviceRecords]; |
| | | [weakSelf.playbackList reloadData]; |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | [weakSelf doPlayback]; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | [UIView dd_showMessage:[NSString stringWithFormat:@"error code is %d",(int) error.code] onParentView:self.view]; |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | [weakSelf.records removeAllObjects]; |
| | | [weakSelf.playbackList reloadData]; |
| | | } |
| | | }]; |
| | | NSLog(@"deviceRecords is %@, error is %@", deviceRecords, error); |
| | | if (!error) |
| | | { |
| | | [weakSelf.records removeAllObjects]; |
| | | if(deviceRecords.count == 0) |
| | | { |
| | | weakSelf.noVideoLabel.hidden = NO; |
| | | weakSelf.noVideoImageView.hidden = NO; |
| | | [weakSelf.playbackList reloadData]; |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | return; |
| | | } |
| | | if (deviceRecords.count > 0) |
| | | { |
| | | [weakSelf.records addObjectsFromArray:deviceRecords]; |
| | | [weakSelf.playbackList reloadData]; |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | [weakSelf doPlayback]; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | NSString *mes = [NSString stringWithFormat:@"%@(%ld)",NSLocalizedString(@"setting_opration_fail", @"操作失败"), (long)error.code]; |
| | | [UIView dd_showMessage:mes onParentView:self.view]; |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | [weakSelf.records removeAllObjects]; |
| | | [weakSelf.playbackList reloadData]; |
| | | } |
| | | }]; |
| | | } |
| | | else |
| | | { |
| | |
| | | beginTime:weakSelf.beginTime |
| | | endTime:weakSelf.endTime |
| | | completion:^(NSArray *cloudRecords, NSError *error) { |
| | | |
| | | NSLog(@"cloudRecords is %@, error is %@", cloudRecords, error); |
| | | if (error) |
| | | { |
| | | if (error.code > 0) { |
| | | [UIView dd_showMessage:[NSString stringWithFormat:@"error code is %d",(int) error.code] onParentView:self.view]; |
| | | } |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | [weakSelf.records removeAllObjects]; |
| | | [weakSelf.playbackList reloadData]; |
| | | return ; |
| | | } |
| | | [weakSelf.records removeAllObjects]; |
| | | if(cloudRecords.count == 0) |
| | | { |
| | | weakSelf.noVideoLabel.hidden = NO; |
| | | weakSelf.noVideoImageView.hidden = NO; |
| | | [weakSelf.playbackList reloadData]; |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | return; |
| | | } |
| | | |
| | | if (cloudRecords.count > 0) |
| | | { |
| | | [weakSelf.records addObjectsFromArray:cloudRecords]; |
| | | [weakSelf.playbackList reloadData]; |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | [weakSelf doPlayback]; |
| | | } |
| | | }]; |
| | | |
| | | NSLog(@"cloudRecords is %@, error is %@", cloudRecords, error); |
| | | if (error) |
| | | { |
| | | if (error.code > 0) { |
| | | NSString *mes = [NSString stringWithFormat:@"%@(%ld)",NSLocalizedString(@"setting_opration_fail", @"操作失败"), (long)error.code]; |
| | | [UIView dd_showMessage:mes onParentView:self.view]; |
| | | |
| | | } |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | [weakSelf.records removeAllObjects]; |
| | | [weakSelf.playbackList reloadData]; |
| | | return ; |
| | | } |
| | | [weakSelf.records removeAllObjects]; |
| | | if(cloudRecords.count == 0) |
| | | { |
| | | weakSelf.noVideoLabel.hidden = NO; |
| | | weakSelf.noVideoImageView.hidden = NO; |
| | | [weakSelf.playbackList reloadData]; |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | return; |
| | | } |
| | | |
| | | if (cloudRecords.count > 0) |
| | | { |
| | | [weakSelf.records addObjectsFromArray:cloudRecords]; |
| | | [weakSelf.playbackList reloadData]; |
| | | [weakSelf.playbackList.header endRefreshing]; |
| | | [weakSelf doPlayback]; |
| | | } |
| | | }]; |
| | | } |
| | | }]; |
| | | self.playbackList.header.automaticallyChangeAlpha = YES; |
| | |
| | | |
| | | - (IBAction)large:(id)sender |
| | | { |
| | | NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]; |
| | | [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; |
| | | // NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]; |
| | | // [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; |
| | | if (_landscape == YES) { |
| | | [self largeBack:self.largeBackButton]; |
| | | return; |
| | | } |
| | | _landscape = YES; |
| | | if (@available(iOS 16.0, *)) { |
| | | if (self.navigationController) { |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [self.navigationController setNeedsUpdateOfSupportedInterfaceOrientations]; |
| | | }); |
| | | } else { |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [self setNeedsUpdateOfSupportedInterfaceOrientations]; |
| | | }); |
| | | } |
| | | NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects]; |
| | | UIWindowScene *ws = (UIWindowScene *)array.firstObject; |
| | | UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] init]; |
| | | geometryPreferences.interfaceOrientations = UIInterfaceOrientationMaskLandscape; |
| | | [ws requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) { |
| | | NSLog(@"iOS 16 Error: %@",error); |
| | | }]; |
| | | } else { |
| | | NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]; |
| | | [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; |
| | | } |
| | | } |
| | | |
| | | - (IBAction)largeBack:(id)sender |
| | | { |
| | | NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait]; |
| | | [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; |
| | | _landscape = NO; |
| | | if (@available(iOS 16.0, *)) { |
| | | if (self.navigationController) { |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [self.navigationController setNeedsUpdateOfSupportedInterfaceOrientations]; |
| | | }); |
| | | } else { |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | [self setNeedsUpdateOfSupportedInterfaceOrientations]; |
| | | }); |
| | | } |
| | | NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects]; |
| | | UIWindowScene *ws = (UIWindowScene *)array.firstObject; |
| | | UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] init]; |
| | | geometryPreferences.interfaceOrientations = UIInterfaceOrientationMaskPortrait; |
| | | [ws requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) { |
| | | NSLog(@"iOS 16 Error: %@",error); |
| | | }]; |
| | | } else { |
| | | NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait]; |
| | | [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; |
| | | } |
| | | } |
| | | |
| | | - (IBAction)voiceButtonClicked:(id)sender |
| | |
| | | [_player setPlaybackRate:rate mode:0]; |
| | | } |
| | | else { |
| | | |
| | | |
| | | EZPlaybackRate rate = [cloudRate[indexPath.row] intValue]; |
| | | [_player setPlaybackRate:rate mode:0]; |
| | | } |
| | |
| | | } |
| | | |
| | | - (IBAction)clickRateBtn:(UIButton *)sender { |
| | | |
| | | |
| | | self.rateBtnTimer = [NSTimer scheduledTimerWithTimeInterval:2.5f target:self selector:@selector(hideRateView) userInfo:nil repeats:NO]; |
| | | |
| | | if(_isSelectedDevice) { |
| | |
| | | self.selectedIndexPath = nil; |
| | | [UIView animateWithDuration:0.3 |
| | | animations:^{ |
| | | self.selectedImageViewConstraint.constant = 0; |
| | | [self.toolView setNeedsUpdateConstraints]; |
| | | [self.toolView layoutIfNeeded]; |
| | | } |
| | | self.selectedImageViewConstraint.constant = 0; |
| | | [self.toolView setNeedsUpdateConstraints]; |
| | | [self.toolView layoutIfNeeded]; |
| | | } |
| | | completion:^(BOOL finished) { |
| | | self.cloudButton.selected = YES; |
| | | self.deviceButton.selected = NO; |
| | | }]; |
| | | self.cloudButton.selected = YES; |
| | | self.deviceButton.selected = NO; |
| | | }]; |
| | | _isSelectedDevice = NO; |
| | | [self.records removeAllObjects]; |
| | | [self.playbackList reloadData]; |
| | |
| | | self.selectedIndexPath = nil; |
| | | [UIView animateWithDuration:0.3 |
| | | animations:^{ |
| | | self.selectedImageViewConstraint.constant = self.view.bounds.size.width / 2.0f; |
| | | [self.toolView setNeedsUpdateConstraints]; |
| | | [self.toolView layoutIfNeeded]; |
| | | } |
| | | self.selectedImageViewConstraint.constant = self.view.bounds.size.width / 2.0f; |
| | | [self.toolView setNeedsUpdateConstraints]; |
| | | [self.toolView layoutIfNeeded]; |
| | | } |
| | | completion:^(BOOL finished) { |
| | | self.cloudButton.selected = NO; |
| | | self.deviceButton.selected = YES; |
| | | }]; |
| | | self.cloudButton.selected = NO; |
| | | self.deviceButton.selected = YES; |
| | | }]; |
| | | _isSelectedDevice = YES; |
| | | [self.records removeAllObjects]; |
| | | [self.playbackList reloadData]; |
| | |
| | | - (void)playBoxToolRefresh:(NSTimer *)timer |
| | | { |
| | | NSDate *currentTime = [_player getOSDTime]; |
| | | NSLog(@"getOSDTime === %@", currentTime); |
| | | NSLog(@"getOSDTime === %@", currentTime); |
| | | if(_isSelectedDevice) |
| | | { |
| | | _playSeconds = [currentTime timeIntervalSinceDate:_deviceRecord.startTime]; |
| | |
| | | { |
| | | _playSeconds = [currentTime timeIntervalSinceDate:_cloudRecord.startTime]; |
| | | } |
| | | |
| | | |
| | | if(_playSeconds >= 3600) |
| | | { |
| | | int hour = (int)_playSeconds / 3600; |
| | |
| | | - (void)streamPlayer:(EZStreamPlayer *)player didReceivedMessage:(EZStreamPlayerMsgType)msgType |
| | | { |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | |
| | | |
| | | NSString *msg; |
| | | switch (msgType) { |
| | | case EZStreamPlayerMsgTypeRealPlayStart: |
| | | msg = @"开启预览成功"; |
| | | break; |
| | | case EZStreamPlayerMsgTypeRealPlayClose: |
| | | case EZStreamPlayerMsgTypeRealPlayClose: |
| | | msg = @"关闭预览成功"; |
| | | break; |
| | | case EZStreamPlayerMsgTypePlayBackStart: |
| | | case EZStreamPlayerMsgTypePlayBackStart: |
| | | msg = @"开启设备回放成功"; |
| | | break; |
| | | case EZStreamPlayerMsgTypePlayBackClose: |
| | | case EZStreamPlayerMsgTypePlayBackClose: |
| | | msg = @"关闭设备回放成功"; |
| | | break; |
| | | default: |
| | |
| | | { |
| | | if (dataType == EZStreamDataTypeHeader) { |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | |
| | | |
| | | [self.navigationController.view makeToast:@"开始写入文件"]; |
| | | }); |
| | | } |
| | | else if (dataType == EZStreamDataTypeStreamEnd) |
| | | { |
| | | dispatch_async(dispatch_get_main_queue(), ^{ |
| | | |
| | | |
| | | self.streamPlayBtn.selected = NO; |
| | | }); |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | - (BOOL)prefersHomeIndicatorAutoHidden { |
| | | return YES; |
| | | } |
| | | |
| | | @end |