From a26b077e310ad07d459cc82ee1489cef0ebd68ca Mon Sep 17 00:00:00 2001 From: HUI Date: Tue, 31 Aug 2021 18:18:08 +0800 Subject: [PATCH] Squashed 'android/src/main/java/io/agora/rtc/base/' changes from 21c7655..0278629 0278629 feat: support 3.5.0.2 45dcd16 chore: add API which is missing 58ca4b0 fix: AudioRecordingConfiguration bug 4a32e12 chore: prepare to migrate to iris 276c9fe chore: support 3.4.5 783aecf chore: add ERR_ALREADY_IN_RECORDING 3aed6ce fix: startAudioRecording bug 510b405 chore: optimize 4f801b9 chore: optimize ab71f52 chore: optimize startAudioRecording 07f81c7 chore: optimize 5a20e13 style: optimize 858b58f fix(uid compatible): int to uint 8d14d2d feat(upgrade): 3.4.1 be5efea Merge pull request #4 from AgoraLibrary/dev/3.3.0 382f858 Merge branch 'master' into dev/3.3.0 8671535 Merge pull request #3 from AgoraLibrary/dev/3.2.0 feabda3 Merge branch 'master' into dev/3.2.0 9e57891 Merge pull request #2 from AgoraLibrary/dev/3.1.0 df303ee fix: merge some bug fix cd7a2cd feat: support 3.3.1 for Android 551ebfe fix: annotation build warning 9c48594 feat: support 3.3.0 for Android de52ca6 Merge branch 'master' into dev/3.2.0 ddeaefb Merge branch 'master' into dev/3.2.0 2fef3ae feat: add `setClientRole(role: ClientRole, options?: ClientRoleOptions): Promise` fcb57cc feat: upgrade to 3.2.0 REVERT: 21c7655 feat: support 3.0.+ git-subtree-dir: android/src/main/java/io/agora/rtc/base git-subtree-split: 02786294fe0fea794942edf5d71036360e887b13 --- Annotations.java | 250 +++++++++++++++++++++-- BeanCovertor.kt | 106 +++++++++- EnumCovertor.kt | 10 + Extensions.kt | 34 +++- MediaObserver.kt | 8 +- RtcChannel.kt | 221 ++++++++++++++++++-- RtcChannelEvent.kt | 330 +++++++++++++++++++++++++----- RtcEngine.kt | 498 +++++++++++++++++++++++++++++++++++++++++---- RtcEngineEvent.kt | 314 +++++++++++++++++++++++----- RtcSurfaceView.kt | 7 +- RtcTextureView.kt | 74 ++++--- 11 files changed, 1630 insertions(+), 222 deletions(-) diff --git a/Annotations.java b/Annotations.java index 58dfe3e2b..e29e42994 100644 --- a/Annotations.java +++ b/Annotations.java @@ -1,15 +1,16 @@ package io.agora.rtc.base; import androidx.annotation.IntDef; -import androidx.annotation.StringDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import io.agora.rtc.Constants; +import io.agora.rtc.IRtcEngineEventHandler; import io.agora.rtc.RtcEngineConfig; import io.agora.rtc.video.BeautyOptions; import io.agora.rtc.video.VideoCanvas; +import io.agora.rtc.video.VirtualBackgroundSource; @SuppressWarnings("deprecation") public class Annotations { @@ -82,6 +83,7 @@ public class Annotations { Constants.LOCAL_AUDIO_STREAM_ERROR_DEVICE_BUSY, Constants.LOCAL_AUDIO_STREAM_ERROR_CAPTURE_FAILURE, Constants.LOCAL_AUDIO_STREAM_ERROR_ENCODE_FAILURE, + Constants.LOCAL_AUDIO_STREAM_ERROR_INTERRUPTED, }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraAudioLocalError { @@ -98,19 +100,27 @@ public class Annotations { } @IntDef({ - Constants.MEDIA_ENGINE_AUDIO_ERROR_MIXING_OPEN, - Constants.MEDIA_ENGINE_AUDIO_ERROR_MIXING_TOO_FREQUENT, - Constants.MEDIA_ENGINE_AUDIO_EVENT_MIXING_INTERRUPTED_EOF, - AgoraAudioMixingErrorCode.MEDIA_ENGINE_AUDIO_ERROR_OK, + Constants.AUDIO_MIXING_REASON_CAN_NOT_OPEN, + Constants.AUDIO_MIXING_REASON_TOO_FREQUENT_CALL, + Constants.AUDIO_MIXING_REASON_INTERRUPTED_EOF, + Constants.AUDIO_MIXING_REASON_STARTED_BY_USER, + Constants.AUDIO_MIXING_REASON_ONE_LOOP_COMPLETED, + Constants.AUDIO_MIXING_REASON_START_NEW_LOOP, + Constants.AUDIO_MIXING_REASON_ALL_LOOPS_COMPLETED, + Constants.AUDIO_MIXING_REASON_STOPPED_BY_USER, + Constants.AUDIO_MIXING_REASON_PAUSED_BY_USER, + Constants.AUDIO_MIXING_REASON_RESUMED_BY_USER, + AgoraAudioMixingReason.MEDIA_ENGINE_AUDIO_ERROR_OK, }) @Retention(RetentionPolicy.SOURCE) - public @interface AgoraAudioMixingErrorCode { + public @interface AgoraAudioMixingReason { int MEDIA_ENGINE_AUDIO_ERROR_OK = 0; } @IntDef({ Constants.MEDIA_ENGINE_AUDIO_EVENT_MIXING_PLAY, Constants.MEDIA_ENGINE_AUDIO_EVENT_MIXING_PAUSED, + Constants.MEDIA_ENGINE_AUDIO_EVENT_MIXING_RESTART, Constants.MEDIA_ENGINE_AUDIO_EVENT_MIXING_STOPPED, Constants.MEDIA_ENGINE_AUDIO_EVENT_MIXING_ERROR, }) @@ -230,6 +240,8 @@ public class Annotations { Constants.AUDIO_SCENARIO_GAME_STREAMING, Constants.AUDIO_SCENARIO_SHOWROOM, Constants.AUDIO_SCENARIO_CHATROOM_GAMING, + Constants.AUDIO_SCENARIO_IOT, + Constants.AUDIO_SCENARIO_MEETING, }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraAudioScenario { @@ -264,12 +276,14 @@ public class Annotations { AgoraCameraCaptureOutputPreference.CAPTURER_OUTPUT_PREFERENCE_AUTO, AgoraCameraCaptureOutputPreference.CAPTURER_OUTPUT_PREFERENCE_PERFORMANCE, AgoraCameraCaptureOutputPreference.CAPTURER_OUTPUT_PREFERENCE_PREVIEW, + AgoraCameraCaptureOutputPreference.CAPTURER_OUTPUT_PREFERENCE_MANUAL, }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraCameraCaptureOutputPreference { int CAPTURER_OUTPUT_PREFERENCE_AUTO = 0; int CAPTURER_OUTPUT_PREFERENCE_PERFORMANCE = 1; int CAPTURER_OUTPUT_PREFERENCE_PREVIEW = 2; + int CAPTURER_OUTPUT_PREFERENCE_MANUAL = 3; } @IntDef({ @@ -313,6 +327,10 @@ public class Annotations { Constants.RELAY_EVENT_PACKET_UPDATE_DEST_CHANNEL_NOT_CHANGE, Constants.RELAY_EVENT_PACKET_UPDATE_DEST_CHANNEL_IS_NULL, Constants.RELAY_EVENT_VIDEO_PROFILE_UPDATE, +// Constants.RELAY_EVENT_PAUSE_SEND_PACKET_TO_DEST_CHANNEL_SUCCESS, +// Constants.RELAY_EVENT_PAUSE_SEND_PACKET_TO_DEST_CHANNEL_FAILED, +// Constants.RELAY_EVENT_RESUME_SEND_PACKET_TO_DEST_CHANNEL_SUCCESS, +// Constants.RELAY_EVENT_RESUME_SEND_PACKET_TO_DEST_CHANNEL_FAILED, }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraChannelMediaRelayEvent { @@ -361,6 +379,7 @@ public class Annotations { Constants.CONNECTION_CHANGED_RENEW_TOKEN, Constants.CONNECTION_CHANGED_CLIENT_IP_ADDRESS_CHANGED, Constants.CONNECTION_CHANGED_KEEP_ALIVE_TIMEOUT, + Constants.CONNECTION_CHANGED_PROXY_SERVER_INTERRUPTED, }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraConnectionChangedReason { @@ -389,16 +408,28 @@ public class Annotations { int MAINTAIN_BALANCED = 2; } - @StringDef({ + @IntDef({ + AgoraEncryptionMode.NONE, AgoraEncryptionMode.AES128XTS, - AgoraEncryptionMode.AES256XTS, AgoraEncryptionMode.AES128ECB, + AgoraEncryptionMode.AES256XTS, + AgoraEncryptionMode.SM4128ECB, + AgoraEncryptionMode.AES128GCM, + AgoraEncryptionMode.AES256GCM, + AgoraEncryptionMode.AES128GCM2, + AgoraEncryptionMode.AES256GCM2, }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraEncryptionMode { - String AES128XTS = "aes-128-xts"; - String AES256XTS = "aes-256-xts"; - String AES128ECB = "aes-128-ecb"; + int NONE = 0; + int AES128XTS = 1; + int AES128ECB = 2; + int AES256XTS = 3; + int SM4128ECB = 4; + int AES128GCM = 5; + int AES256GCM = 6; + int AES128GCM2 = 7; + int AES256GCM2 = 8; } @IntDef({ @@ -422,6 +453,7 @@ public class Annotations { Constants.ERR_ALREADY_IN_USE, Constants.ERR_INVALID_APP_ID, Constants.ERR_INVALID_CHANNEL_NAME, + Constants.ERR_NO_SERVER_RESOURCES, Constants.ERR_TOKEN_EXPIRED, Constants.ERR_INVALID_TOKEN, Constants.ERR_CONNECTION_INTERRUPTED, @@ -446,6 +478,8 @@ public class Annotations { Constants.ERR_PUBLISH_STREAM_INTERNAL_SERVER_ERROR, Constants.ERR_PUBLISH_STREAM_NOT_FOUND, Constants.ERR_PUBLISH_STREAM_FORMAT_NOT_SUPPORTED, + Constants.ERR_MODULE_NOT_FOUND, + Constants.ERR_ALREADY_IN_RECORDING, Constants.ERR_LOAD_MEDIA_ENGINE, Constants.ERR_START_CALL, Constants.ERR_START_CAMERA, @@ -519,6 +553,7 @@ public class Annotations { Constants.LOCAL_VIDEO_STREAM_ERROR_DEVICE_BUSY, Constants.LOCAL_VIDEO_STREAM_ERROR_CAPTURE_FAILURE, Constants.LOCAL_VIDEO_STREAM_ERROR_ENCODE_FAILURE, + Constants.LOCAL_VIDEO_STREAM_ERROR_DEVICE_NOT_FOUND }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraLocalVideoStreamError { @@ -586,6 +621,7 @@ public class Annotations { Constants.RTMP_STREAM_PUBLISH_ERROR_NOT_AUTHORIZED, Constants.RTMP_STREAM_PUBLISH_ERROR_STREAM_NOT_FOUND, Constants.RTMP_STREAM_PUBLISH_ERROR_FORMAT_NOT_SUPPORTED, + Constants.RTMP_STREAM_UNPUBLISH_ERROR_OK, }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraRtmpStreamingErrorCode { @@ -622,7 +658,7 @@ public class Annotations { @IntDef({ Constants.USER_PRIORITY_HIGH, - Constants.USER_PRIORITY_NORANL, + Constants.USER_PRIORITY_NORMAL, }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraUserPriority { @@ -751,26 +787,204 @@ public class Annotations { Constants.WARN_ADM_RUNTIME_PLAYOUT_WARNING, Constants.WARN_ADM_RUNTIME_RECORDING_WARNING, Constants.WARN_ADM_RECORD_AUDIO_SILENCE, + Constants.WARN_ADM_PLAYOUT_ABNORMAL_FREQUENCY, + Constants.WARN_ADM_RECORD_ABNORMAL_FREQUENCY, Constants.WARN_ADM_CALL_INTERRUPTION, Constants.WARN_ADM_RECORD_AUDIO_LOWLEVEL, Constants.WARN_ADM_PLAYOUT_AUDIO_LOWLEVEL, Constants.WARN_ADM_RECORD_IS_OCCUPIED, Constants.WARN_APM_HOWLING, Constants.WARN_ADM_GLITCH_STATE, - Constants.WARN_ADM_IMPROPER_SETTINGS, + Constants.WARN_APM_RESIDUAL_ECHO, + Constants.WARN_SUPER_RESOLUTION_STREAM_OVER_LIMITATION, + Constants.WARN_SUPER_RESOLUTION_USER_COUNT_OVER_LIMITATION, + Constants.WARN_SUPER_RESOLUTION_DEVICE_NOT_SUPPORTED, }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraWarningCode { } @IntDef({ - RtcEngineConfig.IPAreaCode.AREA_CN, - RtcEngineConfig.IPAreaCode.AREA_NA, - RtcEngineConfig.IPAreaCode.AREA_EUR, - RtcEngineConfig.IPAreaCode.AREA_AS, - RtcEngineConfig.IPAreaCode.AREA_GLOBAL, + RtcEngineConfig.AreaCode.AREA_CODE_CN, + RtcEngineConfig.AreaCode.AREA_CODE_NA, + RtcEngineConfig.AreaCode.AREA_CODE_EU, + RtcEngineConfig.AreaCode.AREA_CODE_AS, + RtcEngineConfig.AreaCode.AREA_CODE_JP, + RtcEngineConfig.AreaCode.AREA_CODE_IN, + RtcEngineConfig.AreaCode.AREA_CODE_GLOB, }) @Retention(RetentionPolicy.SOURCE) public @interface AgoraAreaCode { } + + @IntDef({ + Constants.SUB_STATE_IDLE, + Constants.SUB_STATE_NO_SUBSCRIBED, + Constants.SUB_STATE_SUBSCRIBING, + Constants.SUB_STATE_SUBSCRIBED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraStreamSubscribeState { + } + + @IntDef({ + Constants.PUB_STATE_IDLE, + Constants.PUB_STATE_NO_PUBLISHED, + Constants.PUB_STATE_PUBLISHING, + Constants.PUB_STATE_PUBLISHED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraStreamPublishState { + } + + @IntDef({ + Constants.RTMP_STREAMING_EVENT_FAILED_LOAD_IMAGE, + Constants.RTMP_STREAMING_EVENT_URL_ALREADY_IN_USE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraRtmpStreamingEvent { + } + + @IntDef({ + Constants.AUDIO_EFFECT_OFF, + Constants.ROOM_ACOUSTICS_KTV, + Constants.ROOM_ACOUSTICS_VOCAL_CONCERT, + Constants.ROOM_ACOUSTICS_STUDIO, + Constants.ROOM_ACOUSTICS_PHONOGRAPH, + Constants.ROOM_ACOUSTICS_VIRTUAL_STEREO, + Constants.ROOM_ACOUSTICS_SPACIAL, + Constants.ROOM_ACOUSTICS_ETHEREAL, + Constants.ROOM_ACOUSTICS_3D_VOICE, + Constants.VOICE_CHANGER_EFFECT_UNCLE, + Constants.VOICE_CHANGER_EFFECT_OLDMAN, + Constants.VOICE_CHANGER_EFFECT_BOY, + Constants.VOICE_CHANGER_EFFECT_SISTER, + Constants.VOICE_CHANGER_EFFECT_GIRL, + Constants.VOICE_CHANGER_EFFECT_PIGKING, + Constants.VOICE_CHANGER_EFFECT_HULK, + Constants.STYLE_TRANSFORMATION_RNB, + Constants.STYLE_TRANSFORMATION_POPULAR, + Constants.PITCH_CORRECTION, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraAudioEffectPreset { + } + + @IntDef({ + Constants.VOICE_BEAUTIFIER_OFF, + Constants.CHAT_BEAUTIFIER_MAGNETIC, + Constants.CHAT_BEAUTIFIER_FRESH, + Constants.CHAT_BEAUTIFIER_VITALITY, + Constants.SINGING_BEAUTIFIER, + Constants.TIMBRE_TRANSFORMATION_VIGOROUS, + Constants.TIMBRE_TRANSFORMATION_DEEP, + Constants.TIMBRE_TRANSFORMATION_MELLOW, + Constants.TIMBRE_TRANSFORMATION_FALSETTO, + Constants.TIMBRE_TRANSFORMATION_FULL, + Constants.TIMBRE_TRANSFORMATION_CLEAR, + Constants.TIMBRE_TRANSFORMATION_RESOUNDING, + Constants.TIMBRE_TRANSFORMATION_RINGING, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraVoiceBeautifierPreset { + } + + @IntDef({ + Constants.AUDIENCE_LATENCY_LEVEL_LOW_LATENCY, + Constants.AUDIENCE_LATENCY_LEVEL_ULTRA_LOW_LATENCY, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraAudienceLatencyLevelType { + } + + @IntDef({ + Constants.TRANSPORT_TYPE_NONE_PROXY, + Constants.TRANSPORT_TYPE_UDP_PROXY, + Constants.TRANSPORT_TYPE_TCP_PROXY, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraCloudProxyType { + } + + @IntDef({ + AgoraLogLevel.LOG_LEVEL_NONE, + AgoraLogLevel.LOG_LEVEL_INFO, + AgoraLogLevel.LOG_LEVEL_WARN, + AgoraLogLevel.LOG_LEVEL_ERROR, + AgoraLogLevel.LOG_LEVEL_FATAL, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraLogLevel { + int LOG_LEVEL_NONE = 0; + int LOG_LEVEL_INFO = 1; + int LOG_LEVEL_WARN = 2; + int LOG_LEVEL_ERROR = 4; + int LOG_LEVEL_FATAL = 8; + } + + @IntDef({ + Constants.CAPTURE_BRIGHTNESS_LEVEL_INVALID, + Constants.CAPTURE_BRIGHTNESS_LEVEL_NORMAL, + Constants.CAPTURE_BRIGHTNESS_LEVEL_BRIGHT, + Constants.CAPTURE_BRIGHTNESS_LEVEL_DARK, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraCaptureBrightnessLevelType { + } + + @IntDef({ + IRtcEngineEventHandler.UploadErrorReason.UPLOAD_SUCCESS, + IRtcEngineEventHandler.UploadErrorReason.UPLOAD_NET_ERROR, + IRtcEngineEventHandler.UploadErrorReason.UPLOAD_SERVER_ERROR, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraUploadErrorReason { + } + + @IntDef({ + IRtcEngineEventHandler.ExperienceQuality.EXPERIENCE_GOOD, + IRtcEngineEventHandler.ExperienceQuality.EXPERIENCE_BAD, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraExperienceQualityType { + } + + @IntDef({ + IRtcEngineEventHandler.ExperiencePoorReason.EXPERIENCE_REASON_NONE, + IRtcEngineEventHandler.ExperiencePoorReason.REMOTE_NETWORK_QUALITY_POOR, + IRtcEngineEventHandler.ExperiencePoorReason.LOCAL_NETWORK_QUALITY_POOR, + IRtcEngineEventHandler.ExperiencePoorReason.WIRELESS_SIGNAL_POOR, + IRtcEngineEventHandler.ExperiencePoorReason.WIFI_BLUETOOTH_COEXIST, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraExperiencePoorReason { + } + + @IntDef({ + Constants.SR_STATE_REASON_SUCCESS, + Constants.SR_STATE_REASON_STREAM_OVER_LIMITATION, + Constants.SR_STATE_REASON_USER_COUNT_OVER_LIMITATION, + Constants.SR_STATE_REASON_DEVICE_NOT_SUPPORTED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraSuperResolutionStateReason { + } + + @IntDef({ + VirtualBackgroundSource.BACKGROUND_COLOR, + VirtualBackgroundSource.BACKGROUND_IMG, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraVirtualBackgroundSourceType { + } + + @IntDef({ + Constants.VBS_STATE_REASON_SUCCESS, + Constants.VBS_STATE_REASON_IMAGE_NOT_EXIST, + Constants.VBS_STATE_REASON_COLOR_FORMAT_NOT_SUPPORTED, + Constants.VBS_STATE_REASON_DEVICE_NOT_SUPPORTED, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AgoraVirtualBackgroundSourceStateReason { + } } diff --git a/BeanCovertor.kt b/BeanCovertor.kt index 9854fdea3..0f926a7f9 100644 --- a/BeanCovertor.kt +++ b/BeanCovertor.kt @@ -2,11 +2,16 @@ package io.agora.rtc.base import android.graphics.Color import io.agora.rtc.RtcEngineConfig +import io.agora.rtc.audio.AgoraRhythmPlayerConfig +import io.agora.rtc.audio.AudioRecordingConfiguration +import io.agora.rtc.internal.EncryptionConfig import io.agora.rtc.internal.LastmileProbeConfig import io.agora.rtc.live.LiveInjectStreamConfig import io.agora.rtc.live.LiveTranscoding import io.agora.rtc.live.LiveTranscoding.TranscodingUser import io.agora.rtc.models.ChannelMediaOptions +import io.agora.rtc.models.ClientRoleOptions +import io.agora.rtc.models.DataStreamConfig import io.agora.rtc.video.* fun mapToVideoDimensions(map: Map<*, *>): VideoEncoderConfiguration.VideoDimensions { @@ -24,7 +29,9 @@ fun mapToVideoEncoderConfiguration(map: Map<*, *>): VideoEncoderConfiguration { (map["bitrate"] as? Number)?.let { bitrate = it.toInt() } (map["minBitrate"] as? Number)?.let { minBitrate = it.toInt() } (map["orientationMode"] as? Number)?.let { orientationMode = intToOrientationMode(it.toInt()) } - (map["degradationPrefer"] as? Number)?.let { degradationPrefer = intToDegradationPreference(it.toInt()) } + (map["degradationPrefer"] as? Number)?.let { + degradationPrefer = intToDegradationPreference(it.toInt()) + } (map["mirrorMode"] as? Number)?.let { mirrorMode = it.toInt() } } } @@ -50,7 +57,7 @@ fun mapToAgoraImage(map: Map<*, *>): AgoraImage { fun mapToTranscodingUser(map: Map<*, *>): TranscodingUser { return TranscodingUser().apply { - (map["uid"] as? Number)?.let { uid = it.toInt() } + (map["uid"] as? Number)?.let { uid = it.toNativeUInt() } (map["x"] as? Number)?.let { x = it.toInt() } (map["y"] as? Number)?.let { y = it.toInt() } (map["width"] as? Number)?.let { width = it.toInt() } @@ -79,11 +86,17 @@ fun mapToLiveTranscoding(map: Map<*, *>): LiveTranscoding { (map["videoGop"] as? Number)?.let { videoGop = it.toInt() } (map["watermark"] as? Map<*, *>)?.let { watermark = mapToAgoraImage(it) } (map["backgroundImage"] as? Map<*, *>)?.let { backgroundImage = mapToAgoraImage(it) } - (map["audioSampleRate"] as? Number)?.let { audioSampleRate = intToLiveTranscodingAudioSampleRate(it.toInt()) } + (map["audioSampleRate"] as? Number)?.let { + audioSampleRate = intToLiveTranscodingAudioSampleRate(it.toInt()) + } (map["audioBitrate"] as? Number)?.let { audioBitrate = it.toInt() } (map["audioChannels"] as? Number)?.let { audioChannels = it.toInt() } - (map["audioCodecProfile"] as? Number)?.let { audioCodecProfile = intToAudioCodecProfile(it.toInt()) } - (map["videoCodecProfile"] as? Number)?.let { videoCodecProfile = intToVideoCodecProfile(it.toInt()) } + (map["audioCodecProfile"] as? Number)?.let { + audioCodecProfile = intToAudioCodecProfile(it.toInt()) + } + (map["videoCodecProfile"] as? Number)?.let { + videoCodecProfile = intToVideoCodecProfile(it.toInt()) + } (map["backgroundColor"] as? Map<*, *>)?.let { backgroundColor = mapToColor(it) } (map["userConfigExtraInfo"] as? String)?.let { userConfigExtraInfo = it } (map["transcodingUsers"] as? List<*>)?.let { list -> @@ -100,7 +113,7 @@ fun mapToChannelMediaInfo(map: Map<*, *>): ChannelMediaInfo { return ChannelMediaInfo( map["channelName"] as? String, map["token"] as? String, - (map["uid"] as Number).toInt() + (map["uid"] as Number).toNativeUInt() ) } @@ -139,8 +152,12 @@ fun mapToRectangle(map: Map<*, *>): WatermarkOptions.Rectangle { fun mapToWatermarkOptions(map: Map<*, *>): WatermarkOptions { return WatermarkOptions().apply { (map["visibleInPreview"] as? Boolean)?.let { visibleInPreview = it } - (map["positionInLandscapeMode"] as? Map<*, *>)?.let { positionInLandscapeMode = mapToRectangle(it) } - (map["positionInPortraitMode"] as? Map<*, *>)?.let { positionInPortraitMode = mapToRectangle(it) } + (map["positionInLandscapeMode"] as? Map<*, *>)?.let { + positionInLandscapeMode = mapToRectangle(it) + } + (map["positionInPortraitMode"] as? Map<*, *>)?.let { + positionInPortraitMode = mapToRectangle(it) + } } } @@ -151,23 +168,39 @@ fun mapToLiveInjectStreamConfig(map: Map<*, *>): LiveInjectStreamConfig { (map["videoGop"] as? Number)?.let { videoGop = it.toInt() } (map["videoFramerate"] as? Number)?.let { videoFramerate = it.toInt() } (map["videoBitrate"] as? Number)?.let { videoBitrate = it.toInt() } - (map["audioSampleRate"] as? Number)?.let { audioSampleRate = intToLiveInjectStreamConfigAudioSampleRate(it.toInt()) } + (map["audioSampleRate"] as? Number)?.let { + audioSampleRate = intToLiveInjectStreamConfigAudioSampleRate(it.toInt()) + } (map["audioBitrate"] as? Number)?.let { audioBitrate = it.toInt() } (map["audioChannels"] as? Number)?.let { audioChannels = it.toInt() } } } +fun mapToRhythmPlayerConfig(map: Map<*, *>): AgoraRhythmPlayerConfig { + return AgoraRhythmPlayerConfig().apply { + (map["beatsPerMeasure"] as? Number)?.let { beatsPerMeasure = it.toInt() } + (map["beatsPerMinute"] as? Number)?.let { beatsPerMinute = it.toInt() } + (map["publish"] as? Boolean)?.let { publish = it } + } +} + fun mapToCameraCapturerConfiguration(map: Map<*, *>): CameraCapturerConfiguration { return CameraCapturerConfiguration( intToCapturerOutputPreference((map["preference"] as Number).toInt()), intToCameraDirection((map["cameraDirection"] as Number).toInt()) - ) + ).apply { + dimensions = CameraCapturerConfiguration.CaptureDimensions() + (map["captureWidth"] as? Number)?.toInt()?.let { dimensions.width = it } + (map["captureHeight"] as? Number)?.toInt()?.let { dimensions.height = it } + } } fun mapToChannelMediaOptions(map: Map<*, *>): ChannelMediaOptions { return ChannelMediaOptions().apply { (map["autoSubscribeAudio"] as? Boolean)?.let { autoSubscribeAudio = it } (map["autoSubscribeVideo"] as? Boolean)?.let { autoSubscribeVideo = it } + (map["publishLocalAudio"] as? Boolean)?.let { publishLocalAudio = it } + (map["publishLocalVideo"] as? Boolean)?.let { publishLocalVideo = it } } } @@ -175,5 +208,58 @@ fun mapToRtcEngineConfig(map: Map<*, *>): RtcEngineConfig { return RtcEngineConfig().apply { mAppId = map["appId"] as String (map["areaCode"] as? Number)?.toInt()?.let { mAreaCode = it } + (map["logConfig"] as? Map<*, *>)?.let { mLogConfig = mapToLogConfig(it) } + } +} + +fun mapToAudioRecordingConfiguration(map: Map<*, *>): AudioRecordingConfiguration { + return AudioRecordingConfiguration().apply { + (map["filePath"] as? String)?.let { filePath = it } + (map["recordingQuality"] as? Number)?.let { recordingQuality = it.toInt() } + (map["recordingPosition"] as? Number)?.let { recordingPosition = it.toInt() } + (map["recordingSampleRate"] as? Number)?.let { recordingSampleRate = it.toInt() } + } +} + +fun mapToEncryptionConfig(map: Map<*, *>): EncryptionConfig { + return EncryptionConfig().apply { + (map["encryptionMode"] as? Number)?.let { encryptionMode = intToEncryptionMode(it.toInt()) } + (map["encryptionKey"] as? String)?.let { encryptionKey = it } + (map["encryptionKdfSalt"] as? List<*>)?.let { list -> + for (i in list.indices) { + (list[i] as? Number)?.let { + encryptionKdfSalt[i] = it.toByte() + } + } + } + } +} + +fun mapToClientRoleOptions(map: Map<*, *>): ClientRoleOptions { + return ClientRoleOptions().apply { + (map["audienceLatencyLevel"] as? Number)?.let { audienceLatencyLevel = it.toInt() } + } +} + +fun mapToLogConfig(map: Map<*, *>): RtcEngineConfig.LogConfig { + return RtcEngineConfig.LogConfig().apply { + (map["filePath"] as? String)?.let { filePath = it } + (map["fileSize"] as? Number)?.let { fileSize = it.toInt() } + (map["level"] as? Number)?.let { level = it.toInt() } + } +} + +fun mapToDataStreamConfig(map: Map<*, *>): DataStreamConfig { + return DataStreamConfig().apply { + (map["syncWithAudio"] as? Boolean)?.let { syncWithAudio = it } + (map["ordered"] as? Boolean)?.let { ordered = it } + } +} + +fun mapToVirtualBackgroundSource(map: Map<*, *>): VirtualBackgroundSource { + return VirtualBackgroundSource().apply { + (map["backgroundSourceType"] as? Number)?.let { backgroundSourceType = it.toInt() } + (map["color"] as? Number)?.let { color = it.toInt() } + (map["source"] as? String)?.let { source = it } } } diff --git a/EnumCovertor.kt b/EnumCovertor.kt index 166bbfaaf..ea423ce69 100644 --- a/EnumCovertor.kt +++ b/EnumCovertor.kt @@ -1,5 +1,6 @@ package io.agora.rtc.base +import io.agora.rtc.internal.EncryptionConfig import io.agora.rtc.live.LiveInjectStreamConfig import io.agora.rtc.live.LiveTranscoding import io.agora.rtc.video.CameraCapturerConfiguration @@ -85,3 +86,12 @@ fun intToCameraDirection(@Annotations.AgoraCameraDirection intValue: Int): Camer } throw RuntimeException("CameraCapturerConfiguration.CAMERA_DIRECTION not contains $intValue") } + +fun intToEncryptionMode(@Annotations.AgoraEncryptionMode intValue: Int): EncryptionConfig.EncryptionMode { + for (value in EncryptionConfig.EncryptionMode.values()) { + if (value.value == intValue) { + return value + } + } + throw RuntimeException("EncryptionConfig.EncryptionMode not contains $intValue") +} diff --git a/Extensions.kt b/Extensions.kt index 4fc01e114..fb8df0607 100644 --- a/Extensions.kt +++ b/Extensions.kt @@ -6,7 +6,7 @@ import io.agora.rtc.models.UserInfo fun UserInfo.toMap(): Map { return hashMapOf( - "uid" to uid, + "uid" to uid.toUInt().toLong(), "userAccount" to userAccount ) } @@ -15,13 +15,14 @@ fun LocalAudioStats.toMap(): Map { return hashMapOf( "numChannels" to numChannels, "sentSampleRate" to sentSampleRate, - "sentBitrate" to sentBitrate + "sentBitrate" to sentBitrate, + "txPacketLossRate" to txPacketLossRate ) } fun RtcStats.toMap(): Map { return hashMapOf( - "totalDuration" to totalDuration, + "duration" to totalDuration, "txBytes" to txBytes, "rxBytes" to rxBytes, "txAudioBytes" to txAudioBytes, @@ -34,7 +35,7 @@ fun RtcStats.toMap(): Map { "rxAudioKBitRate" to rxAudioKBitRate, "txVideoKBitRate" to txVideoKBitRate, "rxVideoKBitRate" to rxVideoKBitRate, - "users" to users, + "userCount" to users, "lastmileDelay" to lastmileDelay, "txPacketLossRate" to txPacketLossRate, "rxPacketLossRate" to rxPacketLossRate, @@ -58,7 +59,7 @@ fun Rect.toMap(): Map { fun RemoteAudioStats.toMap(): Map { return hashMapOf( - "uid" to uid, + "uid" to uid.toUInt().toLong(), "quality" to quality, "networkTransportDelay" to networkTransportDelay, "jitterBufferDelay" to jitterBufferDelay, @@ -68,7 +69,11 @@ fun RemoteAudioStats.toMap(): Map { "receivedBitrate" to receivedBitrate, "totalFrozenTime" to totalFrozenTime, "frozenRate" to frozenRate, - "totalActiveTime" to totalActiveTime + "totalActiveTime" to totalActiveTime, + "publishDuration" to publishDuration, + "qoeQuality" to qoeQuality, + "qualityChangedReason" to qualityChangedReason, + "mosValue" to mosValue ) } @@ -85,13 +90,16 @@ fun LocalVideoStats.toMap(): Map { "encodedFrameWidth" to encodedFrameWidth, "encodedFrameHeight" to encodedFrameHeight, "encodedFrameCount" to encodedFrameCount, - "codecType" to codecType + "codecType" to codecType, + "txPacketLossRate" to txPacketLossRate, + "captureFrameRate" to captureFrameRate, + "captureBrightnessLevel" to captureBrightnessLevel ) } fun RemoteVideoStats.toMap(): Map { return hashMapOf( - "uid" to uid, + "uid" to uid.toUInt().toLong(), "delay" to delay, "width" to width, "height" to height, @@ -102,13 +110,14 @@ fun RemoteVideoStats.toMap(): Map { "rxStreamType" to rxStreamType, "totalFrozenTime" to totalFrozenTime, "frozenRate" to frozenRate, - "totalActiveTime" to totalActiveTime + "totalActiveTime" to totalActiveTime, + "publishDuration" to publishDuration ) } fun AudioVolumeInfo.toMap(): Map { return hashMapOf( - "uid" to uid, + "uid" to uid.toUInt().toLong(), "volume" to volume, "vad" to vad, "channelId" to channelId @@ -149,3 +158,8 @@ fun AgoraFacePositionInfo.toMap(): Map { fun Array.toMapList(): List> { return List(size) { this[it].toMap() } } + +@ExperimentalUnsignedTypes +internal fun Number.toNativeUInt(): Int { + return toLong().toUInt().toInt() +} diff --git a/MediaObserver.kt b/MediaObserver.kt index 21f3b20c3..b763cedeb 100644 --- a/MediaObserver.kt +++ b/MediaObserver.kt @@ -31,8 +31,10 @@ class MediaObserver( } override fun onMetadataReceived(buffer: ByteArray, uid: Int, timeStampMs: Long) { - emit(hashMapOf( - "data" to arrayListOf(String(buffer), uid, timeStampMs) - )) + emit( + hashMapOf( + "data" to arrayListOf(String(buffer), uid.toUInt().toLong(), timeStampMs) + ) + ) } } diff --git a/RtcChannel.kt b/RtcChannel.kt index 320b51165..72fa2790a 100644 --- a/RtcChannel.kt +++ b/RtcChannel.kt @@ -1,8 +1,10 @@ package io.agora.rtc.base +import io.agora.rtc.Constants import io.agora.rtc.IMetadataObserver import io.agora.rtc.RtcChannel import io.agora.rtc.RtcEngine +import io.agora.rtc.internal.EncryptionConfig import java.util.* class IRtcChannel { @@ -26,8 +28,10 @@ class IRtcChannel { fun getConnectionState(params: Map, callback: Callback) + @Deprecated("") fun publish(params: Map, callback: Callback) + @Deprecated("") fun unpublish(params: Map, callback: Callback) fun getCallId(params: Map, callback: Callback) @@ -36,19 +40,27 @@ class IRtcChannel { interface RtcAudioInterface { fun adjustUserPlaybackSignalVolume(params: Map, callback: Callback) + fun muteLocalAudioStream(params: Map, callback: Callback) + fun muteRemoteAudioStream(params: Map, callback: Callback) fun muteAllRemoteAudioStreams(params: Map, callback: Callback) + @Deprecated("") fun setDefaultMuteAllRemoteAudioStreams(params: Map, callback: Callback) } interface RtcVideoInterface { + fun muteLocalVideoStream(params: Map, callback: Callback) + fun muteRemoteVideoStream(params: Map, callback: Callback) fun muteAllRemoteVideoStreams(params: Map, callback: Callback) + @Deprecated("") fun setDefaultMuteAllRemoteVideoStreams(params: Map, callback: Callback) + + fun enableRemoteSuperResolution(params: Map, callback: Callback) } interface RtcVoicePositionInterface { @@ -69,6 +81,10 @@ class IRtcChannel { fun updateChannelMediaRelay(params: Map, callback: Callback) fun stopChannelMediaRelay(params: Map, callback: Callback) + + fun pauseAllChannelMediaRelay(params: Map, callback: Callback) + + fun resumeAllChannelMediaRelay(params: Map, callback: Callback) } interface RtcDualStreamInterface { @@ -92,9 +108,13 @@ class IRtcChannel { } interface RtcEncryptionInterface { + @Deprecated("") fun setEncryptionSecret(params: Map, callback: Callback) + @Deprecated("") fun setEncryptionMode(params: Map, callback: Callback) + + fun enableEncryption(params: Map, callback: Callback) } interface RtcInjectStreamInterface { @@ -129,7 +149,12 @@ class RtcChannelManager( override fun create(params: Map, callback: Callback) { callback.resolve(params["engine"] as RtcEngine) { e -> e.createRtcChannel(params["channelId"] as String)?.let { - it.setRtcChannelEventHandler(RtcChannelEventHandler { methodName, data -> emit(methodName, data) }) + it.setRtcChannelEventHandler(RtcChannelEventHandler { methodName, data -> + emit( + methodName, + data + ) + }) rtcChannelMap[it.channelId()] = it } Unit @@ -142,15 +167,37 @@ class RtcChannelManager( override fun setClientRole(params: Map, callback: Callback) { val role = (params["role"] as Number).toInt() + (params["options"] as? Map<*, *>)?.let { + callback.code( + this[params["channelId"] as String]?.setClientRole( + role, + mapToClientRoleOptions(it) + ) + ) + return@setClientRole + } callback.code(this[params["channelId"] as String]?.setClientRole(role)) } override fun joinChannel(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.joinChannel(params["token"] as? String, params["optionalInfo"] as? String, (params["optionalUid"] as Number).toInt(), mapToChannelMediaOptions(params["options"] as Map<*, *>))) + callback.code( + this[params["channelId"] as String]?.joinChannel( + params["token"] as? String, + params["optionalInfo"] as? String, + (params["optionalUid"] as Number).toNativeUInt(), + mapToChannelMediaOptions(params["options"] as Map<*, *>) + ) + ) } override fun joinChannelWithUserAccount(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.joinChannelWithUserAccount(params["token"] as? String, params["userAccount"] as String, mapToChannelMediaOptions(params["options"] as Map<*, *>))) + callback.code( + this[params["channelId"] as String]?.joinChannelWithUserAccount( + params["token"] as? String, + params["userAccount"] as String, + mapToChannelMediaOptions(params["options"] as Map<*, *>) + ) + ) } override fun leaveChannel(params: Map, callback: Callback) { @@ -178,11 +225,29 @@ class RtcChannelManager( } override fun adjustUserPlaybackSignalVolume(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.adjustUserPlaybackSignalVolume((params["uid"] as Number).toInt(), (params["volume"] as Number).toInt())) + callback.code( + this[params["channelId"] as String]?.adjustUserPlaybackSignalVolume( + (params["uid"] as Number).toNativeUInt(), + (params["volume"] as Number).toInt() + ) + ) + } + + override fun muteLocalAudioStream(params: Map, callback: Callback) { + callback.code( + this[params["channelId"] as String]?.muteLocalAudioStream( + params["muted"] as Boolean + ) + ) } override fun muteRemoteAudioStream(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.muteRemoteAudioStream((params["uid"] as Number).toInt(), params["muted"] as Boolean)) + callback.code( + this[params["channelId"] as String]?.muteRemoteAudioStream( + (params["uid"] as Number).toNativeUInt(), + params["muted"] as Boolean + ) + ) } override fun muteAllRemoteAudioStreams(params: Map, callback: Callback) { @@ -193,8 +258,21 @@ class RtcChannelManager( callback.code(this[params["channelId"] as String]?.setDefaultMuteAllRemoteAudioStreams(params["muted"] as Boolean)) } + override fun muteLocalVideoStream(params: Map, callback: Callback) { + callback.code( + this[params["channelId"] as String]?.muteLocalVideoStream( + params["muted"] as Boolean + ) + ) + } + override fun muteRemoteVideoStream(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.muteRemoteVideoStream((params["uid"] as Number).toInt(), params["muted"] as Boolean)) + callback.code( + this[params["channelId"] as String]?.muteRemoteVideoStream( + (params["uid"] as Number).toNativeUInt(), + params["muted"] as Boolean + ) + ) } override fun muteAllRemoteVideoStreams(params: Map, callback: Callback) { @@ -205,16 +283,42 @@ class RtcChannelManager( callback.code(this[params["channelId"] as String]?.setDefaultMuteAllRemoteVideoStreams(params["muted"] as Boolean)) } + override fun enableRemoteSuperResolution(params: Map, callback: Callback) { + callback.code( + this[params["channelId"] as String]?.enableRemoteSuperResolution( + (params["uid"] as Number).toNativeUInt(), + params["enable"] as Boolean + ) + ) + } + override fun setRemoteVoicePosition(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.setRemoteVoicePosition((params["uid"] as Number).toInt(), (params["pan"] as Number).toDouble(), (params["gain"] as Number).toDouble())) + callback.code( + this[params["channelId"] as String]?.setRemoteVoicePosition( + (params["uid"] as Number).toNativeUInt(), + (params["pan"] as Number).toDouble(), + (params["gain"] as Number).toDouble() + ) + ) } override fun setLiveTranscoding(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.setLiveTranscoding(mapToLiveTranscoding(params["transcoding"] as Map<*, *>))) + callback.code( + this[params["channelId"] as String]?.setLiveTranscoding( + mapToLiveTranscoding( + params["transcoding"] as Map<*, *> + ) + ) + ) } override fun addPublishStreamUrl(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.addPublishStreamUrl(params["url"] as String, params["transcodingEnabled"] as Boolean)) + callback.code( + this[params["channelId"] as String]?.addPublishStreamUrl( + params["url"] as String, + params["transcodingEnabled"] as Boolean + ) + ) } override fun removePublishStreamUrl(params: Map, callback: Callback) { @@ -222,19 +326,42 @@ class RtcChannelManager( } override fun startChannelMediaRelay(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.startChannelMediaRelay(mapToChannelMediaRelayConfiguration(params["channelMediaRelayConfiguration"] as Map<*, *>))) + callback.code( + this[params["channelId"] as String]?.startChannelMediaRelay( + mapToChannelMediaRelayConfiguration(params["channelMediaRelayConfiguration"] as Map<*, *>) + ) + ) } override fun updateChannelMediaRelay(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.updateChannelMediaRelay(mapToChannelMediaRelayConfiguration(params["channelMediaRelayConfiguration"] as Map<*, *>))) + callback.code( + this[params["channelId"] as String]?.updateChannelMediaRelay( + mapToChannelMediaRelayConfiguration(params["channelMediaRelayConfiguration"] as Map<*, *>) + ) + ) } override fun stopChannelMediaRelay(params: Map, callback: Callback) { callback.code(this[params["channelId"] as String]?.stopChannelMediaRelay()) } + override fun pauseAllChannelMediaRelay(params: Map, callback: Callback) { + callback.code(-Constants.ERR_NOT_SUPPORTED) +// callback.code(this[params["channelId"] as String]?.pauseAllChannelMediaRelay()) + } + + override fun resumeAllChannelMediaRelay(params: Map, callback: Callback) { + callback.code(-Constants.ERR_NOT_SUPPORTED) +// callback.code(this[params["channelId"] as String]?.resumeAllChannelMediaRelay()) + } + override fun setRemoteVideoStreamType(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.setRemoteVideoStreamType((params["uid"] as Number).toInt(), (params["streamType"] as Number).toInt())) + callback.code( + this[params["channelId"] as String]?.setRemoteVideoStreamType( + (params["uid"] as Number).toNativeUInt(), + (params["streamType"] as Number).toInt() + ) + ) } override fun setRemoteDefaultVideoStreamType(params: Map, callback: Callback) { @@ -242,15 +369,27 @@ class RtcChannelManager( } override fun setRemoteUserPriority(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.setRemoteUserPriority((params["uid"] as Number).toInt(), (params["userPriority"] as Number).toInt())) + callback.code( + this[params["channelId"] as String]?.setRemoteUserPriority( + (params["uid"] as Number).toNativeUInt(), + (params["userPriority"] as Number).toInt() + ) + ) } override fun registerMediaMetadataObserver(params: Map, callback: Callback) { val channelId = params["channelId"] as String val mediaObserver = MediaObserver { data -> - emit(RtcChannelEvents.MetadataReceived, data?.toMutableMap()?.apply { put("channelId", channelId) }) + emit( + RtcChannelEvents.MetadataReceived, + data?.toMutableMap()?.apply { put("channelId", channelId) }) } - callback.code(this[channelId]?.registerMediaMetadataObserver(mediaObserver, IMetadataObserver.VIDEO_METADATA)) { + callback.code( + this[channelId]?.registerMediaMetadataObserver( + mediaObserver, + IMetadataObserver.VIDEO_METADATA + ) + ) { mediaObserverMap[channelId] = mediaObserver Unit } @@ -258,7 +397,12 @@ class RtcChannelManager( override fun unregisterMediaMetadataObserver(params: Map, callback: Callback) { val channelId = params["channelId"] as String - callback.code(this[channelId]?.registerMediaMetadataObserver(null, IMetadataObserver.VIDEO_METADATA)) { + callback.code( + this[channelId]?.registerMediaMetadataObserver( + null, + IMetadataObserver.VIDEO_METADATA + ) + ) { mediaObserverMap.remove(channelId) Unit } @@ -283,11 +427,34 @@ class RtcChannelManager( } override fun setEncryptionMode(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.setEncryptionMode(params["encryptionMode"] as String)) + callback.code( + this[params["channelId"] as String]?.setEncryptionMode( + when ((params["encryptionMode"] as Number).toInt()) { + EncryptionConfig.EncryptionMode.AES_128_XTS.value -> "aes-128-xts" + EncryptionConfig.EncryptionMode.AES_128_ECB.value -> "aes-128-ecb" + EncryptionConfig.EncryptionMode.AES_256_XTS.value -> "aes-256-xts" + else -> "" + } + ) + ) + } + + override fun enableEncryption(params: Map, callback: Callback) { + callback.code( + this[params["channelId"] as String]?.enableEncryption( + params["enabled"] as Boolean, + mapToEncryptionConfig(params["config"] as Map<*, *>) + ) + ) } override fun addInjectStreamUrl(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.addInjectStreamUrl(params["url"] as String, mapToLiveInjectStreamConfig(params["config"] as Map<*, *>))) + callback.code( + this[params["channelId"] as String]?.addInjectStreamUrl( + params["url"] as String, + mapToLiveInjectStreamConfig(params["config"] as Map<*, *>) + ) + ) } override fun removeInjectStreamUrl(params: Map, callback: Callback) { @@ -296,10 +463,24 @@ class RtcChannelManager( override fun createDataStream(params: Map, callback: Callback) { val channel = this[params["channelId"] as String] - callback.code(channel?.createDataStream(params["reliable"] as Boolean, params["ordered"] as Boolean)) { it } + (params["config"] as? Map<*, *>)?.let { config -> + callback.code(channel?.createDataStream(mapToDataStreamConfig(config))) { it } + return@createDataStream + } + callback.code( + channel?.createDataStream( + params["reliable"] as Boolean, + params["ordered"] as Boolean + ) + ) { it } } override fun sendStreamMessage(params: Map, callback: Callback) { - callback.code(this[params["channelId"] as String]?.sendStreamMessage((params["streamId"] as Number).toInt(), (params["message"] as String).toByteArray())) + callback.code( + this[params["channelId"] as String]?.sendStreamMessage( + (params["streamId"] as Number).toInt(), + (params["message"] as String).toByteArray() + ) + ) } } diff --git a/RtcChannelEvent.kt b/RtcChannelEvent.kt index e24e0a536..83bc3990c 100644 --- a/RtcChannelEvent.kt +++ b/RtcChannelEvent.kt @@ -37,6 +37,12 @@ class RtcChannelEvents { const val ChannelMediaRelayStateChanged = "ChannelMediaRelayStateChanged" const val ChannelMediaRelayEvent = "ChannelMediaRelayEvent" const val MetadataReceived = "MetadataReceived" + const val AudioPublishStateChanged = "AudioPublishStateChanged" + const val VideoPublishStateChanged = "VideoPublishStateChanged" + const val AudioSubscribeStateChanged = "AudioSubscribeStateChanged" + const val VideoSubscribeStateChanged = "VideoSubscribeStateChanged" + const val RtmpStreamingEvent = "RtmpStreamingEvent" + const val UserSuperResolutionEnabled = "UserSuperResolutionEnabled" fun toMap(): Map { return hashMapOf( @@ -69,7 +75,13 @@ class RtcChannelEvents { "StreamMessageError" to StreamMessageError, "ChannelMediaRelayStateChanged" to ChannelMediaRelayStateChanged, "ChannelMediaRelayEvent" to ChannelMediaRelayEvent, - "MetadataReceived" to MetadataReceived + "MetadataReceived" to MetadataReceived, + "AudioPublishStateChanged" to AudioPublishStateChanged, + "VideoPublishStateChanged" to VideoPublishStateChanged, + "AudioSubscribeStateChanged" to AudioSubscribeStateChanged, + "VideoSubscribeStateChanged" to VideoSubscribeStateChanged, + "RtmpStreamingEvent" to RtmpStreamingEvent, + "UserSuperResolutionEnabled" to UserSuperResolutionEnabled ) } } @@ -84,10 +96,12 @@ class RtcChannelEventHandler( private fun callback(methodName: String, channel: RtcChannel?, vararg data: Any?) { channel?.let { - emitter(methodName, hashMapOf( - "channelId" to it.channelId(), - "data" to data.toList() - )) + emitter( + methodName, hashMapOf( + "channelId" to it.channelId(), + "data" to data.toList() + ) + ) } } @@ -100,30 +114,54 @@ class RtcChannelEventHandler( } override fun onJoinChannelSuccess(rtcChannel: RtcChannel?, uid: Int, elapsed: Int) { - callback(RtcChannelEvents.JoinChannelSuccess, rtcChannel, rtcChannel?.channelId(), uid, elapsed) + callback( + RtcChannelEvents.JoinChannelSuccess, + rtcChannel, + rtcChannel?.channelId(), + uid.toUInt().toLong(), + elapsed + ) } override fun onRejoinChannelSuccess(rtcChannel: RtcChannel?, uid: Int, elapsed: Int) { - callback(RtcChannelEvents.RejoinChannelSuccess, rtcChannel, rtcChannel?.channelId(), uid, elapsed) + callback( + RtcChannelEvents.RejoinChannelSuccess, + rtcChannel, + rtcChannel?.channelId(), + uid.toUInt().toLong(), + elapsed + ) } override fun onLeaveChannel(rtcChannel: RtcChannel?, stats: IRtcEngineEventHandler.RtcStats?) { callback(RtcChannelEvents.LeaveChannel, rtcChannel, stats?.toMap()) } - override fun onClientRoleChanged(rtcChannel: RtcChannel?, @Annotations.AgoraClientRole oldRole: Int, @Annotations.AgoraClientRole newRole: Int) { + override fun onClientRoleChanged( + rtcChannel: RtcChannel?, + @Annotations.AgoraClientRole oldRole: Int, + @Annotations.AgoraClientRole newRole: Int + ) { callback(RtcChannelEvents.ClientRoleChanged, rtcChannel, oldRole, newRole) } override fun onUserJoined(rtcChannel: RtcChannel?, uid: Int, elapsed: Int) { - callback(RtcChannelEvents.UserJoined, rtcChannel, uid, elapsed) + callback(RtcChannelEvents.UserJoined, rtcChannel, uid.toUInt().toLong(), elapsed) } - override fun onUserOffline(rtcChannel: RtcChannel?, uid: Int, @Annotations.AgoraUserOfflineReason reason: Int) { - callback(RtcChannelEvents.UserOffline, rtcChannel, uid, reason) + override fun onUserOffline( + rtcChannel: RtcChannel?, + uid: Int, + @Annotations.AgoraUserOfflineReason reason: Int + ) { + callback(RtcChannelEvents.UserOffline, rtcChannel, uid.toUInt().toLong(), reason) } - override fun onConnectionStateChanged(rtcChannel: RtcChannel?, @Annotations.AgoraConnectionStateType state: Int, @Annotations.AgoraConnectionChangedReason reason: Int) { + override fun onConnectionStateChanged( + rtcChannel: RtcChannel?, + @Annotations.AgoraConnectionStateType state: Int, + @Annotations.AgoraConnectionChangedReason reason: Int + ) { callback(RtcChannelEvents.ConnectionStateChanged, rtcChannel, state, reason) } @@ -140,46 +178,119 @@ class RtcChannelEventHandler( } override fun onActiveSpeaker(rtcChannel: RtcChannel?, uid: Int) { - callback(RtcChannelEvents.ActiveSpeaker, rtcChannel, uid) - } - - override fun onVideoSizeChanged(rtcChannel: RtcChannel?, uid: Int, width: Int, height: Int, @IntRange(from = 0, to = 360) rotation: Int) { - callback(RtcChannelEvents.VideoSizeChanged, rtcChannel, uid, width, height, rotation) - } - - override fun onRemoteVideoStateChanged(rtcChannel: RtcChannel?, uid: Int, @Annotations.AgoraVideoRemoteState state: Int, @Annotations.AgoraVideoRemoteStateReason reason: Int, elapsed: Int) { - callback(RtcChannelEvents.RemoteVideoStateChanged, rtcChannel, uid, state, reason, elapsed) - } - - override fun onRemoteAudioStateChanged(rtcChannel: RtcChannel?, uid: Int, @Annotations.AgoraAudioRemoteState state: Int, @Annotations.AgoraAudioRemoteStateReason reason: Int, elapsed: Int) { - callback(RtcChannelEvents.RemoteAudioStateChanged, rtcChannel, uid, state, reason, elapsed) - } - - override fun onLocalPublishFallbackToAudioOnly(rtcChannel: RtcChannel?, isFallbackOrRecover: Boolean) { + callback(RtcChannelEvents.ActiveSpeaker, rtcChannel, uid.toUInt().toLong()) + } + + override fun onVideoSizeChanged( + rtcChannel: RtcChannel?, + uid: Int, + width: Int, + height: Int, + @IntRange(from = 0, to = 360) rotation: Int + ) { + callback( + RtcChannelEvents.VideoSizeChanged, + rtcChannel, + uid.toUInt().toLong(), + width, + height, + rotation + ) + } + + override fun onRemoteVideoStateChanged( + rtcChannel: RtcChannel?, + uid: Int, + @Annotations.AgoraVideoRemoteState state: Int, + @Annotations.AgoraVideoRemoteStateReason reason: Int, + elapsed: Int + ) { + callback( + RtcChannelEvents.RemoteVideoStateChanged, + rtcChannel, + uid.toUInt().toLong(), + state, + reason, + elapsed + ) + } + + override fun onRemoteAudioStateChanged( + rtcChannel: RtcChannel?, + uid: Int, + @Annotations.AgoraAudioRemoteState state: Int, + @Annotations.AgoraAudioRemoteStateReason reason: Int, + elapsed: Int + ) { + callback( + RtcChannelEvents.RemoteAudioStateChanged, + rtcChannel, + uid.toUInt().toLong(), + state, + reason, + elapsed + ) + } + + override fun onLocalPublishFallbackToAudioOnly( + rtcChannel: RtcChannel?, + isFallbackOrRecover: Boolean + ) { callback(RtcChannelEvents.LocalPublishFallbackToAudioOnly, rtcChannel, isFallbackOrRecover) } - override fun onRemoteSubscribeFallbackToAudioOnly(rtcChannel: RtcChannel?, uid: Int, isFallbackOrRecover: Boolean) { - callback(RtcChannelEvents.RemoteSubscribeFallbackToAudioOnly, rtcChannel, uid, isFallbackOrRecover) + override fun onRemoteSubscribeFallbackToAudioOnly( + rtcChannel: RtcChannel?, + uid: Int, + isFallbackOrRecover: Boolean + ) { + callback( + RtcChannelEvents.RemoteSubscribeFallbackToAudioOnly, + rtcChannel, + uid.toUInt().toLong(), + isFallbackOrRecover + ) } override fun onRtcStats(rtcChannel: RtcChannel?, stats: IRtcEngineEventHandler.RtcStats?) { callback(RtcChannelEvents.RtcStats, rtcChannel, stats?.toMap()) } - override fun onNetworkQuality(rtcChannel: RtcChannel?, uid: Int, @Annotations.AgoraNetworkQuality txQuality: Int, @Annotations.AgoraNetworkQuality rxQuality: Int) { - callback(RtcChannelEvents.NetworkQuality, rtcChannel, uid, txQuality, rxQuality) - } - - override fun onRemoteVideoStats(rtcChannel: RtcChannel?, stats: IRtcEngineEventHandler.RemoteVideoStats?) { + override fun onNetworkQuality( + rtcChannel: RtcChannel?, + uid: Int, + @Annotations.AgoraNetworkQuality txQuality: Int, + @Annotations.AgoraNetworkQuality rxQuality: Int + ) { + callback( + RtcChannelEvents.NetworkQuality, + rtcChannel, + uid.toUInt().toLong(), + txQuality, + rxQuality + ) + } + + override fun onRemoteVideoStats( + rtcChannel: RtcChannel?, + stats: IRtcEngineEventHandler.RemoteVideoStats? + ) { callback(RtcChannelEvents.RemoteVideoStats, rtcChannel, stats?.toMap()) } - override fun onRemoteAudioStats(rtcChannel: RtcChannel?, stats: IRtcEngineEventHandler.RemoteAudioStats?) { + override fun onRemoteAudioStats( + rtcChannel: RtcChannel?, + stats: IRtcEngineEventHandler.RemoteAudioStats? + ) { callback(RtcChannelEvents.RemoteAudioStats, rtcChannel, stats?.toMap()) } - override fun onRtmpStreamingStateChanged(rtcChannel: RtcChannel?, url: String?, @Annotations.AgoraRtmpStreamingState state: Int, @Annotations.AgoraRtmpStreamingErrorCode errCode: Int) { + override fun onRtmpStreamingStateChanged( + rtcChannel: RtcChannel?, + url: String?, + @Annotations.AgoraRtmpStreamingState state: Int, + @Annotations.AgoraRtmpStreamingErrorCode errCode: Int + ) { callback(RtcChannelEvents.RtmpStreamingStateChanged, rtcChannel, url, state, errCode) } @@ -187,23 +298,146 @@ class RtcChannelEventHandler( callback(RtcChannelEvents.TranscodingUpdated, rtcChannel) } - override fun onStreamInjectedStatus(rtcChannel: RtcChannel?, url: String?, uid: Int, @Annotations.AgoraInjectStreamStatus status: Int) { - callback(RtcChannelEvents.StreamInjectedStatus, rtcChannel, url, uid, status) + override fun onStreamInjectedStatus( + rtcChannel: RtcChannel?, + url: String?, + uid: Int, + @Annotations.AgoraInjectStreamStatus status: Int + ) { + callback(RtcChannelEvents.StreamInjectedStatus, rtcChannel, url, uid.toUInt().toLong(), status) } override fun onStreamMessage(rtcChannel: RtcChannel?, uid: Int, streamId: Int, data: ByteArray?) { - callback(RtcChannelEvents.StreamMessage, rtcChannel, uid, streamId, data?.let { String(it, Charsets.UTF_8) }) - } - - override fun onStreamMessageError(rtcChannel: RtcChannel?, uid: Int, streamId: Int, @Annotations.AgoraErrorCode error: Int, missed: Int, cached: Int) { - callback(RtcChannelEvents.StreamMessageError, rtcChannel, uid, streamId, error, missed, cached) - } - - override fun onChannelMediaRelayStateChanged(rtcChannel: RtcChannel?, @Annotations.AgoraChannelMediaRelayState state: Int, @Annotations.AgoraChannelMediaRelayError code: Int) { + callback( + RtcChannelEvents.StreamMessage, + rtcChannel, + uid.toUInt().toLong(), + streamId, + data?.let { String(it, Charsets.UTF_8) }) + } + + override fun onStreamMessageError( + rtcChannel: RtcChannel?, + uid: Int, + streamId: Int, + @Annotations.AgoraErrorCode error: Int, + missed: Int, + cached: Int + ) { + callback( + RtcChannelEvents.StreamMessageError, + rtcChannel, + uid.toUInt().toLong(), + streamId, + error, + missed, + cached + ) + } + + override fun onChannelMediaRelayStateChanged( + rtcChannel: RtcChannel?, + @Annotations.AgoraChannelMediaRelayState state: Int, + @Annotations.AgoraChannelMediaRelayError code: Int + ) { callback(RtcChannelEvents.ChannelMediaRelayStateChanged, rtcChannel, state, code) } - override fun onChannelMediaRelayEvent(rtcChannel: RtcChannel?, @Annotations.AgoraChannelMediaRelayEvent code: Int) { + override fun onChannelMediaRelayEvent( + rtcChannel: RtcChannel?, + @Annotations.AgoraChannelMediaRelayEvent code: Int + ) { callback(RtcChannelEvents.ChannelMediaRelayEvent, rtcChannel, code) } + + override fun onAudioPublishStateChanged( + rtcChannel: RtcChannel?, + @Annotations.AgoraStreamPublishState oldState: Int, + @Annotations.AgoraStreamPublishState newState: Int, + elapseSinceLastState: Int + ) { + callback( + RtcChannelEvents.AudioPublishStateChanged, + rtcChannel, + rtcChannel?.channelId(), + oldState, + newState, + elapseSinceLastState + ) + } + + override fun onVideoPublishStateChanged( + rtcChannel: RtcChannel?, + @Annotations.AgoraStreamPublishState oldState: Int, + @Annotations.AgoraStreamPublishState newState: Int, + elapseSinceLastState: Int + ) { + callback( + RtcChannelEvents.VideoPublishStateChanged, + rtcChannel, + rtcChannel?.channelId(), + oldState, + newState, + elapseSinceLastState + ) + } + + override fun onAudioSubscribeStateChanged( + rtcChannel: RtcChannel?, + uid: Int, + @Annotations.AgoraStreamSubscribeState oldState: Int, + @Annotations.AgoraStreamSubscribeState newState: Int, + elapseSinceLastState: Int + ) { + callback( + RtcChannelEvents.AudioSubscribeStateChanged, + rtcChannel, + rtcChannel?.channelId(), + uid.toUInt().toLong(), + oldState, + newState, + elapseSinceLastState + ) + } + + override fun onVideoSubscribeStateChanged( + rtcChannel: RtcChannel?, + uid: Int, + @Annotations.AgoraStreamSubscribeState oldState: Int, + @Annotations.AgoraStreamSubscribeState newState: Int, + elapseSinceLastState: Int + ) { + callback( + RtcChannelEvents.VideoSubscribeStateChanged, + rtcChannel, + rtcChannel?.channelId(), + uid.toUInt().toLong(), + oldState, + newState, + elapseSinceLastState + ) + } + + override fun onRtmpStreamingEvent( + rtcChannel: RtcChannel?, + url: String?, + @Annotations.AgoraRtmpStreamingEvent errCode: Int + ) { + callback(RtcChannelEvents.RtmpStreamingEvent, rtcChannel, url, errCode) + } + + override fun onUserSuperResolutionEnabled( + rtcChannel: RtcChannel?, + uid: Int, + enabled: Boolean, + @Annotations.AgoraSuperResolutionStateReason reason: Int + ) { + callback( + RtcChannelEvents.UserSuperResolutionEnabled, + rtcChannel, + uid.toUInt().toLong(), + enabled, + reason + ) + } } diff --git a/RtcEngine.kt b/RtcEngine.kt index 7d620e90c..f1b09ca2b 100644 --- a/RtcEngine.kt +++ b/RtcEngine.kt @@ -1,10 +1,8 @@ package io.agora.rtc.base import android.content.Context -import io.agora.rtc.Constants -import io.agora.rtc.IMetadataObserver -import io.agora.rtc.RtcEngine -import io.agora.rtc.RtcEngineEx +import io.agora.rtc.* +import io.agora.rtc.internal.EncryptionConfig import io.agora.rtc.models.UserInfo class IRtcEngine { @@ -36,21 +34,40 @@ class IRtcEngine { fun getConnectionState(callback: Callback) + fun sendCustomReportMessage(params: Map, callback: Callback) + fun getCallId(callback: Callback) fun rate(params: Map, callback: Callback) fun complain(params: Map, callback: Callback) + @Deprecated("") fun setLogFile(params: Map, callback: Callback) + @Deprecated("") fun setLogFilter(params: Map, callback: Callback) + @Deprecated("") fun setLogFileSize(params: Map, callback: Callback) fun setParameters(params: Map, callback: Callback) + fun getSdkVersion(callback: Callback) + + fun getErrorDescription(params: Map, callback: Callback) + fun getNativeHandle(callback: Callback) + + fun enableDeepLearningDenoise(params: Map, callback: Callback) + + fun setCloudProxy(params: Map, callback: Callback) + + fun uploadLogFile(callback: Callback) + + fun setLocalAccessPoint(params: Map, callback: Callback) + + fun enableVirtualBackground(params: Map, callback: Callback) } interface RtcUserInfoInterface { @@ -84,9 +101,16 @@ class IRtcEngine { fun muteAllRemoteAudioStreams(params: Map, callback: Callback) + @Deprecated("") fun setDefaultMuteAllRemoteAudioStreams(params: Map, callback: Callback) fun enableAudioVolumeIndication(params: Map, callback: Callback) + + fun startRhythmPlayer(params: Map, callback: Callback) + + fun stopRhythmPlayer(callback: Callback) + + fun configRhythmPlayer(params: Map, callback: Callback) } interface RtcVideoInterface { @@ -108,9 +132,12 @@ class IRtcEngine { fun muteAllRemoteVideoStreams(params: Map, callback: Callback) + @Deprecated("") fun setDefaultMuteAllRemoteVideoStreams(params: Map, callback: Callback) fun setBeautyEffectOptions(params: Map, callback: Callback) + + fun enableRemoteSuperResolution(params: Map, callback: Callback) } interface RtcAudioMixingInterface { @@ -132,7 +159,7 @@ class IRtcEngine { fun getAudioMixingPublishVolume(callback: Callback) - fun getAudioMixingDuration(callback: Callback) + fun getAudioMixingDuration(params: Map, callback: Callback) fun getAudioMixingCurrentPosition(callback: Callback) @@ -150,6 +177,12 @@ class IRtcEngine { fun playEffect(params: Map, callback: Callback) + fun setEffectPosition(params: Map, callback: Callback) + + fun getEffectDuration(params: Map, callback: Callback) + + fun getEffectCurrentPosition(params: Map, callback: Callback) + fun stopEffect(params: Map, callback: Callback) fun stopAllEffects(callback: Callback) @@ -170,8 +203,10 @@ class IRtcEngine { } interface RtcVoiceChangerInterface { + @Deprecated("") fun setLocalVoiceChanger(params: Map, callback: Callback) + @Deprecated("") fun setLocalVoiceReverbPreset(params: Map, callback: Callback) fun setLocalVoicePitch(params: Map, callback: Callback) @@ -179,6 +214,16 @@ class IRtcEngine { fun setLocalVoiceEqualization(params: Map, callback: Callback) fun setLocalVoiceReverb(params: Map, callback: Callback) + + fun setAudioEffectPreset(params: Map, callback: Callback) + + fun setVoiceBeautifierPreset(params: Map, callback: Callback) + + fun setVoiceConversionPreset(params: Map, callback: Callback) + + fun setAudioEffectParameters(params: Map, callback: Callback) + + fun setVoiceBeautifierParameters(params: Map, callback: Callback) } interface RtcVoicePositionInterface { @@ -201,6 +246,10 @@ class IRtcEngine { fun updateChannelMediaRelay(params: Map, callback: Callback) fun stopChannelMediaRelay(callback: Callback) + + fun pauseAllChannelMediaRelay(callback: Callback) + + fun resumeAllChannelMediaRelay(callback: Callback) } interface RtcAudioRouteInterface { @@ -264,9 +313,13 @@ class IRtcEngine { } interface RtcEncryptionInterface { + @Deprecated("") fun setEncryptionSecret(params: Map, callback: Callback) + @Deprecated("") fun setEncryptionMode(params: Map, callback: Callback) + + fun enableEncryption(params: Map, callback: Callback) } interface RtcAudioRecorderInterface { @@ -351,6 +404,10 @@ class RtcEngineManager( override fun setClientRole(params: Map, callback: Callback) { val role = (params["role"] as Number).toInt() + (params["options"] as? Map<*, *>)?.let { + callback.code(engine?.setClientRole(role, mapToClientRoleOptions(it))) + return@setClientRole + } callback.code(engine?.setClientRole(role)) } @@ -358,13 +415,29 @@ class RtcEngineManager( val token = params["token"] as? String val channelName = params["channelName"] as String val optionalInfo = params["optionalInfo"] as? String - val optionalUid = (params["optionalUid"] as Number).toInt() + val optionalUid = (params["optionalUid"] as Number).toNativeUInt() + (params["options"] as? Map<*, *>)?.let { + callback.code( + engine?.joinChannel( + token, + channelName, + optionalInfo, + optionalUid, + mapToChannelMediaOptions(it) + ) + ) + return@joinChannel + } callback.code(engine?.joinChannel(token, channelName, optionalInfo, optionalUid)) } override fun switchChannel(params: Map, callback: Callback) { val token = params["token"] as? String val channelName = params["channelName"] as String + (params["options"] as? Map<*, *>)?.let { + callback.code(engine?.switchChannel(token, channelName, mapToChannelMediaOptions(it))) + return@switchChannel + } callback.code(engine?.switchChannel(token, channelName)) } @@ -384,12 +457,30 @@ class RtcEngineManager( callback.resolve(engine) { it.connectionState } } + override fun sendCustomReportMessage(params: Map, callback: Callback) { + callback.code( + engine?.sendCustomReportMessage( + params["id"] as String, + params["category"] as String, + params["event"] as String, + params["label"] as String, + (params["value"] as Number).toInt() + ) + ) + } + override fun getCallId(callback: Callback) { callback.resolve(engine) { it.callId } } override fun rate(params: Map, callback: Callback) { - callback.code(engine?.rate(params["callId"] as String, (params["rating"] as Number).toInt(), params["description"] as? String)) + callback.code( + engine?.rate( + params["callId"] as String, + (params["rating"] as Number).toInt(), + params["description"] as? String + ) + ) } override fun complain(params: Map, callback: Callback) { @@ -412,18 +503,80 @@ class RtcEngineManager( callback.code(engine?.setParameters(params["parameters"] as String)) } + override fun getSdkVersion(callback: Callback) { + callback.success(RtcEngine.getSdkVersion()) + } + + override fun getErrorDescription(params: Map, callback: Callback) { + callback.success(RtcEngine.getErrorDescription((params["error"] as Number).toInt())) + } + override fun getNativeHandle(callback: Callback) { callback.resolve(engine) { it.nativeHandle } } + override fun enableDeepLearningDenoise(params: Map, callback: Callback) { + callback.code(engine?.enableDeepLearningDenoise(params["enabled"] as Boolean)) + } + + override fun setCloudProxy(params: Map, callback: Callback) { + callback.code(engine?.setCloudProxy((params["proxyType"] as Number).toInt())) + } + + override fun uploadLogFile(callback: Callback) { + callback.resolve(engine) { it.uploadLogFile() } + } + + override fun setLocalAccessPoint(params: Map, callback: Callback) { + callback.code( + engine?.setLocalAccessPoint( + arrayListOf().apply { + (params["ips"] as? List<*>)?.let { list -> + list.forEach { item -> + (item as? String)?.let { + add(it) + } + } + } + }, + params["domain"] as String + ) + ) + } + + override fun enableVirtualBackground(params: Map, callback: Callback) { + callback.code( + engine?.enableVirtualBackground( + params["enabled"] as Boolean, + mapToVirtualBackgroundSource(params["backgroundSource"] as Map<*, *>) + ) + ) + } + override fun registerLocalUserAccount(params: Map, callback: Callback) { - callback.code(engine?.registerLocalUserAccount(params["appId"] as String, params["userAccount"] as String)) + callback.code( + engine?.registerLocalUserAccount( + params["appId"] as String, + params["userAccount"] as String + ) + ) } override fun joinChannelWithUserAccount(params: Map, callback: Callback) { val token = params["token"] as? String val channelName = params["channelName"] as String val userAccount = params["userAccount"] as String + (params["options"] as? Map<*, *>)?.let { + callback.code( + engine?.joinChannelWithUserAccount( + token, + channelName, + userAccount, + mapToChannelMediaOptions(it) + ) + ) + return@joinChannelWithUserAccount + } callback.code(engine?.joinChannelWithUserAccount(token, channelName, userAccount)) } @@ -438,7 +591,7 @@ class RtcEngineManager( override fun getUserInfoByUid(params: Map, callback: Callback) { callback.resolve(engine) { val userInfo = UserInfo() - it.getUserInfoByUid((params["uid"] as Number).toInt(), userInfo) + it.getUserInfoByUid((params["uid"] as Number).toNativeUInt(), userInfo) userInfo.toMap() } } @@ -452,7 +605,12 @@ class RtcEngineManager( } override fun setAudioProfile(params: Map, callback: Callback) { - callback.code(engine?.setAudioProfile((params["profile"] as Number).toInt(), (params["scenario"] as Number).toInt())) + callback.code( + engine?.setAudioProfile( + (params["profile"] as Number).toInt(), + (params["scenario"] as Number).toInt() + ) + ) } override fun adjustRecordingSignalVolume(params: Map, callback: Callback) { @@ -460,7 +618,12 @@ class RtcEngineManager( } override fun adjustUserPlaybackSignalVolume(params: Map, callback: Callback) { - callback.code(engine?.adjustUserPlaybackSignalVolume((params["uid"] as Number).toInt(), (params["volume"] as Number).toInt())) + callback.code( + engine?.adjustUserPlaybackSignalVolume( + (params["uid"] as Number).toNativeUInt(), + (params["volume"] as Number).toInt() + ) + ) } override fun adjustPlaybackSignalVolume(params: Map, callback: Callback) { @@ -476,7 +639,12 @@ class RtcEngineManager( } override fun muteRemoteAudioStream(params: Map, callback: Callback) { - callback.code(engine?.muteRemoteAudioStream((params["uid"] as Number).toInt(), params["muted"] as Boolean)) + callback.code( + engine?.muteRemoteAudioStream( + (params["uid"] as Number).toNativeUInt(), + params["muted"] as Boolean + ) + ) } override fun muteAllRemoteAudioStreams(params: Map, callback: Callback) { @@ -488,7 +656,31 @@ class RtcEngineManager( } override fun enableAudioVolumeIndication(params: Map, callback: Callback) { - callback.code(engine?.enableAudioVolumeIndication((params["interval"] as Number).toInt(), (params["smooth"] as Number).toInt(), params["report_vad"] as Boolean)) + callback.code( + engine?.enableAudioVolumeIndication( + (params["interval"] as Number).toInt(), + (params["smooth"] as Number).toInt(), + params["report_vad"] as Boolean + ) + ) + } + + override fun startRhythmPlayer(params: Map, callback: Callback) { + callback.code( + engine?.audioEffectManager?.startRhythmPlayer( + params["sound1"] as String, + params["sound2"] as String, + mapToRhythmPlayerConfig(params["config"] as Map<*, *>) + ) + ) + } + + override fun stopRhythmPlayer(callback: Callback) { + callback.code(engine?.audioEffectManager?.stopRhythmPlayer()) + } + + override fun configRhythmPlayer(params: Map, callback: Callback) { + callback.code(engine?.audioEffectManager?.configRhythmPlayer(mapToRhythmPlayerConfig(params as Map<*, *>))) } override fun enableVideo(callback: Callback) { @@ -520,7 +712,12 @@ class RtcEngineManager( } override fun muteRemoteVideoStream(params: Map, callback: Callback) { - callback.code(engine?.muteRemoteVideoStream((params["uid"] as Number).toInt(), params["muted"] as Boolean)) + callback.code( + engine?.muteRemoteVideoStream( + (params["uid"] as Number).toNativeUInt(), + params["muted"] as Boolean + ) + ) } override fun muteAllRemoteVideoStreams(params: Map, callback: Callback) { @@ -532,11 +729,44 @@ class RtcEngineManager( } override fun setBeautyEffectOptions(params: Map, callback: Callback) { - callback.code(engine?.setBeautyEffectOptions(params["enabled"] as Boolean, mapToBeautyOptions(params["options"] as Map<*, *>))) + callback.code( + engine?.setBeautyEffectOptions( + params["enabled"] as Boolean, + mapToBeautyOptions(params["options"] as Map<*, *>) + ) + ) + } + + override fun enableRemoteSuperResolution(params: Map, callback: Callback) { + callback.code( + engine?.enableRemoteSuperResolution( + (params["uid"] as Number).toNativeUInt(), + params["enable"] as Boolean + ) + ) } override fun startAudioMixing(params: Map, callback: Callback) { - callback.code(engine?.startAudioMixing(params["filePath"] as String, params["loopback"] as Boolean, params["replace"] as Boolean, (params["cycle"] as Number).toInt())) + (params["startPos"] as? Number)?.let { startPos -> + callback.code( + engine?.startAudioMixing( + params["filePath"] as String, + params["loopback"] as Boolean, + params["replace"] as Boolean, + (params["cycle"] as Number).toInt(), + startPos.toInt() + ) + ) + return@startAudioMixing + } + callback.code( + engine?.startAudioMixing( + params["filePath"] as String, + params["loopback"] as Boolean, + params["replace"] as Boolean, + (params["cycle"] as Number).toInt() + ) + ) } override fun stopAudioMixing(callback: Callback) { @@ -571,7 +801,11 @@ class RtcEngineManager( callback.code(engine?.audioMixingPublishVolume) { it } } - override fun getAudioMixingDuration(callback: Callback) { + override fun getAudioMixingDuration(params: Map, callback: Callback) { + (params["filePath"] as? String)?.let { file -> + callback.code(engine?.getAudioMixingDuration(file)) { it } + return@getAudioMixingDuration + } callback.code(engine?.audioMixingDuration) { it } } @@ -596,11 +830,60 @@ class RtcEngineManager( } override fun setVolumeOfEffect(params: Map, callback: Callback) { - callback.code(engine?.audioEffectManager?.setVolumeOfEffect((params["soundId"] as Number).toInt(), (params["volume"] as Number).toDouble())) + callback.code( + engine?.audioEffectManager?.setVolumeOfEffect( + (params["soundId"] as Number).toInt(), + (params["volume"] as Number).toDouble() + ) + ) } override fun playEffect(params: Map, callback: Callback) { - callback.code(engine?.audioEffectManager?.playEffect((params["soundId"] as Number).toInt(), params["filePath"] as String, (params["loopCount"] as Number).toInt(), (params["pitch"] as Number).toDouble(), (params["pan"] as Number).toDouble(), (params["gain"] as Number).toDouble(), params["publish"] as Boolean)) + (params["startPos"] as? Number)?.let { startPos -> + callback.code( + engine?.audioEffectManager?.playEffect( + (params["soundId"] as Number).toInt(), + params["filePath"] as String, + (params["loopCount"] as Number).toInt(), + (params["pitch"] as Number).toDouble(), + (params["pan"] as Number).toDouble(), + (params["gain"] as Number).toDouble(), + params["publish"] as Boolean, + startPos.toInt() + ) + ) + return@playEffect + } + callback.code( + engine?.audioEffectManager?.playEffect( + (params["soundId"] as Number).toInt(), + params["filePath"] as String, + (params["loopCount"] as Number).toInt(), + (params["pitch"] as Number).toDouble(), + (params["pan"] as Number).toDouble(), + (params["gain"] as Number).toDouble(), + params["publish"] as Boolean + ) + ) + } + + override fun setEffectPosition(params: Map, callback: Callback) { + callback.code( + engine?.audioEffectManager?.setEffectPosition( + (params["soundId"] as Number).toInt(), + (params["pos"] as Number).toInt() + ) + ) + } + + override fun getEffectDuration(params: Map, callback: Callback) { + callback.code(engine?.audioEffectManager?.getEffectDuration(params["filePath"] as String)) { + it + } + } + + override fun getEffectCurrentPosition(params: Map, callback: Callback) { + callback.code(engine?.audioEffectManager?.getEffectCurrentPosition((params["soundId"] as Number).toInt())) { it } } override fun stopEffect(params: Map, callback: Callback) { @@ -612,7 +895,12 @@ class RtcEngineManager( } override fun preloadEffect(params: Map, callback: Callback) { - callback.code(engine?.audioEffectManager?.preloadEffect((params["soundId"] as Number).toInt(), params["filePath"] as String)) + callback.code( + engine?.audioEffectManager?.preloadEffect( + (params["soundId"] as Number).toInt(), + params["filePath"] as String + ) + ) } override fun unloadEffect(params: Map, callback: Callback) { @@ -652,11 +940,53 @@ class RtcEngineManager( } override fun setLocalVoiceEqualization(params: Map, callback: Callback) { - callback.code(engine?.setLocalVoiceEqualization((params["bandFrequency"] as Number).toInt(), (params["bandGain"] as Number).toInt())) + callback.code( + engine?.setLocalVoiceEqualization( + (params["bandFrequency"] as Number).toInt(), + (params["bandGain"] as Number).toInt() + ) + ) } override fun setLocalVoiceReverb(params: Map, callback: Callback) { - callback.code(engine?.setLocalVoiceReverb((params["reverbKey"] as Number).toInt(), (params["value"] as Number).toInt())) + callback.code( + engine?.setLocalVoiceReverb( + (params["reverbKey"] as Number).toInt(), + (params["value"] as Number).toInt() + ) + ) + } + + override fun setAudioEffectPreset(params: Map, callback: Callback) { + callback.code(engine?.setAudioEffectPreset((params["preset"] as Number).toInt())) + } + + override fun setVoiceBeautifierPreset(params: Map, callback: Callback) { + callback.code(engine?.setVoiceBeautifierPreset((params["preset"] as Number).toInt())) + } + + override fun setVoiceConversionPreset(params: Map, callback: Callback) { + callback.code(engine?.setVoiceConversionPreset((params["preset"] as Number).toInt())) + } + + override fun setAudioEffectParameters(params: Map, callback: Callback) { + callback.code( + engine?.setAudioEffectParameters( + (params["preset"] as Number).toInt(), + (params["param1"] as Number).toInt(), + (params["param2"] as Number).toInt() + ) + ) + } + + override fun setVoiceBeautifierParameters(params: Map, callback: Callback) { + callback.code( + engine?.setVoiceBeautifierParameters( + (params["preset"] as Number).toInt(), + (params["param1"] as Number).toInt(), + (params["param2"] as Number).toInt() + ) + ) } override fun enableSoundPositionIndication(params: Map, callback: Callback) { @@ -664,7 +994,13 @@ class RtcEngineManager( } override fun setRemoteVoicePosition(params: Map, callback: Callback) { - callback.code(engine?.setRemoteVoicePosition((params["uid"] as Number).toInt(), (params["pan"] as Number).toDouble(), (params["gain"] as Number).toDouble())) + callback.code( + engine?.setRemoteVoicePosition( + (params["uid"] as Number).toNativeUInt(), + (params["pan"] as Number).toDouble(), + (params["gain"] as Number).toDouble() + ) + ) } override fun setLiveTranscoding(params: Map, callback: Callback) { @@ -672,7 +1008,12 @@ class RtcEngineManager( } override fun addPublishStreamUrl(params: Map, callback: Callback) { - callback.code(engine?.addPublishStreamUrl(params["url"] as String, params["transcodingEnabled"] as Boolean)) + callback.code( + engine?.addPublishStreamUrl( + params["url"] as String, + params["transcodingEnabled"] as Boolean + ) + ) } override fun removePublishStreamUrl(params: Map, callback: Callback) { @@ -691,6 +1032,16 @@ class RtcEngineManager( callback.code(engine?.stopChannelMediaRelay()) } + override fun pauseAllChannelMediaRelay(callback: Callback) { + callback.code(-Constants.ERR_NOT_SUPPORTED) +// callback.code(engine?.pauseAllChannelMediaRelay()) + } + + override fun resumeAllChannelMediaRelay(callback: Callback) { + callback.code(-Constants.ERR_NOT_SUPPORTED) +// callback.code(engine?.resumeAllChannelMediaRelay()) + } + override fun setDefaultAudioRoutetoSpeakerphone(params: Map, callback: Callback) { callback.code(engine?.setDefaultAudioRoutetoSpeakerphone(params["defaultToSpeaker"] as Boolean)) } @@ -716,7 +1067,12 @@ class RtcEngineManager( } override fun setRemoteVideoStreamType(params: Map, callback: Callback) { - callback.code(engine?.setRemoteVideoStreamType((params["uid"] as Number).toInt(), (params["streamType"] as Number).toInt())) + callback.code( + engine?.setRemoteVideoStreamType( + (params["uid"] as Number).toNativeUInt(), + (params["streamType"] as Number).toInt() + ) + ) } override fun setRemoteDefaultVideoStreamType(params: Map, callback: Callback) { @@ -732,7 +1088,12 @@ class RtcEngineManager( } override fun setRemoteUserPriority(params: Map, callback: Callback) { - callback.code(engine?.setRemoteUserPriority((params["uid"] as Number).toInt(), (params["userPriority"] as Number).toInt())) + callback.code( + engine?.setRemoteUserPriority( + (params["uid"] as Number).toNativeUInt(), + (params["userPriority"] as Number).toInt() + ) + ) } override fun startEchoTest(params: Map, callback: Callback) { @@ -763,7 +1124,12 @@ class RtcEngineManager( val mediaObserver = MediaObserver { data -> emit(RtcEngineEvents.MetadataReceived, data) } - callback.code(engine?.registerMediaMetadataObserver(mediaObserver, IMetadataObserver.VIDEO_METADATA)) { + callback.code( + engine?.registerMediaMetadataObserver( + mediaObserver, + IMetadataObserver.VIDEO_METADATA + ) + ) { this.mediaObserver = mediaObserver Unit } @@ -790,7 +1156,12 @@ class RtcEngineManager( } override fun addVideoWatermark(params: Map, callback: Callback) { - callback.code(engine?.addVideoWatermark(params["watermarkUrl"] as String, mapToWatermarkOptions(params["options"] as Map<*, *>))) + callback.code( + engine?.addVideoWatermark( + params["watermarkUrl"] as String, + mapToWatermarkOptions(params["options"] as Map<*, *>) + ) + ) } override fun clearVideoWatermarks(callback: Callback) { @@ -802,11 +1173,39 @@ class RtcEngineManager( } override fun setEncryptionMode(params: Map, callback: Callback) { - callback.code(engine?.setEncryptionMode(params["encryptionMode"] as String)) + callback.code( + engine?.setEncryptionMode( + when ((params["encryptionMode"] as Number).toInt()) { + EncryptionConfig.EncryptionMode.AES_128_XTS.value -> "aes-128-xts" + EncryptionConfig.EncryptionMode.AES_128_ECB.value -> "aes-128-ecb" + EncryptionConfig.EncryptionMode.AES_256_XTS.value -> "aes-256-xts" + else -> "" + } + ) + ) + } + + override fun enableEncryption(params: Map, callback: Callback) { + callback.code( + engine?.enableEncryption( + params["enabled"] as Boolean, + mapToEncryptionConfig(params["config"] as Map<*, *>) + ) + ) } override fun startAudioRecording(params: Map, callback: Callback) { - callback.code(engine?.startAudioRecording(params["filePath"] as String, (params["sampleRate"] as Number).toInt(), (params["quality"] as Number).toInt())) + (params["config"] as? Map<*, *>)?.let { + callback.code(engine?.startAudioRecording(mapToAudioRecordingConfiguration(it))) + return@startAudioRecording + } + callback.code( + engine?.startAudioRecording( + params["filePath"] as String, + (params["sampleRate"] as Number).toInt(), + (params["quality"] as Number).toInt() + ) + ) } override fun stopAudioRecording(callback: Callback) { @@ -814,7 +1213,12 @@ class RtcEngineManager( } override fun addInjectStreamUrl(params: Map, callback: Callback) { - callback.code(engine?.addInjectStreamUrl(params["url"] as String, mapToLiveInjectStreamConfig(params["config"] as Map<*, *>))) + callback.code( + engine?.addInjectStreamUrl( + params["url"] as String, + mapToLiveInjectStreamConfig(params["config"] as Map<*, *>) + ) + ) } override fun removeInjectStreamUrl(params: Map, callback: Callback) { @@ -854,11 +1258,21 @@ class RtcEngineManager( } override fun setCameraFocusPositionInPreview(params: Map, callback: Callback) { - callback.code(engine?.setCameraFocusPositionInPreview((params["positionX"] as Number).toFloat(), (params["positionY"] as Number).toFloat())) + callback.code( + engine?.setCameraFocusPositionInPreview( + (params["positionX"] as Number).toFloat(), + (params["positionY"] as Number).toFloat() + ) + ) } override fun setCameraExposurePosition(params: Map, callback: Callback) { - callback.code(engine?.setCameraExposurePosition((params["positionXinView"] as Number).toFloat(), (params["positionYinView"] as Number).toFloat())) + callback.code( + engine?.setCameraExposurePosition( + (params["positionXinView"] as Number).toFloat(), + (params["positionYinView"] as Number).toFloat() + ) + ) } override fun enableFaceDetection(params: Map, callback: Callback) { @@ -878,10 +1292,24 @@ class RtcEngineManager( } override fun createDataStream(params: Map, callback: Callback) { - callback.code(engine?.createDataStream(params["reliable"] as Boolean, params["ordered"] as Boolean)) { it } + (params["config"] as? Map<*, *>)?.let { config -> + callback.code(engine?.createDataStream(mapToDataStreamConfig(config))) { it } + return@createDataStream + } + callback.code( + engine?.createDataStream( + params["reliable"] as Boolean, + params["ordered"] as Boolean + ) + ) { it } } override fun sendStreamMessage(params: Map, callback: Callback) { - callback.code(engine?.sendStreamMessage((params["streamId"] as Number).toInt(), (params["message"] as String).toByteArray())) + callback.code( + engine?.sendStreamMessage( + (params["streamId"] as Number).toInt(), + (params["message"] as String).toByteArray() + ) + ) } } diff --git a/RtcEngineEvent.kt b/RtcEngineEvent.kt index 8c689e286..d6df22bd0 100644 --- a/RtcEngineEvent.kt +++ b/RtcEngineEvent.kt @@ -77,6 +77,16 @@ class RtcEngineEvents { const val CameraReady = "CameraReady" const val VideoStopped = "VideoStopped" const val MetadataReceived = "MetadataReceived" + const val FirstLocalAudioFramePublished = "FirstLocalAudioFramePublished" + const val FirstLocalVideoFramePublished = "FirstLocalVideoFramePublished" + const val AudioPublishStateChanged = "AudioPublishStateChanged" + const val VideoPublishStateChanged = "VideoPublishStateChanged" + const val AudioSubscribeStateChanged = "AudioSubscribeStateChanged" + const val VideoSubscribeStateChanged = "VideoSubscribeStateChanged" + const val RtmpStreamingEvent = "RtmpStreamingEvent" + const val UserSuperResolutionEnabled = "UserSuperResolutionEnabled" + const val UploadLogResult = "UploadLogResult" + const val VirtualBackgroundSourceEnabled = "VirtualBackgroundSourceEnabled" fun toMap(): Map { return hashMapOf( @@ -149,7 +159,17 @@ class RtcEngineEvents { "AudioQuality" to AudioQuality, "CameraReady" to CameraReady, "VideoStopped" to VideoStopped, - "MetadataReceived" to MetadataReceived + "MetadataReceived" to MetadataReceived, + "FirstLocalAudioFramePublished" to FirstLocalAudioFramePublished, + "FirstLocalVideoFramePublished" to FirstLocalVideoFramePublished, + "AudioPublishStateChanged" to AudioPublishStateChanged, + "VideoPublishStateChanged" to VideoPublishStateChanged, + "AudioSubscribeStateChanged" to AudioSubscribeStateChanged, + "VideoSubscribeStateChanged" to VideoSubscribeStateChanged, + "RtmpStreamingEvent" to RtmpStreamingEvent, + "UserSuperResolutionEnabled" to UserSuperResolutionEnabled, + "UploadLogResult" to UploadLogResult, + "VirtualBackgroundSourceEnabled" to VirtualBackgroundSourceEnabled ) } } @@ -174,16 +194,20 @@ class RtcEngineEventHandler( callback(RtcEngineEvents.Error, err) } - override fun onApiCallExecuted(@Annotations.AgoraErrorCode error: Int, api: String?, result: String?) { + override fun onApiCallExecuted( + @Annotations.AgoraErrorCode error: Int, + api: String?, + result: String? + ) { callback(RtcEngineEvents.ApiCallExecuted, error, api, result) } override fun onJoinChannelSuccess(channel: String?, uid: Int, elapsed: Int) { - callback(RtcEngineEvents.JoinChannelSuccess, channel, uid, elapsed) + callback(RtcEngineEvents.JoinChannelSuccess, channel, uid.toUInt().toLong(), elapsed) } override fun onRejoinChannelSuccess(channel: String?, uid: Int, elapsed: Int) { - callback(RtcEngineEvents.RejoinChannelSuccess, channel, uid, elapsed) + callback(RtcEngineEvents.RejoinChannelSuccess, channel, uid.toUInt().toLong(), elapsed) } override fun onLeaveChannel(stats: RtcStats?) { @@ -191,26 +215,32 @@ class RtcEngineEventHandler( } override fun onLocalUserRegistered(uid: Int, userAccount: String?) { - callback(RtcEngineEvents.LocalUserRegistered, uid, userAccount) + callback(RtcEngineEvents.LocalUserRegistered, uid.toUInt().toLong(), userAccount) } override fun onUserInfoUpdated(uid: Int, userInfo: UserInfo?) { - callback(RtcEngineEvents.UserInfoUpdated, uid, userInfo?.toMap()) + callback(RtcEngineEvents.UserInfoUpdated, uid.toUInt().toLong(), userInfo?.toMap()) } - override fun onClientRoleChanged(@Annotations.AgoraClientRole oldRole: Int, @Annotations.AgoraClientRole newRole: Int) { + override fun onClientRoleChanged( + @Annotations.AgoraClientRole oldRole: Int, + @Annotations.AgoraClientRole newRole: Int + ) { callback(RtcEngineEvents.ClientRoleChanged, oldRole, newRole) } override fun onUserJoined(uid: Int, elapsed: Int) { - callback(RtcEngineEvents.UserJoined, uid, elapsed) + callback(RtcEngineEvents.UserJoined, uid.toUInt().toLong(), elapsed) } override fun onUserOffline(uid: Int, @Annotations.AgoraUserOfflineReason reason: Int) { - callback(RtcEngineEvents.UserOffline, uid, reason) + callback(RtcEngineEvents.UserOffline, uid.toUInt().toLong(), reason) } - override fun onConnectionStateChanged(@Annotations.AgoraConnectionStateType state: Int, @Annotations.AgoraConnectionChangedReason reason: Int) { + override fun onConnectionStateChanged( + @Annotations.AgoraConnectionStateType state: Int, + @Annotations.AgoraConnectionChangedReason reason: Int + ) { callback(RtcEngineEvents.ConnectionStateChanged, state, reason) } @@ -230,12 +260,15 @@ class RtcEngineEventHandler( callback(RtcEngineEvents.RequestToken) } - override fun onAudioVolumeIndication(speakers: Array?, @IntRange(from = 0, to = 255) totalVolume: Int) { + override fun onAudioVolumeIndication( + speakers: Array?, + @IntRange(from = 0, to = 255) totalVolume: Int + ) { callback(RtcEngineEvents.AudioVolumeIndication, speakers?.toMapList(), totalVolume) } override fun onActiveSpeaker(uid: Int) { - callback(RtcEngineEvents.ActiveSpeaker, uid) + callback(RtcEngineEvents.ActiveSpeaker, uid.toUInt().toLong()) } override fun onFirstLocalAudioFrame(elapsed: Int) { @@ -248,26 +281,47 @@ class RtcEngineEventHandler( @Deprecated("", ReplaceWith("onRemoteVideoStateChanged")) override fun onUserMuteVideo(uid: Int, muted: Boolean) { - callback(RtcEngineEvents.UserMuteVideo, uid, muted) + callback(RtcEngineEvents.UserMuteVideo, uid.toUInt().toLong(), muted) } - override fun onVideoSizeChanged(uid: Int, width: Int, height: Int, @IntRange(from = 0, to = 360) rotation: Int) { - callback(RtcEngineEvents.VideoSizeChanged, uid, width, height, rotation) + override fun onVideoSizeChanged( + uid: Int, + width: Int, + height: Int, + @IntRange(from = 0, to = 360) rotation: Int + ) { + callback(RtcEngineEvents.VideoSizeChanged, uid.toUInt().toLong(), width, height, rotation) } - override fun onRemoteVideoStateChanged(uid: Int, @Annotations.AgoraVideoRemoteState state: Int, @Annotations.AgoraVideoRemoteStateReason reason: Int, elapsed: Int) { - callback(RtcEngineEvents.RemoteVideoStateChanged, uid, state, reason, elapsed) + override fun onRemoteVideoStateChanged( + uid: Int, + @Annotations.AgoraVideoRemoteState state: Int, + @Annotations.AgoraVideoRemoteStateReason reason: Int, + elapsed: Int + ) { + callback(RtcEngineEvents.RemoteVideoStateChanged, uid.toUInt().toLong(), state, reason, elapsed) } - override fun onLocalVideoStateChanged(@Annotations.AgoraLocalVideoStreamState localVideoState: Int, @Annotations.AgoraLocalVideoStreamError error: Int) { + override fun onLocalVideoStateChanged( + @Annotations.AgoraLocalVideoStreamState localVideoState: Int, + @Annotations.AgoraLocalVideoStreamError error: Int + ) { callback(RtcEngineEvents.LocalVideoStateChanged, localVideoState, error) } - override fun onRemoteAudioStateChanged(uid: Int, @Annotations.AgoraAudioRemoteState state: Int, @Annotations.AgoraAudioRemoteStateReason reason: Int, elapsed: Int) { - callback(RtcEngineEvents.RemoteAudioStateChanged, uid, state, reason, elapsed) + override fun onRemoteAudioStateChanged( + uid: Int, + @Annotations.AgoraAudioRemoteState state: Int, + @Annotations.AgoraAudioRemoteStateReason reason: Int, + elapsed: Int + ) { + callback(RtcEngineEvents.RemoteAudioStateChanged, uid.toUInt().toLong(), state, reason, elapsed) } - override fun onLocalAudioStateChanged(@Annotations.AgoraAudioLocalState state: Int, @Annotations.AgoraAudioLocalError error: Int) { + override fun onLocalAudioStateChanged( + @Annotations.AgoraAudioLocalState state: Int, + @Annotations.AgoraAudioLocalError error: Int + ) { callback(RtcEngineEvents.LocalAudioStateChanged, state, error) } @@ -276,7 +330,11 @@ class RtcEngineEventHandler( } override fun onRemoteSubscribeFallbackToAudioOnly(uid: Int, isFallbackOrRecover: Boolean) { - callback(RtcEngineEvents.RemoteSubscribeFallbackToAudioOnly, uid, isFallbackOrRecover) + callback( + RtcEngineEvents.RemoteSubscribeFallbackToAudioOnly, + uid.toUInt().toLong(), + isFallbackOrRecover + ) } override fun onAudioRouteChanged(@Annotations.AgoraAudioOutputRouting routing: Int) { @@ -291,7 +349,11 @@ class RtcEngineEventHandler( callback(RtcEngineEvents.CameraExposureAreaChanged, rect?.toMap()) } - override fun onFacePositionChanged(imageWidth: Int, imageHeight: Int, faces: Array?) { + override fun onFacePositionChanged( + imageWidth: Int, + imageHeight: Int, + faces: Array? + ) { callback(RtcEngineEvents.FacePositionChanged, imageWidth, imageHeight, faces?.toMapList()) } @@ -303,8 +365,12 @@ class RtcEngineEventHandler( callback(RtcEngineEvents.LastmileQuality, quality) } - override fun onNetworkQuality(uid: Int, @Annotations.AgoraNetworkQuality txQuality: Int, @Annotations.AgoraNetworkQuality rxQuality: Int) { - callback(RtcEngineEvents.NetworkQuality, uid, txQuality, rxQuality) + override fun onNetworkQuality( + uid: Int, + @Annotations.AgoraNetworkQuality txQuality: Int, + @Annotations.AgoraNetworkQuality rxQuality: Int + ) { + callback(RtcEngineEvents.NetworkQuality, uid.toUInt().toLong(), txQuality, rxQuality) } override fun onLastmileProbeResult(result: LastmileProbeResult?) { @@ -325,7 +391,12 @@ class RtcEngineEventHandler( } @Deprecated("", ReplaceWith("onRemoteVideoStats")) - override fun onRemoteVideoStat(uid: Int, delay: Int, receivedBitrate: Int, receivedFrameRate: Int) { + override fun onRemoteVideoStat( + uid: Int, + delay: Int, + receivedBitrate: Int, + receivedFrameRate: Int + ) { // TODO Not in iOS } @@ -342,15 +413,22 @@ class RtcEngineEventHandler( callback(RtcEngineEvents.AudioMixingFinished) } - override fun onAudioMixingStateChanged(@Annotations.AgoraAudioMixingStateCode state: Int, @Annotations.AgoraAudioMixingErrorCode errorCode: Int) { - callback(RtcEngineEvents.AudioMixingStateChanged, state, errorCode) + override fun onAudioMixingStateChanged( + @Annotations.AgoraAudioMixingStateCode state: Int, + @Annotations.AgoraAudioMixingReason reason: Int + ) { + callback(RtcEngineEvents.AudioMixingStateChanged, state, reason) } override fun onAudioEffectFinished(soundId: Int) { callback(RtcEngineEvents.AudioEffectFinished, soundId) } - override fun onRtmpStreamingStateChanged(url: String?, @Annotations.AgoraRtmpStreamingState state: Int, @Annotations.AgoraRtmpStreamingErrorCode errCode: Int) { + override fun onRtmpStreamingStateChanged( + url: String?, + @Annotations.AgoraRtmpStreamingState state: Int, + @Annotations.AgoraRtmpStreamingErrorCode errCode: Int + ) { callback(RtcEngineEvents.RtmpStreamingStateChanged, url, state, errCode) } @@ -358,16 +436,37 @@ class RtcEngineEventHandler( callback(RtcEngineEvents.TranscodingUpdated) } - override fun onStreamInjectedStatus(url: String?, uid: Int, @Annotations.AgoraInjectStreamStatus status: Int) { - callback(RtcEngineEvents.StreamInjectedStatus, url, uid, status) + override fun onStreamInjectedStatus( + url: String?, + uid: Int, + @Annotations.AgoraInjectStreamStatus status: Int + ) { + callback(RtcEngineEvents.StreamInjectedStatus, url, uid.toUInt().toLong(), status) } override fun onStreamMessage(uid: Int, streamId: Int, data: ByteArray?) { - callback(RtcEngineEvents.StreamMessage, uid, streamId, data?.let { String(it, Charsets.UTF_8) }) - } - - override fun onStreamMessageError(uid: Int, streamId: Int, @Annotations.AgoraErrorCode error: Int, missed: Int, cached: Int) { - callback(RtcEngineEvents.StreamMessageError, uid, streamId, error, missed, cached) + callback( + RtcEngineEvents.StreamMessage, + uid.toUInt().toLong(), + streamId, + data?.let { String(it, Charsets.UTF_8) }) + } + + override fun onStreamMessageError( + uid: Int, + streamId: Int, + @Annotations.AgoraErrorCode error: Int, + missed: Int, + cached: Int + ) { + callback( + RtcEngineEvents.StreamMessageError, + uid.toUInt().toLong(), + streamId, + error, + missed, + cached + ) } override fun onMediaEngineLoadSuccess() { @@ -378,7 +477,10 @@ class RtcEngineEventHandler( callback(RtcEngineEvents.MediaEngineStartCallSuccess) } - override fun onChannelMediaRelayStateChanged(@Annotations.AgoraChannelMediaRelayState state: Int, @Annotations.AgoraChannelMediaRelayError code: Int) { + override fun onChannelMediaRelayStateChanged( + @Annotations.AgoraChannelMediaRelayState state: Int, + @Annotations.AgoraChannelMediaRelayError code: Int + ) { callback(RtcEngineEvents.ChannelMediaRelayStateChanged, state, code) } @@ -388,22 +490,22 @@ class RtcEngineEventHandler( @Deprecated("", ReplaceWith("onRemoteVideoStateChanged")) override fun onFirstRemoteVideoFrame(uid: Int, width: Int, height: Int, elapsed: Int) { - callback(RtcEngineEvents.FirstRemoteVideoFrame, uid, width, height, elapsed) + callback(RtcEngineEvents.FirstRemoteVideoFrame, uid.toUInt().toLong(), width, height, elapsed) } @Deprecated("", ReplaceWith("onRemoteAudioStateChanged")) override fun onFirstRemoteAudioFrame(uid: Int, elapsed: Int) { - callback(RtcEngineEvents.FirstRemoteAudioFrame, uid, elapsed) + callback(RtcEngineEvents.FirstRemoteAudioFrame, uid.toUInt().toLong(), elapsed) } @Deprecated("", ReplaceWith("onRemoteAudioStateChanged")) override fun onFirstRemoteAudioDecoded(uid: Int, elapsed: Int) { - callback(RtcEngineEvents.FirstRemoteAudioDecoded, uid, elapsed) + callback(RtcEngineEvents.FirstRemoteAudioDecoded, uid.toUInt().toLong(), elapsed) } @Deprecated("", ReplaceWith("onRemoteAudioStateChanged")) override fun onUserMuteAudio(uid: Int, muted: Boolean) { - callback(RtcEngineEvents.UserMuteAudio, uid, muted) + callback(RtcEngineEvents.UserMuteAudio, uid.toUInt().toLong(), muted) } @Deprecated("", ReplaceWith("onRtmpStreamingStateChanged")) @@ -418,27 +520,39 @@ class RtcEngineEventHandler( @Deprecated("", ReplaceWith("onRemoteAudioStats")) override fun onRemoteAudioTransportStats(uid: Int, delay: Int, lost: Int, rxKBitRate: Int) { - callback(RtcEngineEvents.RemoteAudioTransportStats, uid, delay, lost, rxKBitRate) + callback( + RtcEngineEvents.RemoteAudioTransportStats, + uid.toUInt().toLong(), + delay, + lost, + rxKBitRate + ) } @Deprecated("", ReplaceWith("onRemoteVideoStats")) override fun onRemoteVideoTransportStats(uid: Int, delay: Int, lost: Int, rxKBitRate: Int) { - callback(RtcEngineEvents.RemoteVideoTransportStats, uid, delay, lost, rxKBitRate) + callback( + RtcEngineEvents.RemoteVideoTransportStats, + uid.toUInt().toLong(), + delay, + lost, + rxKBitRate + ) } @Deprecated("", ReplaceWith("onRemoteVideoStateChanged")) override fun onUserEnableVideo(uid: Int, enabled: Boolean) { - callback(RtcEngineEvents.UserEnableVideo, uid, enabled) + callback(RtcEngineEvents.UserEnableVideo, uid.toUInt().toLong(), enabled) } @Deprecated("", ReplaceWith("onRemoteVideoStateChanged")) override fun onUserEnableLocalVideo(uid: Int, enabled: Boolean) { - callback(RtcEngineEvents.UserEnableLocalVideo, uid, enabled) + callback(RtcEngineEvents.UserEnableLocalVideo, uid.toUInt().toLong(), enabled) } @Deprecated("", ReplaceWith("onRemoteVideoStateChanged")) override fun onFirstRemoteVideoDecoded(uid: Int, width: Int, height: Int, elapsed: Int) { - callback(RtcEngineEvents.FirstRemoteVideoDecoded, uid, width, height, elapsed) + callback(RtcEngineEvents.FirstRemoteVideoDecoded, uid.toUInt().toLong(), width, height, elapsed) } @Deprecated("", ReplaceWith("onLocalAudioStateChanged")) @@ -457,8 +571,13 @@ class RtcEngineEventHandler( } @Deprecated("", ReplaceWith("onRemoteAudioStats")) - override fun onAudioQuality(uid: Int, @Annotations.AgoraNetworkQuality quality: Int, delay: Short, lost: Short) { - callback(RtcEngineEvents.AudioQuality, uid, quality, delay, lost) + override fun onAudioQuality( + uid: Int, + @Annotations.AgoraNetworkQuality quality: Int, + delay: Short, + lost: Short + ) { + callback(RtcEngineEvents.AudioQuality, uid.toUInt().toLong(), quality, delay, lost) } @Deprecated("", ReplaceWith("onLocalVideoStateChanged")) @@ -470,4 +589,103 @@ class RtcEngineEventHandler( override fun onVideoStopped() { callback(RtcEngineEvents.VideoStopped) } + + override fun onFirstLocalAudioFramePublished(elapsed: Int) { + callback(RtcEngineEvents.FirstLocalAudioFramePublished, elapsed) + } + + override fun onFirstLocalVideoFramePublished(elapsed: Int) { + callback(RtcEngineEvents.FirstLocalVideoFramePublished, elapsed) + } + + override fun onAudioPublishStateChanged( + channel: String?, + @Annotations.AgoraStreamPublishState oldState: Int, + @Annotations.AgoraStreamPublishState newState: Int, + elapseSinceLastState: Int + ) { + callback( + RtcEngineEvents.AudioPublishStateChanged, + channel, + oldState, + newState, + elapseSinceLastState + ) + } + + override fun onVideoPublishStateChanged( + channel: String?, + @Annotations.AgoraStreamPublishState oldState: Int, + @Annotations.AgoraStreamPublishState newState: Int, + elapseSinceLastState: Int + ) { + callback( + RtcEngineEvents.VideoPublishStateChanged, + channel, + oldState, + newState, + elapseSinceLastState + ) + } + + override fun onAudioSubscribeStateChanged( + channel: String?, + uid: Int, + @Annotations.AgoraStreamSubscribeState oldState: Int, + @Annotations.AgoraStreamSubscribeState newState: Int, + elapseSinceLastState: Int + ) { + callback( + RtcEngineEvents.AudioSubscribeStateChanged, + channel, + uid.toUInt().toLong(), + oldState, + newState, + elapseSinceLastState + ) + } + + override fun onVideoSubscribeStateChanged( + channel: String?, + uid: Int, + @Annotations.AgoraStreamSubscribeState oldState: Int, + @Annotations.AgoraStreamSubscribeState newState: Int, + elapseSinceLastState: Int + ) { + callback( + RtcEngineEvents.VideoSubscribeStateChanged, + channel, + uid.toUInt().toLong(), + oldState, + newState, + elapseSinceLastState + ) + } + + override fun onRtmpStreamingEvent(url: String?, @Annotations.AgoraRtmpStreamingEvent error: Int) { + callback(RtcEngineEvents.RtmpStreamingEvent, url, error) + } + + override fun onUserSuperResolutionEnabled( + uid: Int, + enabled: Boolean, + @Annotations.AgoraSuperResolutionStateReason reason: Int + ) { + callback(RtcEngineEvents.UserSuperResolutionEnabled, uid.toUInt().toLong(), enabled, reason) + } + + override fun onUploadLogResult( + requestId: String?, + success: Boolean, + @Annotations.AgoraUploadErrorReason reason: Int + ) { + callback(RtcEngineEvents.UploadLogResult, requestId, success, reason) + } + + override fun onVirtualBackgroundSourceEnabled( + enabled: Boolean, + @Annotations.AgoraVirtualBackgroundSourceStateReason reason: Int + ) { + callback(RtcEngineEvents.VirtualBackgroundSourceEnabled, enabled, reason) + } } diff --git a/RtcSurfaceView.kt b/RtcSurfaceView.kt index 536f7ddaf..ff31727f6 100644 --- a/RtcSurfaceView.kt +++ b/RtcSurfaceView.kt @@ -49,15 +49,16 @@ class RtcSurfaceView( } } - fun setData(engine: RtcEngine, channel: RtcChannel?, uid: Int) { + fun setData(engine: RtcEngine, channel: RtcChannel?, uid: Number) { this.channel = if (channel != null) WeakReference(channel) else null canvas.channelId = this.channel?.get()?.channelId() - canvas.uid = uid + canvas.uid = uid.toNativeUInt() setupVideoCanvas(engine) } fun resetVideoCanvas(engine: RtcEngine) { - val canvas = VideoCanvas(null, canvas.renderMode, canvas.channelId, canvas.uid, canvas.mirrorMode) + val canvas = + VideoCanvas(null, canvas.renderMode, canvas.channelId, canvas.uid, canvas.mirrorMode) if (canvas.uid == 0) { engine.setupLocalVideo(canvas) } else { diff --git a/RtcTextureView.kt b/RtcTextureView.kt index bd8570201..795f7af44 100644 --- a/RtcTextureView.kt +++ b/RtcTextureView.kt @@ -1,59 +1,79 @@ package io.agora.rtc.base import android.content.Context +import android.view.TextureView import android.widget.FrameLayout import io.agora.rtc.RtcChannel import io.agora.rtc.RtcEngine -import io.agora.rtc.mediaio.AgoraTextureView -import io.agora.rtc.mediaio.MediaIO +import io.agora.rtc.video.VideoCanvas import java.lang.ref.WeakReference class RtcTextureView( context: Context ) : FrameLayout(context) { - private var texture: AgoraTextureView = AgoraTextureView(context) - private var uid: Int = 0 + private var texture: TextureView + private var canvas: VideoCanvas private var channel: WeakReference? = null init { - texture.init(null) - texture.setBufferType(MediaIO.BufferType.BYTE_ARRAY) - texture.setPixelFormat(MediaIO.PixelFormat.I420) + try { + texture = RtcEngine.CreateTextureView(context) + } catch (e: UnsatisfiedLinkError) { + throw RuntimeException("Please init RtcEngine first!") + } + canvas = VideoCanvas(texture) addView(texture) } - fun setData(engine: RtcEngine, channel: RtcChannel?, uid: Int) { + fun setData(engine: RtcEngine, channel: RtcChannel?, uid: Number) { this.channel = if (channel != null) WeakReference(channel) else null - this.uid = uid - setupVideoRenderer(engine) + canvas.channelId = this.channel?.get()?.channelId() + canvas.uid = uid.toNativeUInt() + setupVideoCanvas(engine) } - fun setMirror(engine: RtcEngine, mirror: Boolean) { - texture.setMirror(mirror) - setupVideoRenderer(engine) + fun resetVideoCanvas(engine: RtcEngine) { + val canvas = + VideoCanvas(null, canvas.renderMode, canvas.channelId, canvas.uid, canvas.mirrorMode) + if (canvas.uid == 0) { + engine.setupLocalVideo(canvas) + } else { + engine.setupRemoteVideo(canvas) + } } - fun resetVideoRender(engine: RtcEngine) { - if (uid == 0) { - engine.setLocalVideoRenderer(null) + private fun setupVideoCanvas(engine: RtcEngine) { + removeAllViews() + texture = RtcEngine.CreateTextureView(context.applicationContext) + addView(texture) + texture.layout(0, 0, width, height) + canvas.view = texture + if (canvas.uid == 0) { + engine.setupLocalVideo(canvas) } else { - channel?.get()?.let { - it.setRemoteVideoRenderer(uid, null) - return@resetVideoRender - } - engine.setRemoteVideoRenderer(uid, null) + engine.setupRemoteVideo(canvas) } } - private fun setupVideoRenderer(engine: RtcEngine) { - if (uid == 0) { - engine.setLocalVideoRenderer(texture) + 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) } else { channel?.get()?.let { - it.setRemoteVideoRenderer(uid, texture) - return@setupVideoRenderer + it.setRemoteRenderMode(canvas.uid, canvas.renderMode, canvas.mirrorMode) + return@setupRenderMode } - engine.setRemoteVideoRenderer(uid, texture) + engine.setRemoteRenderMode(canvas.uid, canvas.renderMode, canvas.mirrorMode) } }