Ios A音频在混合和非混合模式之间切换

Ios A音频在混合和非混合模式之间切换,ios,video,avfoundation,avplayer,avaudiosession,Ios,Video,Avfoundation,Avplayer,Avaudiosession,我有一个应用程序,可以显示视频,我想以下行为 当视频第一次出现在屏幕上并开始播放时,它的音频应该与其他可能已经在播放的应用程序的音频混合。例如,如果用户正在收听Spotify,他们应该同时听到来自Spotify和播放视频的音频 如果用户点击一个特定的按钮,来自其他应用程序的音频应该被静音,以便只播放来自视频的音频 如果用户再次点击按钮,来自其他应用程序的音频应恢复,视频音频应与来自其他应用程序的音频再次混合 本质上,我希望能够在“混音”和“非混音”之间切换我的应用程序的音频模式 下面是一些代

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

  • 当视频第一次出现在屏幕上并开始播放时,它的音频应该与其他可能已经在播放的应用程序的音频混合。例如,如果用户正在收听Spotify,他们应该同时听到来自Spotify和播放视频的音频

  • 如果用户点击一个特定的按钮,来自其他应用程序的音频应该被静音,以便只播放来自视频的音频

  • 如果用户再次点击按钮,来自其他应用程序的音频应恢复,视频音频应与来自其他应用程序的音频再次混合

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

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

打开混合模式

AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryAmbient
         withOptions:AVAudioSessionCategoryOptionMixWithOthers
               error:nil];
[session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback
         withOptions:0
               error:nil];
[session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
关闭混合模式

AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryAmbient
         withOptions:AVAudioSessionCategoryOptionMixWithOthers
               error:nil];
[session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback
         withOptions:0
               error:nil];
[session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
我遇到的问题是,在之前关闭音频混音后再打开音频混音,并不会通知其他应用程序它们可以重新播放音频。我真的,真的想要那种行为。这是不可能的

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


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

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


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

因此,其他答案指出,您可以“暂停”其他应用程序的音频。但是,您可以使用
.duckWithOthers
将其关闭。音频完成后,您可以将该选项重置回
.mixWithOthers
,并通知其他应用程序,它们的音量可以恢复到完整级别

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

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)")
    }
  }

问题是,我无法在播放视频时将音频会话设置为非活动状态。AVPlayer对此并不酷,而且之后也不会播放声音。你需要暂停并再次播放视频才能从中恢复过来。是的,我担心情况就是这样。如何欺骗iOS向其他进程发送“中断恢复”通知?您认为扩展是否有自己的音频会话?