Slow start for AVAudioPlayer the first time a soun

2019-01-10 07:56发布

I'm trying to eliminate startup lag when playing a (very short -- less than 2 seconds) audio file via AVAudioPlayer on the iPhone.

First, the code:

NSString *audioFile = [NSString stringWithFormat:@"%@/%@.caf", [[NSBundle mainBundle] resourcePath], @"audiofile"];
NSData *audioData = [NSData dataWithContentsOfMappedFile:audioFile];

NSError *err;
AVAudioPlayer *audioPlayer = [(AVAudioPlayer*)[AVAudioPlayer alloc] initWithData:audioData error:&err];

audioPlayer.delegate = self;
[audioPlayer play];

I also implement the audioPlayerDidFinishPlaying method to release the AVAudioPlayer once I'm done.

The first time I play the audio the lag is palpable -- at least 2 seconds. However, after that the sound plays immediately. I suspect that the culprit, then, is the [NSData dataWithContentsOfMappedFile] taking a long time reading from the flash initially, but then being fast on later reads. I'm not sure how to test that, though.

Is that the case? If so, should I just pre-cache the NSData objects and be aggressive about clearing them in low memory conditions?

9条回答
2楼-- · 2019-01-10 08:51

The delay seems to be related to instantiating AVAudioPlayer for the first time. If I load any audio, run [audioPlayer prepareToPlay] and then immediately release it, the load times for all of my other audio is very close to imperceptible. So now I'm doing that in applicationDidFinishLaunching and everything else runs well.

I can't find anything about this in the docs, but it certainly seems to be the case.

查看更多
老娘就宠你
3楼-- · 2019-01-10 08:54

The answer is

AVAudioPlayer *audioplayer;
[audioplayer prepareToPlay];
查看更多
做自己的国王
4楼-- · 2019-01-10 08:58

Here's what I've done (in a separate thread):

[audioplayer start]
[audioplayer stop]
self.audioplayer = audioplayer

[audioplayer prepareToPlay] seems to be an asynchronous method, so you can't be sure when it returns if the audio is in fact ready to play.

In my case I call start to actually start playing - this appears to be synchronous. Then I stop it immediately. In the simulator anyway I don't hear any sound coming out from this activity. Now that the sound is "really" ready to play, I assign the local variable to a member variable so code outside the thread has access to it.

I must say I find it somewhat surprising that even on iOS 4 it takes some 2 seconds just to load an audio file that is only 4 seconds in length....

查看更多
登录 后发表回答