123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 |
- //
- // InCallViewController.m
- // JCSampleOC
- //
- // Created by Ginger on 2017/10/12.
- // Copyright © 2017年 juphoon. All rights reserved.
- //
- #import "SKInCallViewController.h"
- #import "VideoManager+ringtone.h"
- #define kDoodleVersionChecker 1
- #define AUDIO_RECORD_DIR @"audio_record"
- #define SNAPSHOT_DIR @"snapshot"
- #define VIDEO_RECORD_DIR @"video_record"
- @interface SKInCallViewController() {
- JCMediaDeviceVideoCanvas* _localCanvas;
- JCMediaDeviceVideoCanvas* _remoteCanvas;
- JCMediaDeviceVideoCanvas* _mSmallCanvas;
- NSTimer* _timer;
- BOOL isTouchInSmallCanvas;
- BOOL isMoveInSmallCanvas;
- CGPoint mStartPoint;
- }
- @property (weak, nonatomic) IBOutlet UIImageView *backgroudView;
- @property (weak, nonatomic) IBOutlet UIView *mIngHeaderView;
- @property (weak, nonatomic) IBOutlet UILabel *mIngNameLabel;
- @property (weak, nonatomic) IBOutlet UILabel *mIngTimeLabel;
- @property (weak, nonatomic) IBOutlet UILabel *mIngNetWorkLabel;
- @property (weak, nonatomic) IBOutlet UIView *mWaitHeaderView;
- @property (weak, nonatomic) IBOutlet UIImageView *mWaitHeadImage;
- @property (weak, nonatomic) IBOutlet UILabel *mWaitNameLabel;
- @property (weak, nonatomic) IBOutlet UILabel *mWaitInHintLabel;
- @property (weak, nonatomic) IBOutlet UILabel *mWaitOutHintLabel;
- @property (weak, nonatomic) IBOutlet UIView *mInVideoView;
- @property (weak, nonatomic) IBOutlet UIView *mOutView;
- @property (weak, nonatomic) IBOutlet UIView *mIngView;
- // selected 为相机打开状态, default 为相机关闭状态
- @property (weak, nonatomic) IBOutlet UIButton *switchCameraBtn;
- // selected 为保持通话状态, default 为未保持通话状态, disable 为被保持通话状态
- @property (weak, nonatomic) IBOutlet UIButton *holdBtn;
- // selected 为静音状态, default 为正常状态
- @property (weak, nonatomic) IBOutlet UIButton *muteBtn;
- // selected 为听筒模式, default 为扬声器模式
- @property (weak, nonatomic) IBOutlet UIButton *speakerBtn;
- @property (weak, nonatomic) IBOutlet UIButton *endCallBtn;
- @end
- @implementation SKInCallViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
-
- [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
-
- [EUtil setViewShadow:self.mWaitNameLabel color:[UIColor colorWithRed:0/255.0f green:1/255.0f blue:75/255.0f alpha:0.2] offset:CGSizeMake(0, 2) opacity:1 radius:4];
- [EUtil setViewShadow:self.mWaitOutHintLabel color:[UIColor colorWithRed:0/255.0f green:1/255.0f blue:75/255.0f alpha:0.2] offset:CGSizeMake(0, 2) opacity:1 radius:4];
- [EUtil setViewShadow:self.mWaitInHintLabel color:[UIColor colorWithRed:0/255.0f green:1/255.0f blue:75/255.0f alpha:0.2] offset:CGSizeMake(0, 2) opacity:1 radius:4];
- [VideoManager shared].mJuphoonMediaDevice.videoAngle = JCMediaDeviceVideoAngel0;
-
- [EUtil setViewShadow:self.mIngNameLabel color:[UIColor colorWithRed:0/255.0f green:1/255.0f blue:75/255.0f alpha:0.2] offset:CGSizeMake(0, 2) opacity:1 radius:4];
- [EUtil setViewShadow:self.mIngTimeLabel color:[UIColor colorWithRed:0/255.0f green:1/255.0f blue:75/255.0f alpha:0.2] offset:CGSizeMake(0, 2) opacity:1 radius:4];
- [EUtil setViewShadow:self.mIngNetWorkLabel color:[UIColor colorWithRed:0/255.0f green:1/255.0f blue:75/255.0f alpha:0.2] offset:CGSizeMake(0, 2) opacity:1 radius:4];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateUI:) name:kCallNotification object:nil];
-
- _mSmallCanvas = nil;
- isTouchInSmallCanvas = NO;
- isMoveInSmallCanvas = NO;
- [self initView];
- [self updateUI:nil];
- [[VideoManager shared] playVideoWaitingRingtone];
- }
- - (void)viewWillAppear:(BOOL)animated {
- [super viewWillAppear:animated];
- [self.navigationController setNavigationBarHidden:YES animated:NO];
- }
- - (void)viewDidAppear:(BOOL)animated {
- [[VideoManager shared].mJuphoonMediaDevice enableSpeaker:YES];
- }
- - (void)viewWillDisappear:(BOOL)animated {
- [super viewWillDisappear:animated];
- [self.navigationController setNavigationBarHidden:NO animated:NO];
- [self stopTimer];
- self.mIngTimeLabel.text = @"";
- self.mIngNetWorkLabel.text = @"";
- }
- - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
- return UIInterfaceOrientationMaskPortrait;
- }
- - (void)dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
- [[VideoManager shared] playVideoFinishRingtone];
- }
- - (NSObject*)getRemoteCanvas {
- return _remoteCanvas;
- }
- - (void)initView {
- [EUtil setURLImage:self.mWaitHeadImage placeHolderName:@"avatar" imageURL:[[VideoManager shared] getTalkHeadImageURL] cornerRadius:self.mWaitHeadImage.frame.size.width/2];
- }
- - (void)updateUI:(NSNotification *)noti {
- NSInteger count = [VideoManager shared].mJuphoonCall.callItems.count;
- JCCallItem *activeCall = [VideoManager shared].mJuphoonCall.callItems.firstObject;
- HDNormalLog(([NSString stringWithFormat:@"SKJuphoon: updateUI count:%ld updateUI: %ld", count, activeCall.state]));
- if (activeCall.state == JCCallStateInit || activeCall.state == JCCallStatePending) {
-
- self.mInVideoView.hidden = !activeCall.video || activeCall.direction == JCCallDirectionOut;
- self.mOutView.hidden = activeCall.direction != JCCallDirectionOut;
- self.mWaitHeaderView.hidden = NO;
- self.mIngHeaderView.hidden = YES;
- self.mIngView.hidden = YES;
-
- self.mIngNameLabel.text = @"";
- self.mWaitNameLabel.text = [[VideoManager shared] getTalkName];
- self.mWaitInHintLabel.hidden = activeCall.direction != JCCallDirectionIn;
- self.mWaitOutHintLabel.hidden = activeCall.direction != JCCallDirectionOut;
-
- if (activeCall.video) {
- if (_localCanvas == nil && activeCall.uploadVideoStreamSelf) {
- _localCanvas = [[VideoManager shared].mJuphoonMediaDevice startCameraVideo:JCMediaDeviceRenderFullScreen];
- //_localCanvas.videoView.frame = CGRectMake(SCREEN_WIDTH - 150, SCREEN_HEIGHT - 150 - 160, 120, 160);
- _localCanvas.videoView.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
- [self.view insertSubview:_localCanvas.videoView aboveSubview:self.backgroudView];
- } else if (_localCanvas != nil && !activeCall.uploadVideoStreamSelf) {
- [[VideoManager shared].mJuphoonMediaDevice stopVideo:_localCanvas];
- [_localCanvas.videoView removeFromSuperview];
- _localCanvas = nil;
- }
- }
- } else if (activeCall.state == JCCallStateTalking) {
- self.mInVideoView.hidden = YES;
- self.mOutView.hidden = YES;
- self.mWaitHeaderView.hidden = YES;
- self.mIngHeaderView.hidden = NO;
- self.mIngView.hidden = NO;
- self.mIngNameLabel.text = [[VideoManager shared] getTalkName];
- self.switchCameraBtn.enabled = activeCall.video;
- self.holdBtn.enabled = !activeCall.held;
- self.holdBtn.selected = activeCall.hold;
- self.muteBtn.selected = activeCall.mute;
- self.speakerBtn.selected = [VideoManager shared].mJuphoonMediaDevice.isSpeakerOn;
-
- if (activeCall != nil && activeCall.audioRecord && (activeCall.hold || activeCall.held)) {
- [[VideoManager shared].mJuphoonCall audioRecord:activeCall enable:false filePath:@""];
- }
- if (activeCall != nil && activeCall.localVideoRecord && !activeCall.uploadVideoStreamSelf) {
- //[[VideoManager shared].mJuphoonCall videoRecord:activeCall enable:false remote:false width:0 height:0 filePath:@""];
- [[VideoManager shared].mJuphoonCall videoRecord:activeCall enable:false remote:false width:0 height:0 filePath:@"" bothAudio:false keyFrame:10];
- }
- if (activeCall != nil && activeCall.remoteVideoRecord && !activeCall.uploadVideoStreamOther) {
- [[VideoManager shared].mJuphoonCall videoRecord:activeCall enable:false remote:true width:0 height:0 filePath:@"" bothAudio:false keyFrame:10];
- }
- if (activeCall.video) {
- if (_localCanvas != nil && activeCall.uploadVideoStreamSelf) {
- if (_mSmallCanvas == nil) {
- _localCanvas.videoView.frame = CGRectMake(SCREEN_WIDTH - 130, SCREEN_STATUS_HEIGHT+10, 120, 160);
- }
- _mSmallCanvas = _localCanvas;
- }
-
- if (_remoteCanvas == nil && activeCall.uploadVideoStreamOther) {
- _remoteCanvas = [[VideoManager shared].mJuphoonMediaDevice startVideo:activeCall.renderId renderType:JCMediaDeviceRenderFullContent];
- _remoteCanvas.videoView.frame = self.view.frame;
- _remoteCanvas.videoView.hidden = !activeCall.uploadVideoStreamSelf;
- [self.view insertSubview:_remoteCanvas.videoView aboveSubview:self.backgroudView];
- [[VideoManager shared].mJuphoonMediaDevice enableSpeaker:YES];
- } else if (_remoteCanvas != nil && !activeCall.uploadVideoStreamOther) {
- [[VideoManager shared].mJuphoonMediaDevice stopVideo:_remoteCanvas];
- [_remoteCanvas.videoView removeFromSuperview];
- _remoteCanvas = nil;
- }
- }
-
- [self startTimer];
- [[VideoManager shared] stopVideoRingtone];
- } else {
- self.mInVideoView.hidden = YES;
- }
- if (!activeCall.video) {
- [self removeCanvas];
- }
- }
- #pragma mark - Incoming Actions
- - (IBAction)endCall:(id)sender {
- //通话中挂断; 自己发起时,对方未接通,自己挂断//
- [[VideoManager shared] videoEnd:NO isSendMessage:YES];
- }
- - (IBAction)endCallWhenIncoming:(id)sender {
- //对方发起时,自己拒接//
- [[VideoManager shared] videoEnd:YES isSendMessage:YES];
- }
- - (IBAction)videoAnswer:(id)sender {
- [[VideoManager shared].mJuphoonCall answer:[self getActiveCall] video:true];
- }
- - (IBAction)voiceAnswer:(id)sender {
- [[VideoManager shared].mJuphoonCall answer:[self getActiveCall] video:false];
- }
- #pragma mark - In Calling Actions
- - (IBAction)setCameraState:(id)sender {
- [[VideoManager shared].mJuphoonCall enableUploadVideoStream:[self getActiveCall]];
- }
- - (IBAction)addNewCall:(id)sender {
- }
- - (IBAction)switchCamera:(id)sender {
- [[VideoManager shared].mJuphoonMediaDevice switchCamera];
- }
- - (IBAction)hold:(id)sender {
- [[VideoManager shared].mJuphoonCall hold:[self getActiveCall]];
- }
- - (IBAction)mute:(id)sender {
- [[VideoManager shared].mJuphoonCall mute:[self getActiveCall]];
- }
- - (IBAction)audioRecord:(id)sender {
- }
- - (IBAction)videoRecord:(id)sender {
- }
- - (IBAction)snapshot:(id)sender {
- }
- - (IBAction)speaker:(id)sender {
- [[VideoManager shared].mJuphoonMediaDevice enableSpeaker:![VideoManager shared].mJuphoonMediaDevice.isSpeakerOn];
- self.speakerBtn.selected = [VideoManager shared].mJuphoonMediaDevice.isSpeakerOn;
- }
- - (IBAction)callStatistics:(id)sender {
- }
- #pragma mark - 工具函数
- -(JCCallItem*)getActiveCall {
- for (JCCallItem* item in [VideoManager shared].mJuphoonCall.callItems) {
- if (item.active) {
- return item;
- }
- }
- return nil;
- }
- - (NSString *)genCallInfo:(JCCallItem*)item {
- switch (item.state) {
- case JCCallStateTalking:
- return [self formatTalkingTime:((long)[[NSDate date] timeIntervalSince1970] - item.talkingBeginTime)];
- default:
- return @"";
- }
- }
- - (NSString *)genNetStatus:(JCCallItem *)item {
- if (item.state != JCCallStateTalking) {
- return @"";
- }
- switch (item.videoNetSendStatus) {
- case JCCallNetWorkDisconnected:
- return NSLocalizedString(@"Video.Network.Status.0", nil);
- case JCCallNetWorkVeryBad:
- return NSLocalizedString(@"Video.Network.Status.1", nil);
- case JCCallNetWorkBad:
- return NSLocalizedString(@"Video.Network.Status.2", nil);
- case JCCallNetWorkNormal:
- return NSLocalizedString(@"Video.Network.Status.3", nil);
- case JCCallNetWorkGood:
- return NSLocalizedString(@"Video.Network.Status.4", nil);
- case JCCallNetWorkVeryGood:
- return NSLocalizedString(@"Video.Network.Status.5", nil);
- default:
- return @"";
- }
- }
- - (NSString *)formatTalkingTime:(long)time
- {
- return [NSString stringWithFormat:@"%02ld:%02ld", time/60, time%60];
- }
- - (void)removeCanvas {
- if (_localCanvas) {
- [[VideoManager shared].mJuphoonMediaDevice stopVideo:_localCanvas];
- [_localCanvas.videoView removeFromSuperview];
- _localCanvas = nil;
- _mSmallCanvas = nil;
- }
- if (_remoteCanvas) {
- [[VideoManager shared].mJuphoonMediaDevice stopVideo:_remoteCanvas];
- [_remoteCanvas.videoView removeFromSuperview];
- _remoteCanvas = nil;
- }
- }
- #pragma mark - Timer
- - (void)startTimer
- {
- if (_timer == nil) {
- _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerProc) userInfo:nil repeats:YES];
- }
- }
- - (void)stopTimer {
- if (_timer) {
- if ([_timer isValid]) {
- [_timer invalidate];
- _timer = nil;
- }
- }
- }
- - (void)timerProc {
- self.mIngHeaderView.hidden = NO;
- JCCallItem *activeCall = [VideoManager shared].mJuphoonCall.callItems.firstObject;
- self.mIngTimeLabel.text = [self genCallInfo:activeCall];
- self.mIngNetWorkLabel.text = [self genNetStatus:activeCall];
- if (activeCall.direction == JCCallDirectionOut) {
- }
- }
- - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
- //如果不在通话
- JCCallItem *activeCall = [VideoManager shared].mJuphoonCall.callItems.firstObject;
- if (!activeCall.video && activeCall.state != JCCallStateTalking)
- return;
-
- UITouch *touch = [touches anyObject];
- //当前的坐标,第一次触摸
- CGPoint point = [touch locationInView: self.view];
- mStartPoint = point;
-
- point = [_mSmallCanvas.videoView.layer convertPoint:point fromLayer:self.view.layer];
- if ([_mSmallCanvas.videoView.layer containsPoint:point]) {
- isTouchInSmallCanvas = YES;
- }
- else {
- isTouchInSmallCanvas = NO;
- }
- }
- - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
- //如果不在通话
- JCCallItem *activeCall = [VideoManager shared].mJuphoonCall.callItems.firstObject;
- if (!activeCall.video && activeCall.state != JCCallStateTalking)
- return;
-
- if (!isTouchInSmallCanvas)
- return;
-
- UITouch *touch = [touches anyObject];
- CGPoint movePoint = [touch locationInView: self.view];
-
- CGPoint offsetPoint = CGPointMake(movePoint.x - mStartPoint.x, movePoint.y - mStartPoint.y);
- if (offsetPoint.x == 0 && offsetPoint.y == 0)
- return;
-
- isMoveInSmallCanvas = YES;
- CGRect canvasRect = _mSmallCanvas.videoView.frame;
- CGPoint endPoint = CGPointMake(canvasRect.origin.x + offsetPoint.x, canvasRect.origin.y + offsetPoint.y);
-
- //避免超框
- if (endPoint.x < 0.0) {
- endPoint.x = 0.0;
- }
- if (endPoint.y < SCREEN_STATUS_HEIGHT) {
- endPoint.y = SCREEN_STATUS_HEIGHT;
- }
- if (endPoint.x + canvasRect.size.width > SCREEN_WIDTH) {
- endPoint.x = SCREEN_WIDTH - canvasRect.size.width;
- }
- if (endPoint.y + canvasRect.size.height > SCREEN_HEIGHT) {
- endPoint.y = SCREEN_HEIGHT - canvasRect.size.height;
- }
-
- [_mSmallCanvas.videoView setOrigin:endPoint];
-
- mStartPoint = movePoint;
- }
- - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
- //如果不在通话
- JCCallItem *activeCall = [VideoManager shared].mJuphoonCall.callItems.firstObject;
- if (!activeCall.video && activeCall.state != JCCallStateTalking)
- return;
-
- isTouchInSmallCanvas = NO;
- isMoveInSmallCanvas = NO;
- mStartPoint = CGPointMake(0, 0);
- }
- - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
- //如果不在通话
- JCCallItem *activeCall = [VideoManager shared].mJuphoonCall.callItems.firstObject;
- if (!activeCall.video && activeCall.state != JCCallStateTalking)
- return;
-
- isTouchInSmallCanvas = NO;
- isMoveInSmallCanvas = NO;
- mStartPoint = CGPointMake(0, 0);
- }
- @end
|