diff --git a/Ringtones/README.md b/Ringtones/README.md index f8884a97..9fe3f06c 100644 --- a/Ringtones/README.md +++ b/Ringtones/README.md @@ -43,7 +43,3 @@ Application Notes * There is no timeout for the audio player. If the asset plays to completion or there is an error, all calls from OTAudioBus will be passed to the audio driver, and playback/capture for OpenTok will proceed as normal. - -* An additional tap gesture recognizer has been added to this sample to show - and test that this sequence will work through multiple calls. The - `resetSession` method is added to implement this workflow. diff --git a/Ringtones/Ringtones/Assets.xcassets/AppIcon.appiconset/Contents.json b/Ringtones/Ringtones/Assets.xcassets/AppIcon.appiconset/Contents.json index 1d060ed2..9221b9bb 100644 --- a/Ringtones/Ringtones/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Ringtones/Ringtones/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -2,92 +2,97 @@ "images" : [ { "idiom" : "iphone", - "size" : "20x20", - "scale" : "2x" + "scale" : "2x", + "size" : "20x20" }, { "idiom" : "iphone", - "size" : "20x20", - "scale" : "3x" + "scale" : "3x", + "size" : "20x20" }, { "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" + "scale" : "2x", + "size" : "29x29" }, { "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" + "scale" : "3x", + "size" : "29x29" }, { "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" + "scale" : "2x", + "size" : "40x40" }, { "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" + "scale" : "3x", + "size" : "40x40" }, { "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" + "scale" : "2x", + "size" : "60x60" }, { "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" + "scale" : "3x", + "size" : "60x60" }, { "idiom" : "ipad", - "size" : "20x20", - "scale" : "1x" + "scale" : "1x", + "size" : "20x20" }, { "idiom" : "ipad", - "size" : "20x20", - "scale" : "2x" + "scale" : "2x", + "size" : "20x20" }, { "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" + "scale" : "1x", + "size" : "29x29" }, { "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" + "scale" : "2x", + "size" : "29x29" }, { "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" + "scale" : "1x", + "size" : "40x40" }, { "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" + "scale" : "2x", + "size" : "40x40" }, { "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" + "scale" : "1x", + "size" : "76x76" }, { "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" + "scale" : "2x", + "size" : "76x76" }, { "idiom" : "ipad", - "size" : "83.5x83.5", - "scale" : "2x" + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/Ringtones/Ringtones/OTAudioDeviceRingtone.h b/Ringtones/Ringtones/OTAudioDeviceRingtone.h index 6147ff11..0c0abdf8 100644 --- a/Ringtones/Ringtones/OTAudioDeviceRingtone.h +++ b/Ringtones/Ringtones/OTAudioDeviceRingtone.h @@ -18,5 +18,7 @@ // Immediately stops the ringtone and allows OpenTok audio calls to flow - (void)stopRingtone; +- (void)startRingtone; +- (BOOL)isRingTonePlaying; @end diff --git a/Ringtones/Ringtones/OTAudioDeviceRingtone.m b/Ringtones/Ringtones/OTAudioDeviceRingtone.m index c804eaeb..c66c24a8 100644 --- a/Ringtones/Ringtones/OTAudioDeviceRingtone.m +++ b/Ringtones/Ringtones/OTAudioDeviceRingtone.m @@ -18,7 +18,6 @@ @interface OTAudioDeviceRingtone() @implementation OTAudioDeviceRingtone { AVAudioPlayer* _audioPlayer; - NSMutableArray* _deferredCallbacks; BOOL _vibratesWithRingtone; NSTimer* _vibrateTimer; NSURL * ringtoneURL; @@ -29,7 +28,6 @@ @implementation OTAudioDeviceRingtone { - (instancetype)initWithRingtone:(NSURL *)url { self = [super init]; if (self) { - _deferredCallbacks = [NSMutableArray new]; ringtoneURL = url; } @@ -74,110 +72,41 @@ - (void)playRingtoneFromURL:(NSURL*)url [_audioPlayer play]; } -- (void)stopRingtone { - // Stop Audio - [_audioPlayer stop]; - _audioPlayer = nil; - - // Stop vibration - [_vibrateTimer invalidate]; - _vibrateTimer = nil; - - [self startCapture]; - [self startRendering]; - // Allow deferred audio callback calls to flow - [self flushDeferredCallbacks]; -} - - (void)buzz:(NSTimer*)timer { if (_vibratesWithRingtone) { AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); } } -/** - * Private method: Can't always do as requested immediately. Defer incoming - * callbacks from OTAudioBus until we aren't playing anything back - */ -- (void)enqueueDeferredCallback:(SEL)callback -{ - @synchronized(self) { - NSString* selectorString = NSStringFromSelector(callback); - [_deferredCallbacks addObject:selectorString]; - } -} -- (void)flushDeferredCallbacks { - while (_deferredCallbacks.count > 0) { - NSString* selectorString = [_deferredCallbacks objectAtIndex:0]; - NSLog(@"performing deferred callback %@", selectorString); - SEL callback = NSSelectorFromString(selectorString); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" - [self performSelector:callback]; -#pragma clang diagnostic pop - [_deferredCallbacks removeObjectAtIndex:0]; - } -} #pragma mark - OTDefaultAudioDevice overrides +// The following callbacks are overridden just in case you want to add logs etc. +// You could have made a call to the parent methods directly. + - (BOOL)startRendering { - if (_audioPlayer) { - [self enqueueDeferredCallback:_cmd]; - return YES; - } else { - return [super startRendering]; - } + return [super startRendering]; } - (BOOL)stopRendering { - if (_audioPlayer) { - [self enqueueDeferredCallback:_cmd]; - return YES; - } else { - return [super stopRendering]; - } + return [super stopRendering]; } - (BOOL)startCapture { - if (_audioPlayer) { - [self enqueueDeferredCallback:_cmd]; - return YES; - } else { - static dispatch_once_t once; - BOOL ret = [super startCapture]; - dispatch_once(&once, ^{ - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - [self playRingtoneFromURL:self->ringtoneURL]; - }); - }); - return ret; - } + return [super startCapture]; } - (BOOL)stopCapture { - if (_audioPlayer) { - [self enqueueDeferredCallback:_cmd]; - return YES; - } else { - return [super stopCapture]; - } + return [super stopCapture]; } #pragma mark - AVAudioPlayerDelegate -- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player - successfully:(BOOL)flag -{ - NSLog(@"audioPlayerDidFinishPlaying success=%d", flag); - [self stopRingtone]; -} - - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError * __nullable)error { @@ -185,5 +114,29 @@ - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player [self stopRingtone]; } +#pragma mark - Exposed interface methods +- (void)startRingtone { + if (_audioPlayer == nil) { + [self playRingtoneFromURL:ringtoneURL]; + } +} + +- (void)stopRingtone { + // Stop Audio + [_audioPlayer stop]; + _audioPlayer = nil; + + // Stop vibration + [_vibrateTimer invalidate]; + _vibrateTimer = nil; + + [self startCapture]; + [self startRendering]; + +} + +- (BOOL)isRingTonePlaying { + return _audioPlayer != nil; +} @end diff --git a/Ringtones/Ringtones/ViewController.m b/Ringtones/Ringtones/ViewController.m index 97f393f8..390d9349 100644 --- a/Ringtones/Ringtones/ViewController.m +++ b/Ringtones/Ringtones/ViewController.m @@ -15,7 +15,7 @@ @interface ViewController()