新增TRTC语音SDK类型

This commit is contained in:
huangjian
2021-11-24 11:33:57 +08:00
parent 89fd7a023b
commit 8185c60bde
18 changed files with 5613 additions and 1 deletions

View File

@@ -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()

View File

@@ -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;

View File

@@ -6,4 +6,5 @@ public enum EngineType {
TYPE_WJ,
TYPE_QTT_AUDIO,
TYPE_ZEGO,
TYPE_TRTC,
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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: 用于生成测试用的 UserSigUserSig 是腾讯云为其云服务设计的一种安全保护签名。
* 其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。
*
* Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
*
* 本文件中的代码虽然能够正确计算出 UserSig但仅适合快速调通 SDK 的基本功能,不适合线上产品,
* 这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
* 一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
*
* 正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
* 由于破解服务器的成本要高于破解客户端 App所以服务器计算的方案能够更好地保护您的加密密钥。
*
* Referencehttps://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);
}
}

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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) {
}
}

View File

@@ -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) {
}
}

View File

@@ -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 {
}

View File

@@ -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;
}
}

View File

@@ -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 "";
}

View File

@@ -7,5 +7,6 @@ public interface RoomAudioSdkType {
String SHENGWANG = "shengwang"; //声网
String WUJIE = "wujie"; //无界
String ZEGO = "zego"; //zego
String TRTC = "trtc"; //trtc
}