新年好呀网棍。本來應(yīng)該在放假前寫完這篇的兼蜈,比較忙,年前要發(fā)一個小版本序宦,所以推遲到了年后了睁壁。
新的一年,新的開始互捌,新的征程潘明。
??做為一個多年娛樂社交軟件開發(fā)者,接觸最多的就是接入各種SDK秕噪,包括什么友盟钳降、極光、創(chuàng)藍(lán)腌巾、騰訊云遂填、阿里云铲觉、網(wǎng)易云、亞馬遜等等吓坚。其中和項目掛鉤比較緊的撵幽,比如直播、實時語音礁击、實時視頻等也比較多盐杂,從開始接觸到現(xiàn)在,直播接觸過七牛云客税、阿里云况褪、騰訊云、網(wǎng)宿更耻,實時音視頻接觸過騰訊云测垛、聲網(wǎng)、zego秧均。各家的sdk接入方面形形色色食侮,也大同小異。前這段時間項目說需要更換sdk目胡,后續(xù)又說可能需要兼容之前的sdk锯七,本來想著換個就換下,反正之前也接觸過誉己,后來仔細(xì)思考了一下眉尸,還是做一個集合工具,兼容兩家sdk巨双。
??具體的思路是之前在尋找視頻播放器時噪猾,他們有播放內(nèi)核替換的方案,所以在做該功能時筑累,也是借鑒了這個方案袱蜡,同時也參考了工廠模式和單例模式。
??1.根據(jù)業(yè)務(wù)需要慢宗,我們可以先定義一個單例坪蚁,用來初始化sdk,以及提供業(yè)務(wù)需要使用的sdk的方法镜沽,比如推拉流敏晤、開閉麥克風(fēng)、開閉揚聲器缅茉、調(diào)節(jié)聲音等茵典,提供這些方法給業(yè)務(wù)層邏輯調(diào)用。
/**
* 初始化
*/
public void initSDKApi() {
if (mTRTCInterface == null) {
synchronized (TxTRTCController.class) {
if (mTRTCInterface == null) {
mTRTCInterface = new TxTRTCZego();
}
}
}
}
/**
* 開始播放音樂
*/
public void startPlayMusic(int id, String path) {
getSDKEngine().startAudioPlay(id, path);
}
/**
* 恢復(fù)播放音樂
*/
public void resumePlayMusic(int id) {
getSDKEngine().resumeAudioPlay(id);
}
/**
* 暫停播放音樂
*/
public void pausePlayMusic(int id) {
getSDKEngine().pauseAudioPlay(id);
}
/**
* 停止播放音樂
*/
public void stopPlayMusic(int id) {
getSDKEngine().stopAudioPlay(id);
}
/**
* 是否靜音
*/
public void setMuteAllAudio(boolean mute) {
getSDKEngine().setMuteAllAudio(mute);
}
/**
* 發(fā)布流
*
* @param streamId
*/
public void startPublishing(String streamId, boolean openMic) {
getSDKEngine().startPublishingStream(streamId, openMic);
}
/**
* 停止發(fā)布
*/
public void stopPublishing(String streamId) {
getSDKEngine().stopPublishingStream(streamId);
}
與業(yè)務(wù)層相關(guān)聯(lián)的只有這個單例宾舅,不管sdk如何改變统阿,都不會影響到業(yè)務(wù)層的代碼邏輯,也不用修改業(yè)務(wù)層的邏輯筹我,我只需要在這個單例中修改可以了扶平。
具體代碼如下:
public class TxTRTCController {
private static TxTRTCController instance;
public int mBGMId = 1024;//背景音樂ID
public int mSoundEffectId = 1025;//音效ID
private TxTRTCInterface mTRTCInterface;
public TxTRTCController() {
}
public static TxTRTCController getInstance() {
if (instance == null) {
synchronized (TxTRTCController.class) {
if (instance == null) {
instance = new TxTRTCController();
}
}
}
return instance;
}
/**
* 初始化
*/
public void initSDKApi() {
if (mTRTCInterface == null) {
synchronized (TxTRTCController.class) {
if (mTRTCInterface == null) {
mTRTCInterface = new TxTRTCZego();
}
}
}
}
public TxTRTCInterface getSDKEngine() {
initSDKApi();
return mTRTCInterface;
}
/**
* 登錄
*
* @param roomId
*/
public void setLoginRoom(String roomId, boolean video, String quality) {
if (getSDKEngine() == null) return;
if(TxNetConstants.SERVER_IS_TEST){
getSDKEngine().loginRoom(roomId+"dev", video, quality);
}else {
getSDKEngine().loginRoom(roomId, video, quality);
}
}
/**
* 上麥
*/
public void setUpSeat(String roomId) {
getSDKEngine().setUpSeat(roomId);
}
/**
* 下麥
*/
public void setDownSeat(String roomId) {
getSDKEngine().setDownSeat(roomId);
}
/**
* 退出房間
*/
public void setLogoutRoom(String roomId) {
getSDKEngine().logoutRoom(roomId);
}
/**
* 銷毀SDK
*/
public void destroyEngine(String roomId) {
TxRoomJoinGroupUtil.getInstence().quitGroup(roomId);
if(mTRTCInterface!=null) {
getSDKEngine().destroyEngine(roomId);
}
mTRTCInterface = null;
}
//########################################################### 調(diào)用的方法start #####################################################################################################
/**
* 設(shè)置監(jiān)聽
*
* @param musicListener
*/
public void setAudioEffectListener(TxTRTCMusicListener musicListener) {
if(mTRTCInterface instanceof TxTRTCTencent){
getSDKEngine().setAudioEffectListener(TxTRTCInterface.Audio_BGMId,musicListener);
getSDKEngine().setAudioEffectListener(TxTRTCInterface.Audio_SoundEffectId,musicListener);
}else {
getSDKEngine().setAudioEffectListener(TxTRTCInterface.Audio_BGMId,musicListener);
}
}
/**
* 開始播放音樂
*/
public void startPlayMusic(int id, String path) {
getSDKEngine().startAudioPlay(id, path);
}
/**
* 恢復(fù)播放音樂
*/
public void resumePlayMusic(int id) {
getSDKEngine().resumeAudioPlay(id);
}
/**
* 暫停播放音樂
*/
public void pausePlayMusic(int id) {
getSDKEngine().pauseAudioPlay(id);
}
/**
* 停止播放音樂
*/
public void stopPlayMusic(int id) {
getSDKEngine().stopAudioPlay(id);
}
/**
* 設(shè)置人聲
*/
public void setAudioVoiceCaptureVolume(int progress) {
getSDKEngine().setAudioVoiceCaptureVolume(progress);
}
/**
* 設(shè)置背景音樂音量
*
* @param progress
*/
public void setAudioMusicVolume(int id, int progress) {
getSDKEngine().setAudioMusicVolume(id, progress);
}
/**
* 設(shè)置監(jiān)聽
*
* @param listener
*/
public void setCallSDKListener(TxTRTCListener listener) {
getSDKEngine().setCallSDKListener(listener);
}
/**
* 是否關(guān)閉麥克風(fēng)
*/
public void setMicMute(boolean isMute) {
getSDKEngine().setMicMute(isMute);
}
/**
* 是否使用揚聲器
* 揚聲器還是聽筒
*
* @param isHandsFree
*/
public void setHandsFree(boolean isHandsFree) {
getSDKEngine().setHandsFree(isHandsFree);
}
/**
* 是否靜音
*/
public void setMuteAllAudio(boolean mute) {
getSDKEngine().setMuteAllAudio(mute);
}
/**
* 發(fā)布流
*
* @param streamId
*/
public void startPublishing(String streamId, boolean openMic) {
getSDKEngine().startPublishingStream(streamId, openMic);
}
/**
* 停止發(fā)布
*/
public void stopPublishing(String streamId) {
getSDKEngine().stopPublishingStream(streamId);
}
/**
* 停止拉取視頻流(所有流)
*/
public void stopPlayAllVideo(boolean open) {
getSDKEngine().stopPlayAllVideo(open);
}
/**
* 開啟音量回調(diào)
*
* @param enable
*/
public void enableAudioSoundLevelMonitor(boolean enable) {
getSDKEngine().enableAudioSoundLevelMonitor(enable);
}
??2.既然sdk的邏輯調(diào)用抽取出來了,那我們怎么進行內(nèi)核替換呢蔬蕊。這時我想到了工廠模式结澄,提取出一些抽象方法,將不同的sdk作為工廠對象岸夯,這樣在單例中麻献,我只需要初始化相應(yīng)的工廠,獲取到相應(yīng)的對象就行猜扮。
public abstract class TxTRTCInterface {
public static final int Audio_BGMId = 1024;//背景音樂ID
public static final int Audio_SoundEffectId = 1025;//音效ID
public abstract void initSDK();//初始化SDK
public abstract void loginRoom(String roomId, boolean video, String quality);//登錄房間
public abstract void logoutRoom(String roomId);//退出房間
public abstract void setUpSeat(String roomId);//上麥
public abstract void setDownSeat(String roomId);//下麥
public abstract void destroyEngine(String roomId);//銷毀引擎
public abstract void setAudioEffectListener(int id,TxTRTCMusicListener musicListener);//設(shè)置BGM監(jiān)聽
public abstract void startAudioPlay(int id,String path);//播放BGM
public abstract void resumeAudioPlay(int id);//恢復(fù)播放BGM
public abstract void pauseAudioPlay(int id);//暫停播放BGM
public abstract void stopAudioPlay(int id);//停止播放BGM
public abstract void setAudioVoiceCaptureVolume(int progress);//設(shè)置人聲
public abstract void setAudioMusicVolume(int id,int progress);//設(shè)置背景音樂聲音
public abstract void setCallSDKListener(TxTRTCListener listener);//設(shè)置SDK回調(diào)
public abstract void setMicMute(boolean isMute);//是否關(guān)閉麥克風(fēng)
public abstract void setHandsFree(boolean isHandsFree) ;//是否使用揚聲器. 揚聲器還是聽筒
public abstract void setMuteAllAudio(boolean mute);//是否靜音
public abstract void startPublishingStream(String streamId, boolean openMic);//發(fā)布流
public abstract void stopPublishingStream(String streamId) ;//停止發(fā)布
public abstract void stopPlayAllVideo(boolean open);// 停止拉取流(所有流)
public abstract void enableAudioSoundLevelMonitor(boolean enable) ;// 開啟音量回調(diào)
}
抽取的方法大部分sdk都是一樣的勉吻,當(dāng)然也有一些sdk有不同的區(qū)別,這個就需要單獨做一些處理了旅赢。
騰訊sdk:
public class TxTRTCTencent extends TxTRTCInterface {
private TRTCCloud mTRTCCloud;
private TXAudioEffectManager mAudioManager;
public TxTRTCTencent() {
initSDK();
}
@Override
public void initSDK() {
if (mTRTCCloud == null) {
synchronized (TxTRTCTencent.class) {
if (mTRTCCloud == null) {
mTRTCCloud = TRTCCloud.sharedInstance(TxBaseApplication.getContext());
}
if (mAudioManager == null) mAudioManager = mTRTCCloud.getAudioEffectManager();
}
}
}
private TRTCCloud getSDKEngine() {
initSDK();
return mTRTCCloud;
}
@Override
public void loginRoom(String roomId, boolean video, String quality) {
if (getSDKEngine() == null) return;
TRTCCloudDef.TRTCParams tRTCParams = new TRTCCloudDef.TRTCParams((int) TxNetConstants.getTencentImAppid(),
TxUserControl.getInstance().getUserId(),
TxPrefUtils.getString(TxNetConstants.User.USER_IMSIG, ""), roomId, "", "");
tRTCParams.role = TRTCCloudDef.TRTCRoleAnchor;
setHandsFree(true);
getSDKEngine().enterRoom(tRTCParams, TRTCCloudDef.TRTC_APP_SCENE_AUDIOCALL);
}
@Override
public void logoutRoom(String roomId) {
getSDKEngine().exitRoom();
}
@Override
public void setUpSeat(String roomId) {
getSDKEngine().switchRole(TRTCCloudDef.TRTCRoleAnchor);
startLocalAudio();
}
/**
* 開啟音頻預(yù)覽
*/
private void startLocalAudio() {
getSDKEngine().startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_SPEECH);
}
private void stopLocalAudio() {
getSDKEngine().stopLocalAudio();
}
@Override
public void setDownSeat(String roomId) {
getSDKEngine().stopLocalAudio();
stopAudioPlay(Audio_BGMId);
getSDKEngine().switchRole(TRTCCloudDef.TRTCRoleAudience);
}
@Override
public void destroyEngine(String roomId) {
if (mTRTCCloud!= null) {
stopPlayAllVideo(false);
getSDKEngine().stopLocalAudio();
stopPublishingStream(roomId);
logoutRoom(roomId);
}
if (mAudioManager != null) {
mAudioManager.setMusicObserver(Audio_BGMId, null);
mAudioManager.setMusicObserver(Audio_SoundEffectId, null);
}
TRTCCloud.destroySharedInstance();
mTRTCCloud = null;
mAudioManager = null;
}
/**
* 獲取背景音樂管理器
*
* @return
*/
private TXAudioEffectManager getAudioManager() {
if (mAudioManager == null) {
synchronized (TxTRTCTencent.class) {
if (mAudioManager == null) mAudioManager = getSDKEngine().getAudioEffectManager();
}
}
return mAudioManager;
}
@Override
public void setAudioEffectListener(int id, TxTRTCMusicListener musicListener) {
getAudioManager().setMusicObserver(id, null);
getAudioManager().setMusicObserver(id, new TXAudioEffectManager.TXMusicPlayObserver() {
@Override
public void onStart(int id, int errCode) {
if (errCode != 0) {
if (Audio_SoundEffectId == id) {
if (musicListener != null) musicListener.playEnd(id);
} else {
if (musicListener != null) musicListener.playError(id);
}
return;
}
if (musicListener != null) musicListener.playing(id);
}
@Override
public void onPlayProgress(int id, long curPtsMS, long durationMS) {
if (Audio_BGMId == id) {
if (musicListener != null)
musicListener.playProgress(curPtsMS, durationMS);
}
}
@Override
public void onComplete(int id, int errCode) {
if (errCode != 0) {
if (Audio_SoundEffectId == id) {
if (musicListener != null) musicListener.playEnd(id);
} else {
if (musicListener != null) musicListener.playError(id);
}
return;
}
if (musicListener != null) musicListener.playEnd(id);
}
});
}
@Override
public void startAudioPlay(int id, String path) {
TXAudioEffectManager.AudioMusicParam audioMusicParam = new TXAudioEffectManager.AudioMusicParam(id, path);
audioMusicParam.publish = true; //上行
getAudioManager().startPlayMusic(audioMusicParam);
}
@Override
public void resumeAudioPlay(int id) {
getAudioManager().resumePlayMusic(id);
}
@Override
public void pauseAudioPlay(int id) {
getAudioManager().pausePlayMusic(id);
}
@Override
public void stopAudioPlay(int id) {
getAudioManager().stopPlayMusic(id);
}
@Override
public void setAudioVoiceCaptureVolume(int progress) {
getAudioManager().setVoiceCaptureVolume(progress);
}
@Override
public void setAudioMusicVolume(int id, int progress) {
getAudioManager().setMusicPlayoutVolume(id, progress);
getAudioManager().setMusicPublishVolume(id, progress);
}
@Override
public void setCallSDKListener(TxTRTCListener listener) {
getSDKEngine().setListener(null);
getSDKEngine().setListener(new TRTCCloudListener() {
@Override
public void onError(int code, String s, Bundle bundle) {
super.onError(code, s, bundle);
if (listener != null) listener.error(code, s);
}
@Override
public void onEnterRoom(long result) {
super.onEnterRoom(result);
if (listener != null) listener.enterRoom(result);
}
@Override
public void onExitRoom(int i) {
super.onExitRoom(i);
}
@Override
public void onRemoteUserEnterRoom(String userId) {
super.onRemoteUserEnterRoom(userId);
}
@Override
public void onRemoteUserLeaveRoom(String userId, int reason) {
super.onRemoteUserLeaveRoom(userId, reason);
}
@Override
public void onStartPublishing(int errCode, String errMsg) {
super.onStartPublishing(errCode, errMsg);
if (listener != null) listener.publishStreamStateUpdate("",errCode,errMsg);
}
@Override
public void onUserVoiceVolume(ArrayList<TRTCCloudDef.TRTCVolumeInfo> userVolumes, int i) {
super.onUserVoiceVolume(userVolumes, i);
if (listener != null) listener.soundLevelUpdateTencent(userVolumes, i);
}
@Override
public void onUserAudioAvailable(String userId, boolean isVideoAvailable) {
super.onUserAudioAvailable(userId, isVideoAvailable);
/**
* 遠(yuǎn)端用戶開啟/關(guān)閉了麥克風(fēng)
* userId 遠(yuǎn)端用戶ID
* isVideoAvailable true:遠(yuǎn)端用戶打開麥克風(fēng) false:遠(yuǎn)端用戶關(guān)閉麥克風(fēng)
*/
}
@Override
public void onNetworkQuality(TRTCCloudDef.TRTCQuality trtcQuality, ArrayList<TRTCCloudDef.TRTCQuality> arrayList) {
super.onNetworkQuality(trtcQuality, arrayList);
if (TRTCCloudDef.TRTC_QUALITY_Bad == trtcQuality.quality
|| TRTCCloudDef.TRTC_QUALITY_Vbad == trtcQuality.quality
|| TRTCCloudDef.TRTC_QUALITY_Down == trtcQuality.quality) {
if (TRTCCloudDef.TRTC_QUALITY_Down == trtcQuality.quality) {
if (listener != null) listener.networkQuality(true);
} else {
if (listener != null) listener.networkQuality(false);
}
}
}
});
}
@Override
public void setMicMute(boolean isMute) {
getSDKEngine().muteLocalAudio(isMute);
}
@Override
public void setHandsFree(boolean isHandsFree) {
if (isHandsFree) {
getSDKEngine().setAudioRoute(TRTCCloudDef.TRTC_AUDIO_ROUTE_SPEAKER);
} else {
getSDKEngine().setAudioRoute(TRTCCloudDef.TRTC_AUDIO_ROUTE_EARPIECE);
}
}
@Override
public void setMuteAllAudio(boolean mute) {
getSDKEngine().muteAllRemoteAudio(mute);
}
@Override
public void startPublishingStream(String streamId, boolean openMic) {
startLocalAudio();
getSDKEngine().startPublishing(streamId, TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG);
setMicMute(!openMic);
}
@Override
public void stopPublishingStream(String streamId) {
stopLocalAudio();
getSDKEngine().stopPublishing();
}
@Override
public void stopPlayAllVideo(boolean open) {
if (open) {
} else {
getSDKEngine().stopAllRemoteView();
}
}
@Override
public void enableAudioSoundLevelMonitor(boolean enable) {
getSDKEngine().enableAudioVolumeEvaluation(enable ? 400 : 0);
}
}
ZEGOsdk:
public class TxTRTCZego extends TxTRTCInterface {
private final String Zego_Login_RoomId = "Zego_Login_RoomId";//登錄房間的ID
private ZegoMediaPlayer mBGMMediaPlayer, mSoundEffectMediaPlayer;
private int mBGMMediaPlayerIndex = -1, mSoundEffectMediaPlayerIndex = -1;
private TxTRTCMusicListener mMusicListener;
private TxTRTCListener mTRTCListener;
public TxTRTCZego() {
initSDK();
}
@Override
public void initSDK() {
if (0 == TxUserControl.getInstance().getUserZegoAppID()
|| TextUtils.isEmpty(TxUserControl.getInstance().getUserZegoSign())) return;
if (ZegoExpressEngine.getEngine() == null) {
ZegoEngineConfig engineConfig = new ZegoEngineConfig();
engineConfig.advancedConfig.put("audio_device_mode", "4");
engineConfig.advancedConfig.put("init_domain_name", TxUserControl.getInstance().getUserZegoAppUrl());
engineConfig.advancedConfig.put("prep_high_pass_filter", "false");//高通濾波器
ZegoExpressEngine.setEngineConfig(engineConfig);
ZegoEngineProfile profile = new ZegoEngineProfile();
profile.appID = TxUserControl.getInstance().getUserZegoAppID();
profile.application = (Application) TxUiUtils.getContext();
profile.appSign = TxUserControl.getInstance().getUserZegoSign();
profile.scenario = ZegoScenario.GENERAL;
ZegoExpressEngine.createEngine(profile, new IZegoEventHandler() {
@Override
public void onRoomStreamUpdate(String roomID, ZegoUpdateType updateType, ArrayList<ZegoStream> streamList, JSONObject extendedData) {
super.onRoomStreamUpdate(roomID, updateType, streamList, extendedData);
if (updateType == ZegoUpdateType.ADD) {
for (ZegoStream zegoStream : streamList) {
startPlayingStream(zegoStream.streamID, roomID);
TxWriteLogSDCard.writeLog("即構(gòu)Zego--", "開始拉流:" + roomID + "-------" + zegoStream.streamID, null);
}
} else if (updateType == ZegoUpdateType.DELETE) {// callback in UIThread
for (ZegoStream zegoStream : streamList) {
stopPlayingStream(zegoStream.streamID);
TxWriteLogSDCard.writeLog("即構(gòu)Zego--", "停止拉流:" + roomID + "-------" + zegoStream.streamID, null);
}
}
}
@Override
public void onPublisherStateUpdate(String streamID, ZegoPublisherState state, int errorCode, JSONObject extendedData) {
super.onPublisherStateUpdate(streamID, state, errorCode, extendedData);
if (mTRTCListener != null)
mTRTCListener.publishStreamStateUpdate(streamID, errorCode, "");
}
@Override
public void onCapturedSoundLevelUpdate(float soundLevel) {
super.onCapturedSoundLevelUpdate(soundLevel);
if (mTRTCListener != null) mTRTCListener.soundLevelUpdateZegoMine(soundLevel);
}
@Override
public void onRemoteSoundLevelUpdate(HashMap<String, Float> soundLevels) {
super.onRemoteSoundLevelUpdate(soundLevels);
if (mTRTCListener != null) mTRTCListener.soundLevelUpdateZegoOther(soundLevels);
}
@Override
public void onRoomStateUpdate(String roomID, ZegoRoomState state, int errorCode, JSONObject extendedData) {
super.onRoomStateUpdate(roomID, state, errorCode, extendedData);
if (mTRTCListener != null)
mTRTCListener.roomStateUpdateZego(roomID, state, errorCode);
}
});
if (ZegoExpressEngine.getEngine() != null) {
ZegoExpressEngine.getEngine().enableAEC(true);//開/關(guān)回聲消除
ZegoExpressEngine.getEngine().enableHeadphoneAEC(false);//是否在使用耳機時開啟回聲消除
ZegoExpressEngine.getEngine().enableAGC(false);//音頻采集自動增益
ZegoExpressEngine.getEngine().enableANS(true);//音頻采集噪聲抑制
}
}
}
public ZegoExpressEngine getSDKEngine() {
initSDK();
return ZegoExpressEngine.getEngine();
}
@Override
public void loginRoom(String roomId, boolean video, String quality) {
if (getSDKEngine() == null) return;
try {
ZegoAudioConfig audioConfig = new ZegoAudioConfig();
if ("1".equals(quality)) {
audioConfig.bitrate = 192;
} else {
audioConfig.bitrate = 128;
}
audioConfig.channel = ZegoAudioChannel.STEREO;
audioConfig.codecID = ZegoAudioCodecID.NORMAL2;
getSDKEngine().setAudioConfig(audioConfig);
TxWriteLogSDCard.writeLog("Zego--", "LoginRoom--" + roomId, null);
String lastRoomId = null;
if (Hawk.contains(Zego_Login_RoomId)) {
lastRoomId = Hawk.get(Zego_Login_RoomId, "");
}
if (!TextUtils.isEmpty(lastRoomId) && !lastRoomId.equals(roomId)) {
getSDKEngine().logoutRoom(lastRoomId);
}
ZegoRoomConfig config = new ZegoRoomConfig();
config.isUserStatusNotify = true;
Hawk.put(Zego_Login_RoomId, roomId);
getSDKEngine().loginRoom(roomId, new ZegoUser(TxUserControl.getInstance().getUserId(),
TxUserControl.getInstance().getUserName()), config);
} catch (Exception e) {
}
}
@Override
public void logoutRoom(String roomId) {
if (getSDKEngine() == null) return;
getSDKEngine().logoutRoom();
Hawk.delete(Zego_Login_RoomId);
stopPublishingStream(roomId);
getSDKEngine().stopPreview();
}
@Override
public void setUpSeat(String roomId) {
// startPublishingStream(roomId,false);
}
@Override
public void setDownSeat(String roomId) {
setMicMute(true);
stopAudioPlay(Audio_BGMId);
stopPublishingStream(roomId);
}
@Override
public void destroyEngine(String roomId) {
if (ZegoExpressEngine.getEngine() != null) {
if (!TextUtils.isEmpty(roomId)) {
logoutRoom(roomId);
stopPublishingStream(roomId);
getSDKEngine().stopPreview();
}
if (mBGMMediaPlayer != null) {
getSDKEngine().destroyMediaPlayer(mBGMMediaPlayer);
}
if (mSoundEffectMediaPlayer != null) {
getSDKEngine().destroyMediaPlayer(mSoundEffectMediaPlayer);
}
}
Hawk.delete(Zego_Login_RoomId);
setAudioEffectListener(0, null);
setCallSDKListener(null);
ZegoExpressEngine.destroyEngine(new IZegoDestroyCompletionCallback() {
@Override
public void onDestroyCompletion() {
}
});
}
/**
* 獲取背景音樂管理器
*
* @return
*/
private ZegoMediaPlayer getAudioManager(int id) {
if (Audio_SoundEffectId == id) {
if (mSoundEffectMediaPlayer == null) {
synchronized (TxTRTCTencent.class) {
if (mSoundEffectMediaPlayer == null)
mSoundEffectMediaPlayer = getSDKEngine().createMediaPlayer();
mSoundEffectMediaPlayer.muteLocal(false);//可以控制本地靜音播放齿桃。
mSoundEffectMediaPlayer.enableAux(true);//可以將文件的聲音混入正在推的流中。
mSoundEffectMediaPlayer.setEventHandler(new MyIZegoMediaPlayerEventHandler());
mSoundEffectMediaPlayer.setVolume(99);
mSoundEffectMediaPlayerIndex = mSoundEffectMediaPlayer.getIndex();
}
}
return mSoundEffectMediaPlayer;
} else {
if (mBGMMediaPlayer == null) {
synchronized (TxTRTCTencent.class) {
if (mBGMMediaPlayer == null)
mBGMMediaPlayer = getSDKEngine().createMediaPlayer();
mBGMMediaPlayer.muteLocal(false);//可以控制本地靜音播放煮盼。
mBGMMediaPlayer.enableAux(true);//可以將文件的聲音混入正在推的流中短纵。
mBGMMediaPlayer.setEventHandler(new MyIZegoMediaPlayerEventHandler());
mBGMMediaPlayerIndex = mBGMMediaPlayer.getIndex();
}
}
return mBGMMediaPlayer;
}
}
@Override
public void setAudioEffectListener(int id, TxTRTCMusicListener listener) {
mMusicListener = listener;
}
@Override
public void startAudioPlay(int id, String path) {
getAudioManager(id).stop();
getAudioManager(id).loadResource(path, new IZegoMediaPlayerLoadResourceCallback() {
@Override
public void onLoadResourceCallback(int errorCode) {
if (errorCode == 0) {
getAudioManager(id).start();
} else {
if (Audio_SoundEffectId == id) {
if (mMusicListener != null) mMusicListener.playEnd(Audio_SoundEffectId);
} else {
if (mMusicListener != null) mMusicListener.playError(Audio_BGMId);
}
}
}
});
}
@Override
public void resumeAudioPlay(int id) {
getAudioManager(id).resume();
}
@Override
public void pauseAudioPlay(int id) {
getAudioManager(id).pause();
}
@Override
public void stopAudioPlay(int id) {
getAudioManager(id).stop();
}
@Override
public void setAudioVoiceCaptureVolume(int progress) {
getSDKEngine().setCaptureVolume(progress * 2);
}
@Override
public void setAudioMusicVolume(int id, int progress) {
getAudioManager(id).setVolume(progress * 2);
}
@Override
public void setCallSDKListener(TxTRTCListener listener) {
mTRTCListener = listener;
}
@Override
public void setMicMute(boolean isMute) {
getSDKEngine().muteMicrophone(isMute);
}
@Override
public void setHandsFree(boolean isHandsFree) {
getSDKEngine().setAudioRouteToSpeaker(isHandsFree);
}
@Override
public void setMuteAllAudio(boolean mute) {
getSDKEngine().muteSpeaker(mute);
}
@Override
public void startPublishingStream(String streamId, boolean openMic) {
setMicMute(!openMic);
getSDKEngine().startPublishingStream(streamId);
TxWriteLogSDCard.writeLog("Zego--", "startPublishingStream--" + streamId, null);
}
@Override
public void stopPublishingStream(String streamId) {
setMicMute(true);
getSDKEngine().stopPublishingStream();
}
@Override
public void stopPlayAllVideo(boolean open) {
getSDKEngine().muteSpeaker(!open);
}
@Override
public void enableAudioSoundLevelMonitor(boolean enable) {
getSDKEngine().startSoundLevelMonitor(enable ? 400 : 0);
}
/**
* 開始拉流
*
* @param streamId
*/
private void startPlayingStream(String streamId, String roomId) {
try {
if (!TextUtils.isEmpty(roomId)) {
ZegoPlayerConfig config = new ZegoPlayerConfig();
config.roomID = roomId;
getSDKEngine().startPlayingStream(streamId, config);
} else {
getSDKEngine().startPlayingStream(streamId);
}
} catch (Exception e) {
}
}
/**
* 停止拉流
*
* @param streamId
*/
private void stopPlayingStream(String streamId) {
try {
getSDKEngine().stopPlayingStream(streamId);
} catch (Exception e) {
}
}
private class MyIZegoMediaPlayerEventHandler extends IZegoMediaPlayerEventHandler {
private static final String TAG = "MyIZegoExpressMediaplay";
@Override
public void onMediaPlayerStateUpdate(ZegoMediaPlayer mediaPlayer, ZegoMediaPlayerState state, int errorCode) {
// 本回調(diào)在UI線程被回調(diào), 開發(fā)者可以在此進行UI的變化, 例如播放按鈕的變化
if (0 == errorCode) {
if (state == ZegoMediaPlayerState.PLAYING) {//播放中
if (mMusicListener != null)
mMusicListener.playing(mBGMMediaPlayerIndex == mediaPlayer.getIndex() ? Audio_BGMId : Audio_SoundEffectId);
} else if (state == ZegoMediaPlayerState.PAUSING) {//暫停播放
if (mBGMMediaPlayerIndex == mediaPlayer.getIndex()) {
if (mMusicListener != null) mMusicListener.playPause(Audio_BGMId);
} else {
if (mMusicListener != null) mMusicListener.playEnd(Audio_SoundEffectId);
}
} else if (state == ZegoMediaPlayerState.PLAY_ENDED) {//播放結(jié)束
if (mMusicListener != null)
mMusicListener.playEnd(mBGMMediaPlayerIndex == mediaPlayer.getIndex() ? Audio_BGMId : Audio_SoundEffectId);
} else {//不在播放
if (mMusicListener != null)
mMusicListener.playEnd(mBGMMediaPlayerIndex == mediaPlayer.getIndex() ? Audio_BGMId : Audio_SoundEffectId);
}
} else {
if (mMusicListener != null)
mMusicListener.playError(mBGMMediaPlayerIndex == mediaPlayer.getIndex() ? Audio_BGMId : Audio_SoundEffectId);
}
TxWriteLogSDCard.writeLog(TAG, "音樂播放回調(diào) onMediaPlayerStateUpdate:" + state + ";" + errorCode);
}
@Override
public void onMediaPlayerNetworkEvent(ZegoMediaPlayer mediaPlayer, ZegoMediaPlayerNetworkEvent networkEvent) {
// 本回調(diào)在UI線程被回調(diào), 開發(fā)者可以在此進行UI的變化, 例如網(wǎng)絡(luò)不好的情況做友好的提示
}
@Override
public void onMediaPlayerPlayingProgress(ZegoMediaPlayer mediaPlayer, long millisecond) {
// 本回調(diào)在UI線程被回調(diào), 開發(fā)者可以在此進行UI的變化, 例如進度條的變化
if (mBGMMediaPlayerIndex == mediaPlayer.getIndex()) {
if (mMusicListener != null)
mMusicListener.playProgress(millisecond, mediaPlayer.getTotalDuration());
}
}
}
}
??3.替換內(nèi)核 ,只需要單例中在初始化sdk的方法做判斷就行
好了僵控,大致就是這樣了