iPhone AVAudioPlayer应用程序在第一次播放时冻结
我正在使用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秒?
如果你认为我拿错解,请告诉我正确的选择。
问候
从您的代码片段中,audioPlayer
必须是ivar,对不对?
在该方法的顶部,您调用-prepareToPlay
对现有的audioPlayer
实例(可能为零,至少在第一次通过时)。
在后面的方法中,您将用现有的音频播放器替换为全新的AVAudioPlayer实例。之前的-prepareToPlay
被浪费了。而且,每个新的AVAudioPlayer都在泄漏内存。
而不是缓存声音数据或URL,我会尝试创建一个AVAudioPlayer对象的缓存,每个声音一个。在-playSound:
方法中,获取表格行的相应音频播放器的引用,并获取-play
。
您可以使用-tableView:cellForRowAtIndexPath:
作为适当的点来获取该行的AVAudioPlayer实例,可能会延迟创建实例并将其缓存到那里。
您可以尝试-tableView:willDisplayCell:forRowAtIndexPath:
作为您在该行的AVAudioPlayer实例上调用-prepareToPlay
的点。
或者你可以只做-tableView:cellForRowAtIndexPath:
的准备。试验一下,看看哪个效果最好。
这有时会发生在模拟器对我来说太。一切似乎都在设备上正常工作。你在实际的硬件上测试过吗?
你说得对。可能我应该在真实的设备上测试这个。感谢您的建议... – 2010-09-23 08:39:42
确定你是否在功能上异步获取数据..
NSData *soundData = [sharedAppSettingsController getSoundUrl:defaultDictionaryID uri:soundUrl];
如果您收到异步执行将被阻止,直到它会得到数据。
这也应该是一个问题。我会尽力改变这种... – 2010-09-23 08:39:14
如果您的音频小于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);
这适用于我,播放声音非常接近当按钮被按下。希望这可以帮助你。
谢谢,我会试试这个... – 2010-09-23 08:38:26