多人音视频会议功能


环信 sdk 在3.3.6版本加上了多人音视频会议功能,此功能可以实现一对多,多对多音视频功能

接口介绍

多人音视频相关接口类在下方列出,对应操作方法都封装在 EMConferenceManager 类中,Demo 实现部分对应的实现在 com.hyphenate.chatuidemo.conference 包下,

EMConference: 音视频会议对象,保存简单的会议信息
EMConferenceListener: 音视频会议回调接口
EMConferenceManager: 音视频会议管理类,封装对音视频会议的操作方法
EMConferenceStream: 音视频会议内成员推流对象,记录流的一些信息
EMStreamParam: 音视频会议推流配置参数类

开始集成

注册会议监听

首先我们需要实现多人音视频的监听,主要监听别人邀请自己加入,以及会议的一些变化;参考 DemoHelper 类以及 ConferenceActivity 类的实现

EMClient.getInstance().conferenceManager().addConferenceListener(new EMConferenceListener() {
    @Override public void onMemberJoined(String username) {
        // 有成员加入
    }

    @Override public void onMemberExited(String username) {
        // 有成员离开
    }

    @Override public void onStreamAdded(EMConferenceStream stream) {
        // 有流加入
    }

    @Override public void onStreamRemoved(EMConferenceStream stream) {
        // 有流移除
    }

    @Override public void onStreamUpdate(EMConferenceStream stream) {
        // 有流更新
    }

    @Override public void onPassiveLeave(int error, String message) {
        // 被动离开
    }

    @Override public void onConferenceState(ConferenceState state) {
        // 聊天室状态回调
    }

    @Override public void onStreamSetup(String streamId) {
        // 流操作成功回调
    }

    @Override public void onReceiveInvite(String confId, String password, String extension) {
        // 收到会议邀请
        if(easeUI.getTopActivity().getClass().getSimpleName().equals("ConferenceActivity")) {
            return;
        }
        Intent conferenceIntent = new Intent(appContext, ConferenceActivity.class);
        conferenceIntent.putExtra(Constant.EXTRA_CONFERENCE_ID, confId);
        conferenceIntent.putExtra(Constant.EXTRA_CONFERENCE_PASS, password);
        conferenceIntent.putExtra(Constant.EXTRA_CONFERENCE_IS_CREATOR, false);
        conferenceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        appContext.startActivity(conferenceIntent);
    }
});

创建并加入会议

这个接口是由创建者调用

EMStreamParam param = new EMStreamParam();
param.setVideoOff(true);
param.setMute(false);
EMClient.getInstance().conferenceManager().createAndJoinConference(password, param, new EMValueCallBack<EMConference>() {
            @Override public void onSuccess(EMConference value) {
                // 这里保存会议对象,用来邀请他人加入
                conference = value;
            }

            @Override public void onError(int error, String errorMsg) {
                EMLog.e(TAG, "create and join conference failed error " + error + ", msg " + errorMsg);
            }
        });

邀请他人加入会议

SDK 默认实现了一个邀请用户加入会议的接口,但是该邀请方法只有对方在线才能收到该邀请,所以建议用户通过发送扩展消息的方式进行自定义邀请

EMClient.getInstance().conferenceManager().inviteUserToJoinConference(conference.getConferenceId(), conference.getPassword(), username, extension, new EMValueCallBack() {
    @Override public void onSuccess(Object value) {
        EMLog.e(TAG, "invite join conference success");
    }

    @Override public void onError(int error, String errorMsg) {
        EMLog.e(TAG, "invite join conference failed " + error + ", " + errorMsg);
    }
});

加入会议

被邀请者需要根据别人邀请自己得到的会议 id 以及会议密码进行加入会议,当加入会议成功后,其他成员会收到 EMConferenceListener.onMemberJoined() 回调

EMStreamParam param = new EMStreamParam();
param.setVideoOff(true);
param.setMute(false);
EMClient.getInstance().conferenceManager().joinConference(confId, password, param, new EMValueCallBack<EMConference>() {
    @Override public void onSuccess(EMConference value) {
        // 同样,这里也需要保存会议对象,被邀请者也可以邀请其他人加入,这里可以自己控制被邀请者是否能够邀请他人加入
        conference = value;
    }
    @Override public void onError(int error, String errorMsg) {
        EMLog.e(TAG, "join conference failed error " + error + ", msg " + errorMsg);
    }
});

推自己的数据

当加入时 sdk 会自动推自己的流数据,不需要手动调用,这个只是在自己取消推之后,想再次推自己的数据才调用, 当推自己的数据成功后,其他成员会收到 EMConferenceListener.onStreamAdded() 回调

EMClient.getInstance().conferenceManager().publish(param, new EMValueCallBack<String>() {
    @Override public void onSuccess(String value) {
    }
    @Override public void onError(int error, String errorMsg) {
    }
});

取消推自己的数据

当推自己的数据成功后,其他成员会收到 EMConferenceListener.onStreamRemoved() 回调

EMClient.getInstance().conferenceManager().unpublish(conference.getPubStreamId(), new EMValueCallBack<String>() {
    @Override public void onSuccess(String value) {
    }
    @Override public void onError(int error, String errorMsg) {
    }
});

订阅会议成员数据

EMClient.getInstance().conferenceManager().subscribe(stream, memberView.getSurfaceView(), new EMValueCallBack<String>() {
    @Override public void onSuccess(String value) {
    }
    @Override public void onError(int error, String errorMsg) {
    }
});

取消订阅成员数据

EMClient.getInstance().conferenceManager().unsubscribe(stream, new EMValueCallBack<String>() {
    @Override public void onSuccess(String value) {
    }
    @Override public void onError(int error, String errorMsg) {
    }
});

离开会议

当离开会议后,其他成员会收到 EMConferenceListener.onMemberExited() 回调

EMClient.getInstance().conferenceManager().exitConference(new EMValueCallBack() {
    @Override public void onSuccess(Object value) {
    }
    @Override public void onError(int error, String errorMsg) {
    }
});

其他方法

// 开启音频传输
EMClient.getInstance().conferenceManager().openVoiceTransfer();
// 关闭音频传输
EMClient.getInstance().conferenceManager().closeVoiceTransfer();
// 开启视频传输
EMClient.getInstance().conferenceManager().openVideoTransfer();
// 关闭视频传输
EMClient.getInstance().conferenceManager().closeVideoTransfer();

PS:以上这四个方法都是修改 stream,群里其他成员都会收到 EMConferenceListener.onStreamUpdate()回调

// 切换摄像头
EMClient.getInstance().conferenceManager().switchCamera();