TRTC 实时音视频,兼容腾讯、ZEGO内核

新年好呀。本来应该在放假前写完这篇的,比较忙,年前要发一个小版本,所以推迟到了年后了。
新的一年,新的开始,新的征程。

  做为一个多年娱乐社交软件开发者,接触最多的就是接入各种SDK,包括什么友盟、极光、创蓝、腾讯云、阿里云、网易云、亚马逊等等。其中和项目挂钩比较紧的,比如直播、实时语音、实时视频等也比较多,从开始接触到现在,直播接触过七牛云、阿里云、腾讯云、网宿,实时音视频接触过腾讯云、声网、zego。各家的sdk接入方面形形色色,也大同小异。前这段时间项目说需要更换sdk,后续又说可能需要兼容之前的sdk,本来想着换个就换下,反正之前也接触过,后来仔细思考了一下,还是做一个集合工具,兼容两家sdk。
  具体的思路是之前在寻找视频播放器时,他们有播放内核替换的方案,所以在做该功能时,也是借鉴了这个方案,同时也参考了工厂模式和单例模式。

  1.根据业务需要,我们可以先定义一个单例,用来初始化sdk,以及提供业务需要使用的sdk的方法,比如推拉流、开闭麦克风、开闭扬声器、调节声音等,提供这些方法给业务层逻辑调用。
 /**
     * 初始化
     */
    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);
    }

    /**
     * 恢复播放音乐
     */
    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);
    }

    /**
     * 发布流
     *
     * @param streamId
     */
    public void startPublishing(String streamId, boolean openMic) {
        getSDKEngine().startPublishingStream(streamId, openMic);
    }

    /**
     * 停止发布
     */
    public void stopPublishing(String streamId) {
        getSDKEngine().stopPublishingStream(streamId);
    }

与业务层相关联的只有这个单例,不管sdk如何改变,都不会影响到业务层的代码逻辑,也不用修改业务层的逻辑,我只需要在这个单例中修改可以了。
具体代码如下:

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


    //###########################################################   调用的方法start  #####################################################################################################


    /**
     * 设置监听
     *
     * @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);
    }

    /**
     * 恢复播放音乐
     */
    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 setAudioVoiceCaptureVolume(int progress) {
        getSDKEngine().setAudioVoiceCaptureVolume(progress);
    }

    /**
     * 设置背景音乐音量
     *
     * @param progress
     */
    public void setAudioMusicVolume(int id, int progress) {
        getSDKEngine().setAudioMusicVolume(id, progress);
    }

    /**
     * 设置监听
     *
     * @param listener
     */
    public void setCallSDKListener(TxTRTCListener listener) {
        getSDKEngine().setCallSDKListener(listener);
    }


    /**
     * 是否关闭麦克风
     */
    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);
    }

    /**
     * 发布流
     *
     * @param streamId
     */
    public void startPublishing(String streamId, boolean openMic) {
        getSDKEngine().startPublishingStream(streamId, openMic);
    }

    /**
     * 停止发布
     */
    public void stopPublishing(String streamId) {
        getSDKEngine().stopPublishingStream(streamId);
    }

    /**
     * 停止拉取视频流(所有流)
     */
    public void stopPlayAllVideo(boolean open) {
        getSDKEngine().stopPlayAllVideo(open);
    }


    /**
     * 开启音量回调
     *
     * @param enable
     */
    public void enableAudioSoundLevelMonitor(boolean enable) {
        getSDKEngine().enableAudioSoundLevelMonitor(enable);
    }
  2.既然sdk的逻辑调用抽取出来了,那我们怎么进行内核替换呢。这时我想到了工厂模式,提取出一些抽象方法,将不同的sdk作为工厂对象,这样在单例中,我只需要初始化相应的工厂,获取到相应的对象就行。
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);//设置BGM监听
    public abstract  void startAudioPlay(int id,String path);//播放BGM
    public abstract  void resumeAudioPlay(int id);//恢复播放BGM
    public abstract  void pauseAudioPlay(int id);//暂停播放BGM
    public abstract  void stopAudioPlay(int id);//停止播放BGM
    public abstract  void setAudioVoiceCaptureVolume(int progress);//设置人声
    public abstract  void setAudioMusicVolume(int id,int progress);//设置背景音乐声音
    public abstract  void setCallSDKListener(TxTRTCListener listener);//设置SDK回调

    public abstract void setMicMute(boolean isMute);//是否关闭麦克风
    public abstract void setHandsFree(boolean isHandsFree) ;//是否使用扬声器. 扬声器还是听筒
    public abstract void setMuteAllAudio(boolean mute);//是否静音
    public abstract void startPublishingStream(String streamId, boolean openMic);//发布流
    public abstract void stopPublishingStream(String streamId) ;//停止发布
    public abstract void stopPlayAllVideo(boolean open);//  停止拉取流(所有流)
    public abstract void enableAudioSoundLevelMonitor(boolean enable) ;// 开启音量回调
}

抽取的方法大部分sdk都是一样的,当然也有一些sdk有不同的区别,这个就需要单独做一些处理了。
腾讯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();
    }

    /**
     * 开启音频预览
     */
    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);
                /**
                 * 远端用户开启/关闭了麦克风
                 * userId 远端用户ID
                 * isVideoAvailable true:远端用户打开麦克风  false:远端用户关闭麦克风
                 */
            }

            @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("即构Zego--", "开始拉流:" + roomID + "-------" + zegoStream.streamID, null);
                        }
                    } else if (updateType == ZegoUpdateType.DELETE) {// callback in UIThread
                        for (ZegoStream zegoStream : streamList) {
                            stopPlayingStream(zegoStream.streamID);
                            TxWriteLogSDCard.writeLog("即构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);//开/关回声消除
                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) {
            // 本回调在UI线程被回调, 开发者可以在此进行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) {//播放结束
                    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, "音乐播放回调 onMediaPlayerStateUpdate:" + state + ";" + errorCode);
        }

        @Override
        public void onMediaPlayerNetworkEvent(ZegoMediaPlayer mediaPlayer, ZegoMediaPlayerNetworkEvent networkEvent) {
            // 本回调在UI线程被回调, 开发者可以在此进行UI的变化, 例如网络不好的情况做友好的提示
        }

        @Override
        public void onMediaPlayerPlayingProgress(ZegoMediaPlayer mediaPlayer, long millisecond) {
            // 本回调在UI线程被回调, 开发者可以在此进行UI的变化, 例如进度条的变化
            if (mBGMMediaPlayerIndex == mediaPlayer.getIndex()) {
                if (mMusicListener != null)
                    mMusicListener.playProgress(millisecond, mediaPlayer.getTotalDuration());
            }
        }
    }
}

  3.替换内核 ,只需要单例中在初始化sdk的方法做判断就行
image.png

好了,大致就是这样了

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容