新增TRTC语音SDK类型
This commit is contained in:
@@ -105,6 +105,8 @@ dependencies {
|
||||
api project(':nim_uikit')
|
||||
api project(':library')
|
||||
api project(':agora-ktv-kit-release')
|
||||
api 'com.tencent.liteav:LiteAVSDK_TRTC:latest.release'
|
||||
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@@ -3,6 +3,7 @@ package com.yizhuan.xchat_android_core.manager;
|
||||
|
||||
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||
import com.yizhuan.xchat_android_core.manager.agora.RtcEngineManager;
|
||||
import com.yizhuan.xchat_android_core.manager.trtc.TRtcEngineManager;
|
||||
import com.yizhuan.xchat_android_core.manager.wj.WJAudioConstant;
|
||||
import com.yizhuan.xchat_android_core.manager.wj.WJAudioEngineManager;
|
||||
import com.yizhuan.xchat_android_core.manager.zego.ZegoEngineManager;
|
||||
@@ -42,6 +43,9 @@ public class AudioEngineManager {
|
||||
case TYPE_ZEGO:
|
||||
this.iAudioEngine = ZegoEngineManager.get();
|
||||
break;
|
||||
case TYPE_TRTC:
|
||||
this.iAudioEngine = TRtcEngineManager.get();
|
||||
break;
|
||||
case TYPE_AGORA:
|
||||
default:
|
||||
this.iAudioEngine = RtcEngineManager.get();
|
||||
@@ -64,7 +68,9 @@ public class AudioEngineManager {
|
||||
case RoomAudioSdkType.ZEGO:
|
||||
initRtcEngine(EngineType.TYPE_ZEGO);
|
||||
break;
|
||||
|
||||
case RoomAudioSdkType.TRTC:
|
||||
initRtcEngine(EngineType.TYPE_TRTC);
|
||||
break;
|
||||
default:
|
||||
initRtcEngine(EngineType.TYPE_AGORA);
|
||||
break;
|
||||
|
@@ -6,4 +6,5 @@ public enum EngineType {
|
||||
TYPE_WJ,
|
||||
TYPE_QTT_AUDIO,
|
||||
TYPE_ZEGO,
|
||||
TYPE_TRTC,
|
||||
}
|
||||
|
@@ -0,0 +1,896 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import com.tencent.rtmp.ui.TXCloudVideoView;
|
||||
import com.tencent.trtc.TRTCCloud;
|
||||
import com.tencent.trtc.TRTCCloudDef;
|
||||
|
||||
import io.agora.rtc.IAudioEffectManager;
|
||||
import io.agora.rtc.IAudioFrameObserver;
|
||||
import io.agora.rtc.IMetadataObserver;
|
||||
import io.agora.rtc.IRtcEngineEventHandler;
|
||||
import io.agora.rtc.internal.LastmileProbeConfig;
|
||||
import io.agora.rtc.live.LiveInjectStreamConfig;
|
||||
import io.agora.rtc.live.LiveTranscoding;
|
||||
import io.agora.rtc.mediaio.IVideoSink;
|
||||
import io.agora.rtc.mediaio.IVideoSource;
|
||||
import io.agora.rtc.models.UserInfo;
|
||||
import io.agora.rtc.video.AgoraImage;
|
||||
import io.agora.rtc.video.AgoraVideoFrame;
|
||||
import io.agora.rtc.video.BeautyOptions;
|
||||
import io.agora.rtc.video.CameraCapturerConfiguration;
|
||||
import io.agora.rtc.video.ChannelMediaRelayConfiguration;
|
||||
import io.agora.rtc.video.VideoCanvas;
|
||||
import io.agora.rtc.video.VideoEncoderConfiguration;
|
||||
import io.agora.rtc.video.WatermarkOptions;
|
||||
|
||||
/**
|
||||
* 默认实现所有的IRTCEngine,避免两个adapter需要实现所有的接口
|
||||
*/
|
||||
public class BaseAdapterImpl implements IRTCEngine {
|
||||
@Override
|
||||
public void setNetworkQosParam(TRTCCloudDef.TRTCNetworkQosParam param) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showDebugView(int showType) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDebugViewMargin(int userId, TRTCCloud.TRTCViewMargin margin) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startRemoteSubStreamView(int userId, TXCloudVideoView view) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopRemoteSubStreamView(int userId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoteSubStreamViewFillMode(int userId, int mode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEyeScaleLevel(int eyeScaleLevel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFaceSlimLevel(int faceScaleLevel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFaceVLevel(int faceVLevel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFaceShortLevel(int faceShortlevel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChinLevel(int chinLevel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNoseSlimLevel(int noseSlimLevel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setGreenScreenFile(String file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectMotionTmpl(String motionPath) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMotionMute(boolean motionMute) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilter(Bitmap image) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilterConcentration(float concentration) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocalViewRotation(int rotation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVideoEncoderMirror(boolean mirror) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGSensorMode(int mode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ConnectOtherRoom(String param) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void DisconnectOtherRoom() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMixTranscodingConfig(TRTCCloudDef.TRTCTranscodingConfig config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startCdnPlayerWithUrl(String url, TXCloudVideoView view) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopCdnPlayer() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setChannelProfile(int profile) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setClientRole(int role) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int joinChannel(String token, String channelName, String optionalInfo, int optionalUid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int switchChannel(String token, String channelName) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int leaveChannel() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int renewToken(String token) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int registerLocalUserAccount(String appId, String userAccount) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int joinChannelWithUserAccount(String token, String channelName, String userAccount) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUserInfoByUserAccount(String userAccount, UserInfo userInfo) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUserInfoByUid(int uid, UserInfo userInfo) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableWebSdkInteroperability(boolean enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConnectionState() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableAudio() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int disableAudio() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pauseAudio() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int resumeAudio() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setAudioProfile(int profile, int scenario) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setHighQualityAudioParameters(boolean fullband, boolean stereo, boolean fullBitrate) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adjustRecordingSignalVolume(int volume) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adjustPlaybackSignalVolume(int volume) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableAudioVolumeIndication(int interval, int smooth, boolean report_vad) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableAudioQualityIndication(boolean enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableLocalAudio(boolean enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int muteLocalAudioStream(boolean muted) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int muteRemoteAudioStream(int uid, boolean muted) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int muteAllRemoteAudioStreams(boolean muted) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setDefaultMuteAllRemoteAudioStreams(boolean muted) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableVideo() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int disableVideo() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setVideoProfile(int profile, boolean swapWidthAndHeight) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setVideoProfile(int width, int height, int frameRate, int bitrate) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setVideoEncoderConfiguration(VideoEncoderConfiguration config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCameraCapturerConfiguration(CameraCapturerConfiguration config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setupLocalVideo(VideoCanvas local) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setupRemoteVideo(VideoCanvas remote) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLocalRenderMode(int mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setRemoteRenderMode(int uid, int mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startPreview() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopPreview() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableLocalVideo(boolean enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int muteLocalVideoStream(boolean muted) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int muteRemoteVideoStream(int uid, boolean muted) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int muteAllRemoteVideoStreams(boolean muted) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setDefaultMuteAllRemoteVideoStreams(boolean muted) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBeautyEffectOptions(boolean enabled, BeautyOptions options) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setDefaultAudioRoutetoSpeakerphone(boolean defaultToSpeaker) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setEnableSpeakerphone(boolean enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpeakerphoneEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableInEarMonitoring(boolean enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setInEarMonitoringVolume(int volume) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int useExternalAudioDevice() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLocalVoicePitch(double pitch) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLocalVoiceEqualization(int bandFrequency, int bandGain) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLocalVoiceReverb(int reverbKey, int value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLocalVoiceChanger(int voiceChanger) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLocalVoiceReverbPreset(int preset) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableSoundPositionIndication(boolean enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setRemoteVoicePosition(int uid, double pan, double gain) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startAudioMixing(String filePath, boolean loopback, boolean replace, int cycle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopAudioMixing() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pauseAudioMixing() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int resumeAudioMixing() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adjustAudioMixingVolume(int volume) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adjustAudioMixingPlayoutVolume(int volume) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int adjustAudioMixingPublishVolume(int volume) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAudioMixingPlayoutVolume() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAudioMixingPublishVolume() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAudioMixingDuration() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAudioMixingCurrentPosition() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setAudioMixingPosition(int pos) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IAudioEffectManager getAudioEffectManager() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startAudioRecording(String filePath, int quality) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startAudioRecording(String filePath, int sampleRate, int quality) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopAudioRecording() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startEchoTest() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startEchoTest(int intervalInSeconds) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopEchoTest() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableLastmileTest() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int disableLastmileTest() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startLastmileProbeTest(LastmileProbeConfig config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopLastmileProbeTest() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setVideoSource(IVideoSource source) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLocalVideoRenderer(IVideoSink render) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setRemoteVideoRenderer(int uid, IVideoSink render) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setExternalAudioSink(boolean enabled, int sampleRate, int channels) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pullPlaybackAudioFrame(byte[] data, int lengthInByte) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setExternalAudioSource(boolean enabled, int sampleRate, int channels) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pushExternalAudioFrame(byte[] data, long timestamp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExternalVideoSource(boolean enable, boolean useTexture, boolean pushMode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pushExternalVideoFrame(AgoraVideoFrame frame) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTextureEncodeSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int registerAudioFrameObserver(IAudioFrameObserver observer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setRecordingAudioFrameParameters(int sampleRate, int channel, int mode, int samplesPerCall) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setPlaybackAudioFrameParameters(int sampleRate, int channel, int mode, int samplesPerCall) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setMixedAudioFrameParameters(int sampleRate, int samplesPerCall) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addVideoWatermark(AgoraImage watermark) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addVideoWatermark(String watermarkUrl, WatermarkOptions options) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int clearVideoWatermarks() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setRemoteUserPriority(int uid, int userPriority) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLocalPublishFallbackOption(int option) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setRemoteSubscribeFallbackOption(int option) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int enableDualStreamMode(boolean enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setRemoteVideoStreamType(int uid, int streamType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setRemoteDefaultVideoStreamType(int streamType) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setEncryptionSecret(String secret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setEncryptionMode(String encryptionMode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addInjectStreamUrl(String url, LiveInjectStreamConfig config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int removeInjectStreamUrl(String url) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int addPublishStreamUrl(String url, boolean transcodingEnabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int removePublishStreamUrl(String url) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLiveTranscoding(LiveTranscoding transcoding) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int createDataStream(boolean reliable, boolean ordered) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sendStreamMessage(int streamId, byte[] message) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setVideoQualityParameters(boolean preferFrameRateOverImageQuality) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLocalVideoMirrorMode(int mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int switchCamera() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCameraZoomSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCameraTorchSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCameraFocusSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCameraExposurePositionSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCameraAutoFocusFaceModeSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCameraZoomFactor(float factor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getCameraMaxZoomFactor() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCameraFocusPositionInPreview(float positionX, float positionY) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCameraExposurePosition(float positionXinView, float positionYinView) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCameraTorchOn(boolean isOn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setCameraAutoFocusFaceModeEnabled(boolean enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCallId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rate(String callId, int rating, String description) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int complain(String callId, String description) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLogFile(String filePath) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLogFilter(int filter) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setLogFileSize(int fileSizeInKBytes) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getNativeHandle() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHandler(IRtcEngineEventHandler handler) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeHandler(IRtcEngineEventHandler handler) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enableHighPerfWifiMode(boolean enable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void monitorHeadsetEvent(boolean monitor) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void monitorBluetoothHeadsetEvent(boolean monitor) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPreferHeadset(boolean enabled) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setParameters(String parameters) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String parameter, String args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int registerMediaMetadataObserver(IMetadataObserver observer, int type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startChannelMediaRelay(ChannelMediaRelayConfiguration channelMediaRelayConfiguration) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopChannelMediaRelay() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateChannelMediaRelay(ChannelMediaRelayConfiguration channelMediaRelayConfiguration) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startDumpVideoReceiveTrack(int uid) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopDumpVideoReceiveTrack() {
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -0,0 +1,155 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
import io.agora.rtc.IRtcEngineEventHandler;
|
||||
import io.agora.rtc.models.UserInfo;
|
||||
|
||||
/**
|
||||
* 对齐IRtcEngineEventHandler的所有接口
|
||||
*/
|
||||
interface BaseAgoraHandlerInterface {
|
||||
void onWarning(int warn);
|
||||
|
||||
void onError(int err);
|
||||
|
||||
void onJoinChannelSuccess(String channel, int uid, int elapsed);
|
||||
|
||||
void onRejoinChannelSuccess(String channel, int uid, int elapsed);
|
||||
|
||||
void onLeaveChannel(IRtcEngineEventHandler.RtcStats stats);
|
||||
|
||||
void onClientRoleChanged(int oldRole, int newRole);
|
||||
|
||||
@Version(agora = "2.9.2")
|
||||
void onLocalUserRegistered(int uid, String userAccount);
|
||||
|
||||
@Version(agora = "2.9.2")
|
||||
void onUserInfoUpdated(int uid, UserInfo userInfo);
|
||||
|
||||
void onUserJoined(int uid, int elapsed);
|
||||
|
||||
void onUserOffline(int uid, int reason);
|
||||
|
||||
void onConnectionStateChanged(int state, int reason);
|
||||
|
||||
void onConnectionLost();
|
||||
|
||||
@Version(agora = "3.0.0")
|
||||
void onConnectionInterrupted();
|
||||
|
||||
@Version(agora = "3.0.0")
|
||||
void onAudioQuality(int uid, int quality, short delay, short lost);
|
||||
|
||||
void onApiCallExecuted(int error, String api, String result);
|
||||
|
||||
void onTokenPrivilegeWillExpire(String token);
|
||||
|
||||
void onRequestToken();
|
||||
|
||||
void onMicrophoneEnabled(boolean enabled);
|
||||
|
||||
void onAudioVolumeIndication(IRtcEngineEventHandler.AudioVolumeInfo[] speakers, int totalVolume);
|
||||
|
||||
void onActiveSpeaker(int uid);
|
||||
|
||||
void onFirstLocalAudioFrame(int elapsed);
|
||||
|
||||
void onFirstRemoteAudioFrame(int uid, int elapsed);
|
||||
|
||||
void onFirstRemoteAudioDecoded(int uid, int elapsed);
|
||||
|
||||
void onVideoStopped();
|
||||
|
||||
void onFirstLocalVideoFrame(int width, int height, int elapsed);
|
||||
|
||||
void onFirstRemoteVideoDecoded(int uid, int width, int height, int elapsed);
|
||||
|
||||
void onFirstRemoteVideoFrame(int uid, int width, int height, int elapsed);
|
||||
|
||||
void onUserMuteAudio(int uid, boolean muted);
|
||||
|
||||
void onUserMuteVideo(int uid, boolean muted);
|
||||
|
||||
void onUserEnableVideo(int uid, boolean enabled);
|
||||
|
||||
void onUserEnableLocalVideo(int uid, boolean enabled);
|
||||
|
||||
void onVideoSizeChanged(int uid, int width, int height, int rotation);
|
||||
|
||||
@Version(agora = "2.9.2")
|
||||
void onRemoteAudioStateChanged(int uid, int state, int reason, int elapsed);
|
||||
|
||||
@Version(agora = "2.9.2")
|
||||
void onRemoteVideoStateChanged(int uid, int state, int reason, int elapsed);
|
||||
|
||||
@Version(agora = "2.9.2")
|
||||
void onChannelMediaRelayStateChanged(int state, int code);
|
||||
|
||||
@Version(agora = "2.9.2")
|
||||
void onChannelMediaRelayEvent(int code);
|
||||
|
||||
void onLocalPublishFallbackToAudioOnly(boolean isFallbackOrRecover);
|
||||
|
||||
void onRemoteSubscribeFallbackToAudioOnly(int uid, boolean isFallbackOrRecover);
|
||||
|
||||
void onAudioRouteChanged(int routing);
|
||||
|
||||
void onCameraReady();
|
||||
|
||||
void onCameraFocusAreaChanged(Rect rect);
|
||||
|
||||
void onCameraExposureAreaChanged(Rect rect);
|
||||
|
||||
void onRtcStats(IRtcEngineEventHandler.RtcStats stats);
|
||||
|
||||
void onLastmileQuality(int quality);
|
||||
|
||||
void onLastmileProbeResult(IRtcEngineEventHandler.LastmileProbeResult result);
|
||||
|
||||
void onNetworkQuality(int uid, int txQuality, int rxQuality);
|
||||
|
||||
void onLocalVideoStats(IRtcEngineEventHandler.LocalVideoStats stats);
|
||||
|
||||
void onRemoteVideoStats(IRtcEngineEventHandler.RemoteVideoStats stats);
|
||||
|
||||
void onLocalAudioStats(IRtcEngineEventHandler.LocalAudioStats stats);
|
||||
|
||||
@Version(agora = "2.9.2")
|
||||
void onRemoteAudioStats(IRtcEngineEventHandler.RemoteAudioStats stats);
|
||||
|
||||
void onRemoteAudioTransportStats(int uid, int delay, int lost, int rxKBitRate);
|
||||
|
||||
void onRemoteVideoTransportStats(int uid, int delay, int lost, int rxKBitRate);
|
||||
|
||||
void onAudioMixingStateChanged(int state, int errorCode);
|
||||
|
||||
void onAudioMixingFinished();
|
||||
|
||||
void onAudioEffectFinished(int soundId);
|
||||
|
||||
@Version(agora = "2.9.2")
|
||||
void onLocalAudioStateChanged(int state, int error);
|
||||
|
||||
@Version(agora = "2.9.2")
|
||||
void onLocalVideoStateChanged(int localVideoState, int error);
|
||||
|
||||
@Version(agora = "2.9.2")
|
||||
void onRtmpStreamingStateChanged(String url, int state, int errCode);
|
||||
|
||||
void onStreamPublished(String url, int error);
|
||||
|
||||
void onStreamUnpublished(String url);
|
||||
|
||||
void onTranscodingUpdated();
|
||||
|
||||
void onStreamInjectedStatus(String url, int uid, int status);
|
||||
|
||||
void onStreamMessage(int uid, int streamId, byte[] data);
|
||||
|
||||
void onStreamMessageError(int uid, int streamId, int error, int missed, int cached);
|
||||
|
||||
void onMediaEngineLoadSuccess();
|
||||
|
||||
void onMediaEngineStartCallSuccess();
|
||||
}
|
@@ -0,0 +1,352 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import io.agora.rtc.IAudioEffectManager;
|
||||
import io.agora.rtc.IAudioFrameObserver;
|
||||
import io.agora.rtc.IMetadataObserver;
|
||||
import io.agora.rtc.IRtcEngineEventHandler;
|
||||
import io.agora.rtc.internal.LastmileProbeConfig;
|
||||
import io.agora.rtc.live.LiveInjectStreamConfig;
|
||||
import io.agora.rtc.live.LiveTranscoding;
|
||||
import io.agora.rtc.mediaio.IVideoSink;
|
||||
import io.agora.rtc.mediaio.IVideoSource;
|
||||
import io.agora.rtc.models.UserInfo;
|
||||
import io.agora.rtc.video.AgoraImage;
|
||||
import io.agora.rtc.video.AgoraVideoFrame;
|
||||
import io.agora.rtc.video.BeautyOptions;
|
||||
import io.agora.rtc.video.CameraCapturerConfiguration;
|
||||
import io.agora.rtc.video.ChannelMediaRelayConfiguration;
|
||||
import io.agora.rtc.video.VideoCanvas;
|
||||
import io.agora.rtc.video.VideoEncoderConfiguration;
|
||||
import io.agora.rtc.video.WatermarkOptions;
|
||||
|
||||
/**
|
||||
* 接口类,和声网所有接口保持一致
|
||||
*/
|
||||
@Version(agora = "3.0.0", trtc = "6.8")
|
||||
public interface BaseAgoraInterface {
|
||||
int setChannelProfile(int profile);
|
||||
|
||||
int setClientRole(int role);
|
||||
|
||||
int joinChannel(String token, String channelName, String optionalInfo, int optionalUid);
|
||||
|
||||
int switchChannel(String token, String channelName);
|
||||
|
||||
int leaveChannel();
|
||||
|
||||
int renewToken(String token);
|
||||
|
||||
int registerLocalUserAccount(String appId, String userAccount);
|
||||
|
||||
int joinChannelWithUserAccount(String token, String channelName, String userAccount);
|
||||
|
||||
int getUserInfoByUserAccount(String userAccount, UserInfo userInfo);
|
||||
|
||||
int getUserInfoByUid(int uid, UserInfo userInfo);
|
||||
|
||||
int enableWebSdkInteroperability(boolean enabled);
|
||||
|
||||
int getConnectionState();
|
||||
|
||||
int enableAudio();
|
||||
|
||||
int disableAudio();
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int pauseAudio();
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int resumeAudio();
|
||||
|
||||
int setAudioProfile(int profile, int scenario);
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int setHighQualityAudioParameters(boolean fullband, boolean stereo, boolean fullBitrate);
|
||||
|
||||
int adjustRecordingSignalVolume(int volume);
|
||||
|
||||
int adjustPlaybackSignalVolume(int volume);
|
||||
|
||||
int enableAudioVolumeIndication(int interval, int smooth, boolean report_vad);
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int enableAudioQualityIndication(boolean enabled);
|
||||
|
||||
int enableLocalAudio(boolean enabled);
|
||||
|
||||
int muteLocalAudioStream(boolean muted);
|
||||
|
||||
int muteRemoteAudioStream(int uid, boolean muted);
|
||||
|
||||
int muteAllRemoteAudioStreams(boolean muted);
|
||||
|
||||
int setDefaultMuteAllRemoteAudioStreams(boolean muted);
|
||||
|
||||
int enableVideo();
|
||||
|
||||
int disableVideo();
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int setVideoProfile(int profile, boolean swapWidthAndHeight);
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int setVideoProfile(int width, int height, int frameRate, int bitrate);
|
||||
|
||||
int setVideoEncoderConfiguration(VideoEncoderConfiguration config);
|
||||
|
||||
int setCameraCapturerConfiguration(CameraCapturerConfiguration config);
|
||||
|
||||
int setupLocalVideo(VideoCanvas local);
|
||||
|
||||
int setupRemoteVideo(VideoCanvas remote);
|
||||
|
||||
int setLocalRenderMode(int mode);
|
||||
|
||||
int setRemoteRenderMode(int uid, int mode);
|
||||
|
||||
int startPreview();
|
||||
|
||||
int stopPreview();
|
||||
|
||||
int enableLocalVideo(boolean enabled);
|
||||
|
||||
int muteLocalVideoStream(boolean muted);
|
||||
|
||||
int muteRemoteVideoStream(int uid, boolean muted);
|
||||
|
||||
int muteAllRemoteVideoStreams(boolean muted);
|
||||
|
||||
int setDefaultMuteAllRemoteVideoStreams(boolean muted);
|
||||
|
||||
int setBeautyEffectOptions(boolean enabled, BeautyOptions options);
|
||||
|
||||
int setDefaultAudioRoutetoSpeakerphone(boolean defaultToSpeaker);
|
||||
|
||||
int setEnableSpeakerphone(boolean enabled);
|
||||
|
||||
boolean isSpeakerphoneEnabled();
|
||||
|
||||
int enableInEarMonitoring(boolean enabled);
|
||||
|
||||
int setInEarMonitoringVolume(int volume);
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int useExternalAudioDevice();
|
||||
|
||||
int setLocalVoicePitch(double pitch);
|
||||
|
||||
int setLocalVoiceEqualization(int bandFrequency, int bandGain);
|
||||
|
||||
int setLocalVoiceReverb(int reverbKey, int value);
|
||||
|
||||
int setLocalVoiceChanger(int voiceChanger);
|
||||
|
||||
int setLocalVoiceReverbPreset(int preset);
|
||||
|
||||
int enableSoundPositionIndication(boolean enabled);
|
||||
|
||||
int setRemoteVoicePosition(int uid, double pan, double gain);
|
||||
|
||||
int startAudioMixing(String filePath, boolean loopback, boolean replace, int cycle);
|
||||
|
||||
int stopAudioMixing();
|
||||
|
||||
int pauseAudioMixing();
|
||||
|
||||
int resumeAudioMixing();
|
||||
|
||||
int adjustAudioMixingVolume(int volume);
|
||||
|
||||
int adjustAudioMixingPlayoutVolume(int volume);
|
||||
|
||||
int adjustAudioMixingPublishVolume(int volume);
|
||||
|
||||
int getAudioMixingPlayoutVolume();
|
||||
|
||||
int getAudioMixingPublishVolume();
|
||||
|
||||
int getAudioMixingDuration();
|
||||
|
||||
int getAudioMixingCurrentPosition();
|
||||
|
||||
int setAudioMixingPosition(int pos);
|
||||
|
||||
IAudioEffectManager getAudioEffectManager();
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int startAudioRecording(String filePath, int quality);
|
||||
|
||||
int startAudioRecording(String filePath, int sampleRate, int quality);
|
||||
|
||||
int stopAudioRecording();
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int startEchoTest();
|
||||
|
||||
int startEchoTest(int intervalInSeconds);
|
||||
|
||||
int stopEchoTest();
|
||||
|
||||
int enableLastmileTest();
|
||||
|
||||
int disableLastmileTest();
|
||||
|
||||
int startLastmileProbeTest(LastmileProbeConfig config);
|
||||
|
||||
int stopLastmileProbeTest();
|
||||
|
||||
int setVideoSource(IVideoSource source);
|
||||
|
||||
int setLocalVideoRenderer(IVideoSink render);
|
||||
|
||||
int setRemoteVideoRenderer(int uid, IVideoSink render);
|
||||
|
||||
int setExternalAudioSink(boolean enabled, int sampleRate, int channels);
|
||||
|
||||
int pullPlaybackAudioFrame(byte[] data, int lengthInByte);
|
||||
|
||||
int setExternalAudioSource(boolean enabled, int sampleRate, int channels);
|
||||
|
||||
int pushExternalAudioFrame(byte[] data, long timestamp);
|
||||
|
||||
void setExternalVideoSource(boolean enable, boolean useTexture, boolean pushMode);
|
||||
|
||||
boolean pushExternalVideoFrame(AgoraVideoFrame frame);
|
||||
|
||||
boolean isTextureEncodeSupported();
|
||||
|
||||
int registerAudioFrameObserver(IAudioFrameObserver observer);
|
||||
|
||||
int setRecordingAudioFrameParameters(int sampleRate, int channel, int mode, int samplesPerCall);
|
||||
|
||||
int setPlaybackAudioFrameParameters(int sampleRate, int channel, int mode, int samplesPerCall);
|
||||
|
||||
int setMixedAudioFrameParameters(int sampleRate, int samplesPerCall);
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int addVideoWatermark(AgoraImage watermark);
|
||||
|
||||
int addVideoWatermark(String watermarkUrl, WatermarkOptions options);
|
||||
|
||||
int clearVideoWatermarks();
|
||||
|
||||
int setRemoteUserPriority(int uid, int userPriority);
|
||||
|
||||
int setLocalPublishFallbackOption(int option);
|
||||
|
||||
int setRemoteSubscribeFallbackOption(int option);
|
||||
|
||||
int enableDualStreamMode(boolean enabled);
|
||||
|
||||
int setRemoteVideoStreamType(int uid, int streamType);
|
||||
|
||||
int setRemoteDefaultVideoStreamType(int streamType);
|
||||
|
||||
int setEncryptionSecret(String secret);
|
||||
|
||||
int setEncryptionMode(String encryptionMode);
|
||||
|
||||
int addInjectStreamUrl(String url, LiveInjectStreamConfig config);
|
||||
|
||||
int removeInjectStreamUrl(String url);
|
||||
|
||||
int addPublishStreamUrl(String url, boolean transcodingEnabled);
|
||||
|
||||
int removePublishStreamUrl(String url);
|
||||
|
||||
int setLiveTranscoding(LiveTranscoding transcoding);
|
||||
|
||||
int createDataStream(boolean reliable, boolean ordered);
|
||||
|
||||
int sendStreamMessage(int streamId, byte[] message);
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
int setVideoQualityParameters(boolean preferFrameRateOverImageQuality);
|
||||
|
||||
int setLocalVideoMirrorMode(int mode);
|
||||
|
||||
int switchCamera();
|
||||
|
||||
boolean isCameraZoomSupported();
|
||||
|
||||
boolean isCameraTorchSupported();
|
||||
|
||||
boolean isCameraFocusSupported();
|
||||
|
||||
boolean isCameraExposurePositionSupported();
|
||||
|
||||
boolean isCameraAutoFocusFaceModeSupported();
|
||||
|
||||
int setCameraZoomFactor(float factor);
|
||||
|
||||
float getCameraMaxZoomFactor();
|
||||
|
||||
int setCameraFocusPositionInPreview(float positionX, float positionY);
|
||||
|
||||
int setCameraExposurePosition(float positionXinView, float positionYinView);
|
||||
|
||||
int setCameraTorchOn(boolean isOn);
|
||||
|
||||
int setCameraAutoFocusFaceModeEnabled(boolean enabled);
|
||||
|
||||
String getCallId();
|
||||
|
||||
int rate(String callId, int rating, String description);
|
||||
|
||||
int complain(String callId, String description);
|
||||
|
||||
int setLogFile(String filePath);
|
||||
|
||||
int setLogFilter(int filter);
|
||||
|
||||
int setLogFileSize(int fileSizeInKBytes);
|
||||
|
||||
long getNativeHandle();
|
||||
|
||||
void addHandler(IRtcEngineEventHandler handler);
|
||||
|
||||
void removeHandler(IRtcEngineEventHandler handler);
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
boolean enableHighPerfWifiMode(boolean enable);
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
void monitorHeadsetEvent(boolean monitor);
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
void monitorBluetoothHeadsetEvent(boolean monitor);
|
||||
|
||||
/** @deprecated */
|
||||
@Deprecated
|
||||
void setPreferHeadset(boolean enabled);
|
||||
|
||||
int setParameters(String parameters);
|
||||
|
||||
String getParameter(String parameter, String args);
|
||||
|
||||
int registerMediaMetadataObserver(IMetadataObserver observer, int type);
|
||||
|
||||
int startChannelMediaRelay(ChannelMediaRelayConfiguration channelMediaRelayConfiguration);
|
||||
|
||||
int stopChannelMediaRelay();
|
||||
|
||||
int updateChannelMediaRelay(ChannelMediaRelayConfiguration channelMediaRelayConfiguration);
|
||||
|
||||
int startDumpVideoReceiveTrack(int uid);
|
||||
|
||||
int stopDumpVideoReceiveTrack();
|
||||
}
|
@@ -0,0 +1,186 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.Deflater;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/*
|
||||
* Module: GenerateTestUserSig
|
||||
*
|
||||
* Function: 用于生成测试用的 UserSig,UserSig 是腾讯云为其云服务设计的一种安全保护签名。
|
||||
* 其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。
|
||||
*
|
||||
* Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
|
||||
*
|
||||
* 本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
|
||||
* 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
|
||||
* 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
|
||||
*
|
||||
* 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
|
||||
* 由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
|
||||
*
|
||||
* Reference:https://cloud.tencent.com/document/product/269/32688#Server
|
||||
*/
|
||||
public class GenerateTestUserSig {
|
||||
|
||||
/**
|
||||
* 计算签名用的加密密钥,获取步骤如下:
|
||||
* <p>
|
||||
* step1. 进入腾讯云云通信[控制台](https://console.cloud.tencent.com/avc) ,如果还没有应用就创建一个,
|
||||
* step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。
|
||||
* step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中
|
||||
* <p>
|
||||
* 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
|
||||
* 文档:https://cloud.tencent.com/document/product/269/32688#Server
|
||||
*/
|
||||
public static final String SECRETKEY = "b61263a7d5a47ec9f53641fdc4e8c86fcbda584a81b61578ef3f1a60381a4290";
|
||||
/**
|
||||
* 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
|
||||
* <p>
|
||||
* 进入腾讯云云通信[控制台](https://console.cloud.tencent.com/avc) 创建应用,即可看到 SDKAppId,
|
||||
* 它是腾讯云用于区分客户的唯一标识。
|
||||
*/
|
||||
private static final int SDKAPPID = SDKConfig.TX_SDKAPPID;
|
||||
/**
|
||||
* 签名过期时间,建议不要设置的过短
|
||||
* <p>
|
||||
* 时间单位:秒
|
||||
* 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天
|
||||
*/
|
||||
private static final int EXPIRETIME = 604800;
|
||||
private long sdkappid;
|
||||
private String key;
|
||||
|
||||
public GenerateTestUserSig(long sdkappid, String key) {
|
||||
this.sdkappid = sdkappid;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算 UserSig 签名
|
||||
* <p>
|
||||
* 函数内部使用 HMAC-SHA256 非对称加密算法,对 SDKAPPID、userId 和 EXPIRETIME 进行加密。
|
||||
*
|
||||
* @note: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
|
||||
* <p>
|
||||
* 本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
|
||||
* 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
|
||||
* 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
|
||||
* <p>
|
||||
* 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
|
||||
* 由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
|
||||
* <p>
|
||||
* 文档:https://cloud.tencent.com/document/product/269/32688#Server
|
||||
*/
|
||||
public static String genTestUserSig(String userId) {
|
||||
return new GenerateTestUserSig(SDKAPPID, SECRETKEY).genSig(userId, EXPIRETIME);
|
||||
}
|
||||
|
||||
public static byte[] base64EncodeUrl(byte[] input) {
|
||||
byte[] base64 = new String(Base64.encode(input, Base64.NO_WRAP)).getBytes();
|
||||
for (int i = 0; i < base64.length; ++i)
|
||||
switch (base64[i]) {
|
||||
case '+':
|
||||
base64[i] = '*';
|
||||
break;
|
||||
case '/':
|
||||
base64[i] = '-';
|
||||
break;
|
||||
case '=':
|
||||
base64[i] = '_';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return base64;
|
||||
}
|
||||
|
||||
private String hmacsha256(String identifier, long currTime, long expire, String base64Userbuf) {
|
||||
String contentToBeSigned = "TLS.identifier:" + identifier + "\n"
|
||||
+ "TLS.sdkappid:" + sdkappid + "\n"
|
||||
+ "TLS.time:" + currTime + "\n"
|
||||
+ "TLS.expire:" + expire + "\n";
|
||||
if (null != base64Userbuf) {
|
||||
contentToBeSigned += "TLS.userbuf:" + base64Userbuf + "\n";
|
||||
}
|
||||
try {
|
||||
byte[] byteKey = key.getBytes("UTF-8");
|
||||
Mac hmac = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec keySpec = new SecretKeySpec(byteKey, "HmacSHA256");
|
||||
hmac.init(keySpec);
|
||||
byte[] byteSig = hmac.doFinal(contentToBeSigned.getBytes("UTF-8"));
|
||||
return new String(Base64.encode(byteSig, Base64.NO_WRAP));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
return "";
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return "";
|
||||
} catch (InvalidKeyException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String genSig(String identifier, long expire, byte[] userbuf) {
|
||||
|
||||
long currTime = System.currentTimeMillis() / 1000;
|
||||
|
||||
JSONObject sigDoc = new JSONObject();
|
||||
try {
|
||||
sigDoc.put("TLS.ver", "2.0");
|
||||
sigDoc.put("TLS.identifier", identifier);
|
||||
sigDoc.put("TLS.sdkappid", sdkappid);
|
||||
sigDoc.put("TLS.expire", expire);
|
||||
sigDoc.put("TLS.time", currTime);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
String base64UserBuf = null;
|
||||
if (null != userbuf) {
|
||||
//base64UserBuf = new String(Base64.encode(userbuf,Base64.URL_SAFE));
|
||||
base64UserBuf = Base64.encodeToString(userbuf, Base64.NO_WRAP);
|
||||
try {
|
||||
sigDoc.put("TLS.userbuf", base64UserBuf);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
String sig = hmacsha256(identifier, currTime, expire, base64UserBuf);
|
||||
if (sig.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
sigDoc.put("TLS.sig", sig);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Deflater compressor = new Deflater();
|
||||
String s = sigDoc.toString();
|
||||
compressor.setInput(sigDoc.toString().getBytes(Charset.forName("UTF-8")));
|
||||
compressor.finish();
|
||||
byte[] compressedBytes = new byte[2048];
|
||||
int compressedBytesLength = compressor.deflate(compressedBytes);
|
||||
compressor.end();
|
||||
return new String(GenerateTestUserSig.base64EncodeUrl(Arrays.copyOfRange(compressedBytes, 0, compressedBytesLength)));
|
||||
}
|
||||
|
||||
public String genSig(String identifier, long expire) {
|
||||
return genSig(identifier, expire, null);
|
||||
}
|
||||
|
||||
public String genSigWithUserBuf(String identifier, long expire, byte[] userbuf) {
|
||||
return genSig(identifier, expire, userbuf);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import com.tencent.rtmp.ui.TXCloudVideoView;
|
||||
import com.tencent.trtc.TRTCCloud;
|
||||
import com.tencent.trtc.TRTCCloudDef;
|
||||
|
||||
/**
|
||||
* 接口类,包括声网和TRTC自己的函数,可以增加自定义的接口,然后让两套适配层进行适配
|
||||
*/
|
||||
public interface IRTCEngine extends BaseAgoraInterface {
|
||||
/**
|
||||
* ====================这些都是TRTC特有的函数=============
|
||||
*/
|
||||
void setNetworkQosParam(TRTCCloudDef.TRTCNetworkQosParam param);
|
||||
|
||||
void showDebugView(int showType);
|
||||
|
||||
void setDebugViewMargin(int userId, TRTCCloud.TRTCViewMargin margin);
|
||||
|
||||
void startRemoteSubStreamView(int userId, TXCloudVideoView view);
|
||||
|
||||
void stopRemoteSubStreamView(int userId);
|
||||
|
||||
void setRemoteSubStreamViewFillMode(int userId, int mode);
|
||||
|
||||
void setEyeScaleLevel(int eyeScaleLevel);
|
||||
|
||||
void setFaceSlimLevel(int faceScaleLevel);
|
||||
|
||||
void setFaceVLevel(int faceVLevel);
|
||||
|
||||
void setFaceShortLevel(int faceShortlevel);
|
||||
|
||||
void setChinLevel(int chinLevel);
|
||||
|
||||
void setNoseSlimLevel(int noseSlimLevel);
|
||||
|
||||
boolean setGreenScreenFile(String file);
|
||||
|
||||
void selectMotionTmpl(String motionPath);
|
||||
|
||||
void setMotionMute(boolean motionMute);
|
||||
|
||||
void setFilter(Bitmap image);
|
||||
|
||||
void setFilterConcentration(float concentration);
|
||||
|
||||
void setLocalViewRotation(int rotation);
|
||||
|
||||
void setVideoEncoderMirror(boolean mirror);
|
||||
|
||||
void setGSensorMode(int mode);
|
||||
|
||||
void ConnectOtherRoom(String param);
|
||||
|
||||
void DisconnectOtherRoom();
|
||||
|
||||
//设置云端的混流转码参数
|
||||
void setMixTranscodingConfig(TRTCCloudDef.TRTCTranscodingConfig config);
|
||||
|
||||
void startCdnPlayerWithUrl(String url, TXCloudVideoView view);
|
||||
|
||||
void stopCdnPlayer();
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import com.tencent.trtc.TRTCCloudDef;
|
||||
|
||||
/**
|
||||
* 包括声网和腾讯云的回调
|
||||
*/
|
||||
interface IRTCEngineHandler extends BaseAgoraHandlerInterface {
|
||||
|
||||
void onUserSubStreamAvailable(int userId, boolean available);
|
||||
|
||||
void onSpeedTest(TRTCCloudDef.TRTCSpeedTestResult currentResult, int finishedCount, int totalCount);
|
||||
|
||||
void onRecvSEIMsg(int userId, byte[] data);
|
||||
|
||||
void onSetMixTranscodingConfig(int err, String errMsg);
|
||||
|
||||
void onConnectOtherRoom(int userID, int err, String errMsg);
|
||||
|
||||
void onDisConnectOtherRoom(int err, String errMsg);
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
public class SDKConfig {
|
||||
/**
|
||||
* 声网appid,需要替换为尽自己账号下的声网appid
|
||||
*/
|
||||
public static String AGORA_APPID = "";
|
||||
/**
|
||||
* 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
|
||||
* <p>
|
||||
* 进入腾讯云云通信[控制台](https://console.cloud.tencent.com/avc) 创建应用,即可看到 SDKAppId,
|
||||
* 它是腾讯云用于区分客户的唯一标识。
|
||||
*/
|
||||
public static int TX_SDKAPPID = 1400600174;//
|
||||
|
||||
/**
|
||||
* 腾讯云 bizid和appid
|
||||
* 腾讯云的bizid https://console.cloud.tencent.com/rav 点击【应用】【帐号信息】在【直播信息】中可以看到bizid和appid, 分别填到下面这两个符号
|
||||
*/
|
||||
public static int TX_BIZID = 0;//
|
||||
public static int TX_APPID = 0;//
|
||||
|
||||
/**
|
||||
* 混流播放地址,请填写您的播放地址
|
||||
*/
|
||||
public static String TX_PLAYDOMAIN = "";
|
||||
/**
|
||||
* 表示房间号是否为整型值
|
||||
* 0:表示房间号为字符串房间号,不能直接转换为整型,如:"111_222","namme1"
|
||||
* 1:表示房间号为整型房间号,如:"111","123"
|
||||
*/
|
||||
public static int TX_CHANNELNAME_INT = 1;
|
||||
}
|
@@ -0,0 +1,167 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import com.tencent.liteav.audio.TXAudioEffectManager;
|
||||
import com.tencent.trtc.TRTCCloud;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import io.agora.rtc.IAudioEffectManager;
|
||||
|
||||
/**
|
||||
* 音效的控制类
|
||||
*/
|
||||
public class TRTCEffectManager implements IAudioEffectManager {
|
||||
// SDK 核心类
|
||||
private TRTCCloud mTRTCCloud;
|
||||
private double mEffectsVolume;
|
||||
private Set<Integer> mEffectIdSet;
|
||||
private TXAudioEffectManager.TXMusicPlayObserver mMusicPlayObserver;
|
||||
|
||||
public TRTCEffectManager(TRTCCloud trtcCloud) {
|
||||
mTRTCCloud = trtcCloud;
|
||||
mEffectIdSet = new HashSet<>();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
stopAllAudioEffects();
|
||||
}
|
||||
|
||||
/**
|
||||
* ==================================音效面板控制==================================
|
||||
*/
|
||||
private void playAudioEffect(int effectId, String path, int count, boolean publish, double volume) {
|
||||
if (mTRTCCloud != null) {
|
||||
TXAudioEffectManager.AudioMusicParam audioMusicParam = new TXAudioEffectManager.AudioMusicParam(effectId, path);
|
||||
audioMusicParam.loopCount = count;
|
||||
audioMusicParam.publish = publish;
|
||||
audioMusicParam.isShortFile = true;
|
||||
if (mMusicPlayObserver != null) {
|
||||
mTRTCCloud.getAudioEffectManager().setMusicObserver(effectId, mMusicPlayObserver);
|
||||
}
|
||||
mTRTCCloud.getAudioEffectManager().startPlayMusic(audioMusicParam);
|
||||
mEffectIdSet.add(effectId);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopAudioEffect(int effectId) {
|
||||
if (mTRTCCloud != null) {
|
||||
mTRTCCloud.getAudioEffectManager().stopPlayMusic(effectId);
|
||||
mEffectIdSet.remove(effectId);
|
||||
}
|
||||
}
|
||||
|
||||
private void setAudioEffectVolume(int effectId, int gain) {
|
||||
if (mTRTCCloud != null) {
|
||||
mTRTCCloud.getAudioEffectManager().setMusicPublishVolume(effectId, gain);
|
||||
mTRTCCloud.getAudioEffectManager().setMusicPlayoutVolume(effectId, gain);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopAllAudioEffects() {
|
||||
if (mTRTCCloud != null) {
|
||||
for (int i : mEffectIdSet) {
|
||||
mTRTCCloud.getAudioEffectManager().stopPlayMusic(i);
|
||||
}
|
||||
mEffectIdSet.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void setAllAudioEffectsVolume(int gain) {
|
||||
mEffectsVolume = gain;
|
||||
if (mTRTCCloud != null) {
|
||||
mTRTCCloud.getAudioEffectManager().setAllMusicVolume(gain);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getEffectsVolume() {
|
||||
return mEffectsVolume;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setEffectsVolume(double volume) {
|
||||
setAllAudioEffectsVolume((int) volume);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setVolumeOfEffect(int soundId, double volume) {
|
||||
setAudioEffectVolume(soundId, (int) volume);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int playEffect(int soundId, String filePath, int loop, double pitch, double pan, double gain) {
|
||||
playAudioEffect(soundId, filePath, loop, true, gain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int playEffect(int soundId, String filePath, int loopCount, double pitch, double pan, double gain, boolean publish) {
|
||||
playAudioEffect(soundId, filePath, loopCount, publish, gain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopEffect(int soundId) {
|
||||
stopAudioEffect(soundId);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopAllEffects() {
|
||||
stopAllAudioEffects();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int preloadEffect(int soundId, String filePath) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int unloadEffect(int soundId) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pauseEffect(int soundId) {
|
||||
if (mTRTCCloud != null) {
|
||||
mTRTCCloud.getAudioEffectManager().pausePlayMusic(soundId);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pauseAllEffects() {
|
||||
if (mTRTCCloud != null) {
|
||||
for (int i : mEffectIdSet) {
|
||||
mTRTCCloud.getAudioEffectManager().pausePlayMusic(i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int resumeEffect(int soundId) {
|
||||
if (mTRTCCloud != null) {
|
||||
mTRTCCloud.getAudioEffectManager().resumePlayMusic(soundId);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int resumeAllEffects() {
|
||||
if (mTRTCCloud != null) {
|
||||
for (int i : mEffectIdSet) {
|
||||
mTRTCCloud.getAudioEffectManager().resumePlayMusic(i);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setMusicObserver(TXAudioEffectManager.TXMusicPlayObserver observer) {
|
||||
mMusicPlayObserver = observer;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,427 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.os.Message;
|
||||
|
||||
import com.orhanobut.logger.Logger;
|
||||
import com.tencent.trtc.TRTCCloudDef;
|
||||
import com.yizhuan.xchat_android_core.manager.AvRoomDataManager;
|
||||
import com.yizhuan.xchat_android_core.manager.IMNetEaseManager;
|
||||
import com.yizhuan.xchat_android_core.manager.RoomEvent;
|
||||
import com.yizhuan.xchat_android_core.manager.agora.RtcEngineHandler;
|
||||
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
|
||||
|
||||
import io.agora.rtc.Constants;
|
||||
import io.agora.rtc.IRtcEngineEventHandler;
|
||||
import io.agora.rtc.models.UserInfo;
|
||||
|
||||
/**
|
||||
* @author by 梁馨 on 2020/9/14.
|
||||
*/
|
||||
public class TRtcEngineEventHandler implements IRTCEngineHandler {
|
||||
|
||||
public static String TAG = TRtcEngineEventHandler.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public void onWarning(int warn) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int err) {
|
||||
Logger.t(TAG).d("onError" + err);
|
||||
switch (err) {
|
||||
case 1107: {
|
||||
SingleToastUtil.showToast("发生未知错误,请退出房间重新进入");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
|
||||
Logger.t(TAG).d("onJoinChannelSuccess" + channel + "uid:" + uid);
|
||||
//声网进入频道成功日志
|
||||
TRtcEngineManager manager = TRtcEngineManager.get();
|
||||
if (manager != null) {
|
||||
Message message = manager.mRtcEngineHandler.obtainMessage();
|
||||
message.what = RtcEngineHandler.notifyJoinAvRoom;
|
||||
manager.mRtcEngineHandler.sendMessage(message);
|
||||
manager.uid = uid;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRejoinChannelSuccess(String channel, int uid, int elapsed) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLeaveChannel(IRtcEngineEventHandler.RtcStats stats) {
|
||||
Logger.t(TAG).d("onLeaveChannel");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserJoined(int uid, int elapsed) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserOffline(int uid, int reason) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionStateChanged(int state, int reason) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActiveSpeaker(int uid) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLastmileQuality(int quality) {
|
||||
if (quality >= 3) {
|
||||
IMNetEaseManager.postRoomEvent(new RoomEvent().setEvent(RoomEvent.RTC_ENGINE_NETWORK_BAD)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLastmileProbeResult(IRtcEngineEventHandler.LastmileProbeResult result) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetworkQuality(int uid, int txQuality, int rxQuality) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalVideoStats(IRtcEngineEventHandler.LocalVideoStats stats) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteVideoStats(IRtcEngineEventHandler.RemoteVideoStats stats) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalAudioStats(IRtcEngineEventHandler.LocalAudioStats stats) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionInterrupted() {
|
||||
IMNetEaseManager.postRoomEvent(new RoomEvent().setEvent(RoomEvent.RTC_ENGINE_NETWORK_CLOSE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioQuality(int uid, int quality, short delay, short lost) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApiCallExecuted(int error, String api, String result) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTokenPrivilegeWillExpire(String token) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestToken() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMicrophoneEnabled(boolean enabled) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionLost() {
|
||||
IMNetEaseManager.postRoomEvent(new RoomEvent().setEvent(RoomEvent.RTC_ENGINE_NETWORK_CLOSE));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户音量提示回调。
|
||||
*
|
||||
* @param speakers
|
||||
* @param totalVolume
|
||||
*/
|
||||
@Override
|
||||
public void onAudioVolumeIndication(IRtcEngineEventHandler.AudioVolumeInfo[] speakers, int totalVolume) {
|
||||
TRtcEngineManager manager = TRtcEngineManager.get();
|
||||
Message message = manager.mRtcEngineHandler.obtainMessage();
|
||||
message.what = RtcEngineHandler.onAudioVolumeIndication;
|
||||
message.obj = speakers;
|
||||
manager.mRtcEngineHandler.sendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserMuteAudio(int uid, boolean muted) {
|
||||
TRtcEngineManager manager = TRtcEngineManager.get();
|
||||
if (muted) {
|
||||
Message message = manager.mRtcEngineHandler.obtainMessage();
|
||||
message.what = RtcEngineHandler.onUserMuteAudio;
|
||||
message.obj = uid;
|
||||
manager.mRtcEngineHandler.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserMuteVideo(int uid, boolean muted) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserEnableVideo(int uid, boolean enabled) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserEnableLocalVideo(int uid, boolean enabled) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVideoSizeChanged(int uid, int width, int height, int rotation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClientRoleChanged(int oldRole, int newRole) {
|
||||
//角色切换 麦克风切换
|
||||
if (newRole == Constants.CLIENT_ROLE_BROADCASTER) {
|
||||
TRtcEngineManager.get().setMute(TRtcEngineManager.get().isMute);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalUserRegistered(int uid, String userAccount) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserInfoUpdated(int uid, UserInfo userInfo) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioMixingFinished() {//伴奏播放已结束回调
|
||||
IMNetEaseManager.get().getChatRoomEventObservable().onNext(
|
||||
new RoomEvent().setEvent(RoomEvent.METHOD_ON_AUDIO_MIXING_FINISHED)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioEffectFinished(int soundId) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalAudioStateChanged(int state, int error) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalVideoStateChanged(int localVideoState, int error) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRtmpStreamingStateChanged(String url, int state, int errCode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamPublished(String url, int error) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamUnpublished(String url) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTranscodingUpdated() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamInjectedStatus(String url, int uid, int status) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamMessage(int uid, int streamId, byte[] data) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamMessageError(int uid, int streamId, int error, int missed, int cached) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaEngineLoadSuccess() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaEngineStartCallSuccess() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFirstLocalAudioFrame(int i) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFirstRemoteAudioFrame(int uid, int elapsed) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFirstRemoteAudioDecoded(int uid, int elapsed) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVideoStopped() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFirstLocalVideoFrame(int width, int height, int elapsed) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFirstRemoteVideoDecoded(int uid, int width, int height, int elapsed) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFirstRemoteVideoFrame(int uid, int width, int height, int elapsed) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteAudioStateChanged(int i, int i1, int i2, int i3) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteVideoStateChanged(int uid, int state, int reason, int elapsed) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChannelMediaRelayStateChanged(int state, int code) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChannelMediaRelayEvent(int code) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalPublishFallbackToAudioOnly(boolean isFallbackOrRecover) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteSubscribeFallbackToAudioOnly(int uid, boolean isFallbackOrRecover) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioRouteChanged(int routing) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraReady() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraFocusAreaChanged(Rect rect) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraExposureAreaChanged(Rect rect) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRtcStats(IRtcEngineEventHandler.RtcStats stats) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteAudioStats(IRtcEngineEventHandler.RemoteAudioStats remoteAudioStats) {
|
||||
Logger.t(TAG).d("onRemoteAudioStats uid%d", remoteAudioStats.uid);
|
||||
long uid = (long) remoteAudioStats.uid;
|
||||
// 如果麦上没有这个人,不接收这个人的声音
|
||||
TRtcEngineManager.get().setRemoteMute(uid, !AvRoomDataManager.get().checkIsOnMicByAccount(uid + ""));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteAudioTransportStats(int uid, int delay, int lost, int rxKBitRate) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteVideoTransportStats(int uid, int delay, int lost, int rxKBitRate) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioMixingStateChanged(int state, int errorCode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserSubStreamAvailable(int userId, boolean available) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpeedTest(TRTCCloudDef.TRTCSpeedTestResult currentResult, int finishedCount, int totalCount) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecvSEIMsg(int userId, byte[] data) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSetMixTranscodingConfig(int err, String errMsg) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectOtherRoom(int userID, int err, String errMsg) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisConnectOtherRoom(int err, String errMsg) {
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,274 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import static io.agora.rtc.Constants.AUDIO_PROFILE_MUSIC_STANDARD;
|
||||
import static io.agora.rtc.Constants.AUDIO_SCENARIO_GAME_STREAMING;
|
||||
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.orhanobut.logger.Logger;
|
||||
import com.yizhuan.xchat_android_constants.XChatConstants;
|
||||
import com.yizhuan.xchat_android_core.manager.BaseEngine;
|
||||
import com.yizhuan.xchat_android_core.manager.agora.RtcEngineHandler;
|
||||
import com.yizhuan.xchat_android_core.music.db.bean.LocalMusicBean;
|
||||
import com.yizhuan.xchat_android_core.music.model.PlayerModel;
|
||||
import com.yizhuan.xchat_android_library.utils.config.BasicConfig;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Locale;
|
||||
|
||||
import io.agora.rtc.Constants;
|
||||
import io.agora.rtc.RtcEngine;
|
||||
|
||||
|
||||
/**
|
||||
* @author by 梁馨 on 2020/9/14.
|
||||
*/
|
||||
public class TRtcEngineManager extends BaseEngine {
|
||||
public static String TAG = TRtcEngineManager.class.getSimpleName();
|
||||
@Nullable
|
||||
public TRTCEngineAdapter mRtcEngine;
|
||||
@NonNull
|
||||
public final Handler mRtcEngineHandler = new RtcEngineHandler();
|
||||
@NonNull
|
||||
public final TRtcEngineEventHandler mEngineEventHandler = new TRtcEngineEventHandler();
|
||||
|
||||
private static final class Helper {
|
||||
private static final TRtcEngineManager INSTANCE = new TRtcEngineManager();
|
||||
}
|
||||
|
||||
private TRtcEngineManager() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static TRtcEngineManager get() {
|
||||
return TRtcEngineManager.Helper.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterChannel(long channelId, long uid) {
|
||||
Logger.t(TAG).d("enterChannel channelId:%d", channelId);
|
||||
if (mRtcEngine == null) {
|
||||
try {
|
||||
mRtcEngine = TRTCEngineAdapter.create(BasicConfig.INSTANCE.getAppContext(),String.valueOf(SDKConfig.TX_SDKAPPID), mEngineEventHandler);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
|
||||
}
|
||||
//设置频道模式为直播
|
||||
mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING);
|
||||
mRtcEngine.setAudioProfile(AUDIO_PROFILE_MUSIC_STANDARD, AUDIO_SCENARIO_GAME_STREAMING);
|
||||
mRtcEngine.enableAudioVolumeIndication(600, 3, false);
|
||||
mRtcEngine.setDefaultAudioRoutetoSpeakerphone(true);
|
||||
mRtcEngine.setExternalVideoSource(true, false, true);
|
||||
mRtcEngine.setRecordingAudioFrameParameters(48000, 2, 2, 960);
|
||||
mRtcEngine.setVideoProfile(Constants.VIDEO_PROFILE_360P, false);
|
||||
mRtcEngine.enableDualStreamMode(true);
|
||||
mRtcEngine.setParameters(String.format(Locale.US, "{\"che.audio.headset.monitoring,true\"}"));
|
||||
mRtcEngine.setParameters(String.format(Locale.US, "{\"che.audio.enable.androidlowlatencymode,true\"}"));
|
||||
mRtcEngine.setLogFile(Environment.getExternalStorageDirectory()
|
||||
+ File.separator + BasicConfig.INSTANCE.getAppContext().getPackageName()
|
||||
+ "/log/agora-rtc.log");
|
||||
}
|
||||
mRtcEngine.joinChannel(GenerateTestUserSig.genTestUserSig(String.valueOf(uid)), String.valueOf(channelId), null, (int) uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopAudioMixing() {
|
||||
Logger.t(TAG).d("stopAudioMixing ");
|
||||
if (mRtcEngine != null) {
|
||||
int result = mRtcEngine.stopAudioMixing();
|
||||
isMusicPlaying = false;
|
||||
return result;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetChannel() {
|
||||
Logger.t(TAG).d("resetChannel ");
|
||||
|
||||
if (mRtcEngine != null) {
|
||||
stopAudioMixing();
|
||||
mRtcEngine.leaveChannel();
|
||||
mRtcEngine = null;
|
||||
}
|
||||
mRtcEngineHandler.removeCallbacksAndMessages(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reEnterChannel(long channelId, long uid) {
|
||||
enterChannel(channelId, uid);
|
||||
setRemoteMute(isRemoteMute);
|
||||
setMute(isMute);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void leaveChannel() {
|
||||
Logger.t(TAG).d("leaveChannel ");
|
||||
if (mRtcEngine != null) {
|
||||
stopAudioMixing();
|
||||
mRtcEngine.leaveChannel();
|
||||
TRTCEngineAdapter.destroy();
|
||||
mRtcEngine = null;
|
||||
}
|
||||
mRtcEngineHandler.removeCallbacksAndMessages(null);
|
||||
isMute = false;
|
||||
isRemoteMute = false;
|
||||
needRecord = false;
|
||||
inRoom = false;
|
||||
isAudienceRole = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoteMute(boolean mute) {
|
||||
Logger.t(TAG).d("setRemoteMute mute=" + mute);
|
||||
if (mRtcEngine != null) {
|
||||
int result = mRtcEngine.muteAllRemoteAudioStreams(mute);
|
||||
if (result == 0) {
|
||||
isRemoteMute = mute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnableLoopBack() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemoteMute(long uid, boolean mute) {
|
||||
Logger.t(TAG).d("setRemoteMute uid:%s mute:%s", uid, mute);
|
||||
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.muteRemoteAudioStream((int) uid, mute);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setRole(int role) {
|
||||
Logger.t(TAG).d("setRole role=" + role + ",isAudienceRole:" + isAudienceRole);
|
||||
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.setClientRole(role);
|
||||
isAudienceRole = role == Constants.CLIENT_ROLE_AUDIENCE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMute(boolean mute) {
|
||||
Logger.t(TAG).d("setMute bool:" + mute);
|
||||
if (mRtcEngine == null) {
|
||||
return;
|
||||
}
|
||||
mRtcEngine.muteLocalAudioStream(mute);
|
||||
isMute = mute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adjustAudioMixingVolume(int volume) {
|
||||
Logger.t(TAG).d("adjustAudioMixingVolume" + volume);
|
||||
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.adjustAudioMixingVolume(volume);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void adjustRecordingSignalVolume(int volume) {
|
||||
Logger.t(TAG).d("adjustRecordingSignalVolume volume=" + volume);
|
||||
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.adjustRecordingSignalVolume(volume);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int resumeAudioMixing() {
|
||||
Logger.t(TAG).d("resumeAudioMixing");
|
||||
|
||||
if (mRtcEngine == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int currentPosition = mRtcEngine.getAudioMixingCurrentPosition();
|
||||
int result = 0;
|
||||
if (currentPosition > 0) {
|
||||
result = mRtcEngine.resumeAudioMixing();
|
||||
} else {
|
||||
LocalMusicBean current = PlayerModel.get().getCurrent();
|
||||
startAudioMixing(current.getLocalUri(), false, 1);
|
||||
}
|
||||
|
||||
isMusicPlaying = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pauseAudioMixing() {
|
||||
Logger.t(TAG).d("pauseAudioMixing");
|
||||
if (mRtcEngine == null) {
|
||||
return -1;
|
||||
}
|
||||
int result = mRtcEngine.pauseAudioMixing();
|
||||
isMusicPlaying = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int startAudioMixing(String filePath, boolean loopback, int cycle) {
|
||||
Logger.t(TAG).d("startAudioMixing filePath=" + filePath + " loopback=" + loopback + " cycle=" + cycle);
|
||||
if (mRtcEngine == null || TextUtils.isEmpty(filePath)) {
|
||||
return -1;
|
||||
}
|
||||
mRtcEngine.stopAudioMixing();
|
||||
int result;
|
||||
try {
|
||||
result = mRtcEngine.startAudioMixing(filePath, loopback, false, cycle);
|
||||
} catch (Exception e) {
|
||||
return -1;
|
||||
}
|
||||
isMusicPlaying = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//新方法还没有翻译 还没有验证
|
||||
@Override
|
||||
public int getAudioMixingCurrentPosition() {
|
||||
|
||||
if (mRtcEngine != null) {
|
||||
return -1;
|
||||
}
|
||||
int currentPosition = mRtcEngine.getAudioMixingCurrentPosition();
|
||||
|
||||
Logger.t(TAG).d("getAudioMixingCurrentPosition() returned: " + currentPosition);
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAudioMixingDuration() {
|
||||
if (mRtcEngine == null) {
|
||||
return -1;
|
||||
}
|
||||
return mRtcEngine.getAudioMixingDuration();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setChatRoomOnlineStatus(boolean status) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setASMRMode(boolean enable) {
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Unsupport {
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
||||
public class Utils {
|
||||
|
||||
private static boolean isSpace(final String s) {
|
||||
if (s == null) return true;
|
||||
for (int i = 0, len = s.length(); i < len; ++i) {
|
||||
if (!Character.isWhitespace(s.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return bitmap.
|
||||
*
|
||||
* @param filePath The path of file.
|
||||
* @param maxWidth The maximum width.
|
||||
* @param maxHeight The maximum height.
|
||||
* @return bitmap
|
||||
*/
|
||||
public static Bitmap getBitmap(final String filePath, final int maxWidth, final int maxHeight) {
|
||||
if (isSpace(filePath)) return null;
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
BitmapFactory.decodeFile(filePath, options);
|
||||
options.inSampleSize = calculateInSampleSize(options, maxWidth, maxHeight);
|
||||
options.inJustDecodeBounds = false;
|
||||
return BitmapFactory.decodeFile(filePath, options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the sample size.
|
||||
*
|
||||
* @param options The options.
|
||||
* @param maxWidth The maximum width.
|
||||
* @param maxHeight The maximum height.
|
||||
* @return the sample size
|
||||
*/
|
||||
private static int calculateInSampleSize(final BitmapFactory.Options options,
|
||||
final int maxWidth,
|
||||
final int maxHeight) {
|
||||
int height = options.outHeight;
|
||||
int width = options.outWidth;
|
||||
int inSampleSize = 1;
|
||||
while (height > maxHeight || width > maxWidth) {
|
||||
height >>= 1;
|
||||
width >>= 1;
|
||||
inSampleSize <<= 1;
|
||||
}
|
||||
return inSampleSize;
|
||||
}
|
||||
}
|
@@ -0,0 +1,10 @@
|
||||
package com.yizhuan.xchat_android_core.manager.trtc;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Version {
|
||||
String agora() default "";
|
||||
String trtc() default "";
|
||||
}
|
@@ -7,5 +7,6 @@ public interface RoomAudioSdkType {
|
||||
String SHENGWANG = "shengwang"; //声网
|
||||
String WUJIE = "wujie"; //无界
|
||||
String ZEGO = "zego"; //zego
|
||||
String TRTC = "trtc"; //trtc
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user