如何在AppRTC iOS示例中将音频重定向到扬声器?

Alo*_*kin 9 audio avfoundation ios webrtc apprtcdemo

我正在尝试将音频重定向到AppRTC iOS示例中的扬声器.

我试过了:

AVAudioSession* session = [AVAudioSession sharedInstance];

//error handling
BOOL success;
NSError* error;

//set the audioSession category. 
//Needs to be Record or PlayAndRecord to use audioRouteOverride:  

success = [session setCategory:AVAudioSessionCategoryPlayAndRecord
                         error:&error];

if (!success)  NSLog(@"AVAudioSession error setting category:%@",error);

//set the audioSession override
success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
                                      error:&error];
if (!success)  NSLog(@"AVAudioSession error overrideOutputAudioPort:%@",error);

//activate the audio session
success = [session setActive:YES error:&error];
if (!success) NSLog(@"AVAudioSession error activating: %@",error);
else NSLog(@"audioSession active");
Run Code Online (Sandbox Code Playgroud)

没有错误,但它不起作用.我怎样才能解决这个问题?

phu*_*gle 12

我解决了这个问题.只听AVAudioSessionRouteChangeNotification

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didSessionRouteChange:) name:AVAudioSessionRouteChangeNotification object:nil];
Run Code Online (Sandbox Code Playgroud)

并使用didSessionRouteChange选择器如下:

- (void)didSessionRouteChange:(NSNotification *)notification
{
  NSDictionary *interuptionDict = notification.userInfo;
  NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];

  switch (routeChangeReason) {
      case AVAudioSessionRouteChangeReasonCategoryChange: {
          // Set speaker as default route
          NSError* error;
          [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
      }
      break;

    default:
      break;
  }
}
Run Code Online (Sandbox Code Playgroud)


Joe*_*her 6

似乎仍然是一个问题,phuongle 答案对我有用。斯威夫特 4 版本:

NotificationCenter.default.addObserver(forName: .AVAudioSessionRouteChange, object: nil, queue: nil, using: routeChange)    

private func routeChange(_ n: Notification) {
    guard let info = n.userInfo,
        let value = info[AVAudioSessionRouteChangeReasonKey] as? UInt,
        let reason = AVAudioSessionRouteChangeReason(rawValue: value) else { return }
    switch reason {
    case .categoryChange: try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
    default: break
    }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*tin 5

对于来到这里的任何人,在 Swift 中寻找解决方案,该解决方案也可以解决 (BT-) 耳机的变化。下面的示例(Swift 5)就是这样做的。
部分采用@Teivaz

@objc func handleRouteChange(notification: Notification) {
    guard let info = notification.userInfo,
        let value = info[AVAudioSessionRouteChangeReasonKey] as? UInt,
        let reason = AVAudioSession.RouteChangeReason(rawValue: value) else { return }

    switch reason {
    case .categoryChange:
        try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
    case .oldDeviceUnavailable:
        try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
    default:
        l.debug("other")
    }
}
Run Code Online (Sandbox Code Playgroud)


Jos*_* B. 2

我最终找到了解决方案。

原因是您需要将AVAudioSession类别设置为AVAudioSessionCategoryPlayback。但由于某种原因,在建立 webRTC 呼叫后,它被设置回AVAudioSessionCategoryPlayAndRecord。最后,我决定添加观察者并在每次检测到不需要的类别更改时AVAudioSessionRouteChangeNotification切换到。AVAudioSessionCategoryPlayback一些黑客解决方案,但最终成功了。您可以在这里查看。