blob: 593c6a27f81893df92fc1338eb193d6b2ab67630 [file] [log] [blame]
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +00001/*
Donald E Curtisa8736442015-08-05 15:48:13 -07002 * Copyright 2015 The WebRTC Project Authors. All rights reserved.
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +00003 *
Donald E Curtisa8736442015-08-05 15:48:13 -07004 * 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.
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +00009 */
10
11#import "ARDMainViewController.h"
12
Tze Kwang Chin307a0922016-03-21 13:57:40 -070013#import <AVFoundation/AVFoundation.h>
14
tkchin9eeb6242016-04-27 01:54:20 -070015#import "WebRTC/RTCDispatcher.h"
16#import "WebRTC/RTCLogging.h"
Tze Kwang Chin307a0922016-03-21 13:57:40 -070017#import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h"
18#import "webrtc/modules/audio_device/ios/objc/RTCAudioSessionConfiguration.h"
19
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000020#import "ARDAppClient.h"
21#import "ARDMainView.h"
denicija2256e042016-11-09 06:26:18 -080022#import "ARDSettingsModel.h"
denicijad17d5362016-11-02 02:56:09 -070023#import "ARDSettingsViewController.h"
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000024#import "ARDVideoCallViewController.h"
25
denicijad17d5362016-11-02 02:56:09 -070026static NSString *const barButtonImageString = @"ic_settings_black_24dp.png";
denicija6d6762c2016-10-28 04:53:16 -070027
Tze Kwang Chin307a0922016-03-21 13:57:40 -070028@interface ARDMainViewController () <
29 ARDMainViewDelegate,
tkchind2511962016-05-06 18:54:15 -070030 ARDVideoCallViewControllerDelegate,
Tze Kwang Chin307a0922016-03-21 13:57:40 -070031 RTCAudioSessionDelegate>
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000032@end
33
Tze Kwang Chin307a0922016-03-21 13:57:40 -070034@implementation ARDMainViewController {
35 ARDMainView *_mainView;
36 AVAudioPlayer *_audioPlayer;
tkchind2511962016-05-06 18:54:15 -070037 BOOL _useManualAudio;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000038}
39
Tze Kwang Chin307a0922016-03-21 13:57:40 -070040- (void)loadView {
denicija6d6762c2016-10-28 04:53:16 -070041 self.title = @"AppRTC Mobile";
Tze Kwang Chin307a0922016-03-21 13:57:40 -070042 _mainView = [[ARDMainView alloc] initWithFrame:CGRectZero];
43 _mainView.delegate = self;
44 self.view = _mainView;
denicija6d6762c2016-10-28 04:53:16 -070045 [self addSettingsBarButton];
Tze Kwang Chin307a0922016-03-21 13:57:40 -070046
tkchind2511962016-05-06 18:54:15 -070047 RTCAudioSessionConfiguration *webRTCConfig =
48 [RTCAudioSessionConfiguration webRTCConfiguration];
49 webRTCConfig.categoryOptions = webRTCConfig.categoryOptions |
50 AVAudioSessionCategoryOptionDefaultToSpeaker;
51 [RTCAudioSessionConfiguration setWebRTCConfiguration:webRTCConfig];
52
53 RTCAudioSession *session = [RTCAudioSession sharedInstance];
54 [session addDelegate:self];
55
56 [self configureAudioSession];
Tze Kwang Chin307a0922016-03-21 13:57:40 -070057 [self setupAudioPlayer];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000058}
59
denicija6d6762c2016-10-28 04:53:16 -070060- (void)addSettingsBarButton {
61 UIBarButtonItem *settingsButton =
62 [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:barButtonImageString]
63 style:UIBarButtonItemStylePlain
64 target:self
65 action:@selector(showSettings:)];
66 self.navigationItem.rightBarButtonItem = settingsButton;
67}
68
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000069#pragma mark - ARDMainViewDelegate
70
haysc913e6452015-10-02 11:44:03 -070071- (void)mainView:(ARDMainView *)mainView
tkchinab1293a2016-08-30 12:35:05 -070072 didInputRoom:(NSString *)room
73 isLoopback:(BOOL)isLoopback
74 isAudioOnly:(BOOL)isAudioOnly
75 shouldMakeAecDump:(BOOL)shouldMakeAecDump
76 shouldUseLevelControl:(BOOL)shouldUseLevelControl
77 useManualAudio:(BOOL)useManualAudio {
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000078 if (!room.length) {
haysc913e6452015-10-02 11:44:03 -070079 [self showAlertWithMessage:@"Missing room name."];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000080 return;
81 }
82 // Trim whitespaces.
83 NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet];
84 NSString *trimmedRoom = [room stringByTrimmingCharactersInSet:whitespaceSet];
85
86 // Check that room name is valid.
87 NSError *error = nil;
88 NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive;
89 NSRegularExpression *regex =
90 [NSRegularExpression regularExpressionWithPattern:@"\\w+"
91 options:options
92 error:&error];
93 if (error) {
94 [self showAlertWithMessage:error.localizedDescription];
95 return;
96 }
97 NSRange matchRange =
98 [regex rangeOfFirstMatchInString:trimmedRoom
99 options:0
100 range:NSMakeRange(0, trimmedRoom.length)];
101 if (matchRange.location == NSNotFound ||
102 matchRange.length != trimmedRoom.length) {
103 [self showAlertWithMessage:@"Invalid room name."];
104 return;
105 }
106
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700107 RTCAudioSession *session = [RTCAudioSession sharedInstance];
tkchind2511962016-05-06 18:54:15 -0700108 session.useManualAudio = useManualAudio;
109 session.isAudioEnabled = NO;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700110
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000111 // Kick off the video call.
112 ARDVideoCallViewController *videoCallViewController =
haysc913e6452015-10-02 11:44:03 -0700113 [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom
114 isLoopback:isLoopback
tkchind2511962016-05-06 18:54:15 -0700115 isAudioOnly:isAudioOnly
peah5085b0c2016-08-25 22:15:14 -0700116 shouldMakeAecDump:shouldMakeAecDump
tkchinab1293a2016-08-30 12:35:05 -0700117 shouldUseLevelControl:shouldUseLevelControl
tkchind2511962016-05-06 18:54:15 -0700118 delegate:self];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000119 videoCallViewController.modalTransitionStyle =
120 UIModalTransitionStyleCrossDissolve;
121 [self presentViewController:videoCallViewController
122 animated:YES
123 completion:nil];
124}
125
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700126- (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView {
127 if (mainView.isAudioLoopPlaying) {
128 [_audioPlayer stop];
129 } else {
130 [_audioPlayer play];
131 }
132 mainView.isAudioLoopPlaying = _audioPlayer.playing;
133}
134
tkchind2511962016-05-06 18:54:15 -0700135#pragma mark - ARDVideoCallViewControllerDelegate
136
137- (void)viewControllerDidFinish:(ARDVideoCallViewController *)viewController {
138 if (![viewController isBeingDismissed]) {
139 RTCLog(@"Dismissing VC");
140 [self dismissViewControllerAnimated:YES completion:^{
141 [self restartAudioPlayerIfNeeded];
142 }];
143 }
144 RTCAudioSession *session = [RTCAudioSession sharedInstance];
145 session.isAudioEnabled = NO;
146}
147
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700148#pragma mark - RTCAudioSessionDelegate
149
tkchind2511962016-05-06 18:54:15 -0700150- (void)audioSessionDidStartPlayOrRecord:(RTCAudioSession *)session {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700151 // Stop playback on main queue and then configure WebRTC.
152 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
153 block:^{
154 if (_mainView.isAudioLoopPlaying) {
155 RTCLog(@"Stopping audio loop due to WebRTC start.");
156 [_audioPlayer stop];
157 }
tkchind2511962016-05-06 18:54:15 -0700158 RTCLog(@"Setting isAudioEnabled to YES.");
159 session.isAudioEnabled = YES;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700160 }];
161}
162
tkchind2511962016-05-06 18:54:15 -0700163- (void)audioSessionDidStopPlayOrRecord:(RTCAudioSession *)session {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700164 // WebRTC is done with the audio session. Restart playback.
165 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
166 block:^{
tkchind2511962016-05-06 18:54:15 -0700167 RTCLog(@"audioSessionDidStopPlayOrRecord");
168 [self restartAudioPlayerIfNeeded];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700169 }];
170}
171
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000172#pragma mark - Private
denicija6d6762c2016-10-28 04:53:16 -0700173- (void)showSettings:(id)sender {
denicijad17d5362016-11-02 02:56:09 -0700174 ARDSettingsViewController *settingsController =
denicijab04b5c22016-11-09 04:28:46 -0800175 [[ARDSettingsViewController alloc] initWithStyle:UITableViewStyleGrouped
denicija2256e042016-11-09 06:26:18 -0800176 settingsModel:[[ARDSettingsModel alloc] init]];
177
denicijad17d5362016-11-02 02:56:09 -0700178 UINavigationController *navigationController =
179 [[UINavigationController alloc] initWithRootViewController:settingsController];
180 [self presentViewControllerAsModal:navigationController];
181}
182
183- (void)presentViewControllerAsModal:(UIViewController *)viewController {
184 [self presentViewController:viewController animated:YES completion:nil];
denicija6d6762c2016-10-28 04:53:16 -0700185}
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000186
tkchind2511962016-05-06 18:54:15 -0700187- (void)configureAudioSession {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700188 RTCAudioSessionConfiguration *configuration =
189 [[RTCAudioSessionConfiguration alloc] init];
190 configuration.category = AVAudioSessionCategoryAmbient;
191 configuration.categoryOptions = AVAudioSessionCategoryOptionDuckOthers;
192 configuration.mode = AVAudioSessionModeDefault;
193
194 RTCAudioSession *session = [RTCAudioSession sharedInstance];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700195 [session lockForConfiguration];
tkchind2511962016-05-06 18:54:15 -0700196 BOOL hasSucceeded = NO;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700197 NSError *error = nil;
tkchind2511962016-05-06 18:54:15 -0700198 if (session.isActive) {
199 hasSucceeded = [session setConfiguration:configuration error:&error];
200 } else {
201 hasSucceeded = [session setConfiguration:configuration
202 active:YES
203 error:&error];
204 }
205 if (!hasSucceeded) {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700206 RTCLogError(@"Error setting configuration: %@", error.localizedDescription);
207 }
208 [session unlockForConfiguration];
209}
210
211- (void)setupAudioPlayer {
212 NSString *audioFilePath =
213 [[NSBundle mainBundle] pathForResource:@"mozart" ofType:@"mp3"];
214 NSURL *audioFileURL = [NSURL URLWithString:audioFilePath];
215 _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL
216 error:nil];
217 _audioPlayer.numberOfLoops = -1;
218 _audioPlayer.volume = 1.0;
219 [_audioPlayer prepareToPlay];
220}
221
tkchind2511962016-05-06 18:54:15 -0700222- (void)restartAudioPlayerIfNeeded {
223 if (_mainView.isAudioLoopPlaying && !self.presentedViewController) {
224 RTCLog(@"Starting audio loop due to WebRTC end.");
225 [self configureAudioSession];
226 [_audioPlayer play];
227 }
228}
229
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000230- (void)showAlertWithMessage:(NSString*)message {
231 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil
232 message:message
233 delegate:nil
234 cancelButtonTitle:@"OK"
235 otherButtonTitles:nil];
236 [alertView show];
237}
238
239@end