首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >混合模式和非混合模式之间的AVAudioSession交换

混合模式和非混合模式之间的AVAudioSession交换
EN

Stack Overflow用户
提问于 2015-10-28 08:44:49
回答 3查看 2.1K关注 0票数 6

我有一个应用程序,可以显示视频,我想下面的行为。

  • 当视频第一次出现在屏幕上并开始播放时,它的音频应该与其他可能已经播放的应用程序的音频混合在一起。例如,如果用户正在收听Spotify,他们应该同时听到Spotify和播放视频的音频。
  • 如果用户点击一个特定的按钮,来自其他应用程序的音频应该是静音的,这样只有来自视频播放的音频。
  • 如果用户再次点击按钮,其他应用程序的音频应该恢复,视频的音频和其他应用程序的音频应该再次混合。

本质上,我希望能够在“混合”和“非混合”之间切换我的应用程序的音频模式。

下面是一些代码,展示了我是如何修改AVAudioSession以获得这个功能的。

开启混合模式

代码语言:javascript
复制
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryAmbient
         withOptions:AVAudioSessionCategoryOptionMixWithOthers
               error:nil];
[session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

关闭混合模式

代码语言:javascript
复制
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback
         withOptions:0
               error:nil];
[session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

我遇到的问题是,在以前关闭音频之后,打开音频混合,不会通知其他应用程序他们可以再次播放音频。我真的非常想要那样的行为。那是不可能的事。

这似乎是通知其他应用程序可以恢复的唯一方法是将我的应用程序的音频会话设置为“非活动”。不幸的是,在播放视频时,会在控制台中打印一个警告,要求在停用音频会话之前停止播放音频。这也有基本破坏AVPlayer的效果,因为它不能再播放任何音频。

有人知道如何解决这些问题吗?任何解决方案都是受欢迎的,即使是非常复杂的解决方案或使用私有API的解决方案也是如此。

EN

回答 3

Stack Overflow用户

发布于 2019-01-08 12:37:39

因此,正如其他答案所指出的那样,您可以“暂停”另一个应用程序的音频。但是,您可以通过使用.duckWithOthers来拒绝它。一旦您的音频完成,您可以重新设置该选项为.mixWithOthers,并通知其他应用程序,他们的音量可以恢复到完整的水平。

假设您的音频在ViewController出现时启动,当ViewController消失时停止。然后可以使用以下代码:

代码语言:javascript
复制
override func viewWillAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // Use duckOthers so the audio in your VC is slightly louder than the background audio such as Spotify
    updateAVAudioSessionOptions(to: .duckOthers)
  }

  override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    // Reset to mixWithOthers since we are no longer playing audio
    updateAVAudioSessionOptions(to: .mixWithOthers)

    // probably a good idea to stop the audio as well
    player.pause() 
  }

  private func updateAVAudioSessionOptions(to options: AVAudioSession.CategoryOptions) {
    do {
      try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: options)

      if options == .mixWithOthers {
        // Notify other apps that they volume can be restored to the full level
        try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
      }

    } catch let error {
      print("Error: \(error)")
    }
  }
票数 2
EN

Stack Overflow用户

发布于 2015-10-28 23:35:40

我觉得你运气不好。即使是AVAudioSessionCategoryOptionDuckOthers,听起来应该适合您的用例,也要求您停用会话才能将其他应用程序的音量恢复到正常,但正如您所看到的,这会导致错误。

票数 1
EN

Stack Overflow用户

发布于 2015-10-28 09:41:29

也许你应该在你的“关闭混合模式”块中将“是”改为“否”。

代码语言:javascript
复制
[session setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33386405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档