互动直播接入流程

网易云通信提供简单的互动直播和连麦接口,只需要创建并加入互动房间即可以实现直播推流;连麦者使用相同的房间名加入互动房间即可以实现实时连麦互动。阅读该章节,您可以迅速完成一个最简单的互动直播房间的创建、加入,快速实现互动直播的功能。

注意: 互动直播需要 Android 4.1 及以上版本的系统,同时推荐主播使用中高端 Android 机器。

在这里需要明确几个基本概念:

另外,理解网易云通信互动直播与音视频音视频通话的关系可以更好地帮助开发者快速集成: 互动直播与多人音视频通话:云通信互动直播基于多人音视频通话开发,通过将多人会议中用户的音视频数据处理后推送给视频流服务器实现直播和实时连麦。在功能的提供上,互动直播复用多人音视频接口,增加互动开关、推流地址指定与切换、直播角色指定等扩展设置。

互动直播房间接入

sequenceDiagram participant 主播 participant Meeting participant 连麦者 participant ... Meeting->>Meeting:创建互动直播房间(createRoom) 主播->>Meeting:加入互动直播房间(joinRoom2) 连麦者->>Meeting:加入互动直播房间(joinRoom2) Meeting->>主播:用户加入房间通知(onUserJoined) Meeting->>主播:播放本地和远端画面 Meeting->>连麦者:离开互动直播房间(leaveRoom2) Meeting->>主播:用户离开房间通知(onUserLeave) Meeting->>Meeting:互动直播状态回调(onLiveEvent)

创建互动直播房间

通过一个房间名 roomName 来创建互动直播房间。

可以传入一个扩展字段 extraMessage。 后续加入房间的用户会收到这个扩展字段。

如果需要兼容 Web 端音视频可以设置字段 webRTCCompatWebRTC从版本4.5.0开始正式商用,如果没有WebRTC客户端参与时不要设置WebRTC相关参数


    /**
     * 创建多人通话房间
     *
     * 如果你需要使用多人会议和互动直播相关功能, 需要通过此接口创建一个多人房间,
     * 然后通过 {@link AVChatManagerLite#joinRoom2(String, AVChatType, AVChatCallback)} 来加入房间。
     * 房间创建成功后会一直保留, 尽量即时使用, 目前有效期为一个月, 超过有效期后再次加入房间会失败。
     * 如果一个房间已经被创建, 那么再次创建时会返回失败, 提示房间已经存在。</p>
     *
     * 房间创建时机不受音视频通话流程限制, 你可以在任意时间预定自己的多人会议房间。创建成功后即可通知所有会议参与者加入此房间,
     * 你将会在 {@link AVChatStateObserverLite#onUserJoined(String)} 中陆续收到不同的用户加入会议。
     *
     * @param roomName     房间名
     * @param extraMessage 自定义的扩展消息, 其它加入房间的用户都会收到
     * @param callback     创建房间回调接口
     * @see AVChatResCode#ERROR_CREATE_ROOM_ALREADY_EXIST
     * @see AVChatManagerLite#createRoom(String, String, boolean, AVChatCallback)
     * @see AVChatManagerLite#joinRoom2(String, AVChatType, AVChatCallback)
     * @see AVChatManagerLite#leaveRoom2(String, AVChatCallback)
     */
    public abstract void createRoom(String roomName,
                                    String extraMessage,
                                    AVChatCallback<AVChatChannelInfo> callback);
参数 说明
roomName 房间名。
extraMessage 自定义的扩展消息, 其它加入房间的用户都会收到。
callback 创建房间回调接口,参考AVChatCallback,参考AVChatChannelInfo
AVChatManager.getInstance().createRoom(roomName, extraMessage, new AVChatCallback<AVChatChannelInfo>() {});

AVChatManager.getInstance().createRoom(roomName, extraMessage, webRTCCompat, new AVChatCallback<AVChatChannelInfo>() {});

互动直播房间类型

网络通话类型分为音频和视频。

/**
 * 网络通话类型枚举
 */
public enum AVChatType {
    /**
     * 未知
     */
    UNKNOWN(-1),
    /**
     * 音频通话
     */
    AUDIO(1),
    /**
     * 视频通话
     */
    VIDEO(2);
}
参数 说明
UNKNOWN 未知。
AUDIO 音频通话。
VIDEO 视频通话。

加入互动直播房间

graph TB B[enableRtc] --> C[setChannelProfile 可选 用于设置音频场景模式 ] C --> D[enableVideo 视频直播需要 ] D --> E[setupVideoCapturer 视频直播需要 ] E --> F[setupLocalVideoRender 视频直播需要 ] F --> G[setParameter/setParameters 可选 用于设置参数 ] G --> H[startVideoPreview 视频直播需要 ] H --> I[joinRoom2]

通过一个房间名 roomName 来加入一个已经创建好的互动直播房间。

加入房间时需要指定自己的会话类型 AVChatType。 主要为音频通话和视频通话两种。

加入房间前需要进行和双人通话流程中类似的开启音视频引擎、设置通话可选参数、视频通话设置等初始化设置。

其中,设置音频场景模式setChannelProfile详见音频场景模式节;设置打开预览startVideoPreview详见开始和停止视频采集节。

主播加入房间前需要通过设置直播可选参数接口 setParameters 打开直播开关(将AVChatParameters#KEY_SESSION_LIVE_MODE参数设置为 true),打开多人模式(将AVChatParameters#KEY_SESSION_MULTI_MODE_USER_ROLE参数设置为 AVChatUserRole.NORMAL ),指定推流地址(将AVChatParameters#KEY_SESSION_LIVE_URL参数设置为推流的地址)。当收到AVChatStateObserver#onCallEstablished 后,主播就开始推流,观众即可使用拉流播放器观看主播直播。

连麦观众加入房间需要打开AVChatParameters#KEY_SESSION_LIVE_MODE 开关,同时不能指定AVChatParameters#KEY_SESSION_LIVE_URL 推流地址。当连麦观众成功加入房间后,其他观众就可以观看到双人连麦互动直播。

连麦画中画混屏模式设置 AVChatParameters#KEY_SESSION_LIVE_COMPOSITING_LAYOUT ,传入一个AVChatLiveCompositingLayout对象。目前支持多种混屏模式设置,可以参考 AVChatLiveCompositingLayout#Mode。互动直播音视频混屏模式,详见混屏模式图文介绍,互动直播音视频混屏自定义布局配置,详见布局参数配置介绍,同时我们提供了一个参数校验工具,帮助开发者校验参数有效性并快速看到布局效果图。

互动直播服务器录制设置 AVChatParameters#KEY_SERVER_LIVE_RECORD , 需要后台开通相关业务。

    /**
     * 激活音视频通话底层引擎
     *
     * 在进行音视频通话前需要调用此接口来激活音视频通话引擎,
     * 否则后续所有的接口调用会导致异常。如果方法调用成功, 后续需要调用  {@link AVChatManagerLite#disableRtc()}
     * 来关闭音视频底层引擎, 否则会出现资源泄漏。
     *
     * @return {@code true} 方法调用成功,{@code false} 方法调用失败
     *
     * @see AVChatManagerLite#disableRtc()
     */
    public abstract boolean enableRtc();

    /**
     * 激活视频模块
     *
     * 如果你通话过程中有视频相关内容, 那必须在视频相关接口调用前先激活视频模块。
     * 通话结束前需要调用  {@link AVChatManagerLite#disableVideo()} 来关闭视频模块。
     * 在通话过程中, 通过此接口可以实现引擎的音视频通话模式切换,
     * 信令层可以通过使用 {@link AVChatManagerLite#sendControlCommand(long, byte, AVChatCallback)} 来通知
     * 对方目前的会话模式切换。 默认情况下视频模块是处于非激活状态。
     *
     * @return {@code true} 方法调用成功,{@code false} 方法调用失败
     *
     * @see AVChatManagerLite#disableVideo()
     */
    public abstract boolean enableVideo();

    /**
     * 设置一个视频捕获器用于提供视频输入, 每次通话只需设置一次
     * 可以使用{@link AVChatVideoCapturerFactory#createCameraCapturer()}创建一个相机捕获器
     * 该方法需要在{@link AVChatManager#startVideoPreview()}前调用
     *
     * @param videoCapturer 视频采集
     * @return {@code true} 方法调用成功,{@code false} 方法调用失败
     * @see com.netease.nimlib.sdk.avchat.model.AVChatCameraCapturer
     * @see AVChatVideoCapturerFactory#createCameraCapturer()
     * @see com.netease.nimlib.sdk.avchat.model.AVChatExternalVideoCapturer
     */
    public abstract boolean setupVideoCapturer(AVChatVideoCapturer videoCapturer);

    /**
     * 设置本地用户视频画布。
     * 如果需要预览,设置自己视频画面的画布需要在call或者joinRoom的onSuccess回调中调用.
     * 如果不需要预览,设置自己视频画面的画布需要在 AVChatStateObserver#onCallEstablished 后调用.
     *
     * @param render      画布. {@link AVChatSurfaceViewRenderer}, {@link AVChatExternalVideoRender}, {@link AVChatTextureViewRenderer}
     * @param mirror      绘制是否镜像, 设置画布为 {@link AVChatSurfaceViewRenderer} 时有效
     * @param scalingType 绘制模式, 设置画布为 {@link AVChatSurfaceViewRenderer} 时有效
     * @return {@code true} 方法调用成功,{@code false} 方法调用失败
     * @see com.netease.nimlib.sdk.avchat.constant.AVChatVideoScalingType
     */
    public abstract boolean setupLocalVideoRender(IVideoRender render, boolean mirror, int scalingType);

   /**
     * 设置参数。
     * 参数类型参考 {@link AVChatParameters.Key#type()}。
     * 参数可设置时机参考 {@link AVChatParameters.Key#runtime()},支持 {@code runtime} 代表通话过程中可操作,不支持则仅能通话前操作。
     * 参数是否可设置参考 {@link AVChatParameters.Key#writable()}, 支持 {@code writable} 代表能够设置参数值,不支持则仅能获取参数值。
     *
     * @param params 设置参数
     * @throws IllegalArgumentException 参数值非法或者参数不支持运行时设置
     * @see AVChatParameters
     * @see AVChatParameters.Key
     * @see AVChatMediaCodecMode
     * @see AVChatAudioEffectMode
     */
    public abstract void setParameters(AVChatParameters params) throws IllegalArgumentException;
    /**
     * 加入已经预先创建的多人会议房间
     *
     * 加入一个多人会议房间前需要调用以下接口:
     *
     *     开启音视频引擎  {@link AVChatManagerLite#enableRtc()}
     *     可选, 激活视频模块 {@link AVChatManagerLite#enableVideo()}
     *     可选, 设置本地预览画布,{@link AVChatManagerLite#setupLocalVideoRender(IVideoRender, boolean, int)}
     *     可选, 开启视频预览,{@link AVChatManagerLite#startVideoPreview()}
     *     可选, 通话相关参数设置 {@link AVChatManagerLite#setParameters(AVChatParameters)}
     *
     * 当你成功加入会议后, 你会收到 {@link AVChatStateObserverLite#onUserJoined(String)} 来通知目前会议室内已经存在的用户。
     * 在离开房间时需要调用 {@link AVChatManagerLite#leaveRoom2(String, AVChatCallback)}。
     *
     * 多人会议的加入其他用户是不会收到信令层的通知,只能通过媒体层的通知来获取用户加入 {@link AVChatStateObserverLite#onUserJoined(String)}。
     *
     * 如果你的产品加入多人会议是为了进行互动直播, 那么你还需要额外设置以下参数 {@link AVChatManagerLite#setParameter(AVChatParameters.Key, Object)}:
     *     打开互动直播模式, {@link AVChatParameters#KEY_SESSION_LIVE_MODE}
     *     如果你是主播, 还需要设置推流地址 {@link AVChatParameters#KEY_SESSION_LIVE_URL}
     *
     * @param roomName 房间名
     * @param callType 房间通话类型
     * @param callback 加入房间回调接口
     *
     * @see AVChatManagerLite#createRoom(String, String, AVChatCallback)
     * @see AVChatManagerLite#createRoom(String, String, boolean, AVChatCallback)
     * @see AVChatManagerLite#leaveRoom2(String, AVChatCallback)
     */
    public abstract void joinRoom2(String roomName,
                                   final AVChatType callType,
                                   AVChatCallback<AVChatData> callback);
参数 说明
roomName 房间名。
callType 房间通话类型,UNKNOWN未知,AUDIO音频通话,VIDEO视频通话。参考AVChatType
callback 加入房间回调接口,参考AVChatCallback,参考AVChatData
//开启音视频引擎
AVChatManager.getInstance().enableRtc();
//设置场景, 如果需要高清音乐场景,设置 AVChatChannelProfile#CHANNEL_PROFILE_HIGH_QUALITY_MUSIC
AVChatManager.getInstance.setChannelProfile(CHANNEL_PROFILE_DEFAULT);
//设置通话可选参数
AVChatParameters parameters = new AVChatParameters();
AVChatManager.getInstance().setParameters(parameters);
//视频通话设置
AVChatManager.getInstance().enableVideo();
AVChatManager.getInstance().setupLocalVideoRender(IVideoRender render, boolean mirror, int scalingType);
//设置视频采集模块
AVChatCameraCapturer videoCapturer = AVChatVideoCapturerFactory.createCameraCapturer();
AVChatManager.getInstance().setupVideoCapturer(videoCapturer);
//设置视频质量调整策略
AVChatManager.getInstance().setVideoQualityStrategy(boolean preferImageQuality);
//开启视频预览
AVChatManager.getInstance().startVideoPreview();
//加入房间
AVChatManager.getInstance().joinRoom2(roomName, callType, new AVChatCallback<AVChatData>() {});

注意: (1)超时挂断请在APP上层实现,sdk未来会移除超时相关接口,可以参考demo中的AVChatTimeoutObserver类进行实现。 (2)在通话时可以根据需要设置与取消画布,示例如下:

        //取消用户的画布
        AVChatManager.getInstance().setupLocalVideoRender(null, false, 0);

        AVChatManager.getInstance().setupRemoteVideoRender(user, null, false, 0);

        //设置用户的画布
        AVChatManager.getInstance().setupLocalVideoRender(render1, false, AVChatVideoScalingType.SCALE_ASPECT_BALANCED);

        AVChatManager.getInstance().setupRemoteVideoRender(user, render2, false, AVChatVideoScalingType.SCALE_ASPECT_BALANCED);

用户加入房间通知

加入房间以后,当其他用户加入时会收到其他用户加入的通知 AVChatStateObserver#onUserJoined ,表示连麦开始。

    /**
     * 用户加入频道
     *
     * @param account 用户账号
     * @see AVChatManager#call2(String, AVChatType, AVChatNotifyOption, AVChatCallback)
     * @see AVChatManager#accept2(long, AVChatCallback)
     * @see AVChatManager#joinRoom2(String, AVChatType, AVChatCallback)
     */
    void onUserJoined(String account);
参数 说明
account 用户账号。

离开互动直播房间

graph TB B[stopVideoPreview 视频直播需要] --> C[disableVideo 视频直播需要] C --> D[leaveRoom2 ] D --> E[disableRtc]

离开一个已经加入的互动直播房间。 其中,设置关闭预览stopVideoPreview详见开始和停止视频采集节。

    /**
     * 关闭视频模块
     *
     * 关闭视频相关模块。 在通过过程中调用会让引擎切换到语音模式, 如果信令层需要通知对方,则通过
     * {@link AVChatManagerLite#sendControlCommand(long, byte, AVChatCallback)} 实现。
     *
     * @return {@code true} 方法调用成功,{@code false} 方法调用失败
     *
     * @see AVChatManagerLite#enableVideo()
     */
    public abstract boolean disableVideo();

    /**
     * 离开加入的多人会议房间
     *
     * 此接口仅仅是离开多人会话房间,如果需要销毁引擎释放资源需要调用以下接口:
     *
     *     可选, 关闭视频预览 {@link AVChatManagerLite#stopVideoPreview()} ()}
     *     可选, 关闭视频模块 {@link AVChatManagerLite#disableVideo()}}
     *     释放通话资源 {@link AVChatManagerLite#disableRtc()}
     *
     * 多人会议的离开其他用户是不会收到信令层的通知,只能通过媒体层的通知来获取用户离开 {@link AVChatStateObserverLite#onUserLeave(String, int)}。
     *
     *
     * @param roomName 房间名
     * @param callback 离开房间的回调接口
     *
     * @see AVChatManagerLite#createRoom(String, String, AVChatCallback)
     * @see AVChatManagerLite#createRoom(String, String, boolean, AVChatCallback)
     * @see AVChatManagerLite#joinRoom2(String, AVChatType, AVChatCallback)
     *
     */
    public abstract void leaveRoom2(String roomName,
                                    AVChatCallback<Void> callback);
    /**
     * 关闭音视频通话底层引擎
     *
     * 在通话结束后需要调用此接口关闭音视频通话引擎来释放资源。
     * 关闭音视频引擎后后续所有的其他调用都会失败或者异常。
     *
     * @return {@code true} 方法调用成功,{@code false} 方法调用失败
     *
     * @see AVChatManagerLite#enableRtc()
     */
    public abstract boolean disableRtc();
参数 说明
roomName 房间名。
callback 离开房间回调接口
//关闭视频预览
AVChatManager.getInstance().stopVideoPreview();
// 如果是视频通话,关闭视频模块
AVChatManager.getInstance().disableVideo();
//离开房间
AVChatManager.getInstance().leaveRoom2(roomName, new AVChatCallback<Void>() {});
//关闭音视频引擎
AVChatManager.getInstance().disableRtc();

用户离开房间通知

互动直播过程中,若主播或者连麦者离开,则会回调 onUserLeave

    /**
     * 用户离开频道
     *
     * @param account 用户ID
     * @param event   {@link AVChatUserQuitType}
     * @see AVChatManager#hangUp2(long, AVChatCallback)
     * @see AVChatManager#leaveRoom2(String, AVChatCallback)
     */
    void onUserLeave(String account, int event);
参数 说明
account 用户账号。
event 用户退出类型定义,常见类型参考 AVChatUserQuitType
// @param event   -1,用户超时离开  0,正常退出
@Override
public void onUserLeave(String account, int event) {}

互动直播状态回调

通过此回调进行通知互动直播事件,通知的事件包含初始化、设置画中画布局错误、互动直播开始连接、互动直播连接成功、互动直播连接失败、互动直播推流中、互动直播推流失败、互动直播内部错误、人数超出限制。

    /**
     * 互动直播相关事件通知
     *
     * @param event {@link AVChatResCode.LiveEventCode}
     */
    void onLiveEvent(int event);
参数 说明
event 互动直播事件码,参考LiveEventCode