【问题标题】:ios SystemSound will not respond to volume buttonsios SystemSound 不会响应音量按钮
【发布时间】:2013-06-20 11:48:15
【问题描述】:

我在我的应用中使用了 SystemSound 来播放简单的音效。除此之外,我通过 MPMoviePlayerController 播放音乐视频 - 现在,当我调高/调低音量时,视频中的音乐会按预期响应(调高/调低音量)。

但播放的系统声音不响应音量。当用户点击应用程序中的某些区域时,我会播放系统声音。这是我的代码的 sn-p:

- (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。我仔细检查了我的“设置->声音->铃声和警报->使用按钮更改”是否设置为打开(正如我在其他一些 SO 答案中看到的那样,关闭此选项会导致系统声音不响应音量按钮)

使用 systemsound 的另一个原因是它在播放多种声音时(例如在游戏中)提供了最准确和响应最灵敏的结果。

如果可能的话,我宁愿不使用 OpenAL(即使通过像 FinchCocosDenshion 这样的第三方声音库)

有什么想法吗?

【问题讨论】:

    标签: ios mpmovieplayercontroller


    【解决方案1】:

    使用AVAudioPlayer 类播放由用户音量设置控制的声音(非系统声音)。

    您可以为您经常使用的每个声音文件保留AVAudioPlayer 的实例,只需调用play 方法即可。使用prepareToPlay 预加载缓冲区。

    【讨论】:

    • 感谢您的建议,但我之前在 AVAudioPlayer 上做了一些测试,但它有一些滞后问题。猜猜我唯一的选择是使用 OpenAL 库吗?无法让 SystemSound 响应音量按钮?
    • @am_,您是否预加载了文件、保留了我在(更新的)答案中提到的 AVAudioPlayer 实例,并使用了prepareToPlay?它立即为我工作。我什至将它用于 UI 声音。 SystemSound 用于“警报”。无论如何,OpenAL 只会使用 Core Audio (AVAudioPlayer)。
    • 嗯,我想我可以在应用程序启动后立即使用 prepareToPlay 加载我的所有 wav 文件(我有大约 60 个 wav 文件)。在 finch 主页上提到 AVAudioPlayer 的播放方法有滞后。但明天我会试试看它是如何工作的!会告诉你的!
    【解决方案2】:

    感谢 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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-08
      • 2021-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-14
      • 1970-01-01
      相关资源
      最近更新 更多