跳到主要内容

观众端

直播模式中主播发布的音视频流,会在服务端另行合并生成一道音频合流和一道视频合流。观众既可以直接订阅原始音视频流(简称“分流”),也可订阅“合流”。下面将分别介绍这两种订阅方式的区别和适用场景。

提示

观众只能订阅,不能发布。若需发布,请先切换为主播身份,再发布资源。

订阅分流

分流订阅跟会议模式的订阅一样,适合小众玩法灵活的直播业务场景。比如观众被分成多种角色,需要选择性观看或收听部分主播发布的资 源;又或者不同观众的展示布局并不相同,甚至可以随时切换布局的情况,SDK 提供视频展示 View 的创建和与流绑定接口,您可自行编 写展示逻辑。

订阅需要在两个时机进行处理:

  1. 在加入直播间的成功回调中,遍历房间内已存在用户发布的流并订阅;
  2. 在收到主播发布流的通知 onRemoteUserPublishResource 时进行订阅。

您可以调用 RCRTCLocalUser 中的 subscribeStreamsubscribeStreams 来订阅单个或多个媒体流。

Java
    rtcRoom.getLocalUser().subscribeStreams(inputStreams, new IRCRTCResultDataCallback<List<RCRTCInputStream>>() {
@Override
public void onFailed(RTCErrorCode errorCode) {

}

@Override
public void onSuccess(List<RCRTCInputStream> data) {

}

@Override
// 如果 SDK ≥ 5.3.4,您可以使用 IRCRTCResultDataCallback,onFailed 方法会返回订阅失败的流列表和错误码。
// 如果 SDK < 5.3.4,仅支持使用 IRCRTCResultCallback,onFailed 方法仅返回错误码。
public void onFailed(List<RCRTCInputStream> failedStreams, RTCErrorCode errorCode) {

}
});

订阅合流

大多数直播场景中,观众数量较多且观看内容一致。若采用分流订阅,将产生较大带宽消耗并提高成本。为解决该问题,融云服务会将主播发布的音视频资源,按预设的人选、布局与编码参数合并为一道音频合流和一道视频合流(纯音频模式仅有一道音频合流)。观众统一订阅这两道合流,无论主播数量多少,都能以较小资源获得一致的观看体验,从而显著降低成本。订阅合流步骤如下:

  1. 获取合流地址:

    当观众加入房间成功后,会在回调中拿到 RCRTCRoom 对象:

    • 若主播已发布资源,调用其中的 getLiveStreams 获取合流地址列表;
    • 若主播在您加入后发布资源,通过 IRCRTCRoomEventsListeneronPublishLiveStreams 回调方法获取合流地址列表。 合流地址列表可能包含两道音视频流,或一道音频流(纯音频模式)。
    Java
    // 通过 getLiveStreams 方法获取
    List<RCRTCInputStream> streamList = rtcRoom.getLiveStreams();

    // 通过 onPublishLiveStreams 方法获取
    rtcRoom.registerRoomListener(new IRCRTCRoomEventsListener() {
    ....
    @Override
    public void onPublishLiveStreams(List<RCRTCInputStream> streams) {
    // 主播发布的合流资源列表
    }
    ...
    });

  2. 订阅合流:

    获取到合流后,调用 RCRTCLocalUsersubscribeStreamsubscribeStreams 订阅指定的一个或多个合流。用法与订阅分流一致,只是传递的流对象不同。合流中的视频流区分大小流,可通过视频流 RCRTCVideoInputStream 对象的 setStreamType 方法,选择订阅大流(默认)或小流。

    Java
    List<RCRTCInputStream> inputStreams = rtcRoom.getLiveStreams();
    // 获取当前房间所有已发布直播流,可能包括音频、视频、自定义等
    for (RCRTCInputStream inputStream : inputStreams) {
    // 需要渲染的只有视频流,单独筛出来加渲染逻辑
    if (inputStream.getMediaType() == RCRTCMediaType.VIDEO){
    RCRTCVideoInputStream videoInputStream = (RCRTCVideoInputStream) inputStream;
    // 如果未绑定过 VideoView,则需要创建并绑定 VideoView
    if (videoInputStream.getVideoView() == null) {
    VideoView videoView = new VideoView(XXXActivity.this);
    videoInputStream.setVideoView(videoView);
    // 添加到 Activity 布局中,videoViewManager 是官网 Demo 中的一种方式,仅供参考
    videoViewManager.add(videoView);
    }
    }
    }
    rtcRoom.getLocalUser().subscribeStreams(inputStreams, new IRCRTCResultDataCallback<List<RCRTCInputStream>>() {
    @Override
    public void onSuccess(List<RCRTCInputStream> data) {

    }

    @Override
    public void onFailed(RTCErrorCode errorCode) {
    }
    @Override
    // 如果 SDK ≥ 5.3.4,您可以使用 IRCRTCResultDataCallback,onFailed 方法会返回订阅失败的流列表和错误码。
    // 如果 SDK < 5.3.4,仅支持使用 IRCRTCResultCallback,onFailed 方法仅返回错误码。
    public void onFailed(List<RCRTCInputStream> failedStreams, RTCErrorCode errorCode) {

    }
    });

取消订阅

当需要取消订阅分流或合流时,调用 RCRTCLocalUserunsubscribeStreamunsubscribeStreams 取消订阅一个或多个媒体流。取消订阅接口通常与订阅接口配对使用。若用户主动退出房间,无需手动取消订阅;调用退出房间接口时,SDK 会自动进行取消处理。

Java
rtcRoom.getLocalUser().unsubscribeStreams(unPublishResource, new IRCRTCResultCallback() {
@Override
public void onSuccess() {
// 取消成功
}

@Override
public void onFailed(RTCErrorCode errorCode) {
// 取消失败
}
});
参数类型说明
streamsList<? extends RCRTCInputStream>要取消订阅的音视频流
callBackIRCRTCResultCallback取消订阅结果回调