blob: d11f09222f8461cda17b5f6e1e0d806e5123355b [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,
26 RTCAudioSessionDelegate>
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000027@end
28
Tze Kwang Chin307a0922016-03-21 13:57:40 -070029@implementation ARDMainViewController {
30 ARDMainView *_mainView;
31 AVAudioPlayer *_audioPlayer;
32 BOOL _shouldDelayAudioConfig;
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000033}
34
Tze Kwang Chin307a0922016-03-21 13:57:40 -070035- (void)loadView {
36 _mainView = [[ARDMainView alloc] initWithFrame:CGRectZero];
37 _mainView.delegate = self;
38 self.view = _mainView;
39
40 [self setupAudioSession];
41 [self setupAudioPlayer];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000042}
43
44#pragma mark - ARDMainViewDelegate
45
haysc913e6452015-10-02 11:44:03 -070046- (void)mainView:(ARDMainView *)mainView
Tze Kwang Chin307a0922016-03-21 13:57:40 -070047 didInputRoom:(NSString *)room
48 isLoopback:(BOOL)isLoopback
49 isAudioOnly:(BOOL)isAudioOnly
50 shouldDelayAudioConfig:(BOOL)shouldDelayAudioConfig {
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000051 if (!room.length) {
haysc913e6452015-10-02 11:44:03 -070052 [self showAlertWithMessage:@"Missing room name."];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000053 return;
54 }
55 // Trim whitespaces.
56 NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet];
57 NSString *trimmedRoom = [room stringByTrimmingCharactersInSet:whitespaceSet];
58
59 // Check that room name is valid.
60 NSError *error = nil;
61 NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive;
62 NSRegularExpression *regex =
63 [NSRegularExpression regularExpressionWithPattern:@"\\w+"
64 options:options
65 error:&error];
66 if (error) {
67 [self showAlertWithMessage:error.localizedDescription];
68 return;
69 }
70 NSRange matchRange =
71 [regex rangeOfFirstMatchInString:trimmedRoom
72 options:0
73 range:NSMakeRange(0, trimmedRoom.length)];
74 if (matchRange.location == NSNotFound ||
75 matchRange.length != trimmedRoom.length) {
76 [self showAlertWithMessage:@"Invalid room name."];
77 return;
78 }
79
Tze Kwang Chin307a0922016-03-21 13:57:40 -070080 _shouldDelayAudioConfig = shouldDelayAudioConfig;
81 RTCAudioSession *session = [RTCAudioSession sharedInstance];
82 session.shouldDelayAudioConfiguration = _shouldDelayAudioConfig;
83
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000084 // Kick off the video call.
85 ARDVideoCallViewController *videoCallViewController =
haysc913e6452015-10-02 11:44:03 -070086 [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom
87 isLoopback:isLoopback
88 isAudioOnly:isAudioOnly];
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +000089 videoCallViewController.modalTransitionStyle =
90 UIModalTransitionStyleCrossDissolve;
91 [self presentViewController:videoCallViewController
92 animated:YES
93 completion:nil];
94}
95
Tze Kwang Chin307a0922016-03-21 13:57:40 -070096- (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView {
97 if (mainView.isAudioLoopPlaying) {
98 [_audioPlayer stop];
99 } else {
100 [_audioPlayer play];
101 }
102 mainView.isAudioLoopPlaying = _audioPlayer.playing;
103}
104
105#pragma mark - RTCAudioSessionDelegate
106
107- (void)audioSessionShouldConfigure:(RTCAudioSession *)session {
108 // Won't get called unless audio config is delayed.
109 // Stop playback on main queue and then configure WebRTC.
110 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
111 block:^{
112 if (_mainView.isAudioLoopPlaying) {
113 RTCLog(@"Stopping audio loop due to WebRTC start.");
114 [_audioPlayer stop];
115 }
116 // TODO(tkchin): Shouldn't lock on main queue. Figure out better way to
117 // check audio loop state.
118 [session lockForConfiguration];
119 [session configureWebRTCSession:nil];
120 [session unlockForConfiguration];
121 }];
122}
123
124- (void)audioSessionShouldUnconfigure:(RTCAudioSession *)session {
125 // Won't get called unless audio config is delayed.
126 [session lockForConfiguration];
127 [session unconfigureWebRTCSession:nil];
128 [session unlockForConfiguration];
129}
130
131- (void)audioSessionDidUnconfigure:(RTCAudioSession *)session {
132 // WebRTC is done with the audio session. Restart playback.
133 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain
134 block:^{
135 if (_mainView.isAudioLoopPlaying) {
136 RTCLog(@"Starting audio loop due to WebRTC end.");
137 [_audioPlayer play];
138 }
139 }];
140}
141
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000142#pragma mark - Private
143
Tze Kwang Chin307a0922016-03-21 13:57:40 -0700144- (void)setupAudioSession {
145 RTCAudioSessionConfiguration *configuration =
146 [[RTCAudioSessionConfiguration alloc] init];
147 configuration.category = AVAudioSessionCategoryAmbient;
148 configuration.categoryOptions = AVAudioSessionCategoryOptionDuckOthers;
149 configuration.mode = AVAudioSessionModeDefault;
150
151 RTCAudioSession *session = [RTCAudioSession sharedInstance];
152 [session addDelegate:self];
153 [session lockForConfiguration];
154 NSError *error = nil;
155 if (![session setConfiguration:configuration active:YES error:&error]) {
156 RTCLogError(@"Error setting configuration: %@", error.localizedDescription);
157 }
158 [session unlockForConfiguration];
159}
160
161- (void)setupAudioPlayer {
162 NSString *audioFilePath =
163 [[NSBundle mainBundle] pathForResource:@"mozart" ofType:@"mp3"];
164 NSURL *audioFileURL = [NSURL URLWithString:audioFilePath];
165 _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL
166 error:nil];
167 _audioPlayer.numberOfLoops = -1;
168 _audioPlayer.volume = 1.0;
169 [_audioPlayer prepareToPlay];
170}
171
tkchin@webrtc.orgef2a5dd2015-01-15 22:38:21 +0000172- (void)showAlertWithMessage:(NSString*)message {
173 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil
174 message:message
175 delegate:nil
176 cancelButtonTitle:@"OK"
177 otherButtonTitles:nil];
178 [alertView show];
179}
180
181@end