修改交友布局
This commit is contained in:
1278
moduleUtil/src/main/java/com/xscm/moduleutil/rtc/AgoraManager.java
Normal file
1278
moduleUtil/src/main/java/com/xscm/moduleutil/rtc/AgoraManager.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
moduleUtil/src/main/java/com/xscm/moduleutil/rtc/Rtc.java
Normal file
114
moduleUtil/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
moduleUtil/src/main/java/com/xscm/moduleutil/rtc/RtcCore.java
Normal file
345
moduleUtil/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
moduleUtil/src/main/java/com/xscm/moduleutil/rtc/RtcManager.java
Normal file
413
moduleUtil/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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user