用户发布公共流以后,使用同一 appID
的用户,无需进入房间,也可以订阅和播放该流。适合大规模的,低延时和低互动需求的音视频场景,例如以下业务。
教育场景,例如千人自习室,台上 1 个老师和少数学生音视频互动,台下其他学生作为观众只订阅,不发布。
电商直播场景,主播端发流,观众端只订阅,不发布。但观众仍可以通过文字和主播进行互动。
你已经集成 RTC SDK,实现了基本的音视频通话。
你可以在应用服务端和应用客户端发布公共流。查看调用 OpenAPI 发布公共流。本文将介绍如何在客户端发布和订阅公共流。
说明:不同平台的实现的步骤相同,但接口名称、参数名称可能略有差异。以下指南以 Android RTC SDK 为例,参考对应平台的 API 文档获取更多信息。
public int joinRoom(String token, String channelName, String uid, RTCRoomConfig config) { return 0; }
startPushPublicStream
开始发布公共流。除指定 publicStreamId
以外,你还需要传入布局。
publicStreamId
: 是公共流标识,在同一个 appId
内唯一。你需要自行实现 publicStreamId
的生成逻辑。
编码参数:设置视频的编码参数。你可以通过调用 getDefualtPublicStreaming
获取默认编码参数。
布局:将多个用户发布的流进行合并,这些流可以是在不同房间内发布的。通过指定流的发布方 uid
和所在的房间 roomId
,指向了参与合并到公共流的媒体流。在 Region
属性中,为不同的流指定位置、裁剪等布局配置。
public int startPushPublicStream(String publicStreamId) { //获取默认参数 PublicStreaming streaming = PublicStreaming.getDefualtPublicStreaming(); // 修改视频编码参数 streaming.getVideo() .setKBitRate(500000) .setFps(30) .setHeight(640) .setWidth(360); PublicStreaming.Layout.Builder builder = new PublicStreaming.Layout.Builder(); for (int i = 0;i < 2;++i) { PublicStreaming.Layout.Region region = new PublicStreaming.Layout.Region(); user.x = 第i个视频所在的左上角横坐标; user.y = 第i个视频所在的左上角纵坐标; user.width = 第i个视频的宽; user.height = 第i个视频的高; region.userId(第i个用户的ID) .roomId(第i个用户所在的房间ID) .zorder(合成后所在层数) .alpha(1) .position(user.x, user.y) //用户视频的左上角位置 .size(user.width, user.height) //用户视频的宽高 .renderMode(1); builder.addRegoin(region); } PublicStreaming.Layout layout = builder.build(); streaming.setLayout(layout); streaming.setRoomId(推流所在房间ID); return startPushPublicStream(publicStreamId,streaming); }
stopPushPublicStream
停止发布公共流。public int stopPushPublicStream(String streamId) { if (mRtcEventHandlerHost != null) { mRtcEventHandlerHost.notifyApiCall("stopPushPublicStream", streamId); } if (mRtcEngine != null) { mRtcEngine.stopPushPublicStream( streamId ); } return 0; }
setPublicStreamVideoCanvas
绑定内部视图。需要解绑视图时,把 videoCanvas
设置为空。如果你需要使用外部渲染器,调用
setPublicStreamVideoSink
详见自定义视频渲染。
public int setPublicStreamVideoCanvas(String streamId, VideoCanvas canvas) {...}
调用 startPlayPublicStream
开始订阅公共流。
注意
一个客户端最多同时播放 5 路公共流,请及时调用 stopPlayPublicStream
避免订阅的公共流数量超限。
public int startPlayPublicStream(String streamId) {...}
sendSEIMessage
将 SEI 信息插入视频帧中,流中的 SEI 信息将透传并融合到公共流中。
公共流将透传的 SEI 数据添加到当前视频帧开始的连续 30 个视频帧中,提高 SEI 信息的可靠性。
当多条视频流都包含 SEI 信息时,每条流中的 SEI 信息均将透传到公共流中。 然而,公共流中单个视频帧允许携带的 SEI 信息不超过 4 KB。如果合并后的 SEI 信息超过 4 KB,RTC将丢弃超出的部分。例如,组成公共流的三条视频流某视频帧中携带的 SEI 信息分别为 A, B, C,当 A+B+C > 4 KB
且 A+B < 4 KB
时,公共流最终携带的 SEI 信息为 A + B
你需要自行实现 SEI信息的处理逻辑。
public void onPublicStreamSEIMessageReceived(String publicStreamId, ByteBuffer message) { RTCCallEngineController controller = getController(); String callbackLog = "onPublicStreamSEIMessageReceived[streamid:" + publicStreamId + " sei:" + RtmpUrlUtils.byteBufferToString(message) + "]";); }
stopPlayPublicStream
取消订阅公共流。public int stopPlayPublicStream(String streamId) {...}