From e8a38b16de1a2a459b6eac79424a05dcbfeb92db Mon Sep 17 00:00:00 2001 From: HUI <15215604969@163.com> Date: Thu, 9 Jul 2020 20:47:51 +0800 Subject: [PATCH 1/3] - add `constructor` for typescript - fix Android `mapToChannelMediaInfo` crash - fix iOS `switchChannel` `sendMetadata` crash --- BeanCovertor.swift | 74 ++++++++++++++++++++------------------------- Callback.swift | 35 ++++++++++++++++----- MediaObserver.swift | 6 ++-- RtcChannel.swift | 26 ++++++++++++++-- RtcEngine.swift | 4 +-- 5 files changed, 89 insertions(+), 56 deletions(-) diff --git a/BeanCovertor.swift b/BeanCovertor.swift index 359cc7046..07f0ab278 100644 --- a/BeanCovertor.swift +++ b/BeanCovertor.swift @@ -9,7 +9,7 @@ import Foundation import AgoraRtcKit -func mapToPoint(map: Dictionary) -> CGPoint { +func mapToPoint(_ map: Dictionary) -> CGPoint { var point = CGPoint() if let x = map["x"] as? Int { point.x = CGFloat(x) @@ -20,7 +20,7 @@ func mapToPoint(map: Dictionary) -> CGPoint { return point } -func mapToSize(map: Dictionary) -> CGSize { +func mapToSize(_ map: Dictionary) -> CGSize { var size = CGSize() if let width = map["width"] as? Int { size.width = CGFloat(width) @@ -31,17 +31,17 @@ func mapToSize(map: Dictionary) -> CGSize { return size } -func mapToRect(map: Dictionary) -> CGRect { +func mapToRect(_ map: Dictionary) -> CGRect { CGRect( - origin: mapToPoint(map: map), - size: mapToSize(map: map) + origin: mapToPoint(map), + size: mapToSize(map) ) } -func mapToVideoEncoderConfiguration(map: Dictionary) -> AgoraVideoEncoderConfiguration { +func mapToVideoEncoderConfiguration(_ map: Dictionary) -> AgoraVideoEncoderConfiguration { let config = AgoraVideoEncoderConfiguration() if let dimensions = map["dimensions"] as? Dictionary { - config.dimensions = mapToSize(map: dimensions) + config.dimensions = mapToSize(dimensions) } if let frameRate = map["frameRate"] as? Int { config.frameRate = frameRate @@ -73,7 +73,7 @@ func mapToVideoEncoderConfiguration(map: Dictionary) -> AgoraVideoE return config } -func mapToBeautyOptions(map: Dictionary) -> AgoraBeautyOptions { +func mapToBeautyOptions(_ map: Dictionary) -> AgoraBeautyOptions { let options = AgoraBeautyOptions() if let lighteningContrastLevel = map["lighteningContrastLevel"] as? Int { if let lighteningContrastLevel = AgoraLighteningContrastLevel(rawValue: UInt(lighteningContrastLevel)) { @@ -92,23 +92,23 @@ func mapToBeautyOptions(map: Dictionary) -> AgoraBeautyOptions { return options } -func mapToAgoraImage(map: Dictionary) -> AgoraImage { +func mapToAgoraImage(_ map: Dictionary) -> AgoraImage { let image = AgoraImage() if let url = map["url"] as? String { if let url = URL(string: url) { image.url = url } } - image.rect = mapToRect(map: map) + image.rect = mapToRect(map) return image } -func mapToTranscodingUser(map: Dictionary) -> AgoraLiveTranscodingUser { +func mapToTranscodingUser(_ map: Dictionary) -> AgoraLiveTranscodingUser { let user = AgoraLiveTranscodingUser() if let uid = map["uid"] as? Int { user.uid = UInt(uid) } - user.rect = mapToRect(map: map) + user.rect = mapToRect(map) if let zOrder = map["zOrder"] as? Int { user.zOrder = zOrder } @@ -121,7 +121,7 @@ func mapToTranscodingUser(map: Dictionary) -> AgoraLiveTranscodingU return user } -func mapToColor(map: Dictionary) -> UIColor { +func mapToColor(_ map: Dictionary) -> UIColor { UIColor( red: CGFloat(map["red"] as! Int), green: CGFloat(map["green"] as! Int), @@ -130,9 +130,9 @@ func mapToColor(map: Dictionary) -> UIColor { ) } -func mapToLiveTranscoding(map: Dictionary) -> AgoraLiveTranscoding { +func mapToLiveTranscoding(_ map: Dictionary) -> AgoraLiveTranscoding { let transcoding = AgoraLiveTranscoding.default() - transcoding.size = mapToSize(map: map) + transcoding.size = mapToSize(map) if let videoBitrate = map["videoBitrate"] as? Int { transcoding.videoBitrate = videoBitrate } @@ -146,10 +146,10 @@ func mapToLiveTranscoding(map: Dictionary) -> AgoraLiveTranscoding transcoding.videoGop = videoGop } if let watermark = map["watermark"] as? Dictionary { - transcoding.watermark = mapToAgoraImage(map: watermark) + transcoding.watermark = mapToAgoraImage(watermark) } if let backgroundImage = map["backgroundImage"] as? Dictionary { - transcoding.backgroundImage = mapToAgoraImage(map: backgroundImage) + transcoding.backgroundImage = mapToAgoraImage(backgroundImage) } if let audioSampleRate = map["audioSampleRate"] as? Int { if let audioSampleRate = AgoraAudioSampleRateType(rawValue: audioSampleRate) { @@ -173,7 +173,7 @@ func mapToLiveTranscoding(map: Dictionary) -> AgoraLiveTranscoding } } if let backgroundColor = map["backgroundColor"] as? Dictionary { - transcoding.backgroundColor = mapToColor(map: backgroundColor) + transcoding.backgroundColor = mapToColor(backgroundColor) } if let userConfigExtraInfo = map["userConfigExtraInfo"] as? String { transcoding.transcodingExtraInfo = userConfigExtraInfo @@ -181,14 +181,14 @@ func mapToLiveTranscoding(map: Dictionary) -> AgoraLiveTranscoding if let transcodingUsers = map["transcodingUsers"] as? Array { transcodingUsers.forEach { (item) in if let item = item as? Dictionary { - transcoding.add(mapToTranscodingUser(map: item)) + transcoding.add(mapToTranscodingUser(item)) } } } return transcoding } -func mapToChannelMediaInfo(map: Dictionary) -> AgoraChannelMediaRelayInfo { +func mapToChannelMediaInfo(_ map: Dictionary) -> AgoraChannelMediaRelayInfo { let info = AgoraChannelMediaRelayInfo() if let channelName = map["channelName"] as? String { info.channelName = channelName @@ -202,15 +202,15 @@ func mapToChannelMediaInfo(map: Dictionary) -> AgoraChannelMediaRel return info } -func mapToChannelMediaRelayConfiguration(map: Dictionary) -> AgoraChannelMediaRelayConfiguration { +func mapToChannelMediaRelayConfiguration(_ map: Dictionary) -> AgoraChannelMediaRelayConfiguration { let config = AgoraChannelMediaRelayConfiguration() if let srcInfo = map["srcInfo"] as? Dictionary { - config.sourceInfo = mapToChannelMediaInfo(map: srcInfo) + config.sourceInfo = mapToChannelMediaInfo(srcInfo) } if let destInfos = map["destInfos"] as? Array { destInfos.forEach { (item) in if let item = item as? Dictionary { - let info = mapToChannelMediaInfo(map: item) + let info = mapToChannelMediaInfo(item) config.setDestinationInfo(info, forChannelName: info.channelName ?? "") } } @@ -218,7 +218,7 @@ func mapToChannelMediaRelayConfiguration(map: Dictionary) -> AgoraC return config } -func mapToLastmileProbeConfig(map: Dictionary) -> AgoraLastmileProbeConfig { +func mapToLastmileProbeConfig(_ map: Dictionary) -> AgoraLastmileProbeConfig { let config = AgoraLastmileProbeConfig() if let probeUplink = map["probeUplink"] as? Bool { config.probeUplink = probeUplink @@ -235,23 +235,23 @@ func mapToLastmileProbeConfig(map: Dictionary) -> AgoraLastmileProb return config } -func mapToWatermarkOptions(map: Dictionary) -> WatermarkOptions { +func mapToWatermarkOptions(_ map: Dictionary) -> WatermarkOptions { let options = WatermarkOptions() if let visibleInPreview = map["visibleInPreview"] as? Bool { options.visibleInPreview = visibleInPreview } if let positionInLandscapeMode = map["positionInLandscapeMode"] as? Dictionary { - options.positionInLandscapeMode = mapToRect(map: positionInLandscapeMode) + options.positionInLandscapeMode = mapToRect(positionInLandscapeMode) } if let positionInPortraitMode = map["positionInPortraitMode"] as? Dictionary { - options.positionInPortraitMode = mapToRect(map: positionInPortraitMode) + options.positionInPortraitMode = mapToRect(positionInPortraitMode) } return options } -func mapToLiveInjectStreamConfig(map: Dictionary) -> AgoraLiveInjectStreamConfig { +func mapToLiveInjectStreamConfig(_ map: Dictionary) -> AgoraLiveInjectStreamConfig { let config = AgoraLiveInjectStreamConfig.default() - config.size = mapToSize(map: map) + config.size = mapToSize(map) if let videoGop = map["videoGop"] as? Int { config.videoGop = videoGop } @@ -275,22 +275,14 @@ func mapToLiveInjectStreamConfig(map: Dictionary) -> AgoraLiveInjec return config } -func mapToCameraCapturerConfiguration(map: Dictionary) -> AgoraCameraCapturerConfiguration { +func mapToCameraCapturerConfiguration(_ map: Dictionary) -> AgoraCameraCapturerConfiguration { let config = AgoraCameraCapturerConfiguration() - if let preference = map["preference"] as? Int { - if let preference = AgoraCameraCaptureOutputPreference(rawValue: preference) { - config.preference = preference - } - } - if let cameraDirection = map["cameraDirection"] as? Int { - if let cameraDirection = AgoraCameraDirection(rawValue: cameraDirection) { - config.cameraDirection = cameraDirection - } - } + config.preference = AgoraCameraCaptureOutputPreference(rawValue: map["preference"] as! Int)! + config.cameraDirection = AgoraCameraDirection(rawValue: map["cameraDirection"] as! Int)! return config } -func mapToChannelMediaOptions(map: Dictionary) -> AgoraRtcChannelMediaOptions { +func mapToChannelMediaOptions(_ map: Dictionary) -> AgoraRtcChannelMediaOptions { let options = AgoraRtcChannelMediaOptions() if let autoSubscribeAudio = map["autoSubscribeAudio"] as? Bool { options.autoSubscribeAudio = autoSubscribeAudio diff --git a/Callback.swift b/Callback.swift index 562777cae..9d2a22d6f 100644 --- a/Callback.swift +++ b/Callback.swift @@ -10,20 +10,39 @@ import Foundation import AgoraRtcKit protocol Callback: class { - associatedtype T - - func success(_ data: Self.T?) + func success(_ data: Any?) func failure(_ code: String, _ message: String) } extension Callback { - func code(_ code: Int32?) { - let newCode: Int = Int(code ?? Int32(AgoraErrorCode.notInitialized.rawValue)) - if newCode == 0 { + func code(_ code: Int32?, _ runnable: ((Int32) -> Any?)? = nil) { + if code == nil || code! < 0 { + let newCode = abs(Int(code ?? Int32(AgoraErrorCode.notInitialized.rawValue))) + failure(String(newCode), AgoraRtcEngineKit.getErrorDescription(newCode) ?? "") + return + } + + let res = runnable?(code!) + if res is Void { + success(nil) + } else { + success(res) + } + } + + func resolve(_ source: T?, _ runnable: (T) -> Any?) { + guard let `source` = source else { + let code = AgoraErrorCode.notInitialized.rawValue + failure(String(code), AgoraRtcEngineKit.getErrorDescription(code) ?? "") + return + } + + let res = runnable(source) + if res is Void { success(nil) - } else if newCode < 0 { - failure(String(newCode), AgoraRtcEngineKit.getErrorDescription(abs(newCode)) ?? "") + } else { + success(res) } } } diff --git a/MediaObserver.swift b/MediaObserver.swift index 55f053a52..cec16f744 100644 --- a/MediaObserver.swift +++ b/MediaObserver.swift @@ -14,15 +14,15 @@ class MediaObserver: NSObject { private var maxMetadataSize = 0 private var metadataList = [String]() - init(emitter: @escaping (_ data: Dictionary?) -> Void) { + init(_ emitter: @escaping (_ data: Dictionary?) -> Void) { self.emitter = emitter } - func addMetadata(metadata: String) { + func addMetadata(_ metadata: String) { metadataList.append(metadata) } - func setMaxMetadataSize(size: Int) { + func setMaxMetadataSize(_ size: Int) { maxMetadataSize = size } } diff --git a/RtcChannel.swift b/RtcChannel.swift index 7bed428ab..68d4ff4f2 100644 --- a/RtcChannel.swift +++ b/RtcChannel.swift @@ -120,7 +120,7 @@ class RtcChannelManager { func setMaxMetadataSize(_ channelId: String, _ size: Int) -> Int32 { if let observer = mediaObserverMap[channelId] { - observer.setMaxMetadataSize(size: size) + observer.setMaxMetadataSize(size) return 0 } return Int32(AgoraErrorCode.notInitialized.rawValue) @@ -128,11 +128,33 @@ class RtcChannelManager { func addMetadata(_ channelId: String, _ metadata: String) -> Int32 { if let observer = mediaObserverMap[channelId] { - observer.addMetadata(metadata: metadata) + observer.addMetadata(metadata) return 0 } return Int32(AgoraErrorCode.notInitialized.rawValue) } + + func createDataStream(_ channelId: String, _ reliable: Bool, _ ordered: Bool) -> Int32 { + if let rtcChannel = self[channelId] { + var streamId = 0 + let res = rtcChannel.createDataStream(&streamId, reliable: reliable, ordered: ordered) + if res == 0 { + return Int32(streamId) + } + return res + } + return Int32(AgoraErrorCode.notInitialized.rawValue) + } + + func sendStreamMessage(_ channelId: String, _ streamId: Int, _ message: String) -> Int32 { + if let rtcChannel = self[channelId] { + if let data = message.data(using: .utf8) { + return rtcChannel.sendStreamMessage(streamId, data: data) + } + return Int32(AgoraErrorCode.invalidArgument.rawValue) + } + return Int32(AgoraErrorCode.notInitialized.rawValue) + } } protocol RtcChannelAudioInterface { diff --git a/RtcEngine.swift b/RtcEngine.swift index 665666002..a3476c02b 100644 --- a/RtcEngine.swift +++ b/RtcEngine.swift @@ -148,7 +148,7 @@ class RtcEngineManager { func setMaxMetadataSize(_ size: Int) -> Int32 { if let observer = mediaObserver { - observer.setMaxMetadataSize(size: size) + observer.setMaxMetadataSize(size) return 0 } return Int32(AgoraErrorCode.notInitialized.rawValue) @@ -156,7 +156,7 @@ class RtcEngineManager { func addMetadata(_ metadata: String) -> Int32 { if let observer = mediaObserver { - observer.addMetadata(metadata: metadata) + observer.addMetadata(metadata) return 0 } return Int32(AgoraErrorCode.notInitialized.rawValue) From cab5a62d9194dbafea83e7fba97dbf7ab0c8e3cc Mon Sep 17 00:00:00 2001 From: HUI <15215604969@163.com> Date: Sun, 19 Jul 2020 18:26:11 +0800 Subject: [PATCH 2/3] - add `startPreview` `stopPreview` --- RtcEngine.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RtcEngine.swift b/RtcEngine.swift index a3476c02b..dbc7d26c4 100644 --- a/RtcEngine.swift +++ b/RtcEngine.swift @@ -234,6 +234,10 @@ protocol RtcEngineVideoInterface { func disableVideo(_ callback: Callback?) func setVideoEncoderConfiguration(_ config: Map, _ callback: Callback?) + + func startPreview(_ callback: Callback?) + + func stopPreview(_ callback: Callback?) func enableLocalVideo(_ enabled: Bool, _ callback: Callback?) From 6eec86f5da51eff544322e7f6733de5ad0302849 Mon Sep 17 00:00:00 2001 From: HUI <15215604969@163.com> Date: Thu, 30 Jul 2020 15:55:15 +0800 Subject: [PATCH 3/3] - fix multiple channel render bug - remove `Types` from export, you can import enum or class by `import {} from 'react-native-agora'` --- RtcSurfaceView.swift | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/RtcSurfaceView.swift b/RtcSurfaceView.swift index ab25b069c..ed70e403a 100644 --- a/RtcSurfaceView.swift +++ b/RtcSurfaceView.swift @@ -18,34 +18,47 @@ class RtcSurfaceView: UIView { }() private weak var channel: AgoraRtcChannel? - func setRenderMode(_ engine: AgoraRtcEngineKit, _ renderMode: Int) { - canvas.renderMode = AgoraVideoRenderMode(rawValue: UInt(renderMode))! - setupRenderMode(engine) - } - - func setChannel(_ engine: AgoraRtcEngineKit, _ channel: AgoraRtcChannel?) { + func setData(_ engine: AgoraRtcEngineKit, _ channel: AgoraRtcChannel?, _ uid: Int) { + resetVideoCanvas(engine) + self.channel = channel canvas.channelId = channel?.getId() + canvas.uid = UInt(uid) + setupVideoCanvas(engine) + } + + private func resetVideoCanvas(_ engine: AgoraRtcEngineKit) { + let canvas = AgoraRtcVideoCanvas() + canvas.view = nil + canvas.renderMode = self.canvas.renderMode + canvas.channelId = self.canvas.channelId + canvas.uid = self.canvas.uid + canvas.mirrorMode = self.canvas.mirrorMode + if canvas.uid == 0 { engine.setupLocalVideo(canvas) } else { engine.setupRemoteVideo(canvas) } } - - func setMirrorMode(_ engine: AgoraRtcEngineKit, _ mirrorMode: Int) { - canvas.mirrorMode = AgoraVideoMirrorMode(rawValue: UInt(mirrorMode))! - setupRenderMode(engine) - } - - func setUid(_ engine: AgoraRtcEngineKit, _ uid: Int) { - canvas.uid = UInt(uid) + + private func setupVideoCanvas(_ engine: AgoraRtcEngineKit) { if canvas.uid == 0 { engine.setupLocalVideo(canvas) } else { engine.setupRemoteVideo(canvas) } } + + func setRenderMode(_ engine: AgoraRtcEngineKit, _ renderMode: Int) { + canvas.renderMode = AgoraVideoRenderMode(rawValue: UInt(renderMode))! + setupRenderMode(engine) + } + + func setMirrorMode(_ engine: AgoraRtcEngineKit, _ mirrorMode: Int) { + canvas.mirrorMode = AgoraVideoMirrorMode(rawValue: UInt(mirrorMode))! + setupRenderMode(engine) + } private func setupRenderMode(_ engine: AgoraRtcEngineKit) { if canvas.uid == 0 {