WFCUVideoViewController.m 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. //
  2. // ViewController.m
  3. // WFDemo
  4. //
  5. // Created by heavyrain on 17/9/27.
  6. // Copyright © 2017年 WildFireChat. All rights reserved.
  7. //
  8. #import "WFCUVideoViewController.h"
  9. #import <AVFoundation/AVFoundation.h>
  10. #import <AVKit/AVKit.h>
  11. #import <WebRTC/WebRTC.h>
  12. #import <WFAVEngineKit/WFAVEngineKit.h>
  13. #import "SDWebImage.h"
  14. #import "WFCUFloatingWindow.h"
  15. #import <WFChatClient/WFCCConversation.h>
  16. @interface WFCUVideoViewController () <UITextFieldDelegate, WFAVCallSessionDelegate>
  17. @property (nonatomic, strong) UIView *bigVideoView;
  18. @property (nonatomic, strong) UIView *smallVideoView;
  19. @property (nonatomic, strong) UIButton *hangupButton;
  20. @property (nonatomic, strong) UIButton *answerButton;
  21. @property (nonatomic, strong) UIButton *switchCameraButton;
  22. @property (nonatomic, strong) UIButton *audioButton;
  23. @property (nonatomic, strong) UIButton *speakerButton;
  24. @property (nonatomic, strong) UIButton *downgradeButton;
  25. @property (nonatomic, strong) UIButton *videoButton;
  26. @property (nonatomic, strong) UIButton *scalingButton;
  27. @property (nonatomic, strong) UIButton *minimizeButton;
  28. @property (nonatomic, strong) UIImageView *portraitView;
  29. @property (nonatomic, strong) UILabel *userNameLabel;
  30. @property (nonatomic, strong) UILabel *stateLabel;
  31. @property (nonatomic, assign) BOOL audioMuted;
  32. @property (nonatomic, assign) BOOL videoMuted;
  33. @property (nonatomic, strong) WFAVCallSession *currentSession;
  34. @property (nonatomic, strong) RTCVideoTrack *localVideoTrack;
  35. @property (nonatomic, strong) RTCVideoTrack *remoteVideoTrack;
  36. @property (nonatomic, assign) WFAVVideoScalingType scalingType;
  37. @property (nonatomic, assign) CGPoint panStartPoint;
  38. @property (nonatomic, assign) CGRect panStartVideoFrame;
  39. @property (nonatomic, strong) NSTimer *connectedTimer;
  40. @end
  41. #define ButtonSize 90
  42. #define SmallVideoView 120
  43. @implementation WFCUVideoViewController
  44. - (instancetype)initWithSession:(WFAVCallSession *)session {
  45. self = [super init];
  46. if (self) {
  47. self.currentSession = session;
  48. self.currentSession.delegate = self;
  49. [self didChangeState:kWFAVEngineStateIncomming];
  50. self.audioMuted = NO;
  51. self.videoMuted = NO;
  52. }
  53. return self;
  54. }
  55. - (instancetype)initWithTarget:(NSString *)targetId conversation:(WFCCConversation *)conversation audioOnly:(BOOL)audioOnly {
  56. self = [super init];
  57. if (self) {
  58. WFAVCallSession *session = [[WFAVEngineKit sharedEngineKit] startCall:targetId
  59. audioOnly:audioOnly
  60. conversation:conversation
  61. sessionDelegate:self];
  62. self.currentSession = session;
  63. self.audioMuted = NO;
  64. self.videoMuted = NO;
  65. }
  66. return self;
  67. }
  68. - (void)viewDidLoad {
  69. [super viewDidLoad];
  70. [self.view setBackgroundColor:[UIColor blackColor]];
  71. self.scalingType = kWFAVVideoScalingTypeAspectBalanced;
  72. self.bigVideoView = [[UIView alloc] initWithFrame:self.view.bounds];
  73. [self.view addSubview:self.bigVideoView];
  74. self.smallVideoView = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.size.width - SmallVideoView, kStatusBarAndNavigationBarHeight, SmallVideoView, SmallVideoView * 4 /3)];
  75. [self.smallVideoView addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onSmallVideoPan:)]];
  76. [self.view addSubview:self.smallVideoView];
  77. [self checkAVPermission];
  78. if(self.currentSession.state == kWFAVEngineStateOutgoing && !self.currentSession.isAudioOnly) {
  79. [[WFAVEngineKit sharedEngineKit] startPreview];
  80. }
  81. WFCCUserInfo *user = [[WFCCIMService sharedWFCIMService] getUserInfo:self.currentSession.clientId refresh:NO];
  82. self.portraitView = [[UIImageView alloc] init];
  83. [self.portraitView sd_setImageWithURL:[NSURL URLWithString:user.portrait] placeholderImage:[UIImage imageNamed:@"PersonalChat"]];
  84. self.portraitView.layer.masksToBounds = YES;
  85. self.portraitView.layer.cornerRadius = 8.f;
  86. [self.view addSubview:self.portraitView];
  87. self.userNameLabel = [[UILabel alloc] init];
  88. self.userNameLabel.font = [UIFont systemFontOfSize:26];
  89. self.userNameLabel.text = user.displayName;
  90. self.userNameLabel.textColor = [UIColor whiteColor];
  91. [self.view addSubview:self.userNameLabel];
  92. self.stateLabel = [[UILabel alloc] init];
  93. self.stateLabel.font = [UIFont systemFontOfSize:16];
  94. self.stateLabel.textColor = [UIColor whiteColor];
  95. [self.view addSubview:self.stateLabel];
  96. [self updateTopViewFrame];
  97. [self didChangeState:self.currentSession.state];//update ui
  98. }
  99. - (UIButton *)hangupButton {
  100. if (!_hangupButton) {
  101. _hangupButton = [[UIButton alloc] init];
  102. [_hangupButton setImage:[UIImage imageNamed:@"hangup"] forState:UIControlStateNormal];
  103. [_hangupButton setImage:[UIImage imageNamed:@"hangup_hover"] forState:UIControlStateHighlighted];
  104. [_hangupButton setImage:[UIImage imageNamed:@"hangup_hover"] forState:UIControlStateSelected];
  105. _hangupButton.backgroundColor = [UIColor clearColor];
  106. [_hangupButton addTarget:self action:@selector(hanupButtonDidTap:) forControlEvents:UIControlEventTouchDown];
  107. _hangupButton.hidden = YES;
  108. [self.view addSubview:_hangupButton];
  109. }
  110. return _hangupButton;
  111. }
  112. - (UIButton *)answerButton {
  113. if (!_answerButton) {
  114. _answerButton = [[UIButton alloc] init];
  115. [_answerButton setImage:[UIImage imageNamed:@"answer"] forState:UIControlStateNormal];
  116. [_answerButton setImage:[UIImage imageNamed:@"answer_hover"] forState:UIControlStateHighlighted];
  117. [_answerButton setImage:[UIImage imageNamed:@"answer_hover"] forState:UIControlStateSelected];
  118. _answerButton.backgroundColor = [UIColor clearColor];
  119. [_answerButton addTarget:self action:@selector(answerButtonDidTap:) forControlEvents:UIControlEventTouchDown];
  120. _answerButton.hidden = YES;
  121. [self.view addSubview:_answerButton];
  122. }
  123. return _answerButton;
  124. }
  125. - (UIButton *)minimizeButton {
  126. if (!_minimizeButton) {
  127. _minimizeButton = [[UIButton alloc] initWithFrame:CGRectMake(16, 26, 30, 30)];
  128. [_minimizeButton setImage:[UIImage imageNamed:@"minimize"] forState:UIControlStateNormal];
  129. [_minimizeButton setImage:[UIImage imageNamed:@"minimize_hover"] forState:UIControlStateHighlighted];
  130. [_minimizeButton setImage:[UIImage imageNamed:@"minimize_hover"] forState:UIControlStateSelected];
  131. _minimizeButton.backgroundColor = [UIColor clearColor];
  132. [_minimizeButton addTarget:self action:@selector(minimizeButtonDidTap:) forControlEvents:UIControlEventTouchDown];
  133. _minimizeButton.hidden = YES;
  134. [self.view addSubview:_minimizeButton];
  135. }
  136. return _minimizeButton;
  137. }
  138. - (UIButton *)switchCameraButton {
  139. if (!_switchCameraButton) {
  140. _switchCameraButton = [[UIButton alloc] init];
  141. [_switchCameraButton setImage:[UIImage imageNamed:@"switchcamera"] forState:UIControlStateNormal];
  142. [_switchCameraButton setImage:[UIImage imageNamed:@"switchcamera_hover"] forState:UIControlStateHighlighted];
  143. [_switchCameraButton setImage:[UIImage imageNamed:@"switchcamera_hover"] forState:UIControlStateSelected];
  144. _switchCameraButton.backgroundColor = [UIColor clearColor];
  145. [_switchCameraButton addTarget:self action:@selector(switchCameraButtonDidTap:) forControlEvents:UIControlEventTouchDown];
  146. _switchCameraButton.hidden = YES;
  147. [self.view addSubview:_switchCameraButton];
  148. }
  149. return _switchCameraButton;
  150. }
  151. - (UIButton *)downgradeButton {
  152. if (!_downgradeButton) {
  153. _downgradeButton = [[UIButton alloc] init];
  154. [_downgradeButton setImage:[UIImage imageNamed:@"to_audio"] forState:UIControlStateNormal];
  155. [_downgradeButton setImage:[UIImage imageNamed:@"to_audio_hover"] forState:UIControlStateHighlighted];
  156. [_downgradeButton setImage:[UIImage imageNamed:@"to_audio_hover"] forState:UIControlStateSelected];
  157. _downgradeButton.backgroundColor = [UIColor clearColor];
  158. [_downgradeButton addTarget:self action:@selector(downgradeButtonDidTap:) forControlEvents:UIControlEventTouchDown];
  159. _downgradeButton.hidden = YES;
  160. [self.view addSubview:_downgradeButton];
  161. }
  162. return _downgradeButton;
  163. }
  164. - (UIButton *)audioButton {
  165. if (!_audioButton) {
  166. _audioButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2-ButtonSize/2, self.view.frame.size.height-10-ButtonSize, ButtonSize, ButtonSize)];
  167. [_audioButton setImage:[UIImage imageNamed:@"mute"] forState:UIControlStateNormal];
  168. [_audioButton setImage:[UIImage imageNamed:@"mute_hover"] forState:UIControlStateHighlighted];
  169. [_audioButton setImage:[UIImage imageNamed:@"mute_hover"] forState:UIControlStateSelected];
  170. _audioButton.backgroundColor = [UIColor clearColor];
  171. [_audioButton addTarget:self action:@selector(audioButtonDidTap:) forControlEvents:UIControlEventTouchDown];
  172. _audioButton.hidden = YES;
  173. [self.view addSubview:_audioButton];
  174. }
  175. return _audioButton;
  176. }
  177. - (UIButton *)speakerButton {
  178. if (!_speakerButton) {
  179. _speakerButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2-ButtonSize/2, self.view.frame.size.height-10-ButtonSize, ButtonSize, ButtonSize)];
  180. [_speakerButton setImage:[UIImage imageNamed:@"speaker"] forState:UIControlStateNormal];
  181. [_speakerButton setImage:[UIImage imageNamed:@"speaker_hover"] forState:UIControlStateHighlighted];
  182. [_speakerButton setImage:[UIImage imageNamed:@"speaker_hover"] forState:UIControlStateSelected];
  183. _speakerButton.backgroundColor = [UIColor clearColor];
  184. [_speakerButton addTarget:self action:@selector(speakerButtonDidTap:) forControlEvents:UIControlEventTouchDown];
  185. _speakerButton.hidden = YES;
  186. [self.view addSubview:_speakerButton];
  187. }
  188. return _speakerButton;
  189. }
  190. - (UIButton *)videoButton {
  191. if (!_videoButton) {
  192. _videoButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2-ButtonSize/2, self.view.frame.size.height-10-ButtonSize, ButtonSize, ButtonSize)];
  193. [_videoButton setTitle:@"视频" forState:UIControlStateNormal];
  194. _videoButton.backgroundColor = [UIColor greenColor];
  195. [_videoButton addTarget:self action:@selector(videoButtonDidTap:) forControlEvents:UIControlEventTouchDown];
  196. _videoButton.hidden = YES;
  197. [self.view addSubview:_videoButton];
  198. }
  199. return _videoButton;
  200. }
  201. - (UIButton *)scalingButton {
  202. if (!_scalingButton) {
  203. _scalingButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width/2-ButtonSize/2, self.view.frame.size.height-10-ButtonSize, ButtonSize, ButtonSize)];
  204. [_scalingButton setTitle:@"缩放" forState:UIControlStateNormal];
  205. _scalingButton.backgroundColor = [UIColor greenColor];
  206. [_scalingButton addTarget:self action:@selector(scalingButtonDidTap:) forControlEvents:UIControlEventTouchDown];
  207. _scalingButton.hidden = YES;
  208. [self.view addSubview:_scalingButton];
  209. }
  210. return _scalingButton;
  211. }
  212. - (void)startConnectedTimer {
  213. [self stopConnectedTimer];
  214. self.connectedTimer = [NSTimer scheduledTimerWithTimeInterval:1
  215. target:self
  216. selector:@selector(updateConnectedTimeLabel)
  217. userInfo:nil
  218. repeats:YES];
  219. [self.connectedTimer fire];
  220. }
  221. - (void)stopConnectedTimer {
  222. if (self.connectedTimer) {
  223. [self.connectedTimer invalidate];
  224. self.connectedTimer = nil;
  225. }
  226. }
  227. - (void)updateConnectedTimeLabel {
  228. long sec = [[NSDate date] timeIntervalSince1970] - self.currentSession.connectedTime / 1000;
  229. if (sec < 60 * 60) {
  230. self.stateLabel.text = [NSString stringWithFormat:@"%02ld:%02ld", sec / 60, sec % 60];
  231. } else {
  232. self.stateLabel.text = [NSString stringWithFormat:@"%02ld:%02ld:%02ld", sec / 60 / 60, (sec / 60) % 60, sec % 60];
  233. }
  234. }
  235. - (void)hanupButtonDidTap:(UIButton *)button {
  236. if(self.currentSession.state != kWFAVEngineStateIdle) {
  237. [self.currentSession endCall];
  238. }
  239. }
  240. - (void)answerButtonDidTap:(UIButton *)button {
  241. if (self.currentSession.state == kWFAVEngineStateIncomming) {
  242. [self.currentSession answerCall:NO];
  243. }
  244. }
  245. - (void)minimizeButtonDidTap:(UIButton *)button {
  246. [WFCUFloatingWindow startCallFloatingWindow:self.currentSession withTouchedBlock:^(WFAVCallSession *callSession) {
  247. [[WFAVEngineKit sharedEngineKit] presentViewController:[[WFCUVideoViewController alloc] initWithSession:callSession]];
  248. }];
  249. [[WFAVEngineKit sharedEngineKit] dismissViewController:self];
  250. }
  251. - (void)switchCameraButtonDidTap:(UIButton *)button {
  252. if (self.currentSession.state != kWFAVEngineStateIdle) {
  253. [self.currentSession switchCamera];
  254. }
  255. }
  256. - (void)downgradeButtonDidTap:(UIButton *)button {
  257. if (self.currentSession.state == kWFAVEngineStateIncomming) {
  258. [self.currentSession answerCall:YES];
  259. } else if(self.currentSession.state == kWFAVEngineStateConnected) {
  260. self.currentSession.audioOnly = !self.currentSession.isAudioOnly;
  261. }
  262. }
  263. - (void)audioButtonDidTap:(UIButton *)button {
  264. if (self.currentSession.state != kWFAVEngineStateIdle) {
  265. BOOL result = [self.currentSession muteAudio:!self.audioMuted];
  266. if (result) {
  267. self.audioMuted = !self.audioMuted;
  268. if (self.audioMuted) {
  269. [self.audioButton setImage:[UIImage imageNamed:@"mute_hover"] forState:UIControlStateNormal];
  270. } else {
  271. [self.audioButton setImage:[UIImage imageNamed:@"mute"] forState:UIControlStateNormal];
  272. }
  273. }
  274. }
  275. }
  276. - (void)speakerButtonDidTap:(UIButton *)button {
  277. if (self.currentSession.state != kWFAVEngineStateIdle) {
  278. [self.currentSession enableSpeaker:!self.currentSession.isSpeaker];
  279. [self updateSpeakerButton];
  280. }
  281. }
  282. - (void)updateSpeakerButton {
  283. if (!self.currentSession.isSpeaker) {
  284. [self.speakerButton setImage:[UIImage imageNamed:@"speaker"] forState:UIControlStateNormal];
  285. } else {
  286. [self.speakerButton setImage:[UIImage imageNamed:@"speaker_hover"] forState:UIControlStateNormal];
  287. }
  288. }
  289. - (void)viewWillAppear:(BOOL)animated {
  290. [super viewWillAppear:animated];
  291. if (_currentSession.state == kWFAVEngineStateConnected) {
  292. [self updateConnectedTimeLabel];
  293. [self startConnectedTimer];
  294. }
  295. }
  296. - (void)viewWillDisappear:(BOOL)animated {
  297. [super viewWillDisappear:animated];
  298. [self stopConnectedTimer];
  299. }
  300. - (void)setPanStartPoint:(CGPoint)panStartPoint {
  301. _panStartPoint = panStartPoint;
  302. _panStartVideoFrame = self.smallVideoView.frame;
  303. }
  304. - (void)moveToPanPoint:(CGPoint)panPoint {
  305. CGRect frame = self.panStartVideoFrame;
  306. CGSize moveSize = CGSizeMake(panPoint.x - self.panStartPoint.x, panPoint.y - self.panStartPoint.y);
  307. frame.origin.x += moveSize.width;
  308. frame.origin.y += moveSize.height;
  309. self.smallVideoView.frame = frame;
  310. }
  311. - (void)onSmallVideoPan:(UIPanGestureRecognizer *)recognize {
  312. switch (recognize.state) {
  313. case UIGestureRecognizerStateBegan:
  314. self.panStartPoint = [recognize translationInView:self.view];
  315. break;
  316. case UIGestureRecognizerStateChanged: {
  317. CGPoint currentPoint = [recognize translationInView:self.view];
  318. [self moveToPanPoint:currentPoint];
  319. break;
  320. }
  321. case UIGestureRecognizerStateEnded: {
  322. CGPoint endPoint = [recognize translationInView:self.view];
  323. [self moveToPanPoint:endPoint];
  324. break;
  325. }
  326. case UIGestureRecognizerStateCancelled:
  327. case UIGestureRecognizerStateFailed:
  328. default:
  329. break;
  330. }
  331. }
  332. - (void)videoButtonDidTap:(UIButton *)button {
  333. if (self.currentSession.state != kWFAVEngineStateIdle) {
  334. BOOL result = [self.currentSession muteVideo:!self.videoMuted];
  335. if (result) {
  336. self.videoMuted = !self.videoMuted;
  337. }
  338. }
  339. }
  340. - (void)scalingButtonDidTap:(UIButton *)button {
  341. if (self.currentSession.state != kWFAVEngineStateIdle) {
  342. if (self.scalingType < kWFAVVideoScalingTypeAspectBalanced) {
  343. self.scalingType++;
  344. } else {
  345. self.scalingType = kWFAVVideoScalingTypeAspectFit;
  346. }
  347. [self.currentSession setupLocalVideoView:self.smallVideoView scalingType:self.scalingType];
  348. [self.currentSession setupRemoteVideoView:self.bigVideoView scalingType:self.scalingType];
  349. }
  350. }
  351. - (CGRect)getButtomCenterButtonFrame {
  352. return CGRectMake(self.view.frame.size.width/2-ButtonSize/2, self.view.frame.size.height-45-ButtonSize, ButtonSize, ButtonSize);
  353. }
  354. - (CGRect)getButtomLeftButtonFrame {
  355. return CGRectMake(self.view.frame.size.width/4-ButtonSize/2, self.view.frame.size.height-45-ButtonSize, ButtonSize, ButtonSize);
  356. }
  357. - (CGRect)getButtomRightButtonFrame {
  358. return CGRectMake(self.view.frame.size.width*3/4-ButtonSize/2, self.view.frame.size.height-45-ButtonSize, ButtonSize, ButtonSize);
  359. }
  360. - (CGRect)getToAudioButtonFrame {
  361. return CGRectMake(self.view.frame.size.width*3/4-ButtonSize/2, self.view.frame.size.height-45-ButtonSize-ButtonSize-2, ButtonSize, ButtonSize);
  362. }
  363. - (void)updateTopViewFrame {
  364. if (self.currentSession.isAudioOnly) {
  365. CGFloat containerWidth = self.view.bounds.size.width;
  366. self.portraitView.frame = CGRectMake((containerWidth-64)/2, kStatusBarAndNavigationBarHeight, 64, 64);;
  367. self.userNameLabel.frame = CGRectMake((containerWidth - 240)/2, kStatusBarAndNavigationBarHeight + 64 + 8, 240, 26);
  368. self.userNameLabel.textAlignment = NSTextAlignmentCenter;
  369. self.stateLabel.frame = CGRectMake((containerWidth - 240)/2, kStatusBarAndNavigationBarHeight + 64 + 26 + 8, 240, 26);
  370. self.stateLabel.textAlignment = NSTextAlignmentCenter;
  371. } else {
  372. self.portraitView.frame = CGRectMake(16, kStatusBarAndNavigationBarHeight, 64, 64);
  373. self.userNameLabel.frame = CGRectMake(96, kStatusBarAndNavigationBarHeight + 8, 240, 26);
  374. if(![NSThread isMainThread]) {
  375. NSLog(@"error not main thread");
  376. }
  377. self.userNameLabel.textAlignment = NSTextAlignmentLeft;
  378. if(self.currentSession.state == kWFAVEngineStateConnected) {
  379. self.stateLabel.frame = CGRectMake(54, 30, 240, 20);
  380. } else {
  381. self.stateLabel.frame = CGRectMake(96, kStatusBarAndNavigationBarHeight + 26 + 14, 240, 16);
  382. }
  383. self.stateLabel.textAlignment = NSTextAlignmentLeft;
  384. }
  385. }
  386. #pragma mark - WFAVEngineDelegate
  387. - (void)didChangeState:(WFAVEngineState)state {
  388. if (!self.viewLoaded) {
  389. return;
  390. }
  391. switch (state) {
  392. case kWFAVEngineStateIdle:
  393. self.answerButton.hidden = YES;
  394. self.hangupButton.hidden = YES;
  395. self.switchCameraButton.hidden = YES;
  396. self.audioButton.hidden = YES;
  397. self.videoButton.hidden = YES;
  398. self.scalingButton.hidden = YES;
  399. [self stopConnectedTimer];
  400. self.userNameLabel.hidden = NO;
  401. self.portraitView.hidden = NO;
  402. self.stateLabel.text = @"通话已结束";
  403. self.smallVideoView.hidden = YES;
  404. self.bigVideoView.hidden = YES;
  405. self.minimizeButton.hidden = YES;
  406. self.speakerButton.hidden = YES;
  407. self.downgradeButton.hidden = YES;
  408. [self updateTopViewFrame];
  409. break;
  410. case kWFAVEngineStateOutgoing:
  411. self.answerButton.hidden = YES;
  412. self.hangupButton.hidden = NO;
  413. self.hangupButton.frame = [self getButtomCenterButtonFrame];
  414. self.switchCameraButton.hidden = YES;
  415. if (self.currentSession.isAudioOnly) {
  416. self.speakerButton.hidden = NO;
  417. [self updateSpeakerButton];
  418. self.speakerButton.frame = [self getButtomRightButtonFrame];
  419. self.audioButton.hidden = NO;
  420. self.audioButton.frame = [self getButtomLeftButtonFrame];
  421. } else {
  422. self.speakerButton.hidden = YES;
  423. self.audioButton.hidden = YES;
  424. }
  425. self.videoButton.hidden = YES;
  426. self.scalingButton.hidden = YES;
  427. [self.currentSession setupLocalVideoView:self.bigVideoView scalingType:self.scalingType];
  428. [self.currentSession setupRemoteVideoView:nil scalingType:self.scalingType];
  429. self.stateLabel.text = @"等待对方接听";
  430. self.smallVideoView.hidden = YES;
  431. self.userNameLabel.hidden = NO;
  432. self.portraitView.hidden = NO;
  433. [self updateTopViewFrame];
  434. break;
  435. case kWFAVEngineStateConnecting:
  436. self.answerButton.hidden = YES;
  437. self.hangupButton.hidden = NO;
  438. self.speakerButton.hidden = YES;
  439. self.hangupButton.frame = [self getButtomCenterButtonFrame];
  440. self.switchCameraButton.hidden = YES;
  441. self.audioButton.hidden = YES;
  442. self.videoButton.hidden = YES;
  443. self.scalingButton.hidden = YES;
  444. [self.currentSession setupLocalVideoView:self.smallVideoView scalingType:self.scalingType];
  445. [self.currentSession setupRemoteVideoView:self.bigVideoView scalingType:self.scalingType];
  446. self.stateLabel.text = @"连接建立中";
  447. self.smallVideoView.hidden = NO;
  448. self.downgradeButton.hidden = YES;
  449. break;
  450. case kWFAVEngineStateConnected:
  451. self.answerButton.hidden = YES;
  452. self.hangupButton.hidden = NO;
  453. self.hangupButton.frame = [self getButtomCenterButtonFrame];
  454. if (self.currentSession.isAudioOnly) {
  455. self.speakerButton.hidden = NO;
  456. self.speakerButton.frame = [self getButtomRightButtonFrame];
  457. [self updateSpeakerButton];
  458. self.audioButton.hidden = NO;
  459. self.audioButton.frame = [self getButtomLeftButtonFrame];
  460. self.switchCameraButton.hidden = YES;
  461. } else {
  462. self.speakerButton.hidden = YES;
  463. [self.currentSession enableSpeaker:YES];
  464. self.audioButton.hidden = NO;
  465. self.audioButton.frame = [self getButtomLeftButtonFrame];
  466. self.switchCameraButton.hidden = NO;
  467. self.switchCameraButton.frame = [self getButtomRightButtonFrame];
  468. }
  469. self.videoButton.hidden = YES;
  470. self.scalingButton.hidden = YES;
  471. self.minimizeButton.hidden = NO;
  472. if (self.currentSession.isAudioOnly) {
  473. self.downgradeButton.hidden = YES;;
  474. } else {
  475. self.downgradeButton.hidden = NO;
  476. self.downgradeButton.frame = [self getToAudioButtonFrame];
  477. }
  478. if (self.currentSession.isAudioOnly) {
  479. [self.currentSession setupLocalVideoView:nil scalingType:self.scalingType];
  480. [self.currentSession setupRemoteVideoView:nil scalingType:self.scalingType];
  481. self.smallVideoView.hidden = YES;
  482. self.bigVideoView.hidden = YES;
  483. [_downgradeButton setImage:[UIImage imageNamed:@"to_video"] forState:UIControlStateNormal];
  484. [_downgradeButton setImage:[UIImage imageNamed:@"to_video_hover"] forState:UIControlStateHighlighted];
  485. [_downgradeButton setImage:[UIImage imageNamed:@"to_video_hover"] forState:UIControlStateSelected];
  486. } else {
  487. [self.currentSession setupLocalVideoView:self.smallVideoView scalingType:self.scalingType];
  488. [self.currentSession setupRemoteVideoView:self.bigVideoView scalingType:self.scalingType];
  489. self.smallVideoView.hidden = NO;
  490. self.bigVideoView.hidden = NO;
  491. [_downgradeButton setImage:[UIImage imageNamed:@"to_audio"] forState:UIControlStateNormal];
  492. [_downgradeButton setImage:[UIImage imageNamed:@"to_audio_hover"] forState:UIControlStateHighlighted];
  493. [_downgradeButton setImage:[UIImage imageNamed:@"to_audio_hover"] forState:UIControlStateSelected];
  494. }
  495. if (!_currentSession.isAudioOnly) {
  496. self.userNameLabel.hidden = YES;
  497. self.portraitView.hidden = YES;
  498. } else {
  499. self.userNameLabel.hidden = NO;
  500. self.portraitView.hidden = NO;
  501. }
  502. [self updateConnectedTimeLabel];
  503. [self startConnectedTimer];
  504. [self updateTopViewFrame];
  505. break;
  506. case kWFAVEngineStateIncomming:
  507. self.answerButton.hidden = NO;
  508. self.answerButton.frame = [self getButtomRightButtonFrame];
  509. self.hangupButton.hidden = NO;
  510. self.hangupButton.frame = [self getButtomLeftButtonFrame];
  511. self.switchCameraButton.hidden = YES;
  512. self.audioButton.hidden = YES;
  513. self.videoButton.hidden = YES;
  514. self.scalingButton.hidden = YES;
  515. self.downgradeButton.hidden = NO;
  516. self.downgradeButton.frame = [self getToAudioButtonFrame];
  517. [self.currentSession setupLocalVideoView:self.bigVideoView scalingType:self.scalingType];
  518. [self.currentSession setupRemoteVideoView:nil scalingType:self.scalingType];
  519. self.stateLabel.text = @"对方正在邀请您通话";
  520. self.smallVideoView.hidden = YES;
  521. if (self.currentSession.isAudioOnly) {
  522. self.downgradeButton.hidden = YES;;
  523. } else {
  524. self.downgradeButton.hidden = NO;
  525. self.downgradeButton.frame = [self getToAudioButtonFrame];
  526. }
  527. break;
  528. default:
  529. break;
  530. }
  531. }
  532. - (void)didCreateLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
  533. }
  534. - (void)didReceiveRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack {
  535. }
  536. - (void)didCallEndWithReason:(WFAVCallEndReason)reason {
  537. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  538. [[WFAVEngineKit sharedEngineKit] dismissViewController:self];
  539. });
  540. }
  541. - (void)didChangeMode:(BOOL)isAudioOnly {
  542. [self didChangeState:self.currentSession.state];
  543. }
  544. - (void)didError:(NSError *)error {
  545. }
  546. - (void)didGetStats:(NSArray *)stats {
  547. }
  548. - (void)checkAVPermission {
  549. [self checkCapturePermission:nil];
  550. [self checkRecordPermission:nil];
  551. }
  552. - (void)checkCapturePermission:(void (^)(BOOL granted))complete {
  553. AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  554. if (authStatus == AVAuthorizationStatusDenied || authStatus == AVAuthorizationStatusRestricted) {
  555. if (complete) {
  556. complete(NO);
  557. }
  558. } else if (authStatus == AVAuthorizationStatusNotDetermined) {
  559. [AVCaptureDevice
  560. requestAccessForMediaType:AVMediaTypeVideo
  561. completionHandler:^(BOOL granted) {
  562. if (complete) {
  563. complete(granted);
  564. }
  565. }];
  566. } else {
  567. if (complete) {
  568. complete(YES);
  569. }
  570. }
  571. }
  572. - (void)checkRecordPermission:(void (^)(BOOL granted))complete {
  573. if ([[AVAudioSession sharedInstance] respondsToSelector:@selector(requestRecordPermission:)]) {
  574. [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
  575. if (complete) {
  576. complete(granted);
  577. }
  578. }];
  579. }
  580. }
  581. @end