blob: a684ba32b06a94e987a8d10b12bce257f1272384 [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
tkchind2511962016-05-06 18:54:15 -070057 didInputRoom:(NSString *)room
58 isLoopback:(BOOL)isLoopback
59 isAudioOnly:(BOOL)isAudioOnly
60 useManualAudio:(BOOL)useManualAudio {
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000061 if (!room.length) {
haysc913e6452015-10-02 11:44:03 -070062 [self showAlertWithMessage:@"Missing room name."];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000063 return;
64 }
65 // Trim whitespaces.
66 NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet];
67 NSString *trimmedRoom = [room stringByTrimmingCharactersInSet:whitespaceSet];
68
69 // Check that room name is valid.
70 NSError *error = nil;
71 NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive;
72 NSRegularExpression *regex =
73 [NSRegularExpression regularExpressionWithPattern:@"\\w+"
74 options:options
75 error:&error];
76 if (error) {
77 [self showAlertWithMessage:error.localizedDescription];
78 return;
79 }
80 NSRange matchRange =
81 [regex rangeOfFirstMatchInString:trimmedRoom
82 options:0
83 range:NSMakeRange(0, trimmedRoom.length)];
84 if (matchRange.location == NSNotFound ||
85 matchRange.length != trimmedRoom.length) {
86 [self showAlertWithMessage:@"Invalid room name."];
87 return;
88 }
89
Tze Kwang Chin307a0922016-03-21 13:57:40 -070090 RTCAudioSession *session = [RTCAudioSession sharedInstance];
tkchind2511962016-05-06 18:54:15 -070091 session.useManualAudio = useManualAudio;
92 session.isAudioEnabled = NO;
Tze Kwang Chin307a0922016-03-21 13:57:40 -070093
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000094 // Kick off the video call.
95 ARDVideoCallViewController *videoCallViewController =
haysc913e6452015-10-02 11:44:03 -070096 [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom
97 isLoopback:isLoopback
tkchind2511962016-05-06 18:54:15 -070098 isAudioOnly:isAudioOnly
99 delegate:self];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000100 videoCallViewController.modalTransitionStyle =
101 UIModalTransitionStyleCrossDissolve;
102 [self presentViewController:videoCallViewController
103 animated:YES
104 completion:nil];
105}
106
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700107- (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView {
108 if (mainView.isAudioLoopPlaying) {
109 [_audioPlayer stop];
110 } else {
111 [_audioPlayer play];
112 }
113 mainView.isAudioLoopPlaying = _audioPlayer.playing;
114}
115
tkchind2511962016-05-06 18:54:15 -0700116#pragma mark - ARDVideoCallViewControllerDelegate
117
118- (void)viewControllerDidFinish:(ARDVideoCallViewController *)viewController {
119 if (![viewController isBeingDismissed]) {
120 RTCLog(@"Dismissing VC");
121 [self dismissViewControllerAnimated:YES completion:^{
122 [self restartAudioPlayerIfNeeded];
123 }];
124 }
125 RTCAudioSession *session = [RTCAudioSession sharedInstance];
126 session.isAudioEnabled = NO;
127}
128
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700129#pragma mark - RTCAudioSessionDelegate
130
tkchind2511962016-05-06 18:54:15 -0700131- (void)audioSessionDidStartPlayOrRecord:(RTCAudioSession *)session {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700132 // Stop playback on main queue and then configure WebRTC.
133 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
134 block:^{
135 if (_mainView.isAudioLoopPlaying) {
136 RTCLog(@"Stopping audio loop due to WebRTC start.");
137 [_audioPlayer stop];
138 }
tkchind2511962016-05-06 18:54:15 -0700139 RTCLog(@"Setting isAudioEnabled to YES.");
140 session.isAudioEnabled = YES;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700141 }];
142}
143
tkchind2511962016-05-06 18:54:15 -0700144- (void)audioSessionDidStopPlayOrRecord:(RTCAudioSession *)session {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700145 // WebRTC is done with the audio session. Restart playback.
146 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
147 block:^{
tkchind2511962016-05-06 18:54:15 -0700148 RTCLog(@"audioSessionDidStopPlayOrRecord");
149 [self restartAudioPlayerIfNeeded];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700150 }];
151}
152
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000153#pragma mark - Private
154
tkchind2511962016-05-06 18:54:15 -0700155- (void)configureAudioSession {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700156 RTCAudioSessionConfiguration *configuration =
157 [[RTCAudioSessionConfiguration alloc] init];
158 configuration.category = AVAudioSessionCategoryAmbient;
159 configuration.categoryOptions = AVAudioSessionCategoryOptionDuckOthers;
160 configuration.mode = AVAudioSessionModeDefault;
161
162 RTCAudioSession *session = [RTCAudioSession sharedInstance];
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700163 [session lockForConfiguration];
tkchind2511962016-05-06 18:54:15 -0700164 BOOL hasSucceeded = NO;
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700165 NSError *error = nil;
tkchind2511962016-05-06 18:54:15 -0700166 if (session.isActive) {
167 hasSucceeded = [session setConfiguration:configuration error:&error];
168 } else {
169 hasSucceeded = [session setConfiguration:configuration
170 active:YES
171 error:&error];
172 }
173 if (!hasSucceeded) {
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700174 RTCLogError(@"Error setting configuration: %@", error.localizedDescription);
175 }
176 [session unlockForConfiguration];
177}
178
179- (void)setupAudioPlayer {
180 NSString *audioFilePath =
181 [[NSBundle mainBundle] pathForResource:@"mozart" ofType:@"mp3"];
182 NSURL *audioFileURL = [NSURL URLWithString:audioFilePath];
183 _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL
184 error:nil];
185 _audioPlayer.numberOfLoops = -1;
186 _audioPlayer.volume = 1.0;
187 [_audioPlayer prepareToPlay];
188}
189
tkchind2511962016-05-06 18:54:15 -0700190- (void)restartAudioPlayerIfNeeded {
191 if (_mainView.isAudioLoopPlaying && !self.presentedViewController) {
192 RTCLog(@"Starting audio loop due to WebRTC end.");
193 [self configureAudioSession];
194 [_audioPlayer play];
195 }
196}
197
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000198- (void)showAlertWithMessage:(NSString*)message {
199 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil
200 message:message
201 delegate:nil
202 cancelButtonTitle:@"OK"
203 otherButtonTitles:nil];
204 [alertView show];
205}
206
207@end