blob: 2f07c7a4cc48c635ebf4b9314202ef048a453ac5 [file] [log] [blame]
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +00001/*
2 * libjingle
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 * Copyright 2015 Google Inc.
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +00004 *
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
Zeke Chin57cc74e2015-05-05 07:52:31 -070030#import "RTCAVFoundationVideoSource.h"
31
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000032#import "ARDAppClient.h"
33#import "ARDVideoCallView.h"
34
35@interface ARDVideoCallViewController () <ARDAppClientDelegate,
36 ARDVideoCallViewDelegate>
Zeke Chin57cc74e2015-05-05 07:52:31 -070037@property(nonatomic, strong) RTCVideoTrack *localVideoTrack;
38@property(nonatomic, strong) RTCVideoTrack *remoteVideoTrack;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000039@property(nonatomic, readonly) ARDVideoCallView *videoCallView;
40@end
41
42@implementation ARDVideoCallViewController {
43 ARDAppClient *_client;
44 RTCVideoTrack *_remoteVideoTrack;
45 RTCVideoTrack *_localVideoTrack;
46}
47
48@synthesize videoCallView = _videoCallView;
49
50- (instancetype)initForRoom:(NSString *)room {
51 if (self = [super init]) {
52 _client = [[ARDAppClient alloc] initWithDelegate:self];
53 [_client connectToRoomWithId:room options:nil];
54 }
55 return self;
56}
57
58- (void)loadView {
59 _videoCallView = [[ARDVideoCallView alloc] initWithFrame:CGRectZero];
60 _videoCallView.delegate = self;
61 _videoCallView.statusLabel.text =
62 [self statusTextForState:RTCICEConnectionNew];
63 self.view = _videoCallView;
64}
65
66#pragma mark - ARDAppClientDelegate
67
68- (void)appClient:(ARDAppClient *)client
69 didChangeState:(ARDAppClientState)state {
70 switch (state) {
71 case kARDAppClientStateConnected:
72 NSLog(@"Client connected.");
73 break;
74 case kARDAppClientStateConnecting:
75 NSLog(@"Client connecting.");
76 break;
77 case kARDAppClientStateDisconnected:
78 NSLog(@"Client disconnected.");
79 [self hangup];
80 break;
81 }
82}
83
84- (void)appClient:(ARDAppClient *)client
85 didChangeConnectionState:(RTCICEConnectionState)state {
86 NSLog(@"ICE state changed: %d", state);
87 __weak ARDVideoCallViewController *weakSelf = self;
88 dispatch_async(dispatch_get_main_queue(), ^{
89 ARDVideoCallViewController *strongSelf = weakSelf;
90 strongSelf.videoCallView.statusLabel.text =
91 [strongSelf statusTextForState:state];
92 });
93}
94
95- (void)appClient:(ARDAppClient *)client
96 didReceiveLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
Zeke Chin57cc74e2015-05-05 07:52:31 -070097 self.localVideoTrack = localVideoTrack;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000098}
99
100- (void)appClient:(ARDAppClient *)client
101 didReceiveRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack {
Zeke Chin57cc74e2015-05-05 07:52:31 -0700102 self.remoteVideoTrack = remoteVideoTrack;
103 _videoCallView.statusLabel.hidden = YES;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000104}
105
106- (void)appClient:(ARDAppClient *)client
107 didError:(NSError *)error {
108 NSString *message =
109 [NSString stringWithFormat:@"%@", error.localizedDescription];
110 [self showAlertWithMessage:message];
111 [self hangup];
112}
113
114#pragma mark - ARDVideoCallViewDelegate
115
116- (void)videoCallViewDidHangup:(ARDVideoCallView *)view {
117 [self hangup];
118}
119
Zeke Chin57cc74e2015-05-05 07:52:31 -0700120- (void)videoCallViewDidSwitchCamera:(ARDVideoCallView *)view {
121 // TODO(tkchin): Rate limit this so you can't tap continously on it.
122 // Probably through an animation.
123 [self switchCamera];
124}
125
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000126#pragma mark - Private
127
Zeke Chin57cc74e2015-05-05 07:52:31 -0700128- (void)setLocalVideoTrack:(RTCVideoTrack *)localVideoTrack {
129 if (_localVideoTrack == localVideoTrack) {
130 return;
131 }
132 [_localVideoTrack removeRenderer:_videoCallView.localVideoView];
133 _localVideoTrack = nil;
134 [_videoCallView.localVideoView renderFrame:nil];
135 _localVideoTrack = localVideoTrack;
136 [_localVideoTrack addRenderer:_videoCallView.localVideoView];
137}
138
139- (void)setRemoteVideoTrack:(RTCVideoTrack *)remoteVideoTrack {
140 if (_remoteVideoTrack == remoteVideoTrack) {
141 return;
142 }
143 [_remoteVideoTrack removeRenderer:_videoCallView.localVideoView];
144 _remoteVideoTrack = nil;
145 [_videoCallView.remoteVideoView renderFrame:nil];
146 _remoteVideoTrack = remoteVideoTrack;
147 [_remoteVideoTrack addRenderer:_videoCallView.remoteVideoView];
148}
149
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000150- (void)hangup {
Zeke Chin57cc74e2015-05-05 07:52:31 -0700151 self.remoteVideoTrack = nil;
152 self.localVideoTrack = nil;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000153 [_client disconnect];
Jon Hjelle2f65ac12015-06-12 11:33:45 -0700154 if (![self isBeingDismissed]) {
155 [self.presentingViewController dismissViewControllerAnimated:YES
156 completion:nil];
157 }
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000158}
159
Zeke Chin57cc74e2015-05-05 07:52:31 -0700160- (void)switchCamera {
161 RTCVideoSource* source = self.localVideoTrack.source;
162 if ([source isKindOfClass:[RTCAVFoundationVideoSource class]]) {
163 RTCAVFoundationVideoSource* avSource = (RTCAVFoundationVideoSource*)source;
164 avSource.useBackCamera = !avSource.useBackCamera;
165 _videoCallView.localVideoView.transform = avSource.useBackCamera ?
166 CGAffineTransformIdentity : CGAffineTransformMakeScale(-1, 1);
167 }
168}
169
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000170- (NSString *)statusTextForState:(RTCICEConnectionState)state {
171 switch (state) {
172 case RTCICEConnectionNew:
173 case RTCICEConnectionChecking:
174 return @"Connecting...";
175 case RTCICEConnectionConnected:
176 case RTCICEConnectionCompleted:
177 case RTCICEConnectionFailed:
178 case RTCICEConnectionDisconnected:
179 case RTCICEConnectionClosed:
180 return nil;
181 }
182}
183
184- (void)showAlertWithMessage:(NSString*)message {
185 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil
186 message:message
187 delegate:nil
188 cancelButtonTitle:@"OK"
189 otherButtonTitles:nil];
190 [alertView show];
191}
192
193@end