You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

945 lines
34 KiB

//
// CallViewController.m
// OpenDuo
//
// Created by suleyu on 2017/10/31.
// Copyright © 2017 Agora. All rights reserved.
//
//ios > 10
//#import <CallKit/CXCallObserver.h>
//#import <CallKit/CXCall.h>
#import "CallViewController.h"
#import <JLAuthorizationManager.h>
#import <AVFoundation/AVFoundation.h>
#import <AgoraRtcKit/AgoraRtcEngineKit.h>
#import "MJExtension.h"
#import "AppDelegate.h"
//CXCallObserverDelegate
@interface CallViewController ()<AgoraRtcEngineDelegate>
{
AVAudioPlayer *audioPlayer;
AgoraRtcEngineKit *mediaEngine;
int wait_duration;
NSInteger tempElapsed ;
BOOL hangUping;
//CXCallObserver *callObserver;
}
@property (strong, nonatomic) LGAlertView *alertView;
/// 远端摄像头预览
@property (weak, nonatomic) IBOutlet UIView *remoteVideo;
/// 自己摄像头预览
@property (weak, nonatomic) IBOutlet UIView *localVideo;
///头像
@property (weak, nonatomic) IBOutlet UIImageView *headImageView;
/// 名称
@property (weak, nonatomic) UILabel *nameLabel;
/// 通话时间
@property (weak, nonatomic) UILabel *timeLabel;
/// 摄像头开关
@property (weak, nonatomic) UIButton *onSwitchCameraBtn;
/// 摄像头切换
@property (weak, nonatomic) UIButton *switchCameraBtn;
/// 静音按钮
@property (weak, nonatomic) UIButton *muteBtn;
1 year ago
/// 接听按钮
@property (nonatomic ,weak) UIButton *answerBtn;
/// 挂断按钮(接通之后或拨打等待接听)
@property (nonatomic ,weak) UIButton *hangUpBtn;
/// 挂断按钮(被动呼叫等待接听)
@property (nonatomic ,weak) UIButton *lefthangUpBtn;
/// 麦克风开关
@property (nonatomic ,weak) UIButton *microphoneBtn;
/// 呼叫状态
@property (nonatomic ,weak) UILabel *statusLabel;
/// 与谁的通话
@property (nonatomic ,weak) UILabel *tonghuaLabel;
@property (strong, nonatomic) AgoraRtcEngineKit *agoraKit;
@property (nonatomic) int timeLength;
@property (strong, nonatomic) NSTimer *timeTimer;
/**
是否是接通状态
*/
@property (nonatomic) BOOL isCall;
@end
@implementation CallViewController
- (void)subViewsLayout
{
CGSize btnSize = CGSizeMake(70, 100);
WEAKSELF
/// 摄像头切换
UIButton *switchCameraBtn = [UICommon ui_buttonSimple:CGRectZero font:Font_(0) normalColor:KKClearColor normalText:@"" click:^(id x) {
[weakSelf.agoraKit switchCamera];
}];
switchCameraBtn.hidden = YES;
[switchCameraBtn setImage:ImageName_(@"video_icon_camera") forState:0];
self.switchCameraBtn = switchCameraBtn;
[self.view addSubview:switchCameraBtn];
[switchCameraBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view.mas_right).inset(16);
make.top.equalTo(self.view).offset(52);
make.size.mas_equalTo(CGSizeMake(28, 28));
}];
self.remoteVideo.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);
/// 自己摄像头预览
self.localVideo.frame = CGRectMake(ScreenWidth-116, 104, 100, 130);
self.localVideo.layer.borderWidth = 1;
self.localVideo.layer.borderColor = KKWhiteColorColor.CGColor;
self.localVideo.layer.cornerRadius = 4;
self.localVideo.layer.masksToBounds = YES;
self.localVideo.hidden = YES;
self.headImageView.hidden = YES;
self.headImageView.layer.cornerRadius = 12;
self.headImageView.layer.masksToBounds = YES;
[self.headImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.top.equalTo(self.view).offset(154);
make.size.mas_equalTo(CGSizeMake(128, 128));
}];
UILabel *nameLabel = [UICommon ui_label:CGRectZero lines:0 align:NSTextAlignmentCenter font:FontBold_(24) textColor:KKWhiteColorColor text:@"" Radius:0];
nameLabel.hidden = YES;
self.nameLabel = nameLabel;
[self.view addSubview:nameLabel];
[nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.top.equalTo(self.headImageView.mas_bottom).offset(14);
}];
/// 挂断按钮
UIButton *hangUpBtn = [UICommon ui_buttonSimple:CGRectZero font:Font_(14) normalColor:KKWhiteColorColor normalText:@"挂断" click:^(UIButton *btn) {
[weakSelf activeHangUpBtnAction:btn];
}];
hangUpBtn.size = btnSize;
hangUpBtn.hidden = YES;
[hangUpBtn setImage:ImageName_(@"video_icon_cancle") forState:0];
[self setBtnImageAndTitle:hangUpBtn];
self.hangUpBtn = hangUpBtn;
[self.view addSubview:hangUpBtn];
[hangUpBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.bottom.equalTo(self.view.mas_bottom).inset(58);
make.size.mas_equalTo(btnSize);
}];
/// 摄像头开关
UIButton *onSwitchCameraBtn = [UICommon ui_buttonSimple:CGRectZero font:Font_(14) normalColor:KKWhiteColorColor normalText:@"" click:^(UIButton *btn) {
btn.selected = !btn.selected;
[weakSelf.agoraKit enableLocalVideo:!btn.selected];
}];
onSwitchCameraBtn.size = btnSize;
onSwitchCameraBtn.hidden = YES;
[onSwitchCameraBtn setImage:ImageName_(@"video_icon_ cameraono") forState:UIControlStateNormal];
[onSwitchCameraBtn setImage:ImageName_(@"video_icon_ cameraoff") forState:UIControlStateSelected];
[onSwitchCameraBtn setTitle:@"摄像头已开" forState:UIControlStateNormal];
[onSwitchCameraBtn setTitle:@"摄像头已关" forState:UIControlStateSelected];
[self setBtnImageAndTitle:onSwitchCameraBtn];
self.onSwitchCameraBtn = onSwitchCameraBtn;
[self.view addSubview:onSwitchCameraBtn];
[onSwitchCameraBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view.mas_right).inset(40);
make.centerY.equalTo(hangUpBtn);
make.size.mas_equalTo(btnSize);
}];
/// 麦克风开关
UIButton *microphoneBtn = [UICommon ui_buttonSimple:CGRectZero font:Font_(14) normalColor:KKWhiteColorColor normalText:@"" click:^(UIButton *btn) {
btn.selected = !btn.selected;
[weakSelf.agoraKit muteLocalAudioStream:btn.selected];
}];
microphoneBtn.size = btnSize;
microphoneBtn.hidden = YES;
[microphoneBtn setImage:ImageName_(@"video_icon_muteon") forState:UIControlStateNormal];
[microphoneBtn setImage:ImageName_(@"video_icon_muteoff") forState:UIControlStateSelected];
[microphoneBtn setTitle:@"麦克风已开" forState:UIControlStateNormal];
[microphoneBtn setTitle:@"麦克风已关" forState:UIControlStateSelected];
[self setBtnImageAndTitle:microphoneBtn];
self.microphoneBtn = microphoneBtn;
[self.view addSubview:microphoneBtn];
[microphoneBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(40);
make.centerY.equalTo(hangUpBtn);
make.size.mas_equalTo(btnSize);
}];
/// 挂断按钮(被动呼叫等待接听)
UIButton *lefthangUpBtn = [UICommon ui_buttonSimple:CGRectZero font:Font_(14) normalColor:KKWhiteColorColor normalText:@"挂断" click:^(UIButton *btn) {
[weakSelf hangUpButton:btn];
}];
lefthangUpBtn.size = btnSize;
lefthangUpBtn.hidden = YES;
[lefthangUpBtn setImage:ImageName_(@"video_icon_cancle") forState:0];
[self setBtnImageAndTitle:lefthangUpBtn];
self.lefthangUpBtn = lefthangUpBtn;
[self.view addSubview:lefthangUpBtn];
[lefthangUpBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(40);
make.centerY.equalTo(hangUpBtn);
make.size.mas_equalTo(btnSize);
}];
/// 接听按钮
UIButton *answerBtn = [UICommon ui_buttonSimple:CGRectZero font:Font_(14) normalColor:KKWhiteColorColor normalText:@"接听" click:^(UIButton *btn) {
[weakSelf acceptBtnAction:btn];
}];
answerBtn.size = btnSize;
answerBtn.hidden = YES;
[answerBtn setImage:ImageName_(@"video_icon_pickup") forState:UIControlStateNormal];
[self setBtnImageAndTitle:answerBtn];
self.answerBtn = answerBtn;
[self.view addSubview:answerBtn];
[answerBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view.mas_right).inset(40);
make.centerY.equalTo(hangUpBtn);
make.size.mas_equalTo(btnSize);
}];
/// 通话时间
UILabel *timeLabel = [UICommon ui_label:CGRectZero lines:0 align:NSTextAlignmentCenter font:FontBold_(18) textColor:KKWhiteColorColor text:@"" Radius:0];
timeLabel.hidden = YES;
self.timeLabel = timeLabel;
[self.view addSubview:timeLabel];
[timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.bottom.equalTo(hangUpBtn.mas_top).inset(24);
}];
UILabel *statusLabel = [UICommon ui_label:CGRectZero lines:0 align:NSTextAlignmentCenter font:Font_(16) textColor:KKWhiteColorColor text:@"" Radius:0];
statusLabel.hidden = YES;
self.statusLabel = statusLabel;
[self.view addSubview:statusLabel];
[statusLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.top.equalTo(nameLabel.mas_bottom).offset(60);
}];
UILabel *tonghuaLabel = [UICommon ui_label:CGRectZero lines:0 align:NSTextAlignmentCenter font:FontBold_(18) textColor:KKWhiteColorColor text:@"" Radius:0];
tonghuaLabel.hidden = YES;
self.tonghuaLabel = tonghuaLabel;
[self.view addSubview:tonghuaLabel];
[tonghuaLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view).inset(64);
make.centerY.equalTo(switchCameraBtn);
}];
}
- (void)viewDidLoad
{
[super viewDidLoad];
WEAKSELF
//添加通知
[[NSNotificationCenter defaultCenter] addObserverForName:AccountMessageNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
NSDictionary *dic = note.object;
NSDictionary *msgDic = dic[@"message"];
NSString * msgType = msgDic[@"type"];
if([msgType isEqualToString:@"reject"]){
//拒绝视频通话
[weakSelf activeHangUpBtnAction:nil];
}else{
return ;
}
}];
[self subViewsLayout];
1 year ago
//view.layer.masksToBounds = YES;
//判断性别
NSString *sexImageName = [cUser.cDevice.sex isEqualToString:@"girl"] ? @"icon_girl_head_portrait" : @"icon_boy_head_portrait";
[self.headImageView sd_setImageWithURL:[NSURL URLWithString:self.device.avator]
placeholderImage:[myHelper getImageWithName:sexImageName]
options:SDWebImageRetryFailed];
self.nameLabel.text = self.device.name;
//设置视频 分辨率等设置
// [self setupVideo];
//设置 本地视频摄像头
// [self setupLocalVideo];
JLAuthorizationManager *jlManager = [JLAuthorizationManager defaultManager];
[jlManager JL_requestAuthorizationWithAuthorizationType:JLAuthorizationTypeAudio
authorizedHandler:nil
unAuthorizedHandler:^{
LGAlertView *alertView = [[LGAlertView alloc] initWithTitle:@"请为作业帮打开麦克风权限" message:nil style:LGAlertViewStyleAlert buttonTitles:@[@"确定"] cancelButtonTitle:@"取消" destructiveButtonTitle:nil actionHandler:^(LGAlertView *alertView, NSString *title, NSUInteger index) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
} cancelHandler:^(LGAlertView *alertView) {
if(weakSelf.isReceiveCall){
[weakSelf activeHangUpBtnAction:nil];
}else{
[weakSelf hangUpButton:nil];
}
} destructiveHandler:nil];
[alertView showAnimated:YES completionHandler:nil];
}];
// MARK: 处理来电接听挂断
if([UIDevice currentDevice].systemVersion.floatValue > 10.0){
//callObserver= [CXCallObserver new];
//[callObserver setDelegate:self queue:dispatch_get_main_queue()];
}
}
- (void)initializeAgoraEngine
{
xLog(@"声网 SDK 版本 %@",[AgoraRtcEngineKit getSdkVersion]);
AgoraRtcEngineConfig *config = [AgoraRtcEngineConfig new];
config.appId = self.appid;
config.areaCode = AgoraAreaCodeTypeCN;
config.channelProfile = AgoraChannelProfileLiveBroadcasting;
self.agoraKit = [AgoraRtcEngineKit sharedEngineWithConfig:config delegate:self];
//[self.agoraKit setChannelProfile:AgoraChannelProfileLiveBroadcasting];
[self.agoraKit setClientRole:AgoraClientRoleBroadcaster];
//[self.agoraKit setLogFile:@"agorasdk"];
/// 设置默认使用前置摄像头
AgoraCameraCapturerConfiguration *Camera = [[AgoraCameraCapturerConfiguration alloc] init];
Camera.cameraDirection = AgoraCameraDirectionFront;
[self.agoraKit setCameraCapturerConfiguration:Camera];
[self.agoraKit enableVideo];
/// 设置 视频分辨率
[self setupVideo];
}
/**
设置 视频分辨率
*/
- (void)setupVideo
{
// Default mode is disableVideo
[self.agoraKit setParameters:@"{\"engine.video.codec_type\":\"20\"}"];
[self.agoraKit setParameters:@"{\"rtc.audio.acm_ptime\":60}"];
[self.agoraKit setParameters:@"{\"che.audio.custom_payload_type\":9}"];
if(self.videoSize.width == 160 && self.videoSize.height == 128){
self.videoSize = CGSizeMake(160, 128);
AgoraVideoEncoderConfiguration *encoderConfiguration =
[[AgoraVideoEncoderConfiguration alloc] initWithSize:self.videoSize
frameRate:5
bitrate:1000
orientationMode:AgoraVideoOutputOrientationModeFixedLandscape
mirrorMode:AgoraVideoMirrorModeAuto];
encoderConfiguration.dimensions = self.videoSize;
[self.agoraKit setVideoEncoderConfiguration:encoderConfiguration];
}
else
{
//[self.agoraKit setParameters:@"{\"rtc.audio.custom_payload_type\":9}"];
self.videoSize = AgoraVideoDimension240x240;
AgoraVideoEncoderConfiguration *encoderConfiguration =
[[AgoraVideoEncoderConfiguration alloc] initWithSize:self.videoSize
frameRate:5//AgoraVideoFrameRateFps7
bitrate:1000//AgoraVideoBitrateStandard
orientationMode:AgoraVideoOutputOrientationModeFixedPortrait
mirrorMode:AgoraVideoMirrorModeAuto];
encoderConfiguration.dimensions = AgoraVideoDimension240x240;
[self.agoraKit setVideoEncoderConfiguration:encoderConfiguration];
}
[self setupLocalVideo];
//添加拖动手势
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc]
initWithTarget:self
action:@selector(handlePan:)];
[self.remoteVideo addGestureRecognizer:panGestureRecognizer];
//双击手势
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleDoubleTap:)];
doubleTapGesture.numberOfTapsRequired = 2;
doubleTapGesture.numberOfTouchesRequired = 1;
[self.remoteVideo addGestureRecognizer:doubleTapGesture];
}
/**
初始化自己的 视频界面
*/
- (void)setupLocalVideo
{
// if(self.videoSize.width == 160 && self.videoSize.height == 128)
// self.localVideo.frame = CGRectMake(ScreenWidth-(128*Adapted(0.35))-50, 50, 160*Adapted(0.35), 128*Adapted(0.35));
// else
// self.localVideo.frame = CGRectMake(ScreenWidth*(1-0.25)-25, 50, ScreenWidth * 0.25, ScreenHeight*0.25);
self.localVideo.backgroundColor = UIColor.blackColor;
AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
videoCanvas.uid = self.uid;
videoCanvas.view = self.localVideo;
//videoCanvas.renderMode = AgoraVideoRenderModeFit;
videoCanvas.mirrorMode = AgoraVideoMirrorModeAuto;
[self.agoraKit setupLocalVideo:videoCanvas];
[self.agoraKit startPreview];
[self.agoraKit setDefaultAudioRouteToSpeakerphone:YES];
//MARK: 设置录音的音量是原本的4
[self.agoraKit adjustRecordingSignalVolume:400];
self.localVideo.hidden = YES;
//添加拖动手势
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc]
initWithTarget:self
action:@selector(handlePan:)];
[self.localVideo addGestureRecognizer:panGestureRecognizer];
//双击手势
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleDoubleTap:)];
doubleTapGesture.numberOfTapsRequired = 2;
doubleTapGesture.numberOfTouchesRequired = 1;
[self.localVideo addGestureRecognizer:doubleTapGesture];
}
/**
MARK:加入通道
*/
- (void)joinChannel
{
if(self.channelID && self.uid )
{
WeakSelf
AgoraRtcChannelMediaOptions *option = [AgoraRtcChannelMediaOptions new];
[option setPublishCameraTrack:YES];
[option setClientRoleType:AgoraClientRoleBroadcaster];
int res = [self.agoraKit joinChannelByToken:self.token channelId:self.channelID uid:self.uid mediaOptions:option joinSuccess:^(NSString * _Nonnull channel, NSUInteger uid, NSInteger elapsed) {
xLog(@"加入通道");
//启动定时器
[weakSelf _startTimeTimer];
self.agoraKit.delegate = self;
}];
xLog(@"加入通道res == %d" , res);
//音频外放
[self.agoraKit setEnableSpeakerphone:YES];
//启用不自动锁屏
[UIApplication sharedApplication].idleTimerDisabled = YES;
}
}
/**
MARK: APP 接听按钮
*/
- (IBAction)acceptBtnAction:(id)sender {
self.isCall = YES;
[self joinChannel];
[self stopRing];
}
/**
MARK: APP 主动挂断按钮 (接通后APP的挂断)
*/
- (void)activeHangUpBtnAction:(id)sender
{
[self stopRing];
[self leaveChannel];
if(!hangUping)
{
WEAKSELF
if(sender){
//API 接口 下发指令给设备 上传 video_id
[cUser activeHangUpVideoID:self.video_id WithDevice:self.device WithSuccess:^(id responseObject) {
xLog(@"主动挂断成功");
self->hangUping = NO;
[weakSelf dismissViewControllerAnimated:YES completion:nil];
} failure:^{
xLog(@"主动挂断失败");
self->hangUping = NO;
[weakSelf dismissViewControllerAnimated:YES completion:nil];
}];
}
else
{
if(self.isCall){
return;
}
//MARK: 收到设备主动挂断 后的 推送的 动作
//[UICommon MessageUpload:@""InfoWithStatus:[NSString stringWithFormat:@"%@ 拒绝了你的通话请求",cUser.cDevice.name]];
[UICommon MessageSuccessText:@"视频通话结束" isImg:NO];
AfterDispatch(1, ^{
[weakSelf dismissViewControllerAnimated:YES completion:nil];
});
}
}
}
/**
MARK: APP 被动挂断按钮 (接通前APP的挂断)
*/
- (IBAction)hangUpButton:(UIButton *)sender {
[self stopRing];
[self leaveChannel];
if(!hangUping){
hangUping = YES;
WEAKSELF
//API 接口 下发指令给设备 上传 video_id
[cUser activeHangUpVideoID:self.video_id WithDevice:self.device WithSuccess:^(id responseObject) {
xLog(@"主动挂断成功");
[weakSelf dismissViewControllerAnimated:YES completion:nil];
self->hangUping = NO;
} failure:^{
xLog(@"主动挂断失败");
self->hangUping = NO;
}];
}
}
/**
MARK: 离开通道
*/
- (void)leaveChannel
{
xLog(@"调用离开通道接口");
if(self.alertView){
[self.alertView dismissAnimated:YES completionHandler:nil];
}
WEAKSELF
[self.agoraKit leaveChannel:^(AgoraChannelStats *stat) {
//取消不自动锁屏
[UIApplication sharedApplication].idleTimerDisabled = NO;
[weakSelf.remoteVideo removeFromSuperview];
[weakSelf.localVideo removeFromSuperview];
//停止定时器
[weakSelf _stopTimeTimer];
if(weakSelf.isCall){
//上传视频时间
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
long tempTime = stat.duration-self->wait_duration;
if(stat.duration - self->wait_duration < 0){
tempTime = 0;
}
[dic setValue:@(tempTime) forKey:@"duration"];
[dic setValue:@(self->wait_duration) forKey:@"wait_duration"];//wait_duration
[dic setValue:@(weakSelf.videoSize.width) forKey:@"distinguishability_width"];
[dic setValue:@(weakSelf.videoSize.height) forKey:@"distinguishability_heiger"];
[dic setValue:self.video_id forKey:@"video_id"];
[cUser postVideoCallTimeParame:[dic copy] deviceModel:self.device success:^(id responseObject) {
xLog(@"上传视频时间成功");
//MARK: 上传完视频时间后删除存储的 Key
[UserDefaults removeObjectForKey:VideoTimeAndIDAndWHRecordKey];
} failure:^{
xLog(@"上传视频时间失败");
}];
}
[weakSelf dismissViewControllerAnimated:YES completion:^{
}];
}];
}
/**
用户在 视频通话 和 语音通话间切换 (暂时不用)
*/
- (IBAction)didClickVideoMuteButton:(UIButton *)sender {
sender.selected = !sender.selected;
[self.agoraKit muteLocalVideoStream:sender.selected];
//self.localVideo.hidden = sender.selected;
}
#pragma mark AgoraRtcEngineDelegate
/// 发生错误回调
- (void)rtcEngine:(AgoraRtcEngineKit *_Nonnull)engine didOccurError:(AgoraErrorCode)errorCode{
xLog(@"===发生错误回调 errorCode:%ld",errorCode);
}
/// Token 服务即将过期回调
- (void)rtcEngine:(AgoraRtcEngineKit *)engine tokenPrivilegeWillExpire:(NSString *)token
{
xLog(@"Token 服务即将过期回调 token:%@",token);
}
/// Token 过期回调
-(void)rtcEngineRequestToken:(AgoraRtcEngineKit *)engine
{
xLog(@"Token 过期回调");
}
- (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinedOfUid:(NSUInteger)uid elapsed:(NSInteger)elapsed
{
NSLog(@"\n\n\n\n远端用户加入频道\n\n\n\n\n");
[self stopRing];
if(self.isCall == NO){
//MARK: 赋值等待时间
wait_duration = self.timeLength;
self.timeLength = 0;
[self _stopTimeTimer];
[self _startTimeTimer];
}
self.isCall = YES;
if (self.remoteVideo.hidden)
{
self.remoteVideo.hidden = NO;
}
AgoraRtcVideoCanvas *videoCanvas = [[AgoraRtcVideoCanvas alloc] init];
videoCanvas.uid = uid;
1 year ago
videoCanvas.renderMode = AgoraVideoRenderModeHidden;
videoCanvas.view = self.remoteVideo;
[self.agoraKit setupRemoteVideo:videoCanvas];
}
- (void)rtcEngine:(AgoraRtcEngineKit *)engine didJoinChannel:(NSString *)channel withUid:(NSUInteger)uid elapsed:(NSInteger) elapsed
{
NSLog(@"*本地用户成功加入指定通道时发生。");
}
- (void)rtcEngine:(AgoraRtcEngineKit *)engine remoteVideoStateChangedOfUid:(NSUInteger)uid state:(AgoraVideoRemoteState)state reason:(AgoraVideoRemoteReason)reason elapsed:(NSInteger)elapsed
{
NSLog(@"************************");
//self.isCall = YES;
}
- (void)rtcEngine:(AgoraRtcEngineKit *)engine localVideoStats:(AgoraRtcLocalVideoStats * _Nonnull)stats
{
NSLog(@"本地视频流");
}
////MARK: 视频的暂停 和 恢复
//- (void)rtcEngine:(AgoraRtcEngineKit *)engine didVideoMuted:(BOOL)muted byUid:(NSUInteger)uid {
// NSLog(@"//MARK: 视频的暂停 和 恢复");
// self.remoteVideo.hidden = muted;
//}
//MARK: 频道的统计数据 回调 每两秒触发一次。
-(void)rtcEngine:(AgoraRtcEngineKit *)engine reportRtcStats:(AgoraChannelStats *)stats
{
NSLog(@"//MARK: 频道的统计数据 回调 每两秒触发一次。");
if(self.isCall)
{
// self.timeLength = (int)stats.duration - wait_duration;
//MARK:记录视频通话时间
[UserDefaults setValue:[NSString stringWithFormat:@"%@&%@&%@&%@&%@",@(stats.duration),self.video_id,@(self.videoSize.width),@(self.videoSize.height),@(wait_duration)] forKey:VideoTimeAndIDAndWHRecordKey];
}
}
//MARK: 用户离线回调
- (void)rtcEngine:(AgoraRtcEngineKit *)engine didOfflineOfUid:(NSUInteger)uid reason:(AgoraUserOfflineReason)reason
{
self.remoteVideo.hidden = true;
switch (reason) {
case AgoraUserOfflineReasonQuit:
//用户主动离开
xLog(@"用户主动离开");
[self leaveChannel];
break;
case AgoraUserOfflineReasonBecomeAudience:
//用户身份从主播切换为观众时触发
xLog(@"用户身份从主播切换为观众时触发");
break;
case AgoraUserOfflineReasonDropped:
//因过长时间收不到对方数据包,超时掉线。注意:由于 SDK 使用的是不可靠通道,也有可能对方主动离开本方没收到对方离开消息而误判为超时掉线
xLog(@"因过长时间收不到对方数据包,超时掉线。注意:由于 SDK 使用的是不可靠通道,也有可能对方主动离开本方没收到对方离开消息而误判为超时掉线");
break;
}
if(reason == AgoraUserOfflineReasonBecomeAudience)
{
return;
}
if(uid == self.device_uid)
{
[self leaveChannel];
[UICommon MessageSuccessText:[NSString stringWithFormat:@"%@已挂断",cUser.cDevice.name] isImg:NO];
}
if(uid == self.uid){
xLog(@"自己离开通道");
}
}
#pragma mark - 时间定时器
- (void)timeTimerAction:(id)sender
{
self.timeLength += 1;
if(self.isCall == NO)
{
//未接通的情况
if(self.timeLength == self.wait_time)
{
wait_duration = self.wait_time;
[self leaveChannel];
WEAKSELF
[UICommon MessageSuccessText:[NSString stringWithFormat:@"%@ 未接听",self.device.name] isImg:NO];
AfterDispatch(1, ^{
[weakSelf dismissViewControllerAnimated:YES completion:nil];
});
[self _stopTimeTimer];
return;
}
else
{
wait_duration = self.timeLength;
}
}
if(self.timeLength == self.limit_time - DefineVideoLimitBeforeShowTime){
self.alertView = [[LGAlertView alloc] initWithTitle:@"提示" message:@"为防止设备温度过高,即将结束通话,稍后可正常使用" style:LGAlertViewStyleAlert buttonTitles:@[@"确定"] cancelButtonTitle:@"" destructiveButtonTitle:nil actionHandler:^(LGAlertView *alertView, NSString *title, NSUInteger index) {
} cancelHandler:^(LGAlertView *alertView) {
} destructiveHandler:nil];
[self.alertView showAnimated:YES completionHandler:nil];
}
//限制时间, 不能和设备视频太长时间 默认是 180s (3分钟)
if(self.timeLength == self.limit_time)
{
[self hangUpButton:nil];
return;
}
if(self.isCall)
{
int hour = self.timeLength / 3600;
int m = (self.timeLength - hour * 3600) / 60;
int s = self.timeLength - hour * 3600 - m * 60;
if (hour > 0)
{
self.timeLabel.text = [NSString stringWithFormat:@"%02i:%02i:%02i", hour, m, s];
}
else if(m > 0)
{
self.timeLabel.text = [NSString stringWithFormat:@"%02i:%02i", m, s];
}
else
{
self.timeLabel.text = [NSString stringWithFormat:@"00:%02i", s];
}
}
}
- (void)_startTimeTimer
{
[self _stopTimeTimer];
self.timeLength = 0;
self.timeTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeTimerAction:) userInfo:nil repeats:YES];
}
- (void)_stopTimeTimer
{
if (self.timeTimer)
{
[self.timeTimer invalidate];
self.timeTimer = nil;
}
}
//MARK: 响铃的 MP3
- (void)playRing:(NSString *)name
{
[self stopRing];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
NSURL *path = [[NSBundle mainBundle] URLForResource:name withExtension:@"mp3"];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:path error:nil];
audioPlayer.numberOfLoops = -1;
[audioPlayer play];
}
- (void)stopRing
{
if (audioPlayer)
{
[audioPlayer stop];
audioPlayer = nil;
}
}
-(void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[self stopRing]; //停止响铃
//移除通知
[[NSNotificationCenter defaultCenter] removeObserver:self name:AccountMessageNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self initializeAgoraEngine];
WEAKSELF
if(!self.isReceiveCall)
{
//主动拨打
self.hangUpBtn.hidden = NO;
self.headImageView.hidden = NO;
self.nameLabel.hidden = NO;
self.statusLabel.hidden = NO;
self.statusLabel.text = @"正在呼叫中...";
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf playRing:@"ring"];
});
[self joinChannel];
}
else
{
//被动接听
self.headImageView.hidden = NO;
self.nameLabel.hidden = NO;
self.statusLabel.hidden = NO;
self.statusLabel.text = @"连接中";
self.lefthangUpBtn.hidden = NO;
self.answerBtn.hidden = NO;
if([UIApplication sharedApplication].applicationState == UIApplicationStateActive){
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf playRing:@"tones"];
});
}
}
}
- (void)setIsCall:(BOOL)isCall
{
_isCall = isCall;
if(isCall)
{
//隐藏 设备 头像 和 昵称 显示 (默认是显示的)
self.headImageView.hidden = YES;
self.nameLabel.hidden = YES;
self.lefthangUpBtn.hidden = YES;
self.answerBtn.hidden = YES; /// 接听按钮
self.statusLabel.hidden = YES;
self.localVideo.hidden = NO; // 显示自己
self.timeLabel.hidden = NO;
self.switchCameraBtn.hidden = NO;/// 切换摄像头
self.microphoneBtn.hidden = NO; /// 麦克风
self.muteBtn.hidden = NO; /// 静音按钮
self.onSwitchCameraBtn.hidden = NO; /// 摄像头开关
self.hangUpBtn.hidden = NO; /// 接通后挂断按钮
self.tonghuaLabel.hidden = NO;
self.tonghuaLabel.text = [NSString stringWithFormat:@"与%@的对话",self.device.name];
}
}
//MARK: --- 拖动手势 ----
- (void)handlePan:(UIPanGestureRecognizer*)recognizer
{
UIView *selectView = recognizer.view;
if(selectView.bounds.size.width != ScreenWidth)
{ //不是全屏状态
// Figure out where the user is trying to drag the view.
CGPoint translation = [recognizer translationInView:self.view];
CGPoint newCenter = CGPointMake(recognizer.view.center.x+ translation.x,
recognizer.view.center.y + translation.y);// 限制屏幕范围:
newCenter.y = MAX(recognizer.view.frame.size.height/2, newCenter.y);
newCenter.y = MIN(self.view.frame.size.height - recognizer.view.frame.size.height/2, newCenter.y);
newCenter.x = MAX(recognizer.view.frame.size.width/2, newCenter.x);
newCenter.x = MIN(self.view.frame.size.width - recognizer.view.frame.size.width/2,newCenter.x);
recognizer.view.center = newCenter;
[recognizer setTranslation:CGPointZero inView:self.view];
}
}
//MARK: --- 双击放大----
-(void)handleDoubleTap:(UIGestureRecognizer *)recognizer
{
UIView *selectView = recognizer.view;
CGRect tempRect = selectView.frame;
if(selectView.bounds.size.width != ScreenWidth)
{
if([self.localVideo isEqual:selectView])
{
self.localVideo.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);
self.remoteVideo.frame = tempRect;
[self.view exchangeSubviewAtIndex:self.remoteVideo.getInSuperViewIndex withSubviewAtIndex:self.localVideo.getInSuperViewIndex];
}else{
self.remoteVideo.frame = CGRectMake(0, 0, ScreenWidth, ScreenHeight);
self.localVideo.frame = tempRect;
[self.view exchangeSubviewAtIndex:self.localVideo.getInSuperViewIndex withSubviewAtIndex:self.remoteVideo.getInSuperViewIndex];
}
}
}
- (void)setBtnImageAndTitle:(UIButton *)button
{
CGFloat offset = 20.0f;
button.titleEdgeInsets = UIEdgeInsetsMake(0,-button.imageView.frame.size.width,-button.imageView.frame.size.height-offset/2,0);
// button.imageEdgeInsets = UIEdgeInsetsMake(-button.titleLabel.frame.size.height-offset/2,0,0,-button.titleLabel.frame.size.width);
// 由于iOS8中titleLabel的size为0,用上面这样设置有问题,修改一下即可
button.imageEdgeInsets = UIEdgeInsetsMake(-button.titleLabel.intrinsicContentSize.height-offset/2,0,0,-button.titleLabel.intrinsicContentSize.width);
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end