iPhone AVAudioPlayer app freeze on first play

我与影子孤独终老i 提交于 2019-12-04 16:57:43

From your code snippet, audioPlayer must be an ivar, right?

At the top of the method, you invoke -prepareToPlay on the existing audioPlayer instance (which could be nil, at least on the first pass).

Later in the method, you replace this existing audio player with a brand new AVAudioPlayer instance. The previous -prepareToPlay is wasted. And you're leaking memory with each new AVAudioPlayer.

Instead of caching sound data or URLs, I would try creating a cache of AVAudioPlayer objects, one for each sound. In your -playSound: method, get a reference to the appropriate audio player for the table row, and -play.

You can use -tableView:cellForRowAtIndexPath: as the appropriate point to get the AVAudioPlayer instance for that row, maybe lazily creating the instance and caching it there as well.

You can try -tableView:willDisplayCell:forRowAtIndexPath: as the point where you would invoke -prepareToPlay on the row's AVAudioPlayer instance.

Or you could just do the prepare in -tableView:cellForRowAtIndexPath:. Experiment and see which works best.

Check whether you are getting data asynchronously in function..

NSData *soundData = [sharedAppSettingsController getSoundUrl:defaultDictionaryID uri:soundUrl];

If you are getting asynchronously the execution will be blocked until it will get data.

If your audio is less than 30 seconds long in length and is in linear PCM or IMA4 format, and is packaged as a .caf, .wav, or .aiff you can use system sounds:

Import the AudioToolbox Framework

In your .h file create this variable:

SystemSoundID mySound;

In your .m file implement it in your init method:

-(id)init{
if (self) {
//Get path of VICTORY.WAV <-- the sound file in your bundle
 NSString* soundPath = [[NSBundle mainBundle] pathForResource:@"VICTORY" ofType:@"WAV"];
//If the file is in the bundle
if (soundPath) {
    //Create a file URL with this path
    NSURL* soundURL = [NSURL fileURLWithPath:soundPath];

    //Register sound file located at that URL as a system sound
    OSStatus err = AudioServicesCreateSystemSoundID((CFURLRef)soundURL, &mySound);

        if (err != kAudioServicesNoError) {
            NSLog(@"Could not load %@, error code: %ld", soundURL, err);
        }
    }
}
return self;
}

In your IBAction method you call the sound with this:

AudioServicesPlaySystemSound(mySound);

This works for me, plays the sound pretty damn close to when the button is pressed. Hope this helps you.

This sometimes happens in the simulator for me too. Everything seems to work fine on the device. Have you tested on actual hardware?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!