OLD | NEW |
| (Empty) |
1 /* | |
2 * libjingle | |
3 * Copyright 2015 Google Inc. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions are met: | |
7 * | |
8 * 1. Redistributions of source code must retain the above copyright notice, | |
9 * this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
11 * this list of conditions and the following disclaimer in the documentation | |
12 * and/or other materials provided with the distribution. | |
13 * 3. The name of the author may not be used to endorse or promote products | |
14 * derived from this software without specific prior written permission. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | |
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 | |
28 #import "ARDVideoCallViewController.h" | |
29 | |
30 #import "RTCAVFoundationVideoSource.h" | |
31 #import "RTCLogging.h" | |
32 | |
33 #import "ARDAppClient.h" | |
34 #import "ARDVideoCallView.h" | |
35 | |
36 @interface ARDVideoCallViewController () <ARDAppClientDelegate, | |
37 ARDVideoCallViewDelegate> | |
38 @property(nonatomic, strong) RTCVideoTrack *localVideoTrack; | |
39 @property(nonatomic, strong) RTCVideoTrack *remoteVideoTrack; | |
40 @property(nonatomic, readonly) ARDVideoCallView *videoCallView; | |
41 @end | |
42 | |
43 @implementation ARDVideoCallViewController { | |
44 ARDAppClient *_client; | |
45 RTCVideoTrack *_remoteVideoTrack; | |
46 RTCVideoTrack *_localVideoTrack; | |
47 } | |
48 | |
49 @synthesize videoCallView = _videoCallView; | |
50 | |
51 - (instancetype)initForRoom:(NSString *)room { | |
52 if (self = [super init]) { | |
53 _client = [[ARDAppClient alloc] initWithDelegate:self]; | |
54 [_client connectToRoomWithId:room options:nil]; | |
55 } | |
56 return self; | |
57 } | |
58 | |
59 - (void)loadView { | |
60 _videoCallView = [[ARDVideoCallView alloc] initWithFrame:CGRectZero]; | |
61 _videoCallView.delegate = self; | |
62 _videoCallView.statusLabel.text = | |
63 [self statusTextForState:RTCICEConnectionNew]; | |
64 self.view = _videoCallView; | |
65 } | |
66 | |
67 #pragma mark - ARDAppClientDelegate | |
68 | |
69 - (void)appClient:(ARDAppClient *)client | |
70 didChangeState:(ARDAppClientState)state { | |
71 switch (state) { | |
72 case kARDAppClientStateConnected: | |
73 RTCLog(@"Client connected."); | |
74 break; | |
75 case kARDAppClientStateConnecting: | |
76 RTCLog(@"Client connecting."); | |
77 break; | |
78 case kARDAppClientStateDisconnected: | |
79 RTCLog(@"Client disconnected."); | |
80 [self hangup]; | |
81 break; | |
82 } | |
83 } | |
84 | |
85 - (void)appClient:(ARDAppClient *)client | |
86 didChangeConnectionState:(RTCICEConnectionState)state { | |
87 RTCLog(@"ICE state changed: %d", state); | |
88 __weak ARDVideoCallViewController *weakSelf = self; | |
89 dispatch_async(dispatch_get_main_queue(), ^{ | |
90 ARDVideoCallViewController *strongSelf = weakSelf; | |
91 strongSelf.videoCallView.statusLabel.text = | |
92 [strongSelf statusTextForState:state]; | |
93 }); | |
94 } | |
95 | |
96 - (void)appClient:(ARDAppClient *)client | |
97 didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack { | |
98 self.localVideoTrack = localVideoTrack; | |
99 } | |
100 | |
101 - (void)appClient:(ARDAppClient *)client | |
102 didReceiveRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack { | |
103 self.remoteVideoTrack = remoteVideoTrack; | |
104 _videoCallView.statusLabel.hidden = YES; | |
105 } | |
106 | |
107 - (void)appClient:(ARDAppClient *)client | |
108 didError:(NSError *)error { | |
109 NSString *message = | |
110 [NSString stringWithFormat:@"%@", error.localizedDescription]; | |
111 [self showAlertWithMessage:message]; | |
112 [self hangup]; | |
113 } | |
114 | |
115 #pragma mark - ARDVideoCallViewDelegate | |
116 | |
117 - (void)videoCallViewDidHangup:(ARDVideoCallView *)view { | |
118 [self hangup]; | |
119 } | |
120 | |
121 - (void)videoCallViewDidSwitchCamera:(ARDVideoCallView *)view { | |
122 // TODO(tkchin): Rate limit this so you can't tap continously on it. | |
123 // Probably through an animation. | |
124 [self switchCamera]; | |
125 } | |
126 | |
127 #pragma mark - Private | |
128 | |
129 - (void)setLocalVideoTrack:(RTCVideoTrack *)localVideoTrack { | |
130 if (_localVideoTrack == localVideoTrack) { | |
131 return; | |
132 } | |
133 [_localVideoTrack removeRenderer:_videoCallView.localVideoView]; | |
134 _localVideoTrack = nil; | |
135 [_videoCallView.localVideoView renderFrame:nil]; | |
136 _localVideoTrack = localVideoTrack; | |
137 [_localVideoTrack addRenderer:_videoCallView.localVideoView]; | |
138 } | |
139 | |
140 - (void)setRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack { | |
141 if (_remoteVideoTrack == remoteVideoTrack) { | |
142 return; | |
143 } | |
144 [_remoteVideoTrack removeRenderer:_videoCallView.localVideoView]; | |
145 _remoteVideoTrack = nil; | |
146 [_videoCallView.remoteVideoView renderFrame:nil]; | |
147 _remoteVideoTrack = remoteVideoTrack; | |
148 [_remoteVideoTrack addRenderer:_videoCallView.remoteVideoView]; | |
149 } | |
150 | |
151 - (void)hangup { | |
152 self.remoteVideoTrack = nil; | |
153 self.localVideoTrack = nil; | |
154 [_client disconnect]; | |
155 if (![self isBeingDismissed]) { | |
156 [self.presentingViewController dismissViewControllerAnimated:YES | |
157 completion:nil]; | |
158 } | |
159 } | |
160 | |
161 - (void)switchCamera { | |
162 RTCVideoSource* source = self.localVideoTrack.source; | |
163 if ([source isKindOfClass:[RTCAVFoundationVideoSource class]]) { | |
164 RTCAVFoundationVideoSource* avSource = (RTCAVFoundationVideoSource*)source; | |
165 avSource.useBackCamera = !avSource.useBackCamera; | |
166 _videoCallView.localVideoView.transform = avSource.useBackCamera ? | |
167 CGAffineTransformIdentity : CGAffineTransformMakeScale(-1, 1); | |
168 } | |
169 } | |
170 | |
171 - (NSString *)statusTextForState:(RTCICEConnectionState)state { | |
172 switch (state) { | |
173 case RTCICEConnectionNew: | |
174 case RTCICEConnectionChecking: | |
175 return @"Connecting..."; | |
176 case RTCICEConnectionConnected: | |
177 case RTCICEConnectionCompleted: | |
178 case RTCICEConnectionFailed: | |
179 case RTCICEConnectionDisconnected: | |
180 case RTCICEConnectionClosed: | |
181 return nil; | |
182 } | |
183 } | |
184 | |
185 - (void)showAlertWithMessage:(NSString*)message { | |
186 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil | |
187 message:message | |
188 delegate:nil | |
189 cancelButtonTitle:@"OK" | |
190 otherButtonTitles:nil]; | |
191 [alertView show]; | |
192 } | |
193 | |
194 @end | |
OLD | NEW |