blob: e392168dee61b3e2dee72a224c593cad3fc3862e [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
Tze Kwang Chin307a0922016-03-21 13:57:40 -070024@interface ARDMainViewController () <
25 ARDMainViewDelegate,
tkchind2511962016-05-06 18:54:15 -070026 ARDVideoCallViewControllerDelegate,
Tze Kwang Chin307a0922016-03-21 13:57:40 -070027 RTCAudioSessionDelegate>
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000028@end
29
Tze Kwang Chin307a0922016-03-21 13:57:40 -070030@implementation ARDMainViewController {
31 ARDMainView *_mainView;
32 AVAudioPlayer *_audioPlayer;
tkchind2511962016-05-06 18:54:15 -070033 BOOL _useManualAudio;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000034}
35
Tze Kwang Chin307a0922016-03-21 13:57:40 -070036- (void)loadView {
37 _mainView = [[ARDMainView alloc] initWithFrame:CGRectZero];
38 _mainView.delegate = self;
39 self.view = _mainView;
40
tkchind2511962016-05-06 18:54:15 -070041 RTCAudioSessionConfiguration *webRTCConfig =
42 [RTCAudioSessionConfiguration webRTCConfiguration];
43 webRTCConfig.categoryOptions = webRTCConfig.categoryOptions |
44 AVAudioSessionCategoryOptionDefaultToSpeaker;
45 [RTCAudioSessionConfiguration setWebRTCConfiguration:webRTCConfig];
46
47 RTCAudioSession *session = [RTCAudioSession sharedInstance];
48 [session addDelegate:self];
49
50 [self configureAudioSession];
Tze Kwang Chin307a0922016-03-21 13:57:40 -070051 [self setupAudioPlayer];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000052}
53
54#pragma mark - ARDMainViewDelegate
55
haysc913e6452015-10-02 11:44:03 -070056- (void)mainView:(ARDMainView *)mainView
tkchinab1293a2016-08-30 12:35:05 -070057 didInputRoom:(NSString *)room
58 isLoopback:(BOOL)isLoopback
59 isAudioOnly:(BOOL)isAudioOnly
60 shouldMakeAecDump:(BOOL)shouldMakeAecDump
61 shouldUseLevelControl:(BOOL)shouldUseLevelControl
62 useManualAudio:(BOOL)useManualAudio {
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000063 if (!room.length) {
haysc913e6452015-10-02 11:44:03 -070064 [self showAlertWithMessage:@"Missing room name."];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000065 return;
66 }
67 // Trim whitespaces.
68 NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet];
69 NSString *trimmedRoom = [room stringByTrimmingCharactersInSet:whitespaceSet];
70
71 // Check that room name is valid.
72 NSError *error = nil;
73 NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive;
74 NSRegularExpression *regex =
75 [NSRegularExpression regularExpressionWithPattern:@"\\w+"
76 options:options
77 error:&error];
78 if (error) {
79 [self showAlertWithMessage:error.localizedDescription];
80 return;
81 }
82 NSRange matchRange =
83 [regex rangeOfFirstMatchInString:trimmedRoom
84 options:0
85 range:NSMakeRange(0, trimmedRoom.length)];
86 if (matchRange.location == NSNotFound ||
87 matchRange.length != trimmedRoom.length) {
88 [self showAlertWithMessage:@"Invalid room name."];
89 return;
90 }
91
Tze Kwang Chin307a0922016-03-21 13:57:40 -070092 RTCAudioSession *session = [RTCAudioSession sharedInstance];
tkchind2511962016-05-06 18:54:15 -070093 session.useManualAudio = useManualAudio;
94 session.isAudioEnabled = NO;
Tze Kwang Chin307a0922016-03-21 13:57:40 -070095
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000096 // Kick off the video call.
97 ARDVideoCallViewController *videoCallViewController =
haysc913e6452015-10-02 11:44:03 -070098 [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom
99 isLoopback:isLoopback
tkchind2511962016-05-06 18:54:15 -0700100 isAudioOnly:isAudioOnly
peah5085b0c2016-08-25 22:15:14 -0700101 shouldMakeAecDump:shouldMakeAecDump
tkchinab1293a2016-08-30 12:35:05 -0700102 shouldUseLevelControl:shouldUseLevelControl
tkchind2511962016-05-06 18:54:15 -0700103 delegate:self];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000104 videoCallViewController.modalTransitionStyle =
105 UIModalTransitionStyleCrossDissolve;
106 [self presentViewController:videoCallViewController
107 animated:YES
108 completion:nil];
109}
110
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700111- (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView {
112 if (mainView.isAudioLoopPlaying) {
113 [_audioPlayer stop];
114 } else {
115 [_audioPlayer play];
116 }
117 mainView.isAudioLoopPlaying = _audioPlayer.playing;
118}
119
tkchind2511962016-05-06 18:54:15 -0700120#pragma mark - ARDVideoCallViewControllerDelegate
121
122- (void)viewControllerDidFinish:(ARDVideoCallViewController *)viewController {
123 if (![viewController isBeingDismissed]) {
124 RTCLog(@"Dismissing VC");
125 [self dismissViewControllerAnimated:YES completion:^{
126 [self restartAudioPlayerIfNeeded];
127 }];
128 }
129 RTCAudioSession *session = [RTCAudioSession sharedInstance];
130 session.isAudioEnabled = NO;
131}
132
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700133#pragma mark - RTCAudioSessionDelegate
134
tkchind2511962016-05-06 18:54:15 -0700135- (void)audioSessionDidStartPlayOrRecord:(RTCAudioSession *)session {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700136 // Stop playback on main queue and then configure WebRTC.
137 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
138 block:^{
139 if (_mainView.isAudioLoopPlaying) {
140 RTCLog(@"Stopping audio loop due to WebRTC start.");
141 [_audioPlayer stop];
142 }
tkchind2511962016-05-06 18:54:15 -0700143 RTCLog(@"Setting isAudioEnabled to YES.");
144 session.isAudioEnabled = YES;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700145 }];
146}
147
tkchind2511962016-05-06 18:54:15 -0700148- (void)audioSessionDidStopPlayOrRecord:(RTCAudioSession *)session {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700149 // WebRTC is done with the audio session. Restart playback.
150 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
151 block:^{
tkchind2511962016-05-06 18:54:15 -0700152 RTCLog(@"audioSessionDidStopPlayOrRecord");
153 [self restartAudioPlayerIfNeeded];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700154 }];
155}
156
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000157#pragma mark - Private
158
tkchind2511962016-05-06 18:54:15 -0700159- (void)configureAudioSession {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700160 RTCAudioSessionConfiguration *configuration =
161 [[RTCAudioSessionConfiguration alloc] init];
162 configuration.category = AVAudioSessionCategoryAmbient;
163 configuration.categoryOptions = AVAudioSessionCategoryOptionDuckOthers;
164 configuration.mode = AVAudioSessionModeDefault;
165
166 RTCAudioSession *session = [RTCAudioSession sharedInstance];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700167 [session lockForConfiguration];
tkchind2511962016-05-06 18:54:15 -0700168 BOOL hasSucceeded = NO;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700169 NSError *error = nil;
tkchind2511962016-05-06 18:54:15 -0700170 if (session.isActive) {
171 hasSucceeded = [session setConfiguration:configuration error:&error];
172 } else {
173 hasSucceeded = [session setConfiguration:configuration
174 active:YES
175 error:&error];
176 }
177 if (!hasSucceeded) {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700178 RTCLogError(@"Error setting configuration: %@", error.localizedDescription);
179 }
180 [session unlockForConfiguration];
181}
182
183- (void)setupAudioPlayer {
184 NSString *audioFilePath =
185 [[NSBundle mainBundle] pathForResource:@"mozart" ofType:@"mp3"];
186 NSURL *audioFileURL = [NSURL URLWithString:audioFilePath];
187 _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL
188 error:nil];
189 _audioPlayer.numberOfLoops = -1;
190 _audioPlayer.volume = 1.0;
191 [_audioPlayer prepareToPlay];
192}
193
tkchind2511962016-05-06 18:54:15 -0700194- (void)restartAudioPlayerIfNeeded {
195 if (_mainView.isAudioLoopPlaying && !self.presentedViewController) {
196 RTCLog(@"Starting audio loop due to WebRTC end.");
197 [self configureAudioSession];
198 [_audioPlayer play];
199 }
200}
201
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000202- (void)showAlertWithMessage:(NSString*)message {
203 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil
204 message:message
205 delegate:nil
206 cancelButtonTitle:@"OK"
207 otherButtonTitles:nil];
208 [alertView show];
209}
210
211@end