blob: f7e03bc72f318e7784ae589ceb791655983cb765 [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"
22#import "ARDVideoCallViewController.h"
23
denicija6d6762c2016-10-28 04:53:16 -070024static NSString *barButtonImageString = @"ic_settings_black_24dp.png";
25
Tze Kwang Chin307a0922016-03-21 13:57:40 -070026@interface ARDMainViewController () <
27 ARDMainViewDelegate,
tkchind2511962016-05-06 18:54:15 -070028 ARDVideoCallViewControllerDelegate,
Tze Kwang Chin307a0922016-03-21 13:57:40 -070029 RTCAudioSessionDelegate>
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000030@end
31
Tze Kwang Chin307a0922016-03-21 13:57:40 -070032@implementation ARDMainViewController {
33 ARDMainView *_mainView;
34 AVAudioPlayer *_audioPlayer;
tkchind2511962016-05-06 18:54:15 -070035 BOOL _useManualAudio;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000036}
37
Tze Kwang Chin307a0922016-03-21 13:57:40 -070038- (void)loadView {
denicija6d6762c2016-10-28 04:53:16 -070039 self.title = @"AppRTC Mobile";
Tze Kwang Chin307a0922016-03-21 13:57:40 -070040 _mainView = [[ARDMainView alloc] initWithFrame:CGRectZero];
41 _mainView.delegate = self;
42 self.view = _mainView;
denicija6d6762c2016-10-28 04:53:16 -070043 [self addSettingsBarButton];
Tze Kwang Chin307a0922016-03-21 13:57:40 -070044
tkchind2511962016-05-06 18:54:15 -070045 RTCAudioSessionConfiguration *webRTCConfig =
46 [RTCAudioSessionConfiguration webRTCConfiguration];
47 webRTCConfig.categoryOptions = webRTCConfig.categoryOptions |
48 AVAudioSessionCategoryOptionDefaultToSpeaker;
49 [RTCAudioSessionConfiguration setWebRTCConfiguration:webRTCConfig];
50
51 RTCAudioSession *session = [RTCAudioSession sharedInstance];
52 [session addDelegate:self];
53
54 [self configureAudioSession];
Tze Kwang Chin307a0922016-03-21 13:57:40 -070055 [self setupAudioPlayer];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000056}
57
denicija6d6762c2016-10-28 04:53:16 -070058- (void)addSettingsBarButton {
59 UIBarButtonItem *settingsButton =
60 [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:barButtonImageString]
61 style:UIBarButtonItemStylePlain
62 target:self
63 action:@selector(showSettings:)];
64 self.navigationItem.rightBarButtonItem = settingsButton;
65}
66
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000067#pragma mark - ARDMainViewDelegate
68
haysc913e6452015-10-02 11:44:03 -070069- (void)mainView:(ARDMainView *)mainView
tkchinab1293a2016-08-30 12:35:05 -070070 didInputRoom:(NSString *)room
71 isLoopback:(BOOL)isLoopback
72 isAudioOnly:(BOOL)isAudioOnly
73 shouldMakeAecDump:(BOOL)shouldMakeAecDump
74 shouldUseLevelControl:(BOOL)shouldUseLevelControl
75 useManualAudio:(BOOL)useManualAudio {
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000076 if (!room.length) {
haysc913e6452015-10-02 11:44:03 -070077 [self showAlertWithMessage:@"Missing room name."];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000078 return;
79 }
80 // Trim whitespaces.
81 NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet];
82 NSString *trimmedRoom = [room stringByTrimmingCharactersInSet:whitespaceSet];
83
84 // Check that room name is valid.
85 NSError *error = nil;
86 NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive;
87 NSRegularExpression *regex =
88 [NSRegularExpression regularExpressionWithPattern:@"\\w+"
89 options:options
90 error:&error];
91 if (error) {
92 [self showAlertWithMessage:error.localizedDescription];
93 return;
94 }
95 NSRange matchRange =
96 [regex rangeOfFirstMatchInString:trimmedRoom
97 options:0
98 range:NSMakeRange(0, trimmedRoom.length)];
99 if (matchRange.location == NSNotFound ||
100 matchRange.length != trimmedRoom.length) {
101 [self showAlertWithMessage:@"Invalid room name."];
102 return;
103 }
104
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700105 RTCAudioSession *session = [RTCAudioSession sharedInstance];
tkchind2511962016-05-06 18:54:15 -0700106 session.useManualAudio = useManualAudio;
107 session.isAudioEnabled = NO;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700108
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000109 // Kick off the video call.
110 ARDVideoCallViewController *videoCallViewController =
haysc913e6452015-10-02 11:44:03 -0700111 [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom
112 isLoopback:isLoopback
tkchind2511962016-05-06 18:54:15 -0700113 isAudioOnly:isAudioOnly
peah5085b0c2016-08-25 22:15:14 -0700114 shouldMakeAecDump:shouldMakeAecDump
tkchinab1293a2016-08-30 12:35:05 -0700115 shouldUseLevelControl:shouldUseLevelControl
tkchind2511962016-05-06 18:54:15 -0700116 delegate:self];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000117 videoCallViewController.modalTransitionStyle =
118 UIModalTransitionStyleCrossDissolve;
119 [self presentViewController:videoCallViewController
120 animated:YES
121 completion:nil];
122}
123
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700124- (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView {
125 if (mainView.isAudioLoopPlaying) {
126 [_audioPlayer stop];
127 } else {
128 [_audioPlayer play];
129 }
130 mainView.isAudioLoopPlaying = _audioPlayer.playing;
131}
132
tkchind2511962016-05-06 18:54:15 -0700133#pragma mark - ARDVideoCallViewControllerDelegate
134
135- (void)viewControllerDidFinish:(ARDVideoCallViewController *)viewController {
136 if (![viewController isBeingDismissed]) {
137 RTCLog(@"Dismissing VC");
138 [self dismissViewControllerAnimated:YES completion:^{
139 [self restartAudioPlayerIfNeeded];
140 }];
141 }
142 RTCAudioSession *session = [RTCAudioSession sharedInstance];
143 session.isAudioEnabled = NO;
144}
145
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700146#pragma mark - RTCAudioSessionDelegate
147
tkchind2511962016-05-06 18:54:15 -0700148- (void)audioSessionDidStartPlayOrRecord:(RTCAudioSession *)session {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700149 // Stop playback on main queue and then configure WebRTC.
150 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
151 block:^{
152 if (_mainView.isAudioLoopPlaying) {
153 RTCLog(@"Stopping audio loop due to WebRTC start.");
154 [_audioPlayer stop];
155 }
tkchind2511962016-05-06 18:54:15 -0700156 RTCLog(@"Setting isAudioEnabled to YES.");
157 session.isAudioEnabled = YES;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700158 }];
159}
160
tkchind2511962016-05-06 18:54:15 -0700161- (void)audioSessionDidStopPlayOrRecord:(RTCAudioSession *)session {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700162 // WebRTC is done with the audio session. Restart playback.
163 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
164 block:^{
tkchind2511962016-05-06 18:54:15 -0700165 RTCLog(@"audioSessionDidStopPlayOrRecord");
166 [self restartAudioPlayerIfNeeded];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700167 }];
168}
169
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000170#pragma mark - Private
denicija6d6762c2016-10-28 04:53:16 -0700171- (void)showSettings:(id)sender {
172}
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000173
tkchind2511962016-05-06 18:54:15 -0700174- (void)configureAudioSession {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700175 RTCAudioSessionConfiguration *configuration =
176 [[RTCAudioSessionConfiguration alloc] init];
177 configuration.category = AVAudioSessionCategoryAmbient;
178 configuration.categoryOptions = AVAudioSessionCategoryOptionDuckOthers;
179 configuration.mode = AVAudioSessionModeDefault;
180
181 RTCAudioSession *session = [RTCAudioSession sharedInstance];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700182 [session lockForConfiguration];
tkchind2511962016-05-06 18:54:15 -0700183 BOOL hasSucceeded = NO;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700184 NSError *error = nil;
tkchind2511962016-05-06 18:54:15 -0700185 if (session.isActive) {
186 hasSucceeded = [session setConfiguration:configuration error:&error];
187 } else {
188 hasSucceeded = [session setConfiguration:configuration
189 active:YES
190 error:&error];
191 }
192 if (!hasSucceeded) {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700193 RTCLogError(@"Error setting configuration: %@", error.localizedDescription);
194 }
195 [session unlockForConfiguration];
196}
197
198- (void)setupAudioPlayer {
199 NSString *audioFilePath =
200 [[NSBundle mainBundle] pathForResource:@"mozart" ofType:@"mp3"];
201 NSURL *audioFileURL = [NSURL URLWithString:audioFilePath];
202 _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL
203 error:nil];
204 _audioPlayer.numberOfLoops = -1;
205 _audioPlayer.volume = 1.0;
206 [_audioPlayer prepareToPlay];
207}
208
tkchind2511962016-05-06 18:54:15 -0700209- (void)restartAudioPlayerIfNeeded {
210 if (_mainView.isAudioLoopPlaying && !self.presentedViewController) {
211 RTCLog(@"Starting audio loop due to WebRTC end.");
212 [self configureAudioSession];
213 [_audioPlayer play];
214 }
215}
216
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000217- (void)showAlertWithMessage:(NSString*)message {
218 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil
219 message:message
220 delegate:nil
221 cancelButtonTitle:@"OK"
222 otherButtonTitles:nil];
223 [alertView show];
224}
225
226@end