2010-09-22 66 views
2

我正在使用iOS SDK中的AVAudioPlayer在每次点击tableView行时播放短音。 我已经手动在每一行的按钮上启动了@selector,它启动了方法playSound:(id)receiver {}。从接收器我得到声音的URL,所以我可以播放它。iPhone AVAudioPlayer应用程序在第一次播放时冻结

这种方法看起来像这样:

- (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秒?

如果你认为我拿错解,请告诉我正确的选择。

问候

回答

2

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

在该方法的顶部,您调用-prepareToPlay对现有的audioPlayer实例(可能为零,至少在第一次通过时)。

在后面的方法中,您将用现有的音频播放器替换为全新的AVAudioPlayer实例。之前的-prepareToPlay被浪费了。而且,每个新的AVAudioPlayer都在泄漏内存。

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

您可以使用-tableView:cellForRowAtIndexPath:作为适当的点来获取该行的AVAudioPlayer实例,可能会延迟创建实例并将其缓存到那里。

您可以尝试-tableView:willDisplayCell:forRowAtIndexPath:作为您在该行的AVAudioPlayer实例上调用-prepareToPlay的点。

或者你可以只做-tableView:cellForRowAtIndexPath:的准备。试验一下,看看哪个效果最好。

+0

谢谢,我会试试这个... – 2010-09-23 08:38:26

0

这有时会发生在模拟器对我来说太。一切似乎都在设备上正常工作。你在实际的硬件上测试过吗?

+0

你说得对。可能我应该在真实的设备上测试这个。感谢您的建议... – 2010-09-23 08:39:42

2

确定你是否在功能上异步获取数据..

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

如果您收到异步执行将被阻止,直到它会得到数据。

+0

这也应该是一个问题。我会尽力改变这种... – 2010-09-23 08:39:14

1

如果您的音频小于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; 
} 

在你IBAction为方法,你打电话的声音与此:

AudioServicesPlaySystemSound(mySound); 

这适用于我,播放声音非常接近当按钮被按下。希望这可以帮助你。

相关问题