OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #import "ARDMainViewController.h" | 11 #import "ARDMainViewController.h" |
12 | 12 |
13 #import <AVFoundation/AVFoundation.h> | |
14 | |
15 #import "webrtc/base/objc/RTCDispatcher.h" | |
16 #import "webrtc/base/objc/RTCLogging.h" | |
17 #import "webrtc/modules/audio_device/ios/objc/RTCAudioSession.h" | |
18 #import "webrtc/modules/audio_device/ios/objc/RTCAudioSessionConfiguration.h" | |
19 | |
13 #import "ARDAppClient.h" | 20 #import "ARDAppClient.h" |
14 #import "ARDMainView.h" | 21 #import "ARDMainView.h" |
15 #import "ARDVideoCallViewController.h" | 22 #import "ARDVideoCallViewController.h" |
16 | 23 |
17 @interface ARDMainViewController () <ARDMainViewDelegate> | 24 @interface ARDMainViewController () < |
25 ARDMainViewDelegate, | |
26 RTCAudioSessionDelegate> | |
18 @end | 27 @end |
19 | 28 |
20 @implementation ARDMainViewController | 29 @implementation ARDMainViewController { |
30 ARDMainView *_mainView; | |
31 AVAudioPlayer *_audioPlayer; | |
32 BOOL _shouldDelayAudioConfig; | |
33 } | |
21 | 34 |
22 - (void)loadView { | 35 - (void)loadView { |
23 ARDMainView *mainView = [[ARDMainView alloc] initWithFrame:CGRectZero]; | 36 _mainView = [[ARDMainView alloc] initWithFrame:CGRectZero]; |
24 mainView.delegate = self; | 37 _mainView.delegate = self; |
25 self.view = mainView; | 38 self.view = _mainView; |
39 | |
40 [self setupAudioSession]; | |
41 [self setupAudioPlayer]; | |
26 } | 42 } |
27 | 43 |
28 - (void)applicationWillResignActive:(UIApplication *)application { | 44 - (void)applicationWillResignActive:(UIApplication *)application { |
29 // Terminate any calls when we aren't active. | 45 // Terminate any calls when we aren't active. |
30 [self dismissViewControllerAnimated:NO completion:nil]; | 46 // [self dismissViewControllerAnimated:NO completion:nil]; |
Chuck
2016/03/21 17:12:48
Did you mean to remove this? Add a comment if not.
tkchin_webrtc
2016/03/21 18:32:27
Nope! Although there isn't a reason to dismiss it
| |
31 } | 47 } |
32 | 48 |
33 #pragma mark - ARDMainViewDelegate | 49 #pragma mark - ARDMainViewDelegate |
34 | 50 |
35 - (void)mainView:(ARDMainView *)mainView | 51 - (void)mainView:(ARDMainView *)mainView |
36 didInputRoom:(NSString *)room | 52 didInputRoom:(NSString *)room |
37 isLoopback:(BOOL)isLoopback | 53 isLoopback:(BOOL)isLoopback |
38 isAudioOnly:(BOOL)isAudioOnly { | 54 isAudioOnly:(BOOL)isAudioOnly |
55 shouldDelayAudioConfig:(BOOL)shouldDelayAudioConfig { | |
39 if (!room.length) { | 56 if (!room.length) { |
40 [self showAlertWithMessage:@"Missing room name."]; | 57 [self showAlertWithMessage:@"Missing room name."]; |
41 return; | 58 return; |
42 } | 59 } |
43 // Trim whitespaces. | 60 // Trim whitespaces. |
44 NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet]; | 61 NSCharacterSet *whitespaceSet = [NSCharacterSet whitespaceCharacterSet]; |
45 NSString *trimmedRoom = [room stringByTrimmingCharactersInSet:whitespaceSet]; | 62 NSString *trimmedRoom = [room stringByTrimmingCharactersInSet:whitespaceSet]; |
46 | 63 |
47 // Check that room name is valid. | 64 // Check that room name is valid. |
48 NSError *error = nil; | 65 NSError *error = nil; |
49 NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive; | 66 NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive; |
50 NSRegularExpression *regex = | 67 NSRegularExpression *regex = |
51 [NSRegularExpression regularExpressionWithPattern:@"\\w+" | 68 [NSRegularExpression regularExpressionWithPattern:@"\\w+" |
52 options:options | 69 options:options |
53 error:&error]; | 70 error:&error]; |
54 if (error) { | 71 if (error) { |
55 [self showAlertWithMessage:error.localizedDescription]; | 72 [self showAlertWithMessage:error.localizedDescription]; |
56 return; | 73 return; |
57 } | 74 } |
58 NSRange matchRange = | 75 NSRange matchRange = |
59 [regex rangeOfFirstMatchInString:trimmedRoom | 76 [regex rangeOfFirstMatchInString:trimmedRoom |
60 options:0 | 77 options:0 |
61 range:NSMakeRange(0, trimmedRoom.length)]; | 78 range:NSMakeRange(0, trimmedRoom.length)]; |
62 if (matchRange.location == NSNotFound || | 79 if (matchRange.location == NSNotFound || |
63 matchRange.length != trimmedRoom.length) { | 80 matchRange.length != trimmedRoom.length) { |
64 [self showAlertWithMessage:@"Invalid room name."]; | 81 [self showAlertWithMessage:@"Invalid room name."]; |
65 return; | 82 return; |
66 } | 83 } |
67 | 84 |
85 _shouldDelayAudioConfig = shouldDelayAudioConfig; | |
86 RTCAudioSession *session = [RTCAudioSession sharedInstance]; | |
87 session.shouldDelayAudioConfiguration = _shouldDelayAudioConfig; | |
88 | |
68 // Kick off the video call. | 89 // Kick off the video call. |
69 ARDVideoCallViewController *videoCallViewController = | 90 ARDVideoCallViewController *videoCallViewController = |
70 [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom | 91 [[ARDVideoCallViewController alloc] initForRoom:trimmedRoom |
71 isLoopback:isLoopback | 92 isLoopback:isLoopback |
72 isAudioOnly:isAudioOnly]; | 93 isAudioOnly:isAudioOnly]; |
73 videoCallViewController.modalTransitionStyle = | 94 videoCallViewController.modalTransitionStyle = |
74 UIModalTransitionStyleCrossDissolve; | 95 UIModalTransitionStyleCrossDissolve; |
75 [self presentViewController:videoCallViewController | 96 [self presentViewController:videoCallViewController |
76 animated:YES | 97 animated:YES |
77 completion:nil]; | 98 completion:nil]; |
78 } | 99 } |
79 | 100 |
101 - (void)mainViewDidToggleAudioLoop:(ARDMainView *)mainView { | |
102 if (mainView.isAudioLoopPlaying) { | |
103 [_audioPlayer stop]; | |
104 } else { | |
105 [_audioPlayer play]; | |
106 } | |
107 mainView.isAudioLoopPlaying = _audioPlayer.playing; | |
108 } | |
109 | |
110 #pragma mark - RTCAudioSessionDelegate | |
111 | |
112 - (void)audioSessionShouldConfigure:(RTCAudioSession *)session { | |
113 // Won't get called unless audio config is delayed. | |
114 // Stop playback on main queue and then configure WebRTC. | |
115 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain | |
116 block:^{ | |
117 if (_mainView.isAudioLoopPlaying) { | |
118 RTCLog(@"Stopping audio loop due to WebRTC start."); | |
119 [_audioPlayer stop]; | |
120 } | |
121 [session lockForConfiguration]; | |
122 [session configureWebRTCSession:nil]; | |
123 [session unlockForConfiguration]; | |
124 }]; | |
125 } | |
126 | |
127 - (void)audioSessionShouldUnconfigure:(RTCAudioSession *)session { | |
128 // Won't get called unless audio config is delayed. | |
129 [session lockForConfiguration]; | |
130 [session unconfigureWebRTCSession:nil]; | |
131 [session unlockForConfiguration]; | |
132 } | |
133 | |
134 - (void)audioSessionDidUnconfigure:(RTCAudioSession *)session { | |
135 // WebRTC is done with the audio session. Restart playback. | |
136 [RTCDispatcher dispatchAsyncOnType:RTCDispatcherTypeMain | |
137 block:^{ | |
138 if (_mainView.isAudioLoopPlaying) { | |
139 RTCLog(@"Starting audio loop due to WebRTC end."); | |
140 [_audioPlayer play]; | |
141 } | |
142 }]; | |
143 } | |
144 | |
80 #pragma mark - Private | 145 #pragma mark - Private |
81 | 146 |
147 - (void)setupAudioSession { | |
148 RTCAudioSessionConfiguration *configuration = | |
149 [[RTCAudioSessionConfiguration alloc] init]; | |
Chuck
2016/03/21 17:12:48
indent
tkchin_webrtc
2016/03/21 18:32:27
Done.
| |
150 configuration.category = AVAudioSessionCategoryAmbient; | |
151 configuration.categoryOptions = 0; | |
152 configuration.mode = AVAudioSessionModeDefault; | |
153 | |
154 RTCAudioSession *session = [RTCAudioSession sharedInstance]; | |
155 [session addDelegate:self]; | |
156 [session lockForConfiguration]; | |
157 NSError *error = nil; | |
158 if (![session setConfiguration:configuration active:YES error:&error]) { | |
159 RTCLogError(@"Error setting configuration: %@", error.localizedDescription); | |
160 } | |
161 [session unlockForConfiguration]; | |
162 } | |
163 | |
164 - (void)setupAudioPlayer { | |
165 NSString *audioFilePath = | |
166 [[NSBundle mainBundle] pathForResource:@"mozart" ofType:@"mp3"]; | |
Chuck
2016/03/21 17:12:48
indent
tkchin_webrtc
2016/03/21 18:32:27
Done.
| |
167 NSURL *audioFileURL = [NSURL URLWithString:audioFilePath]; | |
168 _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL | |
169 error:nil]; | |
170 _audioPlayer.numberOfLoops = -1; | |
171 _audioPlayer.volume = 1.0; | |
172 [_audioPlayer prepareToPlay]; | |
173 } | |
174 | |
82 - (void)showAlertWithMessage:(NSString*)message { | 175 - (void)showAlertWithMessage:(NSString*)message { |
83 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil | 176 UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:nil |
84 message:message | 177 message:message |
85 delegate:nil | 178 delegate:nil |
86 cancelButtonTitle:@"OK" | 179 cancelButtonTitle:@"OK" |
87 otherButtonTitles:nil]; | 180 otherButtonTitles:nil]; |
88 [alertView show]; | 181 [alertView show]; |
89 } | 182 } |
90 | 183 |
91 @end | 184 @end |
OLD | NEW |