我正在使用iOS SDK中的AVAudioPlayer在tableView行中的每次点击时播放短音。
我已在每行按钮上手动设置了@selector
,以触发方法playSound:(id)receiver {}
。从接收器我得到声音网址所以我可以播放它。
这个方法看起来像这样:
- (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秒钟?
答案 0 :(得分:2)
检查您是否在函数中异步获取数据..
NSData *soundData = [sharedAppSettingsController getSoundUrl:defaultDictionaryID uri:soundUrl];
如果您异步获取,则执行将被阻止,直到获取数据为止。
答案 1 :(得分:2)
在您的代码段中,audioPlayer
必须是ivar,对吧?
在方法的顶部,您在现有-prepareToPlay
实例上调用audioPlayer
(至少在第一次传递时可能为零)。
稍后在该方法中,您将此现有音频播放器替换为全新的AVAudioPlayer实例。之前的-prepareToPlay
被浪费了。而且你每个新的AVAudioPlayer都在泄漏内存。
我会尝试创建AVAudioPlayer对象的缓存,而不是缓存声音数据或URL,每个声音对应一个。在-playSound:
方法中,获取对表格行的相应音频播放器的引用,并-play
。
您可以使用-tableView:cellForRowAtIndexPath:
作为获取该行的AVAudioPlayer实例的适当点,也可以懒惰地创建实例并将其缓存在那里。
您可以尝试-tableView:willDisplayCell:forRowAtIndexPath:
作为在行的AVAudioPlayer实例上调用-prepareToPlay
的点。
或者您可以在-tableView:cellForRowAtIndexPath:
进行准备。试验并看看哪种方法效果最佳。
答案 2 :(得分: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);
这适合我,播放按下按钮时非常接近的声音。希望这会对你有所帮助。
答案 3 :(得分:0)
这有时也会在我的模拟器中发生。一切似乎在设备上正常工作。您是否在实际硬件上进行了测试?