//
|
// ESvideoVideoIntercomViewController.m
|
// ESVideoPhoneSDKDemo
|
//
|
// Created by 陈嘉乐 on 2020/5/11.
|
// Copyright © 2020 eTouchSky. All rights reserved.
|
//
|
|
#import "ESvideoVideoIntercomViewController.h"
|
#import "GDHDLUtlis.h"
|
#import <AVFoundation/AVFoundation.h>
|
#import <ESVideoPhoneSDk/ESVideoPhone.h>
|
#import <ESVideoPhoneSDk/ESError.h>
|
#import "AudioSessionHelper.h"
|
#import <Photos/Photos.h>
|
#import <AudioToolbox/AudioToolbox.h>
|
#import "ESVideo.h"
|
|
|
|
@interface ESvideoVideoIntercomViewController ()<ESVideoPhoneDelegate>
|
|
@property (nonatomic,strong) AudioSessionHelper *sessionHelper;
|
@property (nonatomic,strong) ESVideoPhone *es;
|
@property (nonatomic,assign) BOOL playing;
|
@property (nonatomic,assign) BOOL isInterrupt;
|
@property (nonatomic,assign) BOOL isSpeaking;
|
@property (nonatomic,strong) UIImage *snapImage; //截图
|
|
@property (nonatomic, strong) UIButton *backButton; //
|
@property (nonatomic, strong) UIButton *moreButton; //
|
|
@property (nonatomic, strong) UILabel *titleUILabel; //
|
|
|
|
|
@property (nonatomic, strong) UIView *centerView; //内容背景View
|
@property (nonatomic, strong) UILabel *topUILabel; //标题
|
@property (nonatomic, strong) UIButton *collectButton; //收藏
|
@property (nonatomic, strong) UIView *videoView;
|
@property (nonatomic, strong) UIView *homeView;
|
@property (nonatomic, strong) UILabel *homeUILabel; //房间名字
|
|
@property (nonatomic, strong) UIView *unlockView;
|
|
@property (nonatomic, strong) UIButton *screenshotImgBtn; //截图
|
@property (nonatomic, strong) UIButton *unlockImgBtn; //开锁
|
|
|
@property (nonatomic, strong) UIButton *hangUpImgBtn;//挂断按钮
|
@property (nonatomic, strong) UIButton *hangUpTextBtn;
|
|
@property (nonatomic, strong) UIButton *answerImgBtn;//接听按钮
|
@property (nonatomic, strong) UIButton *answerTextBtn;
|
|
@property (nonatomic, strong) UIButton *calltimeBtn; //通话时间按钮
|
|
//定时器
|
@property (nonatomic,strong) dispatch_source_t countdownTimer;
|
@property (nonatomic,strong) dispatch_source_t openDoorTimer;
|
@property (nonatomic, assign) int openDoorTimeout;
|
@property (nonatomic, assign) int callTimeout;
|
|
|
@end
|
|
@implementation ESvideoVideoIntercomViewController{
|
|
BOOL isAccessAudio;
|
BOOL isAccessVideo;
|
BOOL isBackGround;
|
BOOL iSVideoNotDetermined;
|
BOOL iSAudioNotDetermined;
|
|
NSString * tipStr;
|
NSString * okStr;
|
NSString * saveToTheAlbumsStr;
|
NSString * operationFailedStr;
|
NSString * refuseStr;
|
NSString * answerStr;
|
NSString * unlockSuccessfullyStr;
|
NSString * callingStr;
|
NSString * hangUpStr;
|
// int openDoorTimeout;
|
//全局变量
|
SystemSoundID sound;
|
}
|
|
- (void)viewDidLoad {
|
[super viewDidLoad];
|
self.view.backgroundColor = HEXCOLORA(0xF5F6FA, 1.0);
|
[self initLlanguage];
|
[self initTopBarView];
|
[self initCentetView];
|
[self initData];
|
// [self setAnswerBtnEnable:NO];
|
[self initESVideo];
|
//开始反呼
|
[self StartReverseCall];
|
[self ShowCalltimeBtn:callingStr];
|
// Do any additional setup after loading the view.
|
}
|
|
|
-(void)initLlanguage{
|
NSString *languageName = [[[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"] objectAtIndex:0];
|
|
// 简体中文
|
if ([languageName rangeOfString:@"zh-Hans"].location != NSNotFound) {
|
tipStr = @"提示";
|
okStr = @"确认";
|
saveToTheAlbumsStr = @"已保存至手机相册.";
|
operationFailedStr = @"操作失败";
|
refuseStr = @"拒绝";
|
answerStr = @"接听";
|
hangUpStr = @"挂断";
|
unlockSuccessfullyStr = @"开锁成功";
|
callingStr = @"来电中...";
|
}else{
|
tipStr = @"Prompt";
|
okStr = @"OK";
|
saveToTheAlbumsStr = @"Saved to the albums.";
|
operationFailedStr = @"Operation failed.";
|
refuseStr = @"Refuse";
|
answerStr = @"Answer";
|
hangUpStr = @"Hang up";
|
unlockSuccessfullyStr = @"Unlock successfully";
|
callingStr = @"Incoming call";
|
|
}
|
}
|
|
|
|
- (void)initTopBarView {
|
UIView *TopView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, APP_TOP_BAR_HEIGHT)];
|
TopView.backgroundColor = HEXCOLORA(0xF9F9F9,1.0);
|
// [TopView addSubview:self.backButton];
|
[TopView addSubview:self.moreButton];
|
[self.view addSubview:TopView];
|
TopView.layer.shadowColor = [UIColor colorWithRed:0/255.0 green:0/255.0 blue:0/255.0 alpha:0.25].CGColor;
|
TopView.layer.shadowOffset = CGSizeMake(0,0.5);
|
TopView.layer.shadowOpacity = 1;
|
TopView.layer.shadowRadius = 0;
|
|
}
|
|
- (UIButton *)backButton{
|
if (_backButton == nil) {
|
_backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, APP_STATUS_BAR_HEIGHT, 44, 44)];
|
[_backButton setImage:[UIImage imageNamed:@"ic_esvideo_back"] forState:UIControlStateNormal];
|
_backButton.imageEdgeInsets = UIEdgeInsetsMake(12,12,12,12);
|
[_backButton.imageView setContentMode:UIViewContentModeScaleAspectFit];
|
[_backButton addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
|
}
|
return _backButton;
|
}
|
|
-(void)backAction{
|
[self.navigationController popViewControllerAnimated:true];
|
// [self dismissViewControllerAnimated:YES completion:NULL];
|
|
}
|
|
- (UIButton *)moreButton{
|
if (_moreButton == nil) {
|
_moreButton = [[UIButton alloc] initWithFrame:CGRectMake(APP_SCREEN_WIDTH - 64, APP_STATUS_BAR_HEIGHT, 44, 44)];
|
[_moreButton setImage:[UIImage imageNamed:@"ic_esvideo_more"] forState:UIControlStateNormal];
|
_moreButton.imageEdgeInsets = UIEdgeInsetsMake(12,12,12,12);
|
[_moreButton.imageView setContentMode:UIViewContentModeScaleAspectFit];
|
[_moreButton addTarget:self action:@selector(moreAction) forControlEvents:UIControlEventTouchUpInside];
|
}
|
return _moreButton;
|
}
|
|
-(void)moreAction{
|
|
}
|
|
|
- (void)initCentetView {
|
[self.view addSubview:self.centerView];
|
// [self.centerView addSubview:self.collectButton];
|
[self.centerView addSubview:self.homeView];
|
[self.centerView addSubview:self.unlockView];
|
[self.unlockView addSubview:self.screenshotImgBtn];
|
[self.unlockView addSubview:self.unlockImgBtn];
|
[self.centerView addSubview:self.hangUpImgBtn];
|
[self.centerView addSubview:self.hangUpTextBtn];
|
[self.centerView addSubview:self.answerImgBtn];
|
[self.centerView addSubview:self.answerTextBtn];
|
[self.centerView addSubview:self.calltimeBtn];
|
}
|
|
- (UIView *)centerView{
|
if (_centerView == nil) {
|
_centerView = [[UIButton alloc] initWithFrame:CGRectMake(0, APP_TOP_BAR_HEIGHT + 20, APP_SCREEN_WIDTH, APP_VISIBLE_HEIGHT-20)];
|
_centerView.backgroundColor = UIColor.whiteColor;
|
[self setRadiusWithView:_centerView];
|
|
_topUILabel= [[UILabel alloc] initWithFrame:CGRectMake(80, 20, APP_SCREEN_WIDTH-160, 24)];
|
_topUILabel.font = [UIFont fontWithName:APP_UIFont_BOLD size:15.0];
|
_topUILabel.textColor = HEXCOLORA(0x333333, 1.0);
|
_topUILabel.text = @"二次确认机";
|
_topUILabel.textAlignment = NSTextAlignmentCenter;
|
[_centerView addSubview:self.topUILabel];
|
}
|
return _centerView;
|
}
|
|
-(void)setRadiusWithView:(UIView *)mView{
|
//顶部圆角
|
UIRectCorner corners = UIRectCornerTopLeft | UIRectCornerTopRight;
|
if (@available(iOS 11.0, *)) {
|
mView.layer.cornerRadius = 20;
|
mView.layer.maskedCorners = (CACornerMask)corners;
|
}else{
|
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:mView.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(20,20)];
|
//创建 layer
|
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
|
maskLayer.frame = mView.bounds;
|
//赋值
|
maskLayer.path = maskPath.CGPath;
|
mView.layer.mask = maskLayer;
|
}
|
}
|
|
- (UIButton *)collectButton{
|
if (_collectButton == nil) {
|
_collectButton = [[UIButton alloc] initWithFrame:CGRectMake(APP_SCREEN_WIDTH - 44, 20, 24, 24)];
|
[_collectButton setImage:[UIImage imageNamed:@"ic_esvideo_collect_select"] forState:UIControlStateSelected];
|
[_collectButton setImage:[UIImage imageNamed:@"ic_esvideo_collect_unselect"] forState:UIControlStateNormal];
|
// _collectButton.imageEdgeInsets = UIEdgeInsetsMake(12,12,12,12);
|
[_collectButton.imageView setContentMode:UIViewContentModeScaleAspectFit];
|
[_collectButton addTarget:self action:@selector(collectAction) forControlEvents:UIControlEventTouchUpInside];
|
}
|
return _collectButton;
|
}
|
|
-(void)collectAction{
|
[_collectButton setSelected:!_collectButton.isSelected];
|
_isCollect = _collectButton.isSelected;
|
if(self.collectButtonCallBack != NULL){
|
self.collectButtonCallBack(_isCollect);
|
}
|
}
|
|
- (UIView *)homeView{
|
if (_homeView == nil) {
|
_homeView = [[UIView alloc] initWithFrame:CGRectMake(0, 268, APP_SCREEN_WIDTH, 36)];
|
_homeView.backgroundColor = HEXCOLORA(0x232323, 1.0);
|
UIImageView *mUIImageView= [[UIImageView alloc] initWithFrame:CGRectMake(20, 4, 28, 28)];
|
mUIImageView.image = [UIImage imageNamed:@"ic_esvideo_home"];
|
[mUIImageView setContentMode:UIViewContentModeScaleAspectFit];
|
[_homeView addSubview:mUIImageView];
|
[_homeView addSubview:self.homeUILabel];
|
}
|
return _homeView;
|
}
|
|
- (UILabel *)homeUILabel{
|
if (_homeUILabel == nil) {
|
_homeUILabel = [[UILabel alloc] initWithFrame:CGRectMake(52, 8, APP_SCREEN_WIDTH - 100, 20)];
|
_homeUILabel.font = [UIFont fontWithName:APP_UIFont size:12.0];
|
_homeUILabel.textColor = [UIColor whiteColor];
|
_homeUILabel.text = @"1栋203";
|
}
|
return _homeUILabel;
|
}
|
|
|
- (UIView *)unlockView{
|
if (_unlockView == nil) {
|
_unlockView = [[UIView alloc] initWithFrame:CGRectMake(0, 304, APP_SCREEN_WIDTH, 48)];
|
_unlockView.backgroundColor = HEXCOLORA(0x232323, 1.0);
|
_unlockView.layer.backgroundColor = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1.0].CGColor;
|
_unlockView.layer.shadowColor = [UIColor colorWithRed:204/255.0 green:204/255.0 blue:204/255.0 alpha:0.4].CGColor;
|
_unlockView.layer.shadowOffset = CGSizeMake(0,0.5);
|
_unlockView.layer.shadowOpacity = 1;
|
_unlockView.layer.shadowRadius = 0;
|
}
|
return _unlockView;
|
}
|
|
- (UIButton *)screenshotImgBtn{
|
if (_screenshotImgBtn == nil) {
|
_screenshotImgBtn = [[UIButton alloc] initWithFrame:CGRectMake(65, 6, 36, 36)];
|
[_screenshotImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_takephoto_unselect"] forState:UIControlStateNormal];
|
// [_screenshotImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_takephoto_select"] forState:UIControlStateSelected];
|
[_screenshotImgBtn.imageView setContentMode:UIViewContentModeScaleAspectFit];
|
[_screenshotImgBtn addTarget:self action:@selector(screenshotAction) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
|
[_screenshotImgBtn addTarget:self action:@selector(screenshotDownAction) forControlEvents:UIControlEventTouchDown];
|
_screenshotImgBtn.adjustsImageWhenHighlighted = NO;
|
}
|
return _screenshotImgBtn;
|
}
|
|
-(void)screenshotDownAction{
|
[_screenshotImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_takephoto_select"] forState:UIControlStateNormal];
|
}
|
|
-(void)screenshotAction{
|
[_screenshotImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_takephoto_unselect"] forState:UIControlStateNormal];
|
//截图
|
if(_es){
|
[_es onSnap];
|
}
|
}
|
|
- (UIButton *)unlockImgBtn{
|
if (_unlockImgBtn == nil) {
|
_unlockImgBtn = [[UIButton alloc] initWithFrame:CGRectMake(274, 6, 36, 36)];
|
[_unlockImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_unlock_unselect"] forState:UIControlStateNormal];
|
// [_unlockImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_unlock_select"] forState:UIControlStateSelected];
|
[_unlockImgBtn.imageView setContentMode:UIViewContentModeScaleAspectFit];
|
[_unlockImgBtn addTarget:self action:@selector(unlockAction) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
|
[_unlockImgBtn addTarget:self action:@selector(unlockDownAction) forControlEvents:UIControlEventTouchDown];
|
_unlockImgBtn.adjustsImageWhenHighlighted = NO;
|
}
|
return _unlockImgBtn;
|
}
|
|
-(void)unlockDownAction{
|
[_unlockImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_unlock_select"] forState:UIControlStateNormal];
|
|
}
|
|
-(void)unlockAction{
|
[_unlockImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_unlock_unselect"] forState:UIControlStateNormal];
|
//开锁
|
if(_es){
|
[_es openTheDoorWithRoomid:_mESRoomID];
|
}
|
|
}
|
|
#pragma 挂断和开锁
|
- (UIButton *)hangUpImgBtn{
|
if (_hangUpImgBtn == nil) {
|
_hangUpImgBtn = [[UIButton alloc] initWithFrame:CGRectMake(54, 448, 58, 58)];
|
[_hangUpImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_hangup"] forState:UIControlStateNormal];
|
// [_hangUpImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_hangup"] forState:UIControlStateSelected];
|
[_hangUpImgBtn.imageView setContentMode:UIViewContentModeScaleAspectFit];
|
[_hangUpImgBtn addTarget:self action:@selector(hangUpAction) forControlEvents:UIControlEventTouchUpInside];
|
}
|
return _hangUpImgBtn;
|
}
|
|
//挂断按钮事件
|
-(void)hangUpAction{
|
[self backAction];
|
}
|
|
- (UIButton *)hangUpTextBtn{
|
if (_hangUpTextBtn == nil) {
|
_hangUpTextBtn = [[UIButton alloc] initWithFrame:CGRectMake(33, 514, 100, 21)];
|
[_hangUpTextBtn setTitle:@"拒绝" forState:UIControlStateNormal];
|
_hangUpTextBtn.titleLabel.textAlignment = NSTextAlignmentCenter;
|
_hangUpTextBtn.titleLabel.font = [UIFont fontWithName:APP_UIFont size:15.0];
|
[_hangUpTextBtn setTitleColor:TextColor forState:UIControlStateNormal];
|
[_hangUpTextBtn setTitleColor:TextSelectColor forState:UIControlStateSelected];
|
[_hangUpTextBtn addTarget:self action:@selector(screenshotAction) forControlEvents:UIControlEventTouchUpInside];
|
}
|
return _hangUpTextBtn;
|
}
|
|
- (UIButton *)answerImgBtn{
|
if (_answerImgBtn == nil) {
|
_answerImgBtn = [[UIButton alloc] initWithFrame:CGRectMake(263, 448, 58, 58)];
|
[_answerImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_answer"] forState:UIControlStateNormal];
|
// [_answerImgBtn setImage:[UIImage imageNamed:@"ic_esvideo_answer"] forState:UIControlStateSelected];
|
[_answerImgBtn.imageView setContentMode:UIViewContentModeScaleAspectFit];
|
[_answerImgBtn addTarget:self action:@selector(answerIAction) forControlEvents:UIControlEventTouchUpInside];
|
}
|
return _answerImgBtn;
|
}
|
|
-(void)answerIAction{
|
[self stopPlaySystemSound];
|
if(_es){
|
// [self stopPlaySystemSound];
|
[_es onAccept];
|
}else{
|
NSLog(@"ES初始化失败");
|
}
|
|
_answerImgBtn.hidden = YES;
|
_answerTextBtn.hidden = YES;
|
|
//挂断按钮移动中间
|
_hangUpImgBtn.frame = CGRectMake(159, 448, 58, 58);
|
_hangUpTextBtn.frame = CGRectMake(138, 514, 100, 21);
|
[_hangUpTextBtn setTitle:hangUpStr forState:UIControlStateNormal];
|
//开始计时
|
_callTimeout = 0;
|
[self startCountdown];
|
|
}
|
|
-(void)setAnswerBtnEnable:(BOOL)ISEnable{
|
[_answerImgBtn setEnabled:ISEnable];
|
[_answerTextBtn setEnabled:ISEnable];
|
}
|
|
- (UIButton *)answerTextBtn{
|
if (_answerTextBtn == nil) {
|
_answerTextBtn = [[UIButton alloc] initWithFrame:CGRectMake(242, 514, 100, 21)];
|
[_answerTextBtn setTitle:@"接听" forState:UIControlStateNormal];
|
_answerTextBtn.titleLabel.font = [UIFont fontWithName:APP_UIFont size:15.0];
|
_answerTextBtn.titleLabel.textAlignment = NSTextAlignmentCenter;
|
// _unlockTextBtn.titleLabel.textColor = TextColor;
|
[_answerTextBtn setTitleColor:TextColor forState:UIControlStateNormal];
|
[_answerTextBtn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled];
|
[_answerTextBtn setTitleColor:TextSelectColor forState:UIControlStateSelected];
|
[_answerTextBtn addTarget:self action:@selector(unlockAction) forControlEvents:UIControlEventTouchUpInside];
|
}
|
return _answerTextBtn;
|
}
|
|
- (UIButton *)calltimeBtn{
|
if (_calltimeBtn == nil) {
|
_calltimeBtn = [[UIButton alloc] initWithFrame:CGRectMake(242, 382, 100, 30)];
|
_calltimeBtn.backgroundColor = HEXCOLORA(0x000000, 0.4);
|
[_calltimeBtn setTitle:@"00:00" forState:UIControlStateNormal];
|
_calltimeBtn.titleLabel.font = [UIFont fontWithName:APP_UIFont size:14.0];
|
_calltimeBtn.titleLabel.textAlignment = NSTextAlignmentCenter;
|
[_calltimeBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
_calltimeBtn.center = CGPointMake(APP_SCREEN_WIDTH/2, 397);
|
_calltimeBtn.hidden = YES;
|
_calltimeBtn.layer.cornerRadius = 15;
|
}
|
return _calltimeBtn;
|
}
|
|
|
|
|
-(void)ShowTime:(int)nowTime {
|
if(_calltimeBtn.hidden) _calltimeBtn.hidden = NO;
|
NSString *timeStr = [self timeFormatted:nowTime];
|
[self setCalltimeButtonText:timeStr isTime:YES];
|
}
|
|
-(void)ShowCalltimeBtn:(NSString*) mesStr {
|
if(_calltimeBtn.hidden) _calltimeBtn.hidden = NO;
|
|
[self setCalltimeButtonText:mesStr isTime:NO];
|
|
|
}
|
|
/*
|
根据文字调整按钮宽
|
*/
|
-(void)setCalltimeButtonText:(NSString*) mesStr isTime:(BOOL)isTime
|
{
|
[_calltimeBtn setTitle:mesStr forState:UIControlStateNormal];
|
if(isTime){
|
_calltimeBtn.frame = CGRectMake(0, 0, 80, 30);
|
}else{
|
_calltimeBtn.frame = CGRectMake(0, 0, 115, 30);
|
}
|
_calltimeBtn.center = CGPointMake(APP_SCREEN_WIDTH/2, 397);
|
}
|
|
|
- (NSString *)timeFormatted:(int)totalSeconds
|
{
|
int seconds = totalSeconds % 60;
|
int minutes = (totalSeconds / 60);
|
return [NSString stringWithFormat:@"%02d:%02d", minutes, seconds];
|
|
}
|
|
- (int *)getTextWidth:(UIButton*) btn
|
{
|
int textWidth = 0;
|
// CGSize size = [btn.titleLabel.textsizeWithFont:[UIFontboldSystemFontOfSize:15]constrainedToSize:contentMaxSizes lineBreakMode:UILineBreakModeCharacterWrap];
|
// textWidth = (int)fontSize.Width;
|
return textWidth;
|
}
|
|
|
|
/** 开启倒计时 */
|
- (void)startCountdown {
|
|
if (_callTimeout > 100) {
|
return;
|
}
|
_callTimeout = 0;
|
// GCD定时器
|
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
|
_countdownTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
|
|
dispatch_source_set_timer(_countdownTimer, dispatch_walltime(NULL, 0), 1.0 * NSEC_PER_SEC, 0); //每秒执行
|
|
dispatch_source_set_event_handler(_countdownTimer, ^{
|
WEAKSELF_AT
|
if(weakSelf_AT.callTimeout >= 100 ){// 计时结束
|
// 关闭定时器
|
dispatch_source_cancel(weakSelf_AT.countdownTimer);
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
NSLog(@"超时");
|
[weakSelf_AT backAction];
|
|
});
|
|
}else{// 计时中
|
weakSelf_AT.callTimeout++;
|
dispatch_async(dispatch_get_main_queue(), ^{
|
[weakSelf_AT ShowTime:weakSelf_AT.callTimeout];
|
});
|
|
|
}
|
});
|
|
// 开启定时器
|
dispatch_resume(_countdownTimer);
|
|
}
|
|
#pragma 开锁成功
|
-(void)setOpenDoorSuccess{
|
[self setUnlock:NO];
|
_openDoorTimeout = 0;
|
[self startOpenDoorCountdown];
|
[self showUIAlertView:unlockSuccessfullyStr];
|
|
|
}
|
|
-(void)setUnlock:(BOOL)ISEnable{
|
[_unlockImgBtn setEnabled:ISEnable];
|
}
|
|
|
|
/** 开启倒计时 */
|
- (void)startOpenDoorCountdown {
|
|
if (_openDoorTimeout > 20) {
|
return;
|
}
|
|
_openDoorTimeout = 0;
|
|
// GCD定时器
|
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
|
_openDoorTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
|
|
dispatch_source_set_timer(_openDoorTimer, dispatch_walltime(NULL, 0), 1.0 * NSEC_PER_SEC, 0); //每秒执行
|
|
dispatch_source_set_event_handler(_openDoorTimer, ^{
|
WEAKSELF_AT
|
if(weakSelf_AT.openDoorTimeout >= 20 ){// 计时结束
|
// 关闭定时器
|
dispatch_source_cancel(weakSelf_AT.openDoorTimer);
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
[weakSelf_AT setUnlock:YES];
|
|
});
|
|
}else{// 计时中
|
weakSelf_AT.openDoorTimeout++;
|
|
}
|
});
|
|
// 开启定时器
|
dispatch_resume(_openDoorTimer);
|
|
}
|
|
|
|
#pragma SDK可视对讲 功能部分
|
-(void)initESVideo{
|
_es = ESVideo.shareInstance.es;
|
//初始化中断,进入后台的tag
|
|
|
_playing = NO;
|
_isSpeaking = NO;
|
self.isInterrupt = NO;
|
isBackGround = NO;
|
|
|
|
[self requestAccessForAVMediaType:AVMediaTypeAudio];
|
if (isAccessAudio) {
|
ImageCallback snapImageCallback = ^(UIImage *image){
|
//block是在分线程中调用的,这里要放到主线程
|
dispatch_async(dispatch_get_main_queue(), ^{
|
self->_snapImage = image;
|
[self saveImageToPhotosAlbum:image];
|
});
|
};
|
//门口机会有视频的长宽高,是固定的(暂时还不确定)
|
// _es = [[ESVideoPhone alloc]initESVideoPhoneWithFrame:CGRectMake(0, 57, APP_SCREEN_WIDTH, 211) delegate:self imagecallBack:snapImageCallback];
|
if (_es) {
|
//判断视频渲染是否初始化成功,如果失败会走ESVideoPhoneDelegate方法
|
if (_es.showView) {
|
ESVideo.shareInstance.snapImageCallback = snapImageCallback;
|
_es.delegate = self;
|
_es.showView.backgroundColor = [UIColor whiteColor];
|
[self.centerView addSubview:_es.showView];
|
_es.showView.hidden = YES;
|
}
|
}else{
|
NSLog(@"ESVideoPhone 初始化失败");
|
return;
|
}
|
// 初始化Audio采集Unit
|
if(![_es initAudioCaptureSession]){
|
return;
|
}
|
}else{
|
//音频没有权限建议不要发起通话
|
return;
|
}
|
//初始化视频采集Capture
|
[self requestAccessForAVMediaType:AVMediaTypeVideo];
|
if (isAccessVideo) {
|
if(![_es initVideoCaptureSession]){
|
NSLog(@"VideoCaptureSession 初始化失败");
|
}
|
}
|
//初始化AudioSession
|
_sessionHelper = [[AudioSessionHelper alloc]init];
|
[_sessionHelper setAudioSession];
|
//添加进入后台,中断等通知
|
[self addObservers];
|
|
|
}
|
|
-(void)initData{
|
_topUILabel.text = _deviceName;
|
_homeUILabel.text = _roomName;
|
[_hangUpTextBtn setTitle:refuseStr forState:UIControlStateNormal];
|
[_answerTextBtn setTitle:answerStr forState:UIControlStateNormal];
|
|
[_collectButton setSelected:_isCollect];
|
}
|
|
/**
|
开始反呼
|
*/
|
-(void)StartReverseCall{
|
[self startPlaySystemSound];
|
if(_es){
|
NSString *param = [NSString stringWithFormat:@"address=%@,tag=mobile://123,",_mESVideoID];
|
//NSLog(@"%@", param);
|
[_es onReverseCall:param];
|
|
}else{
|
NSLog(@"ES初始化失败");
|
}
|
|
|
}
|
|
////接听
|
//-(void)onAccept{
|
// if(_es){
|
// [_es onAccept];
|
// }else{
|
// NSLog(@"ES初始化失败");
|
// }
|
//
|
//}
|
|
|
-(NSString *)getCurrentdateInterval
|
{
|
NSDate *datenow = [NSDate date];
|
NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)([datenow timeIntervalSince1970]*1000)];
|
return timeSp;
|
}
|
|
|
-(void)showUIAlertView:(NSString *)mes
|
{
|
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:tipStr message:mes preferredStyle:UIAlertControllerStyleAlert];
|
[alertController addAction:[UIAlertAction actionWithTitle:okStr style:UIAlertActionStyleCancel handler:nil]];
|
[self presentViewController:alertController animated:YES completion:nil];
|
|
// UIAlertView *alertView1 = [[UIAlertView alloc] initWithTitle:tipStr message:mes delegate:self cancelButtonTitle:okStr otherButtonTitles:nil, nil];
|
// [alertView1 show];
|
|
}
|
|
-(void)showUIAlertViewWithBack:(NSString *)mes
|
{
|
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:tipStr message:mes preferredStyle:UIAlertControllerStyleAlert];
|
[alertController addAction:[UIAlertAction actionWithTitle:okStr style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
[self backAction];
|
}]];
|
|
[self presentViewController:alertController animated:YES completion:nil];
|
}
|
|
|
#pragma viewDidAppear
|
-(void)viewDidAppear:(BOOL)animated{
|
//这个方法请根据App的具体情况调用
|
//在viewDidLoad中 调用requestAccessForAVMediaType: 是为了节约初始化的时间
|
//在viewDidAppear中调用requestAccessForAVMediaType: 是为了弹出提示打开权限的Alert
|
//测试的时候发现如下情况:如果只把授权方法放到ViewDidAppear方法中处理,如果没有授权在初始化采集器时会失败。同样AlertView会因为View没有didLoad而导致present不出来
|
if (!isAccessVideo || !isAccessAudio) {
|
[self requestAccessForAVMedia];
|
}
|
}
|
-(void)setIsInterrupt:(BOOL)isInterrupt{
|
if (_es) {
|
_es.isInterrupt = isInterrupt;
|
}
|
}
|
-(void)viewWillDisappear:(BOOL)animated{
|
[super viewWillDisappear:animated];
|
[self stopPlaySystemSound];
|
//防止用户不按挂断,或者不等收到对方的挂断,点击返回按钮。
|
if(_es){
|
[_es onHangup];
|
[_es onStopCapture];
|
[_es stopTalk];
|
|
_es.delegate = nil;
|
ESVideo.shareInstance.snapImageCallback = nil;
|
|
|
}
|
// [_es freeSubClass];
|
}
|
-(void)dealloc{
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
// [_es freeSubClass];
|
|
if(_openDoorTimer){
|
dispatch_source_cancel(_openDoorTimer);
|
_openDoorTimer = nil; // OK
|
}
|
if(_countdownTimer){
|
dispatch_source_cancel(_countdownTimer);
|
_countdownTimer = nil; // OK
|
|
}
|
NSLog(@"==============dealloc");
|
|
|
}
|
|
#pragma mark ESVideoPhoneDelegate
|
//视频通话的状态代理事件,phoneEvent为返回的消息里面包含event状态与与event相关的数据
|
-(void)getPhoneEvent_UI:(NSString *)phoneEvent{
|
NSLog(@"事件%@", phoneEvent);
|
NSArray *strArray = [phoneEvent componentsSeparatedByString:@"\r\n"];
|
NSArray *eventArray = [strArray.firstObject componentsSeparatedByString:@"="];
|
NSString *phoneEventStr = eventArray.lastObject;
|
|
if([phoneEventStr isEqual:@"EVT_Ringing"]){
|
_es.showView.hidden = NO;
|
//反呼成功 允许接听 看需求是否需要播放铃声和震动
|
[self setAnswerBtnEnable:YES];
|
|
// [_mCallOrAccept setTitle:@"接听" forState:UIControlStateNormal];
|
}else if([phoneEventStr isEqual:@"EVT_StartStream"]){
|
|
} else if([phoneEventStr isEqual:@"EVT_StopStream"]){
|
// [_mCallOrAccept setTitle:@"反呼" forState:UIControlStateNormal];
|
}else if([phoneEventStr isEqual:@"EVT_Connected"]){
|
|
// [_mCallOrAccept setTitle:@"通话中..." forState:UIControlStateNormal];
|
}else if([phoneEventStr isEqual:@"EVT_HangUp"]){
|
[self showUIAlertViewWithBack:@"已挂断"];
|
// [_mCallOrAccept setTitle:@"反呼" forState:UIControlStateNormal];
|
}else if([phoneEventStr isEqual:@"EVT_P2POnlineStatusChanged"]){
|
//EVT_P2PStarted(p2p初始化OK,可以连接),EVT_P2POnlineStatusChangedonline=1
|
//p2p初始化成功,手机端目前没有这个回调了
|
//_mCallOrAccept.enabled = YES;
|
//_monitorBtn.enabled = YES;
|
}else if([phoneEventStr isEqual:@"EVT_RECV_CUSTOM_DATA"]){
|
//开门的结果从这里返回
|
NSString *baseStr = [strArray[1] substringFromIndex:5];
|
NSData *data = [[NSData alloc]initWithBase64EncodedString:baseStr options:NSDataBase64DecodingIgnoreUnknownCharacters];
|
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
|
NSInteger status = [[dic valueForKey:@"status"]integerValue];
|
if(status && status == 1){
|
NSLog(@"开门成功");
|
[self setOpenDoorSuccess];
|
}else{
|
NSLog(@"开门失败");
|
}
|
}
|
}
|
|
-(void)getAErrorForESVideoPhone:(NSString *)errorStr type:(NSUInteger)errortype{
|
NSLog(@"错误%@", errorStr);
|
//没有授权
|
if (errortype == LMPVideoCaptureErrorNotAuthorized) {
|
NSLog(@"错误%@", errorStr);
|
}
|
}
|
#pragma mark AudioSession与Notifications处理
|
|
- (void) addObservers
|
{
|
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name: UIKeyboardWillChangeFrameNotification object: nil];
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:nil];
|
|
//isAccessVideo,如果AVCaptureSession没有new出来不会收到通知
|
if (isAccessVideo) {
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionWasInterrupted:) name:AVCaptureSessionWasInterruptedNotification object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionInterruptionEnded:) name:AVCaptureSessionInterruptionEndedNotification object:nil];
|
}else{
|
//object:为nil 可能不会触发通知
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleInterruption:)
|
name:AVAudioSessionInterruptionNotification object:[AVAudioSession
|
sharedInstance]];
|
}
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterForeground:) name:UIApplicationDidBecomeActiveNotification object:nil];
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
|
}
|
|
- (void) sessionRuntimeError:(NSNotification*)notification
|
{
|
NSError* error = notification.userInfo[AVCaptureSessionErrorKey];
|
NSLog(@"Capture session runtime error: %@", error);
|
|
// If media services were reset, and the last start succeeded, restart the session.
|
if (error.code == AVErrorMediaServicesWereReset) {
|
[_es onStopCapture];
|
[_es startTalk];
|
}
|
}
|
|
- (void)handleInterruption:(NSNotification *)notification
|
{
|
NSUInteger interruptionType = [[[notification userInfo]
|
objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
|
|
if (AVAudioSessionInterruptionTypeBegan == interruptionType)
|
{
|
if (isBackGround) {
|
return;
|
}
|
[_es stopTalk];
|
}
|
else if (AVAudioSessionInterruptionTypeEnded == interruptionType)
|
{
|
if (self.isInterrupt == NO) {
|
return;
|
}else{
|
//直接在进入前台那个通知里面实现,实际上进入前台的方法会在这个方法前面调用,效果更好
|
[self InterruptionEndedAVAudioSessionSetActiveYES];
|
}
|
}
|
}
|
|
//AVAudioPlayer 类和 AVAudioRecorder 类,当发生中断时,系统会自动暂停播放或录制
|
- (void) sessionWasInterrupted:(NSNotification*)notification
|
{
|
if (_playing == YES) {
|
self.isInterrupt = YES;
|
//AVCaptureSessionInterruptionReason
|
if (@available(iOS 9.0, *)) {
|
NSInteger reason = [notification.userInfo[AVCaptureSessionInterruptionReasonKey] integerValue]; //电话中断是1
|
NSLog(@"Capture session was interrupted with reason %ld", (long)reason);
|
|
//音频硬件暂时不可用而造成的中断,例如,电话或警报。
|
if (reason == AVCaptureSessionInterruptionReasonAudioDeviceInUseByAnotherClient ||
|
reason == AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient) {
|
NSLog(@"AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient");
|
|
//VAudioPlayer 类和 AVAudioRecorder 类,当发生中断时,系统会自动暂停播放或录制
|
//Audio Queue Services, I/O audio unit
|
[_es onStopCapture];
|
[_es stopTalk];
|
/*
|
NSError *error = nil;
|
[[AVAudioSession sharedInstance] setActive:NO error:&error];
|
if (error) {
|
NSLog(@"sessionWasInterruptedSetActiveNO error:%@", error);
|
}
|
*/
|
}else if (reason == AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableInBackground){
|
NSLog(@"AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableInBackground");
|
//如果是电话中断,不会走进入后台的通知,进入后台再切换到前台这里是不用处理的
|
if (isBackGround) {
|
return;
|
}
|
[_es onStopCapture];
|
[_es stopTalk];
|
}
|
//多个应用程序资源争用质量下降。只有当应用程序占据全屏时,会话才能运行。
|
else if (reason == AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps) {
|
NSLog(@"AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps");
|
// Fade-in a label to inform the user that the camera is unavailable.
|
}else if (@available(iOS 11.1, *)) {
|
if (reason == AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableDueToSystemPressure){
|
NSLog(@"AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableDueToSystemPressure");
|
}
|
} else {
|
// Fallback on earlier versions
|
}
|
} else {
|
if (isBackGround) {
|
return;
|
}
|
[_es onStopCapture];
|
[_es stopTalk];
|
}
|
}
|
}
|
|
//这个通知可能会获取不到,
|
- (void) sessionInterruptionEnded:(NSNotification*)notification
|
{
|
// NSInteger reason = [notification.userInfo[AVCaptureSessionInterruptionReasonKey] integerValue];
|
NSLog(@"Capture session interruption ended");
|
if (self.isInterrupt == NO) {
|
return;
|
}else{
|
//直接在进入前台那个通知里面实现,实际上进入前台的方法会在这个方法前面调用,效果更好
|
[self InterruptionEndedAVAudioSessionSetActiveYES];
|
}
|
|
}
|
|
-(void)InterruptionEndedAVAudioSessionSetActiveYES{
|
if (isBackGround) {
|
return;
|
}
|
if (self.isInterrupt == YES) {
|
[_es onStartCapture];
|
[_es startTalk];
|
self.isInterrupt = NO;
|
}
|
}
|
|
- (void)speaker:(UIButton *)sender {
|
[_es stopTalk];
|
|
NSString *result = nil;
|
//听筒状态 插耳塞后拔掉后恢复到默认设置
|
if (sender == nil) {
|
result = [_sessionHelper speaker:NO];
|
}else{
|
if(!_isSpeaking){
|
result = [_sessionHelper speaker:YES];
|
_isSpeaking = YES;
|
}else{
|
result = [_sessionHelper speaker:NO];
|
_isSpeaking = NO;
|
}
|
}
|
if (result) {
|
[sender setTitle:result forState:UIControlStateNormal];
|
[_es startTalk];
|
}
|
|
}
|
|
- (void)audioRouteChangeListenerCallback:(NSNotification*)notification
|
{
|
|
NSDictionary *interuptionDict = notification.userInfo;
|
NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
|
switch (routeChangeReason) {
|
case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
|
//NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable");
|
//免提状态下耳机插入没有采集,同意切换到默认状态
|
NSLog(@"耳机插入");
|
[self speaker:nil];
|
break;
|
case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
|
//NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
|
NSLog(@"耳机拔出");
|
// if([[_speakerBtn titleForState:UIControlStateNormal] isEqualToString:@"免提"]){
|
// [self speaker:nil];
|
// }else{
|
// [self speaker:_speakerBtn];
|
// }
|
[self speaker:nil];
|
break;
|
case AVAudioSessionRouteChangeReasonCategoryChange:
|
// called at start - also when other audio wants to play
|
//NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange");
|
break;
|
}
|
}
|
|
/*
|
需要注意的是,有一个中断开始消息不一定会有一个中断结束消息,这就意味着中断结束的回调里的处理逻辑可能会没有被执行到。
|
所以需要关注当切到前台运行状态时,是不是需要重新激活你的 Audio Session。
|
*/
|
- (void)willEnterForeground:(NSNotification*)notification{
|
NSLog(@"willEnterForeground");
|
//初次启动会走这个通知(根页面),这时候是没有进入后台的
|
if (isBackGround) {
|
return;
|
}
|
|
[self InterruptionEndedAVAudioSessionSetActiveYES];
|
|
// 这里是考虑到用户没有授权,之后通过AlertAction跳转到设置页面授权后再回到APP时做的重新检测
|
//跳转到设置页面,授权后返回页面,继续初始化采集器
|
if (isAccessAudio && isAccessVideo) {
|
return;
|
}
|
if (isAccessVideo && !isAccessAudio) {
|
[self requestAccessForAVMediaType:AVMediaTypeAudio];
|
if (isAccessAudio) {
|
[_es initAudioCaptureSession];
|
}
|
}else if (!isAccessVideo && isAccessAudio){
|
[self requestAccessForAVMediaType:AVMediaTypeVideo];
|
if (isAccessVideo) {
|
[_es initVideoCaptureSession];
|
}
|
|
}else if (!isAccessVideo && !isAccessAudio){
|
[self requestAccessForAVMediaType:AVMediaTypeAudio];
|
[self requestAccessForAVMediaType:AVMediaTypeVideo];
|
if (isAccessAudio) {
|
[_es initAudioCaptureSession];
|
}
|
if (isAccessVideo) {
|
[_es initVideoCaptureSession];
|
}
|
}
|
}
|
- (void)willEnterBackground:(NSNotification *)notification {
|
isBackGround = YES;
|
}
|
|
//授权Alert
|
-(void)requestAccessForAVMedia{
|
if (!isAccessAudio) {
|
[self requestAccessForAVMediaType:AVMediaTypeAudio];
|
}
|
if (!isAccessVideo) {
|
[self requestAccessForAVMediaType:AVMediaTypeVideo];
|
}
|
if (!iSAudioNotDetermined && iSVideoNotDetermined){
|
[self creatAlertViewWith:@"授权请求" message:@"麦克风没有授权,请在设置中开启权限,否则将影响通讯功能。" cancel:@"确定"];
|
}else if(iSAudioNotDetermined && !iSVideoNotDetermined){
|
[self creatAlertViewWith:@"授权请求" message:@"相机没有授权,请在设置中开启权限,否则将影响通讯功能。" cancel:@"确定"];
|
}else if(!iSAudioNotDetermined && !iSVideoNotDetermined){
|
[self creatAlertViewWith:@"授权请求" message:@"麦克风与相机授权,请在设置中开启权限,否则将影响通讯功能。" cancel:@"确定"];
|
}
|
}
|
|
-(void)requestAccessForAVMediaType:(AVMediaType)type{
|
if (type == AVMediaTypeVideo) {
|
isAccessVideo = YES;
|
iSVideoNotDetermined = YES;
|
}else{
|
isAccessAudio = YES;
|
iSAudioNotDetermined = YES;
|
}
|
switch ([AVCaptureDevice authorizationStatusForMediaType:type])
|
{
|
case AVAuthorizationStatusAuthorized:
|
{
|
break;
|
}
|
case AVAuthorizationStatusNotDetermined:
|
{
|
dispatch_suspend(dispatch_get_main_queue());
|
[AVCaptureDevice requestAccessForMediaType:type completionHandler:^(BOOL granted) {
|
if (!granted) {
|
if (type == AVMediaTypeVideo) {
|
self->isAccessVideo = NO;
|
}else{
|
self->isAccessAudio = NO;
|
}
|
}
|
dispatch_resume(dispatch_get_main_queue());
|
}];
|
break;
|
}
|
default:
|
{
|
if (type == AVMediaTypeVideo) {
|
isAccessVideo = NO;
|
iSVideoNotDetermined = NO;
|
}else{
|
isAccessAudio = NO;
|
iSAudioNotDetermined = NO;
|
}
|
break;
|
}
|
}
|
}
|
|
-(void)creatAlertViewWith:(NSString *)title message:(NSString *) msg cancel:(NSString *)cancelMsg{
|
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
|
[alertController addAction:[UIAlertAction actionWithTitle:cancelMsg style:UIAlertActionStyleCancel handler:nil]];
|
[alertController addAction:[UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
|
}]];
|
[self presentViewController:alertController animated:YES completion:nil];
|
}
|
|
|
|
#pragma 保存图片到相册
|
- (void)saveImageToPhotosAlbum:(UIImage *)savedImage
|
{
|
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
|
if (status == PHAuthorizationStatusNotDetermined)
|
{
|
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
|
if(status == PHAuthorizationStatusAuthorized)
|
{
|
UIImageWriteToSavedPhotosAlbum(savedImage, self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), NULL);
|
}
|
}];
|
}
|
else
|
{
|
if (status == PHAuthorizationStatusAuthorized)
|
{
|
UIImageWriteToSavedPhotosAlbum(savedImage, self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), NULL);
|
}
|
}
|
}
|
|
// 指定回调方法
|
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
|
{
|
NSString *message = nil;
|
if (!error) {
|
message = saveToTheAlbumsStr;
|
}
|
else
|
{
|
message = operationFailedStr;
|
}
|
[self showUIAlertView:message];
|
}
|
|
|
|
#pragma 震动实现貌似和SDK冲突 不能实现震动
|
//开始播放的时候调用
|
-(void)startPlaySystemSound{
|
|
return;
|
// //震动的提示文件名放到资源目录下
|
// NSString *path = [[NSBundle mainBundle] pathForResource:@"ring" ofType:@"wav"];
|
// AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &sound);
|
//分别注册铃声和震动完后的回调
|
AudioServicesAddSystemSoundCompletion(kSystemSoundID_Vibrate, NULL, NULL, vibrationCompleteCallback, NULL);
|
// AudioServicesAddSystemSoundCompletion(sound, NULL, NULL, soundCompleteCallback, NULL);
|
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);//开始震动
|
// AudioServicesPlaySystemSound(sound);//开始播放铃声
|
}
|
|
//手动停止播放的时候调用
|
- (void)stopPlaySystemSound{
|
return;
|
NSLog(@"stop PlaySystemSound");
|
stopRingAndVibration();
|
}
|
|
//停止响铃和震动,移除回调并处理掉铃声和震动
|
void stopRingAndVibration() {
|
AudioServicesRemoveSystemSoundCompletion(kSystemSoundID_Vibrate);
|
// AudioServicesRemoveSystemSoundCompletion(sound);
|
AudioServicesDisposeSystemSoundID(kSystemSoundID_Vibrate);
|
// AudioServicesDisposeSystemSoundID(sound);
|
}
|
|
//震动完成回调,因为震动一下便会调用一次,这里延迟800ms再继续震动,和微信差不多,时间长短可自己控制。参数sound即为注册回调时传的第一个参数
|
void vibrationCompleteCallback(SystemSoundID sound,void * clientData) {
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(800 * NSEC_PER_MSEC)), dispatch_get_global_queue(0, 0), ^{
|
AudioServicesPlaySystemSound(sound);
|
});
|
}
|
|
////铃声播放完成回调,这种方法x播放的音频限制在30秒内,播放完直接响铃和震动
|
//void soundCompleteCallback(SystemSoundID sound,void * clientData) {
|
//
|
// stopRingAndVibration();
|
//}
|
|
|
@end
|