From b17dd472479ada81ac58706b16bbc2d45b3e8164 Mon Sep 17 00:00:00 2001 From: Macrow Date: Fri, 19 Jun 2020 00:05:15 +0800 Subject: [PATCH 1/9] fix convert exception in mapToCameraCapturerConfiguration function --- BeanCovertor.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BeanCovertor.kt b/BeanCovertor.kt index dd88db158..cb22fe536 100644 --- a/BeanCovertor.kt +++ b/BeanCovertor.kt @@ -158,8 +158,8 @@ fun mapToLiveInjectStreamConfig(map: Map<*, *>): LiveInjectStreamConfig { fun mapToCameraCapturerConfiguration(map: Map<*, *>): CameraCapturerConfiguration { return CameraCapturerConfiguration( - intToCapturerOutputPreference(map["preference"] as Int), - intToCameraDirection(map["cameraDirection"] as Int) + intToCapturerOutputPreference((map["preference"] as Double).toInt()), + intToCameraDirection((map["cameraDirection"] as Double).toInt()) ) } From bdd398fd3f5ea5b87a5cd7cec1571f891db3f0ff Mon Sep 17 00:00:00 2001 From: Macrow Date: Fri, 19 Jun 2020 11:28:13 +0800 Subject: [PATCH 2/9] change Double to Number --- BeanCovertor.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BeanCovertor.kt b/BeanCovertor.kt index cb22fe536..fb2870d75 100644 --- a/BeanCovertor.kt +++ b/BeanCovertor.kt @@ -158,8 +158,8 @@ fun mapToLiveInjectStreamConfig(map: Map<*, *>): LiveInjectStreamConfig { fun mapToCameraCapturerConfiguration(map: Map<*, *>): CameraCapturerConfiguration { return CameraCapturerConfiguration( - intToCapturerOutputPreference((map["preference"] as Double).toInt()), - intToCameraDirection((map["cameraDirection"] as Double).toInt()) + intToCapturerOutputPreference((map["preference"] as Number).toInt()), + intToCameraDirection((map["cameraDirection"] as Number).toInt()) ) } From 93621d39dfc3df015349b16c00cc744acdf0e787 Mon Sep 17 00:00:00 2001 From: HUI <15215604969@163.com> Date: Thu, 9 Jul 2020 20:47:51 +0800 Subject: [PATCH 3/9] - add `constructor` for typescript - fix Android `mapToChannelMediaInfo` crash - fix iOS `switchChannel` `sendMetadata` crash --- BeanCovertor.kt | 4 ++-- Callback.kt | 35 ++++++++++++++++++++++++++++------- RtcChannel.kt | 14 ++++++++++++++ RtcSurfaceView.kt | 8 +++++++- 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/BeanCovertor.kt b/BeanCovertor.kt index fb2870d75..978eff655 100644 --- a/BeanCovertor.kt +++ b/BeanCovertor.kt @@ -97,8 +97,8 @@ fun mapToLiveTranscoding(map: Map<*, *>): LiveTranscoding { fun mapToChannelMediaInfo(map: Map<*, *>): ChannelMediaInfo { return ChannelMediaInfo( - map["channelName"] as String, - map["token"] as String, + map["channelName"] as? String, + map["token"] as? String, (map["uid"] as Number).toInt() ) } diff --git a/Callback.kt b/Callback.kt index affe4c5b8..3394d8303 100644 --- a/Callback.kt +++ b/Callback.kt @@ -4,17 +4,38 @@ import io.agora.rtc.Constants import io.agora.rtc.RtcEngine import kotlin.math.abs -abstract class Callback { - fun code(code: Int?) { - val newCode = code ?: Constants.ERR_NOT_INITIALIZED - if (newCode == 0) { +abstract class Callback { + fun code(code: Int?, runnable: ((Int) -> Any?)? = null) { + if (code == null || code < 0) { + val newCode = abs(code ?: Constants.ERR_NOT_INITIALIZED) + failure(newCode.toString(), RtcEngine.getErrorDescription(newCode)) + return + } + + val res = if (runnable != null) runnable(code) else Unit + if (res is Unit) { + success(null) + } else { + success(res) + } + } + + fun resolve(source: T?, runnable: (T) -> Any?) { + if (source == null) { + val code = Constants.ERR_NOT_INITIALIZED + failure(code.toString(), RtcEngine.getErrorDescription(code)) + return + } + + val res = runnable(source) + if (res is Unit) { success(null) - } else if (newCode < 0) { - failure(newCode.toString(), RtcEngine.getErrorDescription(abs(newCode))) + } else { + success(res) } } - abstract fun success(data: T?) + abstract fun success(data: Any?) abstract fun failure(code: String, message: String) } diff --git a/RtcChannel.kt b/RtcChannel.kt index 7860fa65a..be3a45cb1 100644 --- a/RtcChannel.kt +++ b/RtcChannel.kt @@ -110,6 +110,20 @@ class RtcChannelManager { return Constants.ERR_NOT_INITIALIZED } + fun createDataStream(channelId: String, reliable: Boolean, ordered: Boolean): Int { + this[channelId]?.let { + return@createDataStream it.createDataStream(reliable, ordered) + } + return Constants.ERR_NOT_INITIALIZED + } + + fun sendStreamMessage(channelId: String, streamId: Int, message: String): Int { + this[channelId]?.let { + return@sendStreamMessage it.sendStreamMessage(streamId, message.toByteArray()) + } + return Constants.ERR_NOT_INITIALIZED + } + interface RtcAudioInterface { fun adjustUserPlaybackSignalVolume(channelId: String, uid: Int, @IntRange(from = 0, to = 100) volume: Int, callback: Callback?) diff --git a/RtcSurfaceView.kt b/RtcSurfaceView.kt index ad7e9036b..891a0c7b2 100644 --- a/RtcSurfaceView.kt +++ b/RtcSurfaceView.kt @@ -11,11 +11,17 @@ import java.lang.ref.WeakReference class RtcSurfaceView( context: Context ) : FrameLayout(context) { - private var surface: SurfaceView = RtcEngine.CreateRendererView(context) + private var surface: SurfaceView private var canvas: VideoCanvas private var channel: WeakReference? = null init { + try { + surface = RtcEngine.CreateRendererView(context) + } catch (e: UnsatisfiedLinkError) { + surface = SurfaceView(context) + e.printStackTrace() + } canvas = VideoCanvas(surface) addView(surface) } 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 4/9] - 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 d998401a890e123824527c536655ef40b1bd09a0 Mon Sep 17 00:00:00 2001 From: HUI <15215604969@163.com> Date: Sun, 19 Jul 2020 18:26:11 +0800 Subject: [PATCH 5/9] - add `startPreview` `stopPreview` --- RtcEngine.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RtcEngine.kt b/RtcEngine.kt index e24f74724..e8eab447d 100644 --- a/RtcEngine.kt +++ b/RtcEngine.kt @@ -206,6 +206,10 @@ class RtcEngineManager { fun setVideoEncoderConfiguration(config: Map, callback: Callback?) + fun startPreview(callback: Callback?) + + fun stopPreview(callback: Callback?) + fun enableLocalVideo(enabled: Boolean, callback: Callback?) fun muteLocalVideoStream(muted: Boolean, callback: Callback?) 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 6/9] - 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 10a3d013c231c7e38e68b801b8734b64fc122c69 Mon Sep 17 00:00:00 2001 From: HUI <15215604969@163.com> Date: Thu, 30 Jul 2020 15:55:15 +0800 Subject: [PATCH 7/9] - fix multiple channel render bug - remove `Types` from export, you can import enum or class by `import {} from 'react-native-agora'` --- RtcSurfaceView.kt | 33 ++++++++++++++++++++------------- RtcTextureView.kt | 21 ++++++++++++++------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/RtcSurfaceView.kt b/RtcSurfaceView.kt index 891a0c7b2..d665d8143 100644 --- a/RtcSurfaceView.kt +++ b/RtcSurfaceView.kt @@ -46,14 +46,17 @@ class RtcSurfaceView( } } - fun setRenderMode(engine: RtcEngine, @Annotations.AgoraVideoRenderMode renderMode: Int) { - canvas.renderMode = renderMode - setupRenderMode(engine) - } + fun setData(engine: RtcEngine, channel: RtcChannel?, uid: Int) { + resetVideoCanvas(engine) - fun setChannel(engine: RtcEngine, channel: RtcChannel?) { this.channel = if (channel != null) WeakReference(channel) else null - canvas.channelId = channel?.channelId() + canvas.channelId = this.channel?.get()?.channelId() + canvas.uid = uid + setupVideoCanvas(engine) + } + + private fun resetVideoCanvas(engine: RtcEngine) { + val canvas = VideoCanvas(null, canvas.renderMode, canvas.channelId, canvas.uid, canvas.mirrorMode) if (canvas.uid == 0) { engine.setupLocalVideo(canvas) } else { @@ -61,13 +64,7 @@ class RtcSurfaceView( } } - fun setMirrorMode(engine: RtcEngine, @Annotations.AgoraVideoMirrorMode mirrorMode: Int) { - canvas.mirrorMode = mirrorMode - setupRenderMode(engine) - } - - fun setUid(engine: RtcEngine, uid: Int) { - canvas.uid = uid + private fun setupVideoCanvas(engine: RtcEngine) { if (canvas.uid == 0) { engine.setupLocalVideo(canvas) } else { @@ -75,6 +72,16 @@ class RtcSurfaceView( } } + fun setRenderMode(engine: RtcEngine, @Annotations.AgoraVideoRenderMode renderMode: Int) { + canvas.renderMode = renderMode + setupRenderMode(engine) + } + + fun setMirrorMode(engine: RtcEngine, @Annotations.AgoraVideoMirrorMode mirrorMode: Int) { + canvas.mirrorMode = mirrorMode + setupRenderMode(engine) + } + private fun setupRenderMode(engine: RtcEngine) { if (canvas.uid == 0) { engine.setLocalRenderMode(canvas.renderMode, canvas.mirrorMode) diff --git a/RtcTextureView.kt b/RtcTextureView.kt index e028b55c4..be98e356a 100644 --- a/RtcTextureView.kt +++ b/RtcTextureView.kt @@ -22,8 +22,11 @@ class RtcTextureView( addView(texture) } - fun setChannel(engine: RtcEngine, channel: RtcChannel?) { + fun setData(engine: RtcEngine, channel: RtcChannel?, uid: Int) { + resetVideoRender(engine) + this.channel = if (channel != null) WeakReference(channel) else null + this.uid = uid setupVideoRenderer(engine) } @@ -32,22 +35,26 @@ class RtcTextureView( setupVideoRenderer(engine) } - fun setUid(engine: RtcEngine, uid: Int) { - this.uid = uid - setupVideoRenderer(engine) + private fun resetVideoRender(engine: RtcEngine) { + if (uid == 0) { + engine.setLocalVideoRenderer(null) + } else { + channel?.get()?.let { + it.setRemoteVideoRenderer(uid, null) + return@resetVideoRender + } + engine.setRemoteVideoRenderer(uid, null) + } } private fun setupVideoRenderer(engine: RtcEngine) { if (uid == 0) { - engine.setLocalVideoRenderer(null) engine.setLocalVideoRenderer(texture) } else { channel?.get()?.let { - it.setRemoteVideoRenderer(uid, null) it.setRemoteVideoRenderer(uid, texture) return@setupVideoRenderer } - engine.setRemoteVideoRenderer(uid, null) engine.setRemoteVideoRenderer(uid, texture) } } 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 8/9] - 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 { From c7feadc28c2895dc8e93f9bfe2804694ab49edce Mon Sep 17 00:00:00 2001 From: HUI <15215604969@163.com> Date: Tue, 4 Aug 2020 16:46:28 +0800 Subject: [PATCH 9/9] - fix crash when rendering view without `channelId` property - fix `RtcLocalView` freezes after rendering remote view --- CHANGELOG.md | 4 ++++ .../src/main/java/io/agora/rtc/base/RtcSurfaceView.kt | 4 +--- .../src/main/java/io/agora/rtc/base/RtcTextureView.kt | 4 +--- .../io/agora/rtc/react/RCTAgoraRtcSurfaceViewManager.kt | 5 +++++ .../io/agora/rtc/react/RCTAgoraRtcTextureViewManager.kt | 9 ++++++--- ios/RCTAgora/Base/RtcSurfaceView.swift | 4 +--- ios/RCTAgora/React/RCTAgoraRtcSurfaceViewManager.swift | 6 ++++++ package.json | 2 +- src/src/RtcRenderView.native.tsx | 6 ++++-- 9 files changed, 29 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f41a2027..6d1ca190c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## THE CHANGELOG +#### 3.0.1-rc.4 + - fix crash when rendering view without `channelId` property + - fix `RtcLocalView` freezes after rendering remote view + #### 3.0.1-rc.3 - fix multiple channel render bug - remove `Types` from export, you can import enum or class by `import {} from 'react-native-agora'` diff --git a/android/src/main/java/io/agora/rtc/base/RtcSurfaceView.kt b/android/src/main/java/io/agora/rtc/base/RtcSurfaceView.kt index d665d8143..59b5dbf3b 100644 --- a/android/src/main/java/io/agora/rtc/base/RtcSurfaceView.kt +++ b/android/src/main/java/io/agora/rtc/base/RtcSurfaceView.kt @@ -47,15 +47,13 @@ class RtcSurfaceView( } fun setData(engine: RtcEngine, channel: RtcChannel?, uid: Int) { - resetVideoCanvas(engine) - this.channel = if (channel != null) WeakReference(channel) else null canvas.channelId = this.channel?.get()?.channelId() canvas.uid = uid setupVideoCanvas(engine) } - private fun resetVideoCanvas(engine: RtcEngine) { + fun resetVideoCanvas(engine: RtcEngine) { val canvas = VideoCanvas(null, canvas.renderMode, canvas.channelId, canvas.uid, canvas.mirrorMode) if (canvas.uid == 0) { engine.setupLocalVideo(canvas) diff --git a/android/src/main/java/io/agora/rtc/base/RtcTextureView.kt b/android/src/main/java/io/agora/rtc/base/RtcTextureView.kt index be98e356a..1d4199d66 100644 --- a/android/src/main/java/io/agora/rtc/base/RtcTextureView.kt +++ b/android/src/main/java/io/agora/rtc/base/RtcTextureView.kt @@ -23,8 +23,6 @@ class RtcTextureView( } fun setData(engine: RtcEngine, channel: RtcChannel?, uid: Int) { - resetVideoRender(engine) - this.channel = if (channel != null) WeakReference(channel) else null this.uid = uid setupVideoRenderer(engine) @@ -35,7 +33,7 @@ class RtcTextureView( setupVideoRenderer(engine) } - private fun resetVideoRender(engine: RtcEngine) { + fun resetVideoRender(engine: RtcEngine) { if (uid == 0) { engine.setLocalVideoRenderer(null) } else { diff --git a/android/src/main/java/io/agora/rtc/react/RCTAgoraRtcSurfaceViewManager.kt b/android/src/main/java/io/agora/rtc/react/RCTAgoraRtcSurfaceViewManager.kt index 7a54a991f..af12fad81 100644 --- a/android/src/main/java/io/agora/rtc/react/RCTAgoraRtcSurfaceViewManager.kt +++ b/android/src/main/java/io/agora/rtc/react/RCTAgoraRtcSurfaceViewManager.kt @@ -20,6 +20,11 @@ class RCTAgoraRtcSurfaceViewManager : SimpleViewManager() { return RtcSurfaceView(reactContext) } + override fun onDropViewInstance(view: RtcSurfaceView) { + // getEngine()?.let { view.resetVideoCanvas(it) } + super.onDropViewInstance(view) + } + override fun getName(): String { return REACT_CLASS } diff --git a/android/src/main/java/io/agora/rtc/react/RCTAgoraRtcTextureViewManager.kt b/android/src/main/java/io/agora/rtc/react/RCTAgoraRtcTextureViewManager.kt index 60b0691e2..13e6aa3f7 100644 --- a/android/src/main/java/io/agora/rtc/react/RCTAgoraRtcTextureViewManager.kt +++ b/android/src/main/java/io/agora/rtc/react/RCTAgoraRtcTextureViewManager.kt @@ -20,6 +20,11 @@ class RCTAgoraRtcTextureViewManager : SimpleViewManager() { return RtcTextureView(reactContext) } + override fun onDropViewInstance(view: RtcTextureView) { + // getEngine()?.let { view.resetVideoRender(it) } + super.onDropViewInstance(view) + } + override fun getName(): String { return REACT_CLASS } @@ -27,9 +32,7 @@ class RCTAgoraRtcTextureViewManager : SimpleViewManager() { @ReactProp(name = "data") fun setData(view: RtcTextureView, data: ReadableMap) { val channel = data.getString("channelId")?.let { getChannel(it) } - getEngine()?.let { - view.setData(it, channel, data.getInt("uid")) - } + getEngine()?.let { view.setData(it, channel, data.getInt("uid")) } } @ReactProp(name = "mirror") diff --git a/ios/RCTAgora/Base/RtcSurfaceView.swift b/ios/RCTAgora/Base/RtcSurfaceView.swift index ed70e403a..2d20efc0c 100644 --- a/ios/RCTAgora/Base/RtcSurfaceView.swift +++ b/ios/RCTAgora/Base/RtcSurfaceView.swift @@ -19,15 +19,13 @@ class RtcSurfaceView: UIView { private weak var 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) { + func resetVideoCanvas(_ engine: AgoraRtcEngineKit) { let canvas = AgoraRtcVideoCanvas() canvas.view = nil canvas.renderMode = self.canvas.renderMode diff --git a/ios/RCTAgora/React/RCTAgoraRtcSurfaceViewManager.swift b/ios/RCTAgora/React/RCTAgoraRtcSurfaceViewManager.swift index 660c8084a..80eddf16d 100644 --- a/ios/RCTAgora/React/RCTAgoraRtcSurfaceViewManager.swift +++ b/ios/RCTAgora/React/RCTAgoraRtcSurfaceViewManager.swift @@ -40,6 +40,12 @@ class RtcView: RtcSurfaceView { private var getEngine: (() -> AgoraRtcEngineKit?)? private var getChannel: ((_ channelId: String) -> AgoraRtcChannel?)? + deinit { + // if let engine = getEngine?() { + // resetVideoCanvas(engine) + // } + } + func setEngine(_ getEngine: @escaping () -> AgoraRtcEngineKit?) { self.getEngine = getEngine } diff --git a/package.json b/package.json index 4debe3cd1..6f9954476 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-agora", - "version": "3.0.1-rc.3", + "version": "3.0.1-rc.4", "description": "React Native around the Agora RTC SDKs for Android and iOS agora", "summary": "agora native sdk for react-native", "main": "lib/index.js", diff --git a/src/src/RtcRenderView.native.tsx b/src/src/RtcRenderView.native.tsx index 57a00382a..53c695415 100644 --- a/src/src/RtcRenderView.native.tsx +++ b/src/src/RtcRenderView.native.tsx @@ -69,9 +69,10 @@ const RCTRtcSurfaceView = requireNativeComponent('RCTAgoraRtcSurfaceView'); */ export class RtcSurfaceView extends Component { render() { - const {channelId, uid, ...others} = this.props + const {channelId = null, uid, ...others} = this.props return ( ) @@ -88,9 +89,10 @@ const RCTRtcTextureView = requireNativeComponent('RCTAgoraRtcTextureView'); */ export class RtcTextureView extends Component { render() { - const {channelId, uid, ...others} = this.props + const {channelId = null, uid, ...others} = this.props return ( )