修改名称。
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
*@author qx
|
||||
*@data 2025/9/18
|
||||
*@description: 加入声网返回
|
||||
*/
|
||||
@Data
|
||||
public class AgoraIsOPen {
|
||||
private boolean isOpen;
|
||||
}
|
||||
1529
BaseModule/src/main/java/com/xscm/moduleutil/rtc/AgoraManager.java
Normal file
1529
BaseModule/src/main/java/com/xscm/moduleutil/rtc/AgoraManager.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,353 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceView;
|
||||
|
||||
import com.blankj.utilcode.util.LogUtils;
|
||||
import com.blankj.utilcode.util.ThreadUtils;
|
||||
import com.xscm.moduleutil.base.CommonAppContext;
|
||||
import com.xscm.moduleutil.event.ColoseCardEvent;
|
||||
import com.xscm.moduleutil.event.SurfaceEvent;
|
||||
import com.xscm.moduleutil.interfaces.SoundLevelUpdateListener;
|
||||
import com.xscm.moduleutil.utils.SpUtil;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import io.agora.musiccontentcenter.IAgoraMusicContentCenter;
|
||||
import io.agora.musiccontentcenter.IAgoraMusicPlayer;
|
||||
import io.agora.musiccontentcenter.Music;
|
||||
import io.agora.musiccontentcenter.MusicContentCenterConfiguration;
|
||||
import io.agora.rtc2.ChannelMediaOptions;
|
||||
import io.agora.rtc2.Constants;
|
||||
import io.agora.rtc2.IRtcEngineEventHandler;
|
||||
import io.agora.rtc2.RtcConnection;
|
||||
import io.agora.rtc2.RtcEngineEx;
|
||||
import io.agora.rtc2.video.VideoCanvas;
|
||||
|
||||
/**
|
||||
* com.xscm.moduleutil.rtc
|
||||
* qx
|
||||
* 2025/10/29
|
||||
*/
|
||||
public class AgoraManagerEx {
|
||||
|
||||
private static volatile AgoraManagerEx instance;
|
||||
private static RtcEngineEx rtcEngineEx;
|
||||
// private RtcEngineEx rtcEngineEx;
|
||||
private static Context context;
|
||||
private boolean isLocalAudioEnabled = true; // 默认开启麦克风
|
||||
// private final List<IRtcEngineEventHandler> eventHandlers = new ArrayList<>();
|
||||
private static IAgoraMusicContentCenter musicContentCenter;
|
||||
private static IAgoraMusicPlayer musicPlayer;
|
||||
private static MusicContentCenterConfiguration contentCenterConfiguration;
|
||||
private static String mRoomId = "";
|
||||
private static long mSongCode;
|
||||
|
||||
private static List<Music> musicList;
|
||||
private static boolean isBjMusic = false;
|
||||
private static List<SoundLevelUpdateListener> soundLevelUpdateListeners = new CopyOnWriteArrayList<>();
|
||||
private static ChannelMediaOptions options;
|
||||
private static RtcConnection connection;
|
||||
private String pkRoomId = "";
|
||||
private static String lastRoomId;
|
||||
|
||||
public int pkUserId;
|
||||
|
||||
public int getPkUserId() {
|
||||
return pkUserId;
|
||||
}
|
||||
|
||||
public void setPkUserId(int pkUserId) {
|
||||
this.pkUserId = pkUserId;
|
||||
}
|
||||
private static boolean isOnJoin = false;
|
||||
public void setLastRoomId(String value) {
|
||||
lastRoomId = value;
|
||||
}
|
||||
|
||||
public String getLastRoomId() {
|
||||
LogUtils.e("上次的房间id:" + lastRoomId);
|
||||
return lastRoomId;
|
||||
}
|
||||
|
||||
private AgoraManagerEx() {
|
||||
|
||||
}
|
||||
|
||||
public static AgoraManagerEx getInstance(Context con) {
|
||||
if (instance == null) {
|
||||
synchronized (AgoraManagerEx.class) {
|
||||
if (instance == null) {
|
||||
instance = new AgoraManagerEx();
|
||||
context = con.getApplicationContext(); // 使用ApplicationContext避免内存泄漏
|
||||
}
|
||||
}
|
||||
}
|
||||
// 确保引擎已初始化
|
||||
if (rtcEngineEx == null) {
|
||||
synchronized (AgoraManagerEx.class) {
|
||||
if (rtcEngineEx == null) {
|
||||
init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void init(String appId) {
|
||||
if (rtcEngineEx != null) {
|
||||
return;
|
||||
};
|
||||
|
||||
synchronized (AgoraManager.class) {
|
||||
if (rtcEngineEx != null) {
|
||||
return;
|
||||
}
|
||||
rtcEngineEx =AgoraManager.getInstance( context).rtcEngine;
|
||||
|
||||
// try {
|
||||
// RtcEngineConfig config = new RtcEngineConfig();
|
||||
// config.mContext = context;
|
||||
// config.mAppId = appId;
|
||||
// config.mEventHandler = getDefaultEventHandler();
|
||||
// config.mChannelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
|
||||
// config.mAudioScenario = Constants.AUDIO_SCENARIO_CHORUS;
|
||||
// config.mAreaCode = 1;
|
||||
//
|
||||
// rtcEngineEx = (RtcEngineEx) RtcEngineEx.create(config);
|
||||
// } catch (Exception e) {
|
||||
// Log.e("AgoraManager", "Failed to create RtcEngine", e);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (rtcEngineEx != null) {
|
||||
// try {
|
||||
// rtcEngineEx.setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY_STEREO,
|
||||
// Constants.AUDIO_SCENARIO_GAME_STREAMING);
|
||||
// rtcEngineEx.enableAudioVolumeIndication(200, 3, true);
|
||||
// rtcEngineEx.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
|
||||
// rtcEngineEx.muteLocalAudioStream(true); // 默认静音
|
||||
// rtcEngineEx.muteAllRemoteAudioStreams(false); // 监听远端的音频
|
||||
//
|
||||
// // 设置参数时添加异常处理
|
||||
// try {
|
||||
// rtcEngineEx.setParameters("{\"che.audio.custom_payload_type\":73}");
|
||||
// rtcEngineEx.setParameters("{\"che.audio.custom_bitrate\":128000}");
|
||||
// rtcEngineEx.setParameters("{\"rtc.enable_nasa2\": true}");
|
||||
// rtcEngineEx.setParameters("{\"rtc.use_audio4\": true}");
|
||||
// rtcEngineEx.setParameters("{" +
|
||||
// "\"rtc.report_app_scenario\":" +
|
||||
// "{" +
|
||||
// "\"appScenario\":" + 100 + "," +
|
||||
// "\"serviceType\":" + 11 + "," +
|
||||
// "\"appVersion\":\"" + rtcEngineEx.getSdkVersion() + "\"" +
|
||||
// "}" +
|
||||
// "}");
|
||||
// rtcEngineEx.setParameters("{\"che.video.mobile_1080p\":true}");
|
||||
// } catch (Exception e) {
|
||||
// Log.w("AgoraManager", "Failed to set parameters", e);
|
||||
// }
|
||||
// /*Enable video module*/
|
||||
// rtcEngineEx.enableVideo();
|
||||
// /*Set up to play remote sound with receiver*/
|
||||
// rtcEngineEx.setDefaultAudioRoutetoSpeakerphone(true);
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// Log.e("AgoraManager", "Failed to configure rtcEngineEx", e);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
private static IRtcEngineEventHandler getDefaultEventHandler() {
|
||||
return new IRtcEngineEventHandler() {
|
||||
|
||||
@Override
|
||||
public void onRemoteAudioStateChanged(int uid, int state, int reason, int elapsed) {
|
||||
super.onRemoteAudioStateChanged(uid, state, reason, elapsed);
|
||||
LogUtils.e("onRemoteAudioStateChanged", "uid------>" + uid, "state------>" + state, "reason------>" + reason, "elapsed------>" + elapsed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserMuteAudio(int uid, boolean muted) {
|
||||
super.onUserMuteAudio(uid, muted);
|
||||
LogUtils.e("onUserMuteAudio", "uid------>" + uid, "muted------>" + muted);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
|
||||
LogUtils.e("onJoinChannelSuccess", "channel------>" + channel, "uid------>" + uid, "elapsed------>" + elapsed);
|
||||
if (!isOnJoin) {
|
||||
AgoraIsOPen isOPen = new AgoraIsOPen();
|
||||
isOPen.setOpen(true);
|
||||
EventBus.getDefault().post(isOPen);
|
||||
isOnJoin = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserJoined(int uid, int elapsed) {//远端用户加入频道
|
||||
|
||||
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
|
||||
if (listener != null) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
// 远程用户音量变化
|
||||
listener.userJoined(uid, elapsed);
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserOffline(int uid, int reason) {//远端用户离开频道
|
||||
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
|
||||
if (listener != null) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
// 远程用户音量变化
|
||||
listener.userOffline(uid, reason);
|
||||
// }
|
||||
});
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioVolumeIndication(AudioVolumeInfo[] speakers, int totalVolume) {
|
||||
super.onAudioVolumeIndication(speakers, totalVolume);
|
||||
|
||||
if (speakers == null || speakers.length == 0) return;
|
||||
|
||||
for (final AudioVolumeInfo info : speakers) {
|
||||
final int uid = info.uid;
|
||||
final int volume = info.volume;
|
||||
|
||||
// 回调所有监听器
|
||||
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
|
||||
if (listener != null) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
// 远程用户音量变化
|
||||
listener.onRemoteSoundLevelUpdate(uid > 0 ? String.valueOf(uid) : SpUtil.getUserId() + "", volume);
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocalVideoStateChanged(Constants.VideoSourceType source, int state, int reason) {
|
||||
super.onLocalVideoStateChanged(source, state, reason);
|
||||
if (state == Constants.LOCAL_VIDEO_STREAM_STATE_CAPTURING && source.getValue() == Constants.VIDEO_SOURCE_SCREEN_PRIMARY) {
|
||||
options.publishScreenCaptureAudio = true;
|
||||
options.publishScreenCaptureVideo = true;
|
||||
options.publishCameraTrack = false;
|
||||
rtcEngineEx.updateChannelMediaOptions(options);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFirstRemoteAudioFrame(int uid, int elapsed) {
|
||||
super.onFirstRemoteAudioFrame(uid, elapsed);
|
||||
Log.i("RoomCabinFragment", "onFirstRemoteAudioFrame: uid->" + uid);
|
||||
|
||||
|
||||
}
|
||||
// 可继续扩展其他回调...
|
||||
|
||||
|
||||
@Override
|
||||
public void onFirstRemoteVideoFrame(int uid, int width, int height, int elapsed) {
|
||||
super.onFirstRemoteVideoFrame(uid, width, height, elapsed);
|
||||
SurfaceView renderView = new SurfaceView(context);
|
||||
SurfaceEvent surfaceEvent = new SurfaceEvent();
|
||||
surfaceEvent.setSurfaceView(renderView);
|
||||
surfaceEvent.setType(2);
|
||||
rtcEngineEx.setupRemoteVideo(new VideoCanvas(renderView, Constants.RENDER_MODE_FIT, uid));
|
||||
EventBus.getDefault().post(surfaceEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteVideoStateChanged(int uid, int state, int reason, int elapsed) {
|
||||
super.onRemoteVideoStateChanged(uid, state, reason, elapsed);
|
||||
Log.i("RoomCabinFragment", "onRemoteVideoStateChanged:uid->" + uid + ", state->" + state);
|
||||
if (state == Constants.REMOTE_AUDIO_STATE_STOPPED) {
|
||||
ColoseCardEvent renderView = new ColoseCardEvent();
|
||||
EventBus.getDefault().post(renderView);
|
||||
} else if (state == Constants.REMOTE_AUDIO_STATE_STARTING) {
|
||||
|
||||
SurfaceView renderView = new SurfaceView(context);
|
||||
rtcEngineEx.setupRemoteVideo(new VideoCanvas(renderView, Constants.RENDER_MODE_FIT, uid));
|
||||
SurfaceEvent surfaceEvent = new SurfaceEvent();
|
||||
surfaceEvent.setSurfaceView(renderView);
|
||||
surfaceEvent.setType(2);
|
||||
EventBus.getDefault().post(surfaceEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int err) {
|
||||
super.onError(err);
|
||||
}
|
||||
};
|
||||
}
|
||||
public void joinChannelEx(String token, String channelId, String pkUserIds) {
|
||||
if (rtcEngineEx != null) {
|
||||
options = new ChannelMediaOptions();
|
||||
options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
|
||||
options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
|
||||
options.publishMicrophoneTrack = true; // 是否发布麦克风音频
|
||||
options.enableAudioRecordingOrPlayout = true;
|
||||
options.autoSubscribeAudio = true;
|
||||
connection = new RtcConnection();
|
||||
connection.channelId = channelId;
|
||||
connection.localUid = SpUtil.getUserId();
|
||||
pkRoomId = channelId;
|
||||
pkUserId = Integer.parseInt(pkUserIds);
|
||||
rtcEngineEx.joinChannelEx(token, connection, options, getDefaultEventHandler());
|
||||
muteAllRemoteAudioStreamsEx(true);
|
||||
muteAllRemoteAudioStreamsExUserId(false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void muteAllRemoteAudioStreamsEx(boolean enabled) {
|
||||
if (rtcEngineEx == null) {
|
||||
init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
}
|
||||
if (rtcEngineEx != null) {
|
||||
rtcEngineEx.muteAllRemoteAudioStreamsEx(enabled, connection);
|
||||
}
|
||||
}
|
||||
|
||||
public void muteLocalAudioStreamEx(boolean enabled) {
|
||||
if (rtcEngineEx == null) {
|
||||
init(CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId());
|
||||
}
|
||||
// 正确做法
|
||||
rtcEngineEx.muteLocalAudioStreamEx(enabled, connection);
|
||||
}
|
||||
|
||||
public void muteAllRemoteAudioStreamsExUserId(boolean enabled){
|
||||
if (rtcEngineEx != null){
|
||||
rtcEngineEx.muteRemoteAudioStreamEx(pkUserId,enabled,connection);
|
||||
}
|
||||
}
|
||||
|
||||
public void leaveChannelEx(String mRoomId, int uid) {
|
||||
if (rtcEngineEx != null) {
|
||||
RtcConnection connection = new RtcConnection();
|
||||
connection.channelId = mRoomId;
|
||||
connection.localUid = uid;
|
||||
rtcEngineEx.leaveChannelEx(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* @Author lxj$
|
||||
* @Time $ $
|
||||
* @Description $
|
||||
*/
|
||||
public class MeForegroundService extends Service {
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.agora.musiccontentcenter.Music;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MusicBean {
|
||||
private List<Music> musicList;
|
||||
private int page;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MusicFileBean {
|
||||
private byte[] fileData ;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class MusicPlayBean {
|
||||
private long position;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
import com.blankj.utilcode.util.ObjectUtils;
|
||||
import com.blankj.utilcode.util.ThreadUtils;
|
||||
import com.xscm.moduleutil.interfaces.SoundLevelUpdateListener;
|
||||
import com.xscm.moduleutil.utils.SpUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.agora.rtc2.Constants;
|
||||
import io.agora.rtc2.IRtcEngineEventHandler;
|
||||
|
||||
|
||||
public class MyIRtcEngineEventHandler extends IRtcEngineEventHandler {
|
||||
|
||||
private RtcEventListener mRtcEventListener;
|
||||
private List<SoundLevelUpdateListener> soundLevelUpdateListeners;
|
||||
|
||||
|
||||
public MyIRtcEngineEventHandler(RtcEventListener mRtcEventListener) {
|
||||
this.mRtcEventListener = mRtcEventListener;
|
||||
}
|
||||
|
||||
public MyIRtcEngineEventHandler(RtcEventListener mRtcEventListener,List<SoundLevelUpdateListener> soundLevelUpdateListeners) {
|
||||
this.soundLevelUpdateListeners = soundLevelUpdateListeners;
|
||||
this.mRtcEventListener = mRtcEventListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接状态
|
||||
*
|
||||
* @param state
|
||||
* @param reason
|
||||
*/
|
||||
@Override
|
||||
public void onConnectionStateChanged(final int state, int reason) {
|
||||
try {
|
||||
if (mRtcEventListener != null) {
|
||||
ThreadUtils.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
switch (state) {
|
||||
case Constants.CONNECTION_STATE_CONNECTED:
|
||||
mRtcEventListener.onRoomConnected();
|
||||
break;
|
||||
case Constants.CONNECTION_STATE_DISCONNECTED:
|
||||
mRtcEventListener.onRoomDisConnect();
|
||||
break;
|
||||
case Constants.CONNECTION_STATE_CONNECTING:
|
||||
mRtcEventListener.onRoomconnecting();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 声浪
|
||||
*
|
||||
* @param speakers
|
||||
* @param totalVolume
|
||||
*/
|
||||
@Override
|
||||
public void onAudioVolumeIndication(AudioVolumeInfo[] speakers, int totalVolume) {
|
||||
for (final AudioVolumeInfo info : speakers) {
|
||||
|
||||
if (mRtcEventListener != null)
|
||||
ThreadUtils.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mRtcEventListener.onRemoteSoundLevelUpdate(String.valueOf(info.uid), info.volume);
|
||||
}
|
||||
});
|
||||
if (!ObjectUtils.isEmpty(soundLevelUpdateListeners)) {
|
||||
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
|
||||
if (listener != null) {
|
||||
listener.onRemoteSoundLevelUpdate(info.uid > 0 ? String.valueOf(info.uid) : SpUtil.getUserId()+"", info.volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAudioMixingStateChanged(final int state, int errorCode) {
|
||||
if (mRtcEventListener != null) {
|
||||
ThreadUtils.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
switch (state) {
|
||||
case 3:
|
||||
mRtcEventListener.playIng();
|
||||
break;
|
||||
case 1:
|
||||
mRtcEventListener.pausIng();
|
||||
break;
|
||||
case 2:
|
||||
mRtcEventListener.playEnded();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
114
BaseModule/src/main/java/com/xscm/moduleutil/rtc/Rtc.java
Normal file
114
BaseModule/src/main/java/com/xscm/moduleutil/rtc/Rtc.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
|
||||
import com.xscm.moduleutil.bean.room.Config;
|
||||
|
||||
public interface Rtc {
|
||||
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @param rtcType rtc类型
|
||||
* @param scenariosType 应用场景
|
||||
*/
|
||||
void init(int rtcType, int scenariosType, Config config);
|
||||
|
||||
/**
|
||||
* 进入房间
|
||||
*
|
||||
* @param roomId
|
||||
* @param userId
|
||||
* @param userName
|
||||
* @param token
|
||||
*/
|
||||
void loginRoom(String roomId, String userId, String userName, String token);
|
||||
|
||||
|
||||
/**
|
||||
* 离开房间
|
||||
*/
|
||||
void leaveChannel(String roomId);
|
||||
|
||||
|
||||
/**
|
||||
* 设置变声
|
||||
*
|
||||
* @param type
|
||||
*/
|
||||
// void setTone(int type);
|
||||
|
||||
|
||||
/**
|
||||
* 是否开启耳返
|
||||
*
|
||||
* @param b
|
||||
*/
|
||||
void enableHeadphoneMonitor(boolean b);
|
||||
|
||||
|
||||
/**
|
||||
* 设置耳返音量
|
||||
*
|
||||
* @param volume
|
||||
*/
|
||||
void setHeadphoneMonitorVolume(int volume);
|
||||
|
||||
/**
|
||||
* 设置音乐播放音量
|
||||
* @param volume
|
||||
*/
|
||||
void setAudioMixingVolume(int volume);
|
||||
|
||||
/**
|
||||
* 播放音乐
|
||||
*
|
||||
* @param url
|
||||
*/
|
||||
void startAudioMixing(String url);
|
||||
|
||||
|
||||
/**
|
||||
* 停止播放音乐
|
||||
*/
|
||||
void stopAudioMixing();
|
||||
|
||||
/**
|
||||
* 暂停音乐播放
|
||||
*/
|
||||
void pauseAudioMixing();
|
||||
|
||||
/**
|
||||
* 恢复播放
|
||||
*/
|
||||
void resumeAudioMixing();
|
||||
|
||||
|
||||
/**
|
||||
* 上麦
|
||||
*
|
||||
* @param streamID
|
||||
*/
|
||||
void applyWheat(String streamID);
|
||||
|
||||
/**
|
||||
* 下麦
|
||||
*/
|
||||
void downWheat();
|
||||
|
||||
|
||||
/**
|
||||
* 开麦,闭麦
|
||||
*
|
||||
* @param b
|
||||
*/
|
||||
void muteLocalAudioStream(boolean b);
|
||||
|
||||
|
||||
/**
|
||||
* 设备静音
|
||||
*/
|
||||
void muteSpeaker(boolean b);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
public class RtcConstants {
|
||||
|
||||
public static final int RtcType_AGORA = 1;//声网
|
||||
public static final int RtcType_ZEGO = 2;//zego
|
||||
public static final int RtcType_CURR = 2;//当前使用的SDK类型
|
||||
|
||||
public static final int SCENARIOSTYPE_TALKING = 1;//语聊
|
||||
public static final int SCENARIOSTYPE_SING = 2;//唱歌
|
||||
public static final int SCENARIOSTYPE_GAME = 0;//游戏
|
||||
|
||||
|
||||
public static final int SOUNDEFFECTTYPE_NONE = 0; //默认原声
|
||||
|
||||
public static final int AUDIO_EFFECT_OFF = 1;//原唱
|
||||
public static final int AUDIO_EFFECT_CPJ = 2;//唱片机
|
||||
public static final int AUDIO_EFFECT_3W = 3;//3维声音
|
||||
public static final int AUDIO_EFFECT_XN = 4;//虚拟环绕
|
||||
public static final int AUDIO_EFFECT_KTV = 5;//ktv
|
||||
|
||||
public static final int SOUNDEFFECTTYPE_CHANGE_VOICE1 = 6;//萝莉
|
||||
public static final int SOUNDEFFECTTYPE_CHANGE_VOICE2 = 7;//大叔
|
||||
public static final int SOUNDEFFECTTYPE_CHANGE_VOICE3 = 8;//绿巨人
|
||||
public static final int SOUNDEFFECTTYPE_CHANGE_VOICE4 = 9;//大堂
|
||||
public static final int SOUNDEFFECTTYPE_CHANGE_VOICE5 = 10;//山谷
|
||||
public static final int SOUNDEFFECTTYPE_CHANGE_VOICE6 = 6;//山谷
|
||||
|
||||
|
||||
}
|
||||
345
BaseModule/src/main/java/com/xscm/moduleutil/rtc/RtcCore.java
Normal file
345
BaseModule/src/main/java/com/xscm/moduleutil/rtc/RtcCore.java
Normal file
@@ -0,0 +1,345 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.xscm.moduleutil.interfaces.SoundLevelUpdateListener;
|
||||
import com.xscm.moduleutil.utils.SpUtil;
|
||||
import com.tencent.liteav.base.Log;
|
||||
import com.tencent.liteav.base.ThreadUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import io.agora.karaoke_view.v11.downloader.LyricsFileDownloader;
|
||||
import io.agora.mediaplayer.IMediaPlayerObserver;
|
||||
import io.agora.mediaplayer.data.CacheStatistics;
|
||||
import io.agora.mediaplayer.data.PlayerPlaybackStats;
|
||||
import io.agora.mediaplayer.data.PlayerUpdatedInfo;
|
||||
import io.agora.mediaplayer.data.SrcInfo;
|
||||
import io.agora.musiccontentcenter.IAgoraMusicContentCenter;
|
||||
import io.agora.musiccontentcenter.IAgoraMusicPlayer;
|
||||
import io.agora.musiccontentcenter.IMusicContentCenterEventHandler;
|
||||
import io.agora.musiccontentcenter.Music;
|
||||
import io.agora.musiccontentcenter.MusicChartInfo;
|
||||
import io.agora.musiccontentcenter.MusicContentCenterConfiguration;
|
||||
import io.agora.rtc2.ChannelMediaOptions;
|
||||
import io.agora.rtc2.Constants;
|
||||
import io.agora.rtc2.IRtcEngineEventHandler;
|
||||
import io.agora.rtc2.RtcEngine;
|
||||
import io.agora.rtc2.RtcEngineConfig;
|
||||
|
||||
public class RtcCore {
|
||||
|
||||
private static volatile RtcCore instance;
|
||||
private RtcEngine rtcEngine;
|
||||
private Context context;
|
||||
|
||||
// 音乐相关
|
||||
private IAgoraMusicContentCenter musicContentCenter;
|
||||
private IAgoraMusicPlayer musicPlayer;
|
||||
private long mSongCode;
|
||||
|
||||
// 麦克风状态
|
||||
private boolean isLocalAudioEnabled = true;
|
||||
|
||||
// 音量监听器
|
||||
private final List<SoundLevelUpdateListener> soundLevelUpdateListeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
private RtcCore(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
}
|
||||
|
||||
public static RtcCore getInstance(Context context) {
|
||||
if (instance == null) {
|
||||
synchronized (RtcCore.class) {
|
||||
if (instance == null) {
|
||||
instance = new RtcCore(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. 初始化 Agora 引擎
|
||||
*/
|
||||
public void initAgora(String appId) {
|
||||
try {
|
||||
RtcEngineConfig config = new RtcEngineConfig();
|
||||
config.mContext = context;
|
||||
config.mAppId = appId;
|
||||
config.mEventHandler = getEventHandler();
|
||||
config.mChannelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
|
||||
config.mAudioScenario = Constants.AUDIO_SCENARIO_GAME_STREAMING;
|
||||
|
||||
rtcEngine = RtcEngine.create(config);
|
||||
if (rtcEngine != null) {
|
||||
rtcEngine.setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_STANDARD_STEREO, Constants.AUDIO_SCENARIO_GAME_STREAMING);
|
||||
rtcEngine.enableAudioVolumeIndication(200, 3, true); // 启用声浪检测
|
||||
rtcEngine.enableLocalAudio(true);
|
||||
rtcEngine.muteLocalAudioStream(false);
|
||||
rtcEngine.setParameters("{\"che.audio.custom_payload_type\":73}");
|
||||
rtcEngine.setParameters("{\"che.audio.custom_bitrate\":128000}");
|
||||
rtcEngine.setParameters("{\"rtc.enable_nasa2\": true}");
|
||||
rtcEngine.setParameters("{\"rtc.use_audio4\": true}");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("RtcCore", "初始化失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 2. 加入房间
|
||||
*/
|
||||
public void joinRoom(String token, String roomId, int uid, boolean isMicrophoneEnabled) {
|
||||
if (rtcEngine == null) return;
|
||||
|
||||
ChannelMediaOptions options = new ChannelMediaOptions();
|
||||
options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
|
||||
options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
|
||||
options.publishMicrophoneTrack = isMicrophoneEnabled;
|
||||
options.autoSubscribeAudio = true;
|
||||
|
||||
rtcEngine.joinChannel(token, roomId, uid, options);
|
||||
setLocalAudioEnabled(isMicrophoneEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* 3. 离开房间
|
||||
*/
|
||||
public void leaveRoom() {
|
||||
if (rtcEngine != null) {
|
||||
rtcEngine.leaveChannel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 4. 播放背景音乐
|
||||
*/
|
||||
public void playBackgroundMusic(long songCode) {
|
||||
if (musicContentCenter == null) {
|
||||
musicContentCenter = IAgoraMusicContentCenter.create(rtcEngine);
|
||||
}
|
||||
if (musicPlayer == null) {
|
||||
musicPlayer = musicContentCenter.createMusicPlayer();
|
||||
}
|
||||
|
||||
MusicContentCenterConfiguration config = new MusicContentCenterConfiguration();
|
||||
config.appId = "your_app_id";
|
||||
config.mccUid = 123456;
|
||||
config.token = SpUtil.getRtmToken();
|
||||
config.eventHandler = getMusicEventHandler();
|
||||
|
||||
musicContentCenter.initialize(config);
|
||||
musicPlayer.registerPlayerObserver(getMediaPlayerObserver());
|
||||
musicPlayer.open(songCode, 0);
|
||||
musicPlayer.play();
|
||||
}
|
||||
|
||||
/**
|
||||
* 5. KTV 功能:预加载歌曲并播放
|
||||
*/
|
||||
public void preloadAndPlaySong(long songCode) {
|
||||
if (musicContentCenter == null || musicPlayer == null) return;
|
||||
|
||||
int code = musicContentCenter.isPreloaded(songCode);
|
||||
if (code < 0) {
|
||||
new android.os.Handler(android.os.Looper.getMainLooper()).postDelayed(() -> {
|
||||
musicContentCenter.preload(songCode);
|
||||
preloadAndPlaySong(songCode);
|
||||
}, 3000);
|
||||
} else {
|
||||
musicPlayer.open(songCode, 0);
|
||||
musicPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 6. 声浪检测回调注册
|
||||
*/
|
||||
public void addSoundLevelListener(SoundLevelUpdateListener listener) {
|
||||
if (listener != null && !soundLevelUpdateListeners.contains(listener)) {
|
||||
soundLevelUpdateListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSoundLevelListener(SoundLevelUpdateListener listener) {
|
||||
if (listener != null) {
|
||||
soundLevelUpdateListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 7. 设置麦克风开关
|
||||
*/
|
||||
public void setLocalAudioEnabled(boolean enabled) {
|
||||
if (rtcEngine != null) {
|
||||
rtcEngine.enableLocalAudio(enabled);
|
||||
rtcEngine.muteLocalAudioStream(!enabled);
|
||||
rtcEngine.setClientRole(enabled ? Constants.CLIENT_ROLE_BROADCASTER : Constants.CLIENT_ROLE_AUDIENCE);
|
||||
isLocalAudioEnabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置远端音频静音
|
||||
*/
|
||||
public void muteRemoteAudio(boolean mute) {
|
||||
if (rtcEngine != null) {
|
||||
rtcEngine.muteAllRemoteAudioStreams(mute);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------- 内部辅助方法 --------------------------
|
||||
|
||||
private IRtcEngineEventHandler getEventHandler() {
|
||||
return new IRtcEngineEventHandler() {
|
||||
@Override
|
||||
public void onAudioVolumeIndication(AudioVolumeInfo[] speakers, int totalVolume) {
|
||||
for (AudioVolumeInfo info : speakers) {
|
||||
int uid = info.uid;
|
||||
int volume = info.volume;
|
||||
for (SoundLevelUpdateListener listener : soundLevelUpdateListeners) {
|
||||
ThreadUtils.runOnUiThread(() -> {
|
||||
// if (uid <= 0) {
|
||||
// listener.onLocalSoundLevelUpdate(volume);
|
||||
// } else {
|
||||
listener.onRemoteSoundLevelUpdate(String.valueOf(uid), volume);
|
||||
// }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IMusicContentCenterEventHandler getMusicEventHandler() {
|
||||
return new IMusicContentCenterEventHandler() {
|
||||
@Override
|
||||
public void onLyricResult(String requestId, long songCode, String lyricUrl, int errorCode) {
|
||||
if (errorCode == 0 && lyricUrl != null) {
|
||||
LyricsFileDownloader.getInstance(context).download(lyricUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSongSimpleInfoResult(String requestId, long songCode, String simpleInfo, int errorCode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreLoadEvent(String requestId, long songCode, int percent, String lyricUrl, int status, int errorCode) {
|
||||
if (errorCode == 0 && percent == 100) {
|
||||
LyricsFileDownloader.getInstance(context).download(lyricUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMusicCollectionResult(String requestId, int page, int pageSize, int total, Music[] list, int errorCode) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMusicChartsResult(String requestId, MusicChartInfo[] list, int errorCode) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private IMediaPlayerObserver getMediaPlayerObserver() {
|
||||
return new IMediaPlayerObserver() {
|
||||
// @Override
|
||||
// public void onPlayerStateChanged(io.agora.mediaplayer.Constants.MediaPlayerState state, io.agora.mediaplayer.Constants.MediaPlayerError error) {
|
||||
// if (state == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_OPEN_COMPLETED) {
|
||||
// musicContentCenter.getLyric(mSongCode, 1);
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void onPlayerStateChanged(io.agora.mediaplayer.Constants.MediaPlayerState state, io.agora.mediaplayer.Constants.MediaPlayerReason reason) {
|
||||
if (state == io.agora.mediaplayer.Constants.MediaPlayerState.PLAYER_STATE_OPEN_COMPLETED) {
|
||||
musicContentCenter.getLyric(mSongCode, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPositionChanged(long positionMs, long timestampMs) {
|
||||
// 可选:发送位置信息到 EventBus 或通知 UI
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerEvent(io.agora.mediaplayer.Constants.MediaPlayerEvent eventCode, long elapsedTime, String message) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMetaData(io.agora.mediaplayer.Constants.MediaPlayerMetadataType type, byte[] data) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayBufferUpdated(long playCachedBuffer) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPreloadEvent(String src, io.agora.mediaplayer.Constants.MediaPlayerPreloadEvent event) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAgoraCDNTokenWillExpire() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerSrcInfoChanged(SrcInfo from, SrcInfo to) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerInfoUpdated(PlayerUpdatedInfo info) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerCacheStats(CacheStatistics stats) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerPlaybackStats(PlayerPlaybackStats stats) {
|
||||
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void onPlayerPlaybackStats(PlayerPlaybackStats stats) {
|
||||
//
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void onAudioVolumeIndication(int volume) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁引擎
|
||||
*/
|
||||
public void destroy() {
|
||||
if (musicPlayer != null) {
|
||||
musicPlayer.destroy();
|
||||
musicPlayer = null;
|
||||
}
|
||||
if (musicContentCenter != null) {
|
||||
musicContentCenter.destroy();
|
||||
musicContentCenter = null;
|
||||
}
|
||||
if (rtcEngine != null) {
|
||||
rtcEngine.leaveChannel();
|
||||
rtcEngine.destroy();
|
||||
rtcEngine = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
/**
|
||||
* @author xf
|
||||
*/
|
||||
public interface RtcDestroyCallback {
|
||||
|
||||
void onDestroySuccess();
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
|
||||
public interface RtcEventListener {
|
||||
|
||||
|
||||
/**
|
||||
* 断开连接
|
||||
*/
|
||||
void onRoomDisConnect();
|
||||
|
||||
/**
|
||||
* 已连接
|
||||
*/
|
||||
void onRoomConnected();
|
||||
|
||||
/**
|
||||
* 连接中
|
||||
*/
|
||||
void onRoomconnecting();
|
||||
|
||||
|
||||
/**
|
||||
* 远端拉流音频声浪回调
|
||||
*/
|
||||
void onRemoteSoundLevelUpdate(String streamID, int soundLevel);
|
||||
|
||||
/**
|
||||
* 不在播放中
|
||||
*/
|
||||
void noPlay();
|
||||
|
||||
/**
|
||||
* 暂停播放
|
||||
*/
|
||||
void pausIng();
|
||||
|
||||
/**
|
||||
* 播放中
|
||||
*/
|
||||
void playIng();
|
||||
|
||||
/**
|
||||
* 播放结束
|
||||
*/
|
||||
void playEnded();
|
||||
|
||||
void destroy();
|
||||
|
||||
}
|
||||
413
BaseModule/src/main/java/com/xscm/moduleutil/rtc/RtcManager.java
Normal file
413
BaseModule/src/main/java/com/xscm/moduleutil/rtc/RtcManager.java
Normal file
@@ -0,0 +1,413 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
|
||||
import static com.xscm.moduleutil.rtc.RtcConstants.SCENARIOSTYPE_GAME;
|
||||
|
||||
import android.app.Application;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.xscm.moduleutil.bean.room.Config;
|
||||
import com.xscm.moduleutil.interfaces.SoundLevelUpdateListener;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import io.agora.rtc2.Constants;
|
||||
import io.agora.rtc2.RtcEngine;
|
||||
|
||||
|
||||
/**
|
||||
* @author xf
|
||||
*/
|
||||
public class RtcManager implements Rtc {
|
||||
|
||||
private final static String TAG = "RTC";
|
||||
|
||||
// private String agoraAppId = CommonAppContext.getInstance().getCurrentEnvironment().getSwSdkAppId();
|
||||
|
||||
private Application mApplication;
|
||||
private static RtcManager instance;
|
||||
private static RtcEventListener mRtcEventListener;
|
||||
private int mRtcType = -1;
|
||||
private static RtcEngine mRtcEngine;
|
||||
private int mScenariosType = -1;
|
||||
private Config mConfig;
|
||||
String mRoomId;
|
||||
String mUserId;
|
||||
String mUserName;
|
||||
String mToken;
|
||||
String mStreamID;
|
||||
private boolean isGame;//是否游戏语音
|
||||
private boolean muteMic = true;//麦克风状态,默认关闭
|
||||
private String audioUrl;
|
||||
|
||||
private List<SoundLevelUpdateListener> soundLevelUpdateListeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
public RtcManager(Application application) {
|
||||
this.mApplication = application;
|
||||
}
|
||||
|
||||
public void addRtcEventListener(RtcEventListener rtcEventListener) {
|
||||
mRtcEventListener = rtcEventListener;
|
||||
}
|
||||
|
||||
public static RtcManager instance(Application application) {
|
||||
if (instance == null) {
|
||||
synchronized (RtcManager.class) {
|
||||
if (instance == null) {
|
||||
instance = new RtcManager(application);
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
public static RtcManager getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void init(int rtcType, int scenariosType, Config config) {
|
||||
this.mRtcType = rtcType;
|
||||
if (rtcType == RtcConstants.RtcType_AGORA) {
|
||||
initAgora(scenariosType);
|
||||
}
|
||||
mScenariosType = scenariosType;
|
||||
mConfig = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginRoom(String roomId, String userId, String userName, String token) {
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
|
||||
//mRtcEngine.joinChannel(token, roomId, "Extra Optional Data", Integer.parseInt(userId));
|
||||
mRtcEngine.joinChannel(token, roomId, "OpenVCall", Integer.parseInt(userId));
|
||||
}
|
||||
}
|
||||
mRoomId = roomId;
|
||||
mUserName = userName;
|
||||
mUserId = userId;
|
||||
mToken = token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leaveChannel(String roomId) {
|
||||
downWheat();
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.leaveChannel();
|
||||
}
|
||||
}
|
||||
mRoomId = null;
|
||||
setGame(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void enableHeadphoneMonitor(boolean b) {
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.enableInEarMonitoring(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHeadphoneMonitorVolume(int volume) {
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.setInEarMonitoringVolume(volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAudioMixingVolume(int volume) {
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.adjustAudioMixingVolume(volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startAudioMixing(String url) {
|
||||
this.audioUrl = url;
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.startAudioMixing(url, false, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopAudioMixing() {
|
||||
this.audioUrl = null;
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.stopAudioMixing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pauseAudioMixing() {
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.pauseAudioMixing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeAudioMixing() {
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.resumeAudioMixing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyWheat(String streamID) {
|
||||
mStreamID = streamID;
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
|
||||
mRtcEngine.enableLocalAudio(true);
|
||||
mRtcEngine.muteLocalAudioStream(muteMic);
|
||||
mRtcEngine.enableAudioVolumeIndication(1000, 3,true);//监听远端说话
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downWheat() {
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.setClientRole(Constants.CLIENT_ROLE_AUDIENCE);
|
||||
mRtcEngine.enableLocalAudio(false);
|
||||
mRtcEngine.muteLocalAudioStream(true);
|
||||
}
|
||||
}
|
||||
mStreamID = "";
|
||||
}
|
||||
|
||||
public void startPublishingStream() {
|
||||
if (!TextUtils.isEmpty(mStreamID)) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void stopPublishingStream() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void muteLocalAudioStream(boolean b) {
|
||||
this.muteMic = b;
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.muteLocalAudioStream(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void muteMicWithNoNetwork(boolean b) {
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.muteLocalAudioStream(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void muteSpeaker(boolean b) {
|
||||
if (mRtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (mRtcEngine != null) {
|
||||
mRtcEngine.muteAllRemoteAudioStreams(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initAgora(int scenariosType) {
|
||||
try {
|
||||
mRtcEngine = RtcEngine.create(mApplication, "4a521d6f1c6343998b1c8fd425dea02a", new MyIRtcEngineEventHandler(mRtcEventListener,soundLevelUpdateListeners));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
switch (scenariosType) {
|
||||
case RtcConstants.SCENARIOSTYPE_SING:
|
||||
mRtcEngine.setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_HIGH_QUALITY_STEREO, Constants.AUDIO_SCENARIO_GAME_STREAMING);
|
||||
break;
|
||||
default:
|
||||
mRtcEngine.setAudioProfile(Constants.AUDIO_PROFILE_MUSIC_STANDARD_STEREO,
|
||||
Constants.AUDIO_SCENARIO_GAME_STREAMING);
|
||||
break;
|
||||
}
|
||||
|
||||
mRtcEngine.enableLocalAudio(false);
|
||||
mRtcEngine.muteLocalAudioStream(true);
|
||||
}
|
||||
|
||||
|
||||
public void destroy(final RtcDestroyCallback callback) {
|
||||
if (mRtcEngine != null) {
|
||||
RtcEngine.destroy();
|
||||
mRtcEngine = null;
|
||||
if (callback != null) {
|
||||
callback.onDestroySuccess();
|
||||
}
|
||||
}
|
||||
if (mRtcEngine == null ) {
|
||||
if (callback != null) {
|
||||
callback.onDestroySuccess();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止/开启声浪检测
|
||||
*
|
||||
* @param atWheat 停止 true 开启
|
||||
*/
|
||||
public void setSoundLevelMonitor(boolean atWheat) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传即构日志
|
||||
*/
|
||||
public void uploadLog() {
|
||||
|
||||
}
|
||||
|
||||
public void removeRtcEventListener() {
|
||||
mRtcEventListener = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出房閒
|
||||
*/
|
||||
public void leaveChannel() {
|
||||
if (isGame && mRoomId != null) {
|
||||
leaveChannel(mRoomId);
|
||||
setAudioUrl(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void loginRoom(final int rtcType, final int scenariosType, final Config config, final String roomId, final String userId, final String userName, final String token, RtcDestroyCallback rtcDestroyCallback) {
|
||||
if (mRoomId != null && !mRoomId.equals(roomId)) {
|
||||
destroyAndLogin(rtcType, scenariosType, config, roomId, userId, userName, token, rtcDestroyCallback);
|
||||
return;
|
||||
}
|
||||
if (rtcType == mRtcType) {//sdk没切换
|
||||
if (rtcType == RtcConstants.RtcType_AGORA) {
|
||||
if (scenariosType == mScenariosType && mRtcEngine != null) {//场景没切换
|
||||
//mRtcEngine.joinChannel(token, roomId, "Extra Optional Data", Integer.parseInt(userId));
|
||||
mRtcEngine.joinChannel(token, roomId, "OpenVCall", Integer.parseInt(userId));
|
||||
//加入房间先下麦操作 处理进入房间就开始音频推流问题
|
||||
downWheat();
|
||||
if (rtcDestroyCallback != null) {
|
||||
rtcDestroyCallback.onDestroySuccess();
|
||||
}
|
||||
} else {//场景切换了
|
||||
destroyAndLogin(rtcType, scenariosType, config, roomId, userId, userName, token, rtcDestroyCallback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
destroyAndLogin(rtcType, scenariosType, config, roomId, userId, userName, token, rtcDestroyCallback);
|
||||
return;
|
||||
}
|
||||
mRtcType = rtcType;
|
||||
mScenariosType = scenariosType;
|
||||
mConfig = config;
|
||||
mRoomId = roomId;
|
||||
mUserId = userId;
|
||||
mUserName = userName;
|
||||
mToken = token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁并加入房间
|
||||
*
|
||||
* @param rtcType
|
||||
* @param scenariosType
|
||||
* @param config
|
||||
* @param roomId
|
||||
* @param userId
|
||||
* @param userName
|
||||
* @param token
|
||||
* @param rtcDestroyCallback
|
||||
*/
|
||||
public void destroyAndLogin(final int rtcType, final int scenariosType, final Config config, final String roomId, final String userId, final String userName, final String token, final RtcDestroyCallback rtcDestroyCallback) {
|
||||
destroy(new RtcDestroyCallback() {
|
||||
@Override
|
||||
public void onDestroySuccess() {
|
||||
init(rtcType, scenariosType, config);
|
||||
loginRoom(roomId, userId, userName, token);
|
||||
if (rtcDestroyCallback != null) {
|
||||
rtcDestroyCallback.onDestroySuccess();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setGame(boolean game) {
|
||||
isGame = game;
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录H5小游戏
|
||||
*
|
||||
* @param roomId
|
||||
* @param userId
|
||||
* @param userName
|
||||
* @param token
|
||||
*/
|
||||
public void loginRoomGame(String roomId, String userId, String userName, String token) {
|
||||
if (mRtcEngine != null ) {
|
||||
loginRoom(roomId, userId, userName, token);
|
||||
} else {
|
||||
destroyAndLogin(RtcConstants.RtcType_CURR, SCENARIOSTYPE_GAME, null, roomId, userId, userName, token, null);
|
||||
}
|
||||
setGame(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复麦克风状态
|
||||
*/
|
||||
public void resumeMic() {
|
||||
muteLocalAudioStream(muteMic);
|
||||
}
|
||||
|
||||
public void resumeAudio() {
|
||||
if (!TextUtils.isEmpty(audioUrl)) {
|
||||
startAudioMixing(audioUrl);
|
||||
}
|
||||
}
|
||||
|
||||
public void setAudioUrl(String audioUrl) {
|
||||
this.audioUrl = audioUrl;
|
||||
}
|
||||
|
||||
public boolean isMuteMic() {
|
||||
return muteMic;
|
||||
}
|
||||
|
||||
public void addSoundLevelListener(SoundLevelUpdateListener listener) {
|
||||
if (soundLevelUpdateListeners != null) {
|
||||
soundLevelUpdateListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSoundLevelListener(SoundLevelUpdateListener listener) {
|
||||
if (soundLevelUpdateListeners != null) {
|
||||
soundLevelUpdateListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.agora.musiccontentcenter.Music;
|
||||
|
||||
public class SharedViewModel extends AndroidViewModel {
|
||||
private MutableLiveData<List<Music>> musicList = new MutableLiveData<>();
|
||||
private MusicBean musicBean=new MusicBean();
|
||||
|
||||
public SharedViewModel(@NonNull Application application) {
|
||||
super(application);
|
||||
}
|
||||
|
||||
public LiveData<List<Music>> getMusicList() {
|
||||
return musicList;
|
||||
}
|
||||
|
||||
public void setMusicList(List<Music> list) {
|
||||
musicList.postValue(list);
|
||||
}
|
||||
|
||||
public MusicBean getMusicBean() {
|
||||
return musicBean;
|
||||
}
|
||||
|
||||
public void setMusicBean(MusicBean musicBean) {
|
||||
this.musicBean = musicBean;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.xscm.moduleutil.rtc;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* com.xscm.moduleutil.rtc
|
||||
* qx
|
||||
* 2025/11/3
|
||||
* 声网声音管理类
|
||||
*/
|
||||
public class VolumeManager {
|
||||
private static VolumeManager instance;
|
||||
private Map<String, Integer> userMusicVolumeMap = new HashMap<>();
|
||||
private Map<String, Integer> userPlayoutVolumeMap = new HashMap<>();
|
||||
private Map<String, Boolean> userPlayoutBzMap = new HashMap<>();
|
||||
private String currentUserId;
|
||||
|
||||
private VolumeManager() {}
|
||||
|
||||
public static VolumeManager getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (VolumeManager.class) {
|
||||
if (instance == null) {
|
||||
instance = new VolumeManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void setCurrentUserId(String userId) {
|
||||
this.currentUserId = userId;
|
||||
}
|
||||
|
||||
public void saveCurrentVolumes(int musicVolume, int playoutVolume) {
|
||||
if (currentUserId != null) {
|
||||
userMusicVolumeMap.put(currentUserId, musicVolume);
|
||||
userPlayoutVolumeMap.put(currentUserId, playoutVolume);
|
||||
}
|
||||
}
|
||||
public void clearCurrentVolumes() {
|
||||
if (currentUserId != null) {
|
||||
userMusicVolumeMap.remove(currentUserId);
|
||||
userPlayoutVolumeMap.remove(currentUserId);
|
||||
}
|
||||
userPlayoutBzMap.clear();
|
||||
}
|
||||
|
||||
public void saveBz(String userId, boolean bz){
|
||||
userPlayoutBzMap.clear();
|
||||
userPlayoutBzMap.put(userId, bz);
|
||||
}
|
||||
|
||||
public boolean getBz(String userId){
|
||||
Boolean bz = userPlayoutBzMap.get(userId);
|
||||
if (bz == null) {
|
||||
bz = true; // 默认值原唱 false 伴奏
|
||||
}
|
||||
return bz;
|
||||
}
|
||||
|
||||
public int[] getUserVolumes(String userId) {
|
||||
Integer musicVolume = userMusicVolumeMap.get(userId);
|
||||
Integer playoutVolume = userPlayoutVolumeMap.get(userId);
|
||||
|
||||
if (musicVolume == null) {
|
||||
musicVolume = 100; // 默认值
|
||||
}
|
||||
if (playoutVolume == null) {
|
||||
playoutVolume = 50; // 默认值
|
||||
}
|
||||
|
||||
return new int[]{musicVolume, playoutVolume};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user