我在我的应用程序中使用SystemSound以播放简单的声音效果。除此之外,我通过MPMoviePlayerController播放音乐视频 - 现在当我上调/下调音量时,视频中的音乐会按预期响应(降低音量上调/下降)。
但播放的系统声音不会响应音量。当用户点击应用中的某些区域时,我正在播放系统。下面是我的代码片段:
- (void)handleTap:(UITapGestureRecognizer *)recognizer {
SystemSoundID completeSound = nil;
//yellow folder in xcode doesnt need subdirectory param
//blue folder (true folder) will need to use subdirectory:@"dirname"
NSURL *sound_path = [[NSBundle mainBundle] URLForResource: target_sound_filename withExtension: @"wav"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)sound_path, &completeSound);
AudioServicesPlaySystemSound(completeSound);
}
PS。我仔细检查了我的“设置 - >声音 - >振铃和警报 - >按钮更改”设置为ON(当我读到其他一些SO答案时,将此选项设置为OFF将导致系统响应无法响应音量按钮)
进一步使用systemound的原因是它在播放多个声音时给出了最准确和最敏感的结果(如在游戏中)。
如果可能,我倾向于不使用OpenAL(即使通过第三方声音库,如Finch或CocosDenshion)
有什么想法吗?
答案 0 :(得分:2)
使用AVAudioPlayer课程播放由用户音量设置(非系统声音)控制的声音。
您可以为经常使用的每个声音文件保留AVAudioPlayer
的实例,只需调用play
方法即可。使用prepareToPlay
预加载缓冲区。
答案 1 :(得分:1)
向Marcus致敬,建议我可以为每个声音文件保留AVAudioPlayer的实例,并使用prepareToPlay预加载声音。它可能是为了帮助其他人寻找相同的解决方案,所以我就是这样做的(如果有人有改进的建议,请随时评论)
//top of viewcontroller.m
@property (nonatomic, strong) NSMutableDictionary *audioPlayers;
@synthesize audioPlayers = _audioPlayers;
//on viewDidLoad
self.audioPlayers = [NSMutableDictionary new];
//creating the instances and adding them to the nsmutabledictonary in order to retain them
//soundFile is just a NSString containing the name of the wav file
NSString *soundFile = [[NSBundle mainBundle] pathForResource:s ofType:@"wav"];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:soundFile] error:nil];
//audioPlayer.numberOfLoops = -1;
[audioPlayer prepareToPlay];
//add to dictonary with filename (omit extension) as key
[self.audioPlayers setObject:audioPlayer forKey:s];
//then i use the following to play the sound later on (i have it on a tap event)
//get pointer reference to the correct AVAudioPlayer instance for this sound, and play it
AVAudioPlayer *foo = [self.audioPlayers objectForKey:target_sound_filename];
[foo play];
//also im not sure how ARC will treat the strong property, im setting it to nil in dealloc atm.
-(void)dealloc {
self.audioPlayers = nil;
}