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 |