diff --git a/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCAudioOutputQueue.h b/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCAudioOutputQueue.h index 8d746f0..b083aa6 100644 --- a/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCAudioOutputQueue.h +++ b/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCAudioOutputQueue.h @@ -15,6 +15,7 @@ @property (nonatomic,assign,readonly) AudioStreamBasicDescription format; @property (nonatomic,assign) float volume; @property (nonatomic,assign) UInt32 bufferSize; +@property (nonatomic,assign,readonly) BOOL isRunning; /** * return playedTime of audioqueue, return invalidPlayedTime when error occurs. diff --git a/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCAudioOutputQueue.m b/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCAudioOutputQueue.m index b196e7a..e6a868a 100644 --- a/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCAudioOutputQueue.m +++ b/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCAudioOutputQueue.m @@ -24,6 +24,7 @@ @interface MCAudioOutputQueue () NSMutableArray *_buffers; NSMutableArray *_reusableBuffers; + BOOL _isRunning; BOOL _started; NSTimeInterval _playedTime; @@ -37,6 +38,7 @@ @implementation MCAudioOutputQueue @dynamic available; @synthesize volume = _volume; @synthesize bufferSize = _bufferSize; +@synthesize isRunning = _isRunning; #pragma mark - init & dealloc - (instancetype)initWithFormat:(AudioStreamBasicDescription)format bufferSize:(UInt32)bufferSize macgicCookie:(NSData *)macgicCookie @@ -105,6 +107,15 @@ - (void)_createAudioOutputQueue:(NSData *)magicCookie if (status != noErr) { _audioQueue = NULL; + return; + } + + status = AudioQueueAddPropertyListener(_audioQueue, kAudioQueueProperty_IsRunning, MCAudioQueuePropertyCallback, (__bridge void *)(self)); + if (status != noErr) + { + AudioQueueDispose(_audioQueue, YES); + _audioQueue = NULL; + return; } if (_buffers.count == 0) @@ -333,4 +344,21 @@ - (void)handleAudioQueueOutputCallBack:(AudioQueueRef)audioQueue buffer:(AudioQu [self _mutexSignal]; } + +static void MCAudioQueuePropertyCallback(void *inUserData, AudioQueueRef inAQ, AudioQueuePropertyID inID) +{ + __unsafe_unretained MCAudioOutputQueue *audioQueue = (__bridge MCAudioOutputQueue *)inUserData; + [audioQueue handleAudioQueuePropertyCallBack:inAQ property:inID]; +} + +- (void)handleAudioQueuePropertyCallBack:(AudioQueueRef)audioQueue property:(AudioQueuePropertyID)property +{ + if (property == kAudioQueueProperty_IsRunning) + { + UInt32 isRunning = 0; + UInt32 size = sizeof(isRunning); + AudioQueueGetProperty(audioQueue, property, &isRunning, &size); + _isRunning = isRunning; + } +} @end diff --git a/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCSimpleAudioPlayer.h b/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCSimpleAudioPlayer.h index 72715a8..c945d95 100644 --- a/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCSimpleAudioPlayer.h +++ b/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCSimpleAudioPlayer.h @@ -15,6 +15,7 @@ typedef NS_ENUM(NSUInteger, MCSAPStatus) MCSAPStatusPlaying = 1, MCSAPStatusWaiting = 2, MCSAPStatusPaused = 3, + MCSAPStatusFlushing = 4, }; @interface MCSimpleAudioPlayer : NSObject diff --git a/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCSimpleAudioPlayer.m b/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCSimpleAudioPlayer.m index fb1fed8..fc49232 100644 --- a/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCSimpleAudioPlayer.m +++ b/MCSimpleAudioPlayerDemo/MCSimpleAudioPlayer/MCSimpleAudioPlayer.m @@ -127,7 +127,7 @@ - (void)cleanup #pragma mark - status - (BOOL)isPlayingOrWaiting { - return self.status == MCSAPStatusWaiting || self.status == MCSAPStatusPlaying; + return self.status == MCSAPStatusWaiting || self.status == MCSAPStatusPlaying || self.status == MCSAPStatusFlushing; } - (MCSAPStatus)status @@ -292,6 +292,11 @@ - (void)threadMain continue; } + if (self.status == MCSAPStatusFlushing && !_audioQueue.isRunning) + { + break; + } + //stop if (_stopRequired) { @@ -328,10 +333,14 @@ - (void)threadMain if (![_buffer hasData] && isEof) { - [_audioQueue flush]; - break; + [_audioQueue stop:NO]; + [self setStatusInternal:MCSAPStatusFlushing]; } } + else if (isEof) + { + //do nothing wait for end + } else { _failed = YES; @@ -456,7 +465,7 @@ - (void)_resume - (void)pause { - if (self.isPlayingOrWaiting) + if (self.isPlayingOrWaiting && self.status != MCSAPStatusFlushing) { _pauseRequired = YES; }