OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #import "ARDVideoCallViewController.h" |
| 12 |
| 13 #import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h" |
| 14 |
| 15 #import "WebRTC/RTCAVFoundationVideoSource.h" |
| 16 #import "WebRTC/RTCDispatcher.h" |
| 17 #import "WebRTC/RTCLogging.h" |
| 18 |
| 19 #import "ARDAppClient.h" |
| 20 #import "ARDVideoCallView.h" |
| 21 |
| 22 @interface ARDVideoCallViewController () <ARDAppClientDelegate, |
| 23 ARDVideoCallViewDelegate> |
| 24 @property(nonatomic, strong) RTCVideoTrack *localVideoTrack; |
| 25 @property(nonatomic, strong) RTCVideoTrack *remoteVideoTrack; |
| 26 @property(nonatomic, readonly) ARDVideoCallView *videoCallView; |
| 27 @end |
| 28 |
| 29 @implementation ARDVideoCallViewController { |
| 30 ARDAppClient *_client; |
| 31 RTCVideoTrack *_remoteVideoTrack; |
| 32 RTCVideoTrack *_localVideoTrack; |
| 33 AVAudioSessionPortOverride _portOverride; |
| 34 } |
| 35 |
| 36 @synthesize videoCallView = _videoCallView; |
| 37 @synthesize delegate = _delegate; |
| 38 |
| 39 - (instancetype)initForRoom:(NSString *)room |
| 40 isLoopback:(BOOL)isLoopback |
| 41 isAudioOnly:(BOOL)isAudioOnly |
| 42 shouldMakeAecDump:(BOOL)shouldMakeAecDump |
| 43 shouldUseLevelControl:(BOOL)shouldUseLevelControl |
| 44 delegate:(id<ARDVideoCallViewControllerDelegate>)delegate { |
| 45 if (self = [super init]) { |
| 46 _delegate = delegate; |
| 47 _client = [[ARDAppClient alloc] initWithDelegate:self]; |
| 48 [_client connectToRoomWithId:room |
| 49 isLoopback:isLoopback |
| 50 isAudioOnly:isAudioOnly |
| 51 shouldMakeAecDump:shouldMakeAecDump |
| 52 shouldUseLevelControl:shouldUseLevelControl]; |
| 53 } |
| 54 return self; |
| 55 } |
| 56 |
| 57 - (void)loadView { |
| 58 _videoCallView = [[ARDVideoCallView alloc] initWithFrame:CGRectZero]; |
| 59 _videoCallView.delegate = self; |
| 60 _videoCallView.statusLabel.text = |
| 61 [self statusTextForState:RTCIceConnectionStateNew]; |
| 62 self.view = _videoCallView; |
| 63 } |
| 64 |
| 65 #pragma mark - ARDAppClientDelegate |
| 66 |
| 67 - (void)appClient:(ARDAppClient *)client |
| 68 didChangeState:(ARDAppClientState)state { |
| 69 switch (state) { |
| 70 case kARDAppClientStateConnected: |
| 71 RTCLog(@"Client connected."); |
| 72 break; |
| 73 case kARDAppClientStateConnecting: |
| 74 RTCLog(@"Client connecting."); |
| 75 break; |
| 76 case kARDAppClientStateDisconnected: |
| 77 RTCLog(@"Client disconnected."); |
| 78 [self hangup]; |
| 79 break; |
| 80 } |
| 81 } |
| 82 |
| 83 - (void)appClient:(ARDAppClient *)client |
| 84 didChangeConnectionState:(RTCIceConnectionState)state { |
| 85 RTCLog(@"ICE state changed: %ld", (long)state); |
| 86 __weak ARDVideoCallViewController *weakSelf = self; |
| 87 dispatch_async(dispatch_get_main_queue(), ^{ |
| 88 ARDVideoCallViewController *strongSelf = weakSelf; |
| 89 strongSelf.videoCallView.statusLabel.text = |
| 90 [strongSelf statusTextForState:state]; |
| 91 }); |
| 92 } |
| 93 |
| 94 - (void)appClient:(ARDAppClient *)client |
| 95 didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack { |
| 96 self.localVideoTrack = localVideoTrack; |
| 97 } |
| 98 |
| 99 - (void)appClient:(ARDAppClient *)client |
| 100 didReceiveRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack { |
| 101 self.remoteVideoTrack = remoteVideoTrack; |
| 102 _videoCallView.statusLabel.hidden = YES; |
| 103 } |
| 104 |
| 105 - (void)appClient:(ARDAppClient *)client |
| 106 didGetStats:(NSArray *)stats { |
| 107 _videoCallView.statsView.stats = stats; |
| 108 [_videoCallView setNeedsLayout]; |
| 109 } |
| 110 |
| 111 - (void)appClient:(ARDAppClient *)client |
| 112 didError:(NSError *)error { |
| 113 NSString *message = |
| 114 [NSString stringWithFormat:@"%@", error.localizedDescription]; |
| 115 [self showAlertWithMessage:message]; |
| 116 [self hangup]; |
| 117 } |
| 118 |
| 119 #pragma mark - ARDVideoCallViewDelegate |
| 120 |
| 121 - (void)videoCallViewDidHangup:(ARDVideoCallView *)view { |
| 122 [self hangup]; |
| 123 } |
| 124 |
| 125 - (void)videoCallViewDidSwitchCamera:(ARDVideoCallView *)view { |
| 126 // TODO(tkchin): Rate limit this so you can't tap continously on it. |
| 127 // Probably through an animation. |
| 128 [self switchCamera]; |
| 129 } |
| 130 |
| 131 - (void)videoCallViewDidChangeRoute:(ARDVideoCallView *)view { |
| 132 AVAudioSessionPortOverride override = AVAudioSessionPortOverrideNone; |
| 133 if (_portOverride == AVAudioSessionPortOverrideNone) { |
| 134 override = AVAudioSessionPortOverrideSpeaker; |
| 135 } |
| 136 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeAudioSession |
| 137 block:^{ |
| 138 RTCAudioSession *session = [RTCAudioSession sharedInstance]; |
| 139 [session lockForConfiguration]; |
| 140 NSError *error = nil; |
| 141 if ([session overrideOutputAudioPort:override error:&error]) { |
| 142 _portOverride = override; |
| 143 } else { |
| 144 RTCLogError(@"Error overriding output port: %@", |
| 145 error.localizedDescription); |
| 146 } |
| 147 [session unlockForConfiguration]; |
| 148 }]; |
| 149 } |
| 150 |
| 151 - (void)videoCallViewDidEnableStats:(ARDVideoCallView *)view { |
| 152 _client.shouldGetStats = YES; |
| 153 _videoCallView.statsView.hidden = NO; |
| 154 } |
| 155 |
| 156 #pragma mark - Private |
| 157 |
| 158 - (void)setLocalVideoTrack:(RTCVideoTrack *)localVideoTrack { |
| 159 if (_localVideoTrack == localVideoTrack) { |
| 160 return; |
| 161 } |
| 162 _localVideoTrack = nil; |
| 163 _localVideoTrack = localVideoTrack; |
| 164 RTCAVFoundationVideoSource *source = nil; |
| 165 if ([localVideoTrack.source |
| 166 isKindOfClass:[RTCAVFoundationVideoSource class]]) { |
| 167 source = (RTCAVFoundationVideoSource*)localVideoTrack.source; |
| 168 } |
| 169 _videoCallView.localVideoView.captureSession = source.captureSession; |
| 170 } |
| 171 |
| 172 - (void)setRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack { |
| 173 if (_remoteVideoTrack == remoteVideoTrack) { |
| 174 return; |
| 175 } |
| 176 [_remoteVideoTrack removeRenderer:_videoCallView.remoteVideoView]; |
| 177 _remoteVideoTrack = nil; |
| 178 [_videoCallView.remoteVideoView renderFrame:nil]; |
| 179 _remoteVideoTrack = remoteVideoTrack; |
| 180 [_remoteVideoTrack addRenderer:_videoCallView.remoteVideoView]; |
| 181 } |
| 182 |
| 183 - (void)hangup { |
| 184 self.remoteVideoTrack = nil; |
| 185 self.localVideoTrack = nil; |
| 186 [_client disconnect]; |
| 187 [_delegate viewControllerDidFinish:self]; |
| 188 } |
| 189 |
| 190 - (void)switchCamera { |
| 191 RTCVideoSource* source = self.localVideoTrack.source; |
| 192 if ([source isKindOfClass:[RTCAVFoundationVideoSource class]]) { |
| 193 RTCAVFoundationVideoSource* avSource = (RTCAVFoundationVideoSource*)source; |
| 194 avSource.useBackCamera = !avSource.useBackCamera; |
| 195 } |
| 196 } |
| 197 |
| 198 - (NSString *)statusTextForState:(RTCIceConnectionState)state { |
| 199 switch (state) { |
| 200 case RTCIceConnectionStateNew: |
| 201 case RTCIceConnectionStateChecking: |
| 202 return @"Connecting..."; |
| 203 case RTCIceConnectionStateConnected: |
| 204 case RTCIceConnectionStateCompleted: |
| 205 case RTCIceConnectionStateFailed: |
| 206 case RTCIceConnectionStateDisconnected: |
| 207 case RTCIceConnectionStateClosed: |
| 208 case RTCIceConnectionStateCount: |
| 209 return nil; |
| 210 } |
| 211 } |
| 212 |
| 213 - (void)showAlertWithMessage:(NSString*)message { |
| 214 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil |
| 215 message:message |
| 216 delegate:nil |
| 217 cancelButtonTitle:@"OK" |
| 218 otherButtonTitles:nil]; |
| 219 [alertView show]; |
| 220 } |
| 221 |
| 222 @end |
OLD | NEW |