4

I'm using the Opus codec for webrtc audio streaming (libjingle_peerconnection) on iOS. How do I enable stereo sound for audio playback?

I borrowed some ideas from this blog post here hoping that I could get it to work. We were able to enable stereo sound for our web client but not our iOS client.

https://www.webrtcexample.com/blog/?go=all/how-to-support-stereo-in-a-webrtc-application/

I’m disabling echo cancellation in the constraints for the offer and peer connection constraints like this:

private func initializeConstraints() -> RTCMediaConstraints {
    let mandatoryConstraints = [
        RTCPair(key: "OfferToReceiveAudio", value: "true"),
        RTCPair(key: "OfferToReceiveVideo", value: "false"),
        RTCPair(key: "echoCancellation", value: "false"),
        RTCPair(key: "googEchoCancellation", value: "false")
    ]
    let optionalConstraints = [
        RTCPair(key: "internalSctpDataChannels", value: "true"),
        RTCPair(key: "DtlsSrtpKeyAgreement", value: "true")
    ]
    return RTCMediaConstraints(mandatoryConstraints: mandatoryConstraints, optionalConstraints: optionalConstraints)
}

I’m enabling stereo for the Opus audio codec like this:

func peerConnection(peerConnection: RTCPeerConnection!, didCreateSessionDescription sdp: RTCSessionDescription!, error: NSError?) {
    LOGD("created sdp")

    guard error == nil else {
        LOGE("error creating session description: \(error!)")
        delegate.onError(self, description: "Error creating sdp")
        return
    }

    dispatch_async(dispatch_get_main_queue()) {
        let replaceThis = "fmtp:111 minptime=10; useinbandfec=1"
        let replaceWith = "fmtp:111 minptime=10; useinbandfec=1; stereo=1; sprop-stereo=1"
        let sdpDescriptionWithStereo = sdp.description.stringByReplacingOccurrencesOfString(replaceThis, withString: replaceWith)
        let sdpWithStereo = RTCSessionDescription(type: sdp.type, sdp: sdpDescriptionWithStereo)
        peerConnection.setLocalDescriptionWithDelegate(self, sessionDescription: sdpWithStereo)

        self.delegate.onLocalSDP(self, type: sdp.type, sdp: sdpDescriptionWithStereo)
    }
}

I'm getting the desired result in sdpDescriptionWithStereo. But I still can't get stereo sound to work.

(And, yes, I am aware that stringByReplacingOccurrencesOfString is a total hack but I'll get to that later)

Rob C
  • 4,877
  • 1
  • 11
  • 24

1 Answers1

1

You can catch the event in a Notification centre and then switch it.

     NotificationCenter.default.addObserver(self, selector: #selector(JanusCommunicationManager.didSessionRouteChange), name: NSNotification.Name.AVAudioSessionRouteChange, object: nil)

     @objc func didSessionRouteChange(notification:Notification) {
        let dict = notification.userInfo
        let routeChangeReason = dict![AVAudioSessionRouteChangeReasonKey] as! UInt
        let error:Error? = nil
        switch routeChangeReason {
        case AVAudioSessionRouteChangeReason.categoryChange.rawValue:
            try? AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
            break
        default:
            break
        }

    }
WorieN
  • 1,276
  • 1
  • 11
  • 30