OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | |
3 * | |
4 * 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. | |
9 */ | |
10 | |
11 #import "ARDMainViewController.h" | |
12 | |
13 #import <AVFoundation/AVFoundation.h> | |
14 | |
15 #import "WebRTC/RTCDispatcher.h" | |
16 #import "WebRTC/RTCLogging.h" | |
17 #import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h" | |
18 #import "webrtc/modules/audio_device/ios/objc/RTCAudioSessionConfiguration.h" | |
19 | |
20 #import "ARDAppClient.h" | |
21 #import "ARDMainView.h" | |
22 #import "ARDVideoCallViewController.h" | |
23 | |
24 @interface ARDMainViewController () < | |
25 ARDMainViewDelegate, | |
26 ARDVideoCallViewControllerDelegate, | |
27 RTCAudioSessionDelegate> | |
28 @end | |
29 | |
30 @implementation ARDMainViewController { | |
31 ARDMainView *_mainView; | |
32 AVAudioPlayer *_audioPlayer; | |
33 BOOL _useManualAudio; | |
34 } | |
35 | |
36 - (void)loadView { | |
37 _mainView = [[ARDMainView alloc] initWithFrame:CGRectZero]; | |
38 _mainView.delegate = self; | |
39 self.view = _mainView; | |
40 | |
41 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]; | |
51 [self setupAudioPlayer]; | |
52 } | |
53 | |
54 #pragma mark - ARDMainViewDelegate | |
55 | |
56 - (void)mainView:(ARDMainView *)mainView | |
57 didInputRoom:(NSString *)room | |
58 isLoopback:(BOOL)isLoopback | |
59 isAudioOnly:(BOOL)isAudioOnly | |
60 shouldMakeAecDump:(BOOL)shouldMakeAecDump | |
61 shouldUseLevelControl:(BOOL)shouldUseLevelControl | |
62 useManualAudio:(BOOL)useManualAudio { | |
63 if (!room.length) { | |
64 [self showAlertWithMessage:@"Missing room name."]; | |
65 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 | |
92 RTCAudioSession *session = [RTCAudioSession sharedInstance]; | |
93 session.useManualAudio = useManualAudio; | |
94 session.isAudioEnabled = NO; | |
95 | |
96 // Kick off the video call. | |
97 ARDVideoCallViewController *videoCallViewController = | |
98 [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom | |
99 isLoopback:isLoopback | |
100 isAudioOnly:isAudioOnly | |
101 shouldMakeAecDump:shouldMakeAecDump | |
102 shouldUseLevelControl:shouldUseLevelControl | |
103 delegate:self]; | |
104 videoCallViewController.modalTransitionStyle = | |
105 UIModalTransitionStyleCrossDissolve; | |
106 [self presentViewController:videoCallViewController | |
107 animated:YES | |
108 completion:nil]; | |
109 } | |
110 | |
111 - (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView { | |
112 if (mainView.isAudioLoopPlaying) { | |
113 [_audioPlayer stop]; | |
114 } else { | |
115 [_audioPlayer play]; | |
116 } | |
117 mainView.isAudioLoopPlaying = _audioPlayer.playing; | |
118 } | |
119 | |
120 #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 | |
133 #pragma mark - RTCAudioSessionDelegate | |
134 | |
135 - (void)audioSessionDidStartPlayOrRecord:(RTCAudioSession *)session { | |
136 // 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 } | |
143 RTCLog(@"Setting isAudioEnabled to YES."); | |
144 session.isAudioEnabled = YES; | |
145 }]; | |
146 } | |
147 | |
148 - (void)audioSessionDidStopPlayOrRecord:(RTCAudioSession *)session { | |
149 // WebRTC is done with the audio session. Restart playback. | |
150 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain | |
151 block:^{ | |
152 RTCLog(@"audioSessionDidStopPlayOrRecord"); | |
153 [self restartAudioPlayerIfNeeded]; | |
154 }]; | |
155 } | |
156 | |
157 #pragma mark - Private | |
158 | |
159 - (void)configureAudioSession { | |
160 RTCAudioSessionConfiguration *configuration = | |
161 [[RTCAudioSessionConfiguration alloc] init]; | |
162 configuration.category = AVAudioSessionCategoryAmbient; | |
163 configuration.categoryOptions = AVAudioSessionCategoryOptionDuckOthers; | |
164 configuration.mode = AVAudioSessionModeDefault; | |
165 | |
166 RTCAudioSession *session = [RTCAudioSession sharedInstance]; | |
167 [session lockForConfiguration]; | |
168 BOOL hasSucceeded = NO; | |
169 NSError *error = nil; | |
170 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) { | |
178 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 | |
194 - (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 | |
202 - (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 | |
OLD | NEW |