blob: 21f00cb4c0447070a64f3d22de3386f6afa94db8 [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
peah5085b0c2016-08-25 22:15:14 -070057 didInputRoom:(NSString *)room
58 isLoopback:(BOOL)isLoopback
59 isAudioOnly:(BOOL)isAudioOnly
60 shouldMakeAecDump:(BOOL)shouldMakeAecDump
tkchind2511962016-05-06 18:54:15 -070061 useManualAudio:(BOOL)useManualAudio {
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000062 if (!room.length) {
haysc913e6452015-10-02 11:44:03 -070063 [self showAlertWithMessage:@"Missing room name."];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000064 return;
65 }
66 // Trim whitespaces.
67 NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet];
68 NSString *trimmedRoom = [room stringByTrimmingCharactersInSet:whitespaceSet];
69
70 // Check that room name is valid.
71 NSError *error = nil;
72 NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive;
73 NSRegularExpression *regex =
74 [NSRegularExpression regularExpressionWithPattern:@"\\w+"
75 options:options
76 error:&error];
77 if (error) {
78 [self showAlertWithMessage:error.localizedDescription];
79 return;
80 }
81 NSRange matchRange =
82 [regex rangeOfFirstMatchInString:trimmedRoom
83 options:0
84 range:NSMakeRange(0, trimmedRoom.length)];
85 if (matchRange.location == NSNotFound ||
86 matchRange.length != trimmedRoom.length) {
87 [self showAlertWithMessage:@"Invalid room name."];
88 return;
89 }
90
Tze Kwang Chin307a0922016-03-21 13:57:40 -070091 RTCAudioSession *session = [RTCAudioSession sharedInstance];
tkchind2511962016-05-06 18:54:15 -070092 session.useManualAudio = useManualAudio;
93 session.isAudioEnabled = NO;
Tze Kwang Chin307a0922016-03-21 13:57:40 -070094
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000095 // Kick off the video call.
96 ARDVideoCallViewController *videoCallViewController =
haysc913e6452015-10-02 11:44:03 -070097 [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom
98 isLoopback:isLoopback
tkchind2511962016-05-06 18:54:15 -070099 isAudioOnly:isAudioOnly
peah5085b0c2016-08-25 22:15:14 -0700100 shouldMakeAecDump:shouldMakeAecDump
tkchind2511962016-05-06 18:54:15 -0700101 delegate:self];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000102 videoCallViewController.modalTransitionStyle =
103 UIModalTransitionStyleCrossDissolve;
104 [self presentViewController:videoCallViewController
105 animated:YES
106 completion:nil];
107}
108
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700109- (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView {
110 if (mainView.isAudioLoopPlaying) {
111 [_audioPlayer stop];
112 } else {
113 [_audioPlayer play];
114 }
115 mainView.isAudioLoopPlaying = _audioPlayer.playing;
116}
117
tkchind2511962016-05-06 18:54:15 -0700118#pragma mark - ARDVideoCallViewControllerDelegate
119
120- (void)viewControllerDidFinish:(ARDVideoCallViewController *)viewController {
121 if (![viewController isBeingDismissed]) {
122 RTCLog(@"Dismissing VC");
123 [self dismissViewControllerAnimated:YES completion:^{
124 [self restartAudioPlayerIfNeeded];
125 }];
126 }
127 RTCAudioSession *session = [RTCAudioSession sharedInstance];
128 session.isAudioEnabled = NO;
129}
130
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700131#pragma mark - RTCAudioSessionDelegate
132
tkchind2511962016-05-06 18:54:15 -0700133- (void)audioSessionDidStartPlayOrRecord:(RTCAudioSession *)session {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700134 // Stop playback on main queue and then configure WebRTC.
135 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
136 block:^{
137 if (_mainView.isAudioLoopPlaying) {
138 RTCLog(@"Stopping audio loop due to WebRTC start.");
139 [_audioPlayer stop];
140 }
tkchind2511962016-05-06 18:54:15 -0700141 RTCLog(@"Setting isAudioEnabled to YES.");
142 session.isAudioEnabled = YES;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700143 }];
144}
145
tkchind2511962016-05-06 18:54:15 -0700146- (void)audioSessionDidStopPlayOrRecord:(RTCAudioSession *)session {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700147 // WebRTC is done with the audio session. Restart playback.
148 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
149 block:^{
tkchind2511962016-05-06 18:54:15 -0700150 RTCLog(@"audioSessionDidStopPlayOrRecord");
151 [self restartAudioPlayerIfNeeded];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700152 }];
153}
154
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000155#pragma mark - Private
156
tkchind2511962016-05-06 18:54:15 -0700157- (void)configureAudioSession {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700158 RTCAudioSessionConfiguration *configuration =
159 [[RTCAudioSessionConfiguration alloc] init];
160 configuration.category = AVAudioSessionCategoryAmbient;
161 configuration.categoryOptions = AVAudioSessionCategoryOptionDuckOthers;
162 configuration.mode = AVAudioSessionModeDefault;
163
164 RTCAudioSession *session = [RTCAudioSession sharedInstance];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700165 [session lockForConfiguration];
tkchind2511962016-05-06 18:54:15 -0700166 BOOL hasSucceeded = NO;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700167 NSError *error = nil;
tkchind2511962016-05-06 18:54:15 -0700168 if (session.isActive) {
169 hasSucceeded = [session setConfiguration:configuration error:&error];
170 } else {
171 hasSucceeded = [session setConfiguration:configuration
172 active:YES
173 error:&error];
174 }
175 if (!hasSucceeded) {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700176 RTCLogError(@"Error setting configuration: %@", error.localizedDescription);
177 }
178 [session unlockForConfiguration];
179}
180
181- (void)setupAudioPlayer {
182 NSString *audioFilePath =
183 [[NSBundle mainBundle] pathForResource:@"mozart" ofType:@"mp3"];
184 NSURL *audioFileURL = [NSURL URLWithString:audioFilePath];
185 _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL
186 error:nil];
187 _audioPlayer.numberOfLoops = -1;
188 _audioPlayer.volume = 1.0;
189 [_audioPlayer prepareToPlay];
190}
191
tkchind2511962016-05-06 18:54:15 -0700192- (void)restartAudioPlayerIfNeeded {
193 if (_mainView.isAudioLoopPlaying && !self.presentedViewController) {
194 RTCLog(@"Starting audio loop due to WebRTC end.");
195 [self configureAudioSession];
196 [_audioPlayer play];
197 }
198}
199
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000200- (void)showAlertWithMessage:(NSString*)message {
201 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil
202 message:message
203 delegate:nil
204 cancelButtonTitle:@"OK"
205 otherButtonTitles:nil];
206 [alertView show];
207}
208
209@end