多人音视频互动直播


多人音视频采用的是媒体流发布和订阅的技术架构。发布是指参会者发布媒体流(即发言,包括视频流和音频流)到服务器,其他人收到发布事件然后去订阅拉取媒体流。

多人音视频里有管理员,主播和观众三种角色。

  • 管理员拥有最高权限,可以发布媒体流,订阅媒体流,设定其他人是主播还是观众
  • 主播可以发布媒体流,订阅媒体流
  • 观众只有订阅媒体流权限

环信多人音视频有2种比较常见的使用模式:多人音视频会议和多人音视频互动直播。2种模式使用的是相同的技术架构,开发者可以根据业务场景设置不同的参数,主要区别是:

  • 多人音视频会议场景中,在创建会议时指定默认角色为主播,即每个参会者加入会议后都可以发言。开发者也可以根据场景需要,设定一些参会者是以观众角色加入会议。
  • 多人音视频互动直播场景中,在创建会议时指定默认角色为观众,除了管理员(同时也可以是主播)以外,其他人默认是观众。管理员可以设置指定观众成主播实现上麦操作;或设置指定主播为观众,实现下麦操作。

多人音视频会议和多人音视频互动直播模式都支持白板、共享桌面。

注意:会议类型将只支持Communication类型,原Large Communication和Live会议类型将弃用。

多人音视频互动直播的基本操作(创建、邀请人、发布流、取消发布流、订阅流、取消订阅流、更新发布流程、离开)对应的接口和回调同多人音视频会议是一样的。也可以说多人音视频互动直播是在多人音视频会议的基础上,增加了角色管理功能。用户加入会议时,除了以主播身份加入外,还可以以观众身份加入。并因此,后续多了上麦、上麦批准、下麦的操作。

以下着重讲解多人音视频互动直播中的角色管理相关知识点。其余部分请直接参考多人音视频会议文档。

以观众身份加入会议

创建者createAndJoin后的角色是Admin,其他成员第一次调用接口EMConferenceManager#joinConference(String confId, String password, EMValueCallBack<EMConference> callback)加入直播后的权限是观众Audience,Audience只能订阅数据流

上麦请求

观众Audience如果想发布数据流 即上麦,需要给管理员发申请。SDK没有提供申请接口,可以通过IM消息申请,也可以通过其他通道自己实现。我们的demo的LiveActivity中有通过IM消息通道申请的示例,可以参考。

sendRequestMessage(content, inviter, Constant.OP_REQUEST_TOBE_SPEAKER);

同样,如果需要下麦操作,也需要通知管理员

sendRequestMessage(content, inviter, Constant.OP_REQUEST_TOBE_AUDIENCE);

上麦请求批准

管理员如果同意Audience上麦,需要调用接口EMConferenceManager#grantRole(String confId, EMConferenceMember member, EMConferenceRole toRole, EMValueCallBack<String> callback)将角色Audience更改为Speaker

EMClient.getInstance().conferenceManager().grantRole(conference.getConferenceId()
        , new EMConferenceMember(jid, null, null)
        , EMConferenceManager.EMConferenceRole.Talker, new EMValueCallBack<String>() {
            @Override
            public void onSuccess(String value) {
                EMLog.i(TAG, "changeRole success, result: " + value);
            }
 
            @Override
            public void onError(int error, String errorMsg) {
                EMLog.i(TAG, "changeRole failed, error: " + error + " - " + errorMsg);
            }
});

成员角色改变后,被改变的成员会在接口EMConferenceManager#onRoleChanged(EMConferenceManager.EMConferenceRole role)中收到回调

public void onRoleChanged(EMConferenceManager.EMConferenceRole role) {
    EMLog.i(TAG, "onRoleChanged, role: " + role);
    currentRole = role;

    if (role == EMConferenceManager.EMConferenceRole.Talker) {
        // 管理员把当前用户角色更改为主播,可以进行publish本地流等操作
    } else if (role == EMConferenceManager.EMConferenceRole.Audience) {
        // 管理员把当前用户角色改变为观众
    }
}

角色变为Speaker发布数据流

角色从Audience变为Speaker,成员就可以发布数据流了

  注意:
  >> MemberName和UserName是两个不同的概念,UserName是环信ID,MemberName是环信AppKey和环信ID拼接成的字符串,可通过接口EasyUtils#getMediaRequestUid(String appKey, String username)获取
  >> 接口中的MemberName参数都是一样的类型