Ios iPhone AVAudioPlayer应用程序首次播放时冻结

Ios iPhone AVAudioPlayer应用程序首次播放时冻结,ios,audio,avaudioplayer,Ios,Audio,Avaudioplayer,我正在使用iOS SDK中的AVAudioPlayer在tableView行中的每次单击上播放简短的声音。 我已经在每一行中手动创建了@selector on按钮,用于激发方法playSound:idreceiver{}。从接收器我得到声音的网址,所以我可以播放它 此方法如下所示: - (void)playSound:(id)sender { [audioPlayer prepareToPlay]; UIButton *audioButton = (UIButton *)send

我正在使用iOS SDK中的AVAudioPlayer在tableView行中的每次单击上播放简短的声音。 我已经在每一行中手动创建了@selector on按钮,用于激发方法playSound:idreceiver{}。从接收器我得到声音的网址,所以我可以播放它

此方法如下所示:

- (void)playSound:(id)sender {
    [audioPlayer prepareToPlay];
    UIButton *audioButton = (UIButton *)sender;
    [audioButton setImage:[UIImage imageNamed:@"sound_preview.png"] forState:UIControlStateNormal];
    NSString *soundUrl = [[listOfItems objectForKey:[NSString stringWithFormat:@"%i",currentPlayingIndex]] objectForKey:@"sound_url"];

    //here I get mp3 file from http url via NSRequest in NSData
    NSData *soundData = [sharedAppSettingsController getSoundUrl:defaultDictionaryID uri:soundUrl];
    NSError *error;
    audioPlayer = [[AVAudioPlayer alloc] initWithData:soundData error:&error];
    audioPlayer.numberOfLoops = 0;
    if (error) {
        NSLog(@"Error: %@",[error description]);
    }
    else {
        audioPlayer.delegate = self;
        [audioPlayer play];
    }
}
除了第一次播放一些声音外,一切正常。应用程序冻结约2秒钟,然后播放声音。第二个和每一个其他的声音播放工作后,点击声音按钮


我想知道为什么在应用程序启动时第一次播放时会有2秒左右的时间冻结?

对我来说,有时在模拟器中也会发生这种情况。这台设备似乎一切正常。您是否在实际硬件上进行了测试?

检查您是否在函数中异步获取数据

NSData *soundData = [sharedAppSettingsController getSoundUrl:defaultDictionaryID uri:soundUrl];
如果是异步获取,执行将被阻止,直到它获取数据。

从您的代码片段中,audioPlayer必须是ivar,对吗

在方法的顶部,对现有audioPlayer实例调用-prepareToPlay,至少在第一次调用时,该实例可能为nil

在该方法的后面部分,您将使用全新的AVAudioPlayer实例替换现有的音频播放器。前一场比赛被浪费了。每一个新的AVAudioPlayer都在泄漏内存

我不会缓存声音数据或URL,而是尝试创建AVAudioPlayer对象的缓存,每个声音一个。在-playSound:method中,获取表行的相应音频播放器的引用,然后-play

您可以使用-tableView:cellforrowatinexpath:作为获取该行的AVAudioPlayer实例的适当点,也可以延迟创建实例并将其缓存在那里

您可以尝试将-tableView:willDisplayCell:forrowatinexpath:作为在行的AVAudioPlayer实例上调用-preparetoplayer的点


或者您可以在-tableView:cellforrowatinexpath:中执行准备操作。试试看哪个效果最好。

如果您的音频长度小于30秒,并且是线性PCM或IMA4格式,并且打包为.caf、.wav或.aiff,则可以使用系统声音:

导入AudioToolbox框架

在.h文件中创建此变量:

SystemSoundID mySound;
在.m文件中,在init方法中实现它:

-(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;
}

这对我来说很管用,当按下按钮时,声音播放得非常接近。希望这对你有帮助。

你说得对。也许我应该在真正的设备上测试一下。谢谢你的建议。。。
AudioServicesPlaySystemSound(mySound);