I am using below code to loop a single playerItem
with the AVQueuePlayer
:
-(void) init {
_soundPlayer = [ [ AVQueuePlayer alloc ] init ];
[ _soundPlayer addObserver: self forKeyPath: @"status" options: NSKeyValueObservingOptionNew context: NULL ];
[ [ NSNotificationCenter defaultCenter ] addObserver: self selector: @selector ( playerItemDidReachEnd: ) name: AVPlayerItemDidPlayToEndTimeNotification object: nil ];
[ [ NSNotificationCenter defaultCenter ] postNotificationName: AVPlayerItemDidPlayToEndTimeNotification object: nil ];
}
- ( void ) observeValueForKeyPath: ( NSString * ) keyPath ofObject: ( AVPlayer * ) object change: ( NSDictionary * ) change context: ( void * ) context {
if ( _soundPlayer.status == AVPlayerStatusReadyToPlay )
[ _soundPlayer play ];
}
- ( void ) playerItemDidReachEnd: ( NSNotification * ) notification {
AVPlayerItem *playerItem = [ [ AVPlayerItem alloc ] initWithURL: [ NSURL fileURLWithPath: _playerItemFilePath ] ];
[ _soundPlayer insertItem: playerItem afterItem: nil ];
[ playerItem release ];
}
It works fine on the simulator, even though the instruments indicated that a leak something like AudioToolbox SimAggregateDevice::SimAggregateDevice(__CFString const*, __CFString const*, long&)
, people said that is just some "frame leaks", it will be fine on the device, but when I run it on device, no leaks indicated from instruments, but crash instead...Anything I miss? Thanks if anyone can help me on this.
Sometimes playerItem would be stream file online, so can not use AVAudioPlayer
instead.
Finally, I found that is because of the _playerItemFilePath
. It is no longer existed, the NSString
return by NSBundle's
method pathForResource
need to be retained. But I still wondering why it can be run on the simulator. After all, the leak about audioToolbox
is also fixed, so anyone meet the "frame leaks" some people mentioned may be need to look around the code somewhere again. It would come out because of some small mistakes.