From 8b73c31faea543fa3fcd62be244a98455c8ba0af Mon Sep 17 00:00:00 2001 From: zztkm Date: Thu, 12 Sep 2024 18:44:35 +0900 Subject: [PATCH] =?UTF-8?q?Answer=20=E3=81=AE=20SDP=20=E3=82=92=E6=9B=B8?= =?UTF-8?q?=E3=81=8D=E6=8F=9B=E3=81=88=E3=82=8B=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sora/Configuration.swift | 3 +++ Sora/PeerChannel.swift | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Sora/Configuration.swift b/Sora/Configuration.swift index 72e8c426..fa4c9d99 100644 --- a/Sora/Configuration.swift +++ b/Sora/Configuration.swift @@ -215,6 +215,9 @@ public struct Configuration { /// 通常、指定する必要はありません。 public var publisherAudioTrackId: String = defaultPublisherAudioTrackId + /// ステレオ出力を許可するための設定です。 + public var forceStereoOutput: Bool = false + /** 初期化します。 diff --git a/Sora/PeerChannel.swift b/Sora/PeerChannel.swift index 6c33f7f6..a912a2f4 100644 --- a/Sora/PeerChannel.swift +++ b/Sora/PeerChannel.swift @@ -577,7 +577,6 @@ class PeerChannel: NSObject, RTCPeerConnectionDelegate { Logger.debug(type: .peerChannel, message: "try create answer") Logger.debug(type: .peerChannel, message: offer) - Logger.debug(type: .peerChannel, message: "try setting remote description") let offer = RTCSessionDescription(type: .offer, sdp: offer) nativeChannel.setRemoteDescription(offer) { error in @@ -689,7 +688,36 @@ class PeerChannel: NSObject, RTCPeerConnectionDelegate { return } - let answer = SignalingAnswer(sdp: sdp!) + var sdp = sdp! + + // Chrome/Edge 向けのハック stereo=1 が CreateOffer では付与されないので、 + // SDP を書き換えて stereo=1 を付与する + // https://github.com/w3c/webrtc-stats/issues/686 + // https://github.com/w3c/webrtc-extensions/issues/63 + // https://issues.webrtc.org/issues/41481053#comment18 + if (self.configuration.forceStereoOutput) { + Logger.debug(type: .peerChannel, message: "stereo=1 を付与する") + let pattern = "minptime=\\d+" + let regexp = try! NSRegularExpression(pattern: pattern) + let replacementFunc: (String) -> String = { match in + if !match.contains("stereo=1") { + return "\(match);stereo=1" + } + return match + } + + let matches = regexp.matches(in: sdp, range: NSRange(sdp.startIndex..., in: sdp)) + for match in matches.reversed() { + print("kensaku: match: \(match)") + let range = match.range + let matchedString = (sdp as NSString).substring(with: range) + let replacedString = replacementFunc(matchedString) + print("kensaku: replacedString: \(replacedString)") + sdp = (sdp as NSString).replacingCharacters(in: range, with: replacedString) + } + } + + let answer = SignalingAnswer(sdp: sdp) self.signalingChannel.send(message: Signaling.answer(answer)) self.lock.unlock() Logger.debug(type: .peerChannel, message: "did send answer")