本文详细介绍如何使用百家云 AndroidSDK 订阅和取消订阅远端音视频
相关函数接口在 android-sdk 2.8.9 及以上版本支持
您可以通过调用 BRTC 中的 setDefaultStreamRecvMode 接口设置订阅模式,需要在进入房间(enterRoom)前调用该接口,设置才能生效。BRTC 提供了两种订阅模式:
需要您注意的是,如果您不调用 setDefaultStreamRecvMode 也是没有关系的,SDK 的默认行为是自动订阅。但如果您希望设置为手动订阅,请务必注意 setDefaultStreamRecvMode 只有在 enterRoom 之前调用才有效果。
您可以通过调用接口 muteRemoteAudio(userId,true) 来静音远端用户 userId 的声音,之后也可以通过调用接口 muteRemoteAudio(userId,false) 来解除对他的静音。
//静音指定用户userID的音频 engine.muteRemoteAudio(userID, true); //恢复指定用户userID的音频播放 engine.muteRemoteAudio(userID, false); //静音所有远端用户的音频流 engine.muteAllRemoteAudio(true); //恢复播放所有远端用户的音频流 engine.muteAllRemoteAudio(false);
您可以通过调用接口 startRemoteView 来播放远端用户的视频画面,但前提是您需要传递给 SDK 一个 view 对象,用来作为承载该用户的视频画面的渲染控件。
startRemoteView 的第一个参数是远端用户的 userId,第二个参数是远端用户的流类型,第三个参数则是您需要传递的 view 对象。其中第二个参数 streamType(流类型) 有三个可选的值,分别是:
注意事项
engine.muteRemoteVideoStream(userID, false); // 指定渲染远端用户的大流画面 engine.setRemoteVideoStreamType(userID, BRTCDef.BRTCVideoStreamType.BRTCVideoStreamTypeBig); // 播放用户的主画面 engine.startRemoteView(userID, BRTCDef.BRTCVideoStreamType.BRTCVideoStreamTypeBig, playCanvas); // 可以改变远端用户视频的默认渲染参数 BRTCDef.BRTCRenderParams remoteRenderParams = new BRTCDef.BRTCRenderParams(); remoteRenderParams.fillMode = BRTCDef.BRTCVideoFillMode.BRTCVideoFillMode_Fill; engine.setRemoteRenderParams(userID, BRTCDef.BRTCVideoStreamType.BRTCVideoStreamTypeBig, remoteRenderParams); // 显示远端用户视频后,还可以临时暂停(或恢复) engine.muteRemoteVideoStream(userID, BRTCDef.BRTCVideoStreamType.BRTCVideoStreamTypeBig, true or false);
通过调用 stopRemoteView 接口,您可以停止播放某一个远端用户的视频。
engine.muteRemoteVideoStream(userID, true); engine.stopRemoteView(userID, BRTCDef.BRTCVideoStreamType.BRTCVideoStreamTypeBig);
通过调用 updateRemoteView 接口,您可以在播放中变更 view 对象,这在切换视频渲染控件时非常有用。 通过 setRemoteRenderParams 您可以设置画面的填充模式、旋转角度和镜像模式。
// 将 userId 的主路画面切换到一个悬浮的窗口中(假定该小窗口为 floatingView) engine.updateRemoteView(userId, BRTCDef.BRTCVideoStreamType.BRTCVideoStreamTypeBig,floatingView); BRTCDef.BRTCRenderParams remoteRenderParams = new BRTCDef.BRTCRenderParams(); //适配长边模式,短边区域填充黑色 remoteRenderParams.fillMode = BRTCDef.BRTCVideoFillMode.BRTCVideoFillMode_Fit; //画面不旋转 remoteRenderParams.rotation = BRTCDef.BRTCVideoRotation.BRTCVideoRotation_0; //前后置摄像头画面均不镜像 remoteRenderParams.mirrorType = BRTCDef.BRTCVideoMirrorType.BRTCVideoMirrorTypeDisable; engine.setRemoteRenderParams(userID, BRTCDef.BRTCVideoStreamType.BRTCVideoStreamTypeBig, remoteRenderParams);
您可以控制对远端用户的声音和视频的播放,需要通过如下接口获取房间中推流的用户信息、推流的摄像头和麦克风设备状态:
视频状态变化通知
屏幕共享流可用状态通知
准确地说,onRemoteUserEnter/LeaveRoom 仅能感知角色(role)为主播(anchor)的用户的进出房间的通知,之所以这样设计,是为了避免当一个房间中观众(audience)在线人数较多时,会因为频繁有人进出房间导致房间中的所有用户被其他用户进出房间的“信令风暴“攻击到。
BRTCListener brtcListener = new BRTCBaseListener() { public void onRemoteUserEnterRoom(String userId) { Log.d(TAG, "onRemoteUserEnterRoom: " + userId); BRTCUser brtcUser = new BRTCUser(userId, null); videoViewAdapter.userList.add(brtcUser); } @Override public void onRemoteUserLeaveRoom(String userId, int reason) { Log.d(TAG, "onRemoteUserLeaveRoom, userId: " + userId + ", reason: " + reason); for (int i = 0; i < videoViewAdapter.userList.size(); i++) { if (videoViewAdapter.userList.get(i).userID.equals(userId)) { videoViewAdapter.userList.remove(i); break; } } } @Override public void onUserAudioAvailable(String userId, boolean available) { Log.d(TAG, "onUserAudioAvailable, userId: " + userId + ", available: " + available); if (!isContainRemoteStream(userId)) { if (available) { //添加可用的用户和流信息 BRTCStream stream = new BRTCStream(); stream.user = getRemoteUser(userId); stream.streamID = userId; stream.enableAudio = available; videoViewAdapter.streams.add(stream); } } else { int index = getStreamIndex(userId, videoViewAdapter.streams); if (index == -1) return; BRTCStream stream = videoViewAdapter.streams.get(index - 1); if (!available && !stream.enableVideo) { //删除用户及流信息 videoViewAdapter.isPlay.remove(userId); videoViewAdapter.playerState.remove(userId); videoViewAdapter.streams.remove(index - 1); } else { //修改流信息状态 stream.enableAudio = available; videoViewAdapter.streams.set((index - 1), stream); } } } @Override public void onUserVideoAvailable(String userId, boolean available) { Log.d(TAG, "onUserVideoAvailable, userId: " + userId + ", available: " + available); if (!isContainRemoteStream(userId)) { if (available) { //添加用户和流信息 BRTCStream stream = new BRTCStream(); stream.user = getRemoteUser(userId); stream.streamID = userId; stream.enableVideo = available; videoViewAdapter.streams.add(stream); } } else { int index = getStreamIndex(userId, videoViewAdapter.streams); if (index < 1) return; BRTCStream stream = videoViewAdapter.streams.get(index - 1); if (!available && !stream.enableAudio) { //音视频流都不可用,删除用户和流信息 videoViewAdapter.isPlay.remove(userId); videoViewAdapter.playerState.remove(userId); videoViewAdapter.streams.remove(index - 1); } else { //修改视频流状态 stream.enableVideo = available; videoViewAdapter.streams.set((index - 1), stream); } } } @Override public void onUserSubStreamAvailable(String userId, boolean available) { //屏幕共享数据流可用,处理逻辑 } };
随着您的业务需求不断深入,您会发现有三种不同的“静音”,虽然他们都叫“静音”,但是实现机制和效果完全不同
订阅音视频流
本文详细介绍如何使用百家云 AndroidSDK 订阅和取消订阅远端音视频
相关函数接口在 android-sdk 2.8.9 及以上版本支持
设定订阅模式
您可以通过调用 BRTC 中的 setDefaultStreamRecvMode 接口设置订阅模式,需要在进入房间(enterRoom)前调用该接口,设置才能生效。BRTC 提供了两种订阅模式:
需要您注意的是,如果您不调用 setDefaultStreamRecvMode 也是没有关系的,SDK 的默认行为是自动订阅。但如果您希望设置为手动订阅,请务必注意 setDefaultStreamRecvMode 只有在 enterRoom 之前调用才有效果。
音频流的播放
您可以通过调用接口 muteRemoteAudio(userId,true) 来静音远端用户 userId 的声音,之后也可以通过调用接口 muteRemoteAudio(userId,false) 来解除对他的静音。
视频流的播放
您可以通过调用接口 startRemoteView 来播放远端用户的视频画面,但前提是您需要传递给 SDK 一个 view 对象,用来作为承载该用户的视频画面的渲染控件。
startRemoteView 的第一个参数是远端用户的 userId,第二个参数是远端用户的流类型,第三个参数则是您需要传递的 view 对象。其中第二个参数 streamType(流类型) 有三个可选的值,分别是:
注意事项
视频流停止播放
通过调用 stopRemoteView 接口,您可以停止播放某一个远端用户的视频。
设置播放参数
通过调用 updateRemoteView 接口,您可以在播放中变更 view 对象,这在切换视频渲染控件时非常有用。 通过 setRemoteRenderParams 您可以设置画面的填充模式、旋转角度和镜像模式。
感知房间中远端用户的音视频状态
您可以控制对远端用户的声音和视频的播放,需要通过如下接口获取房间中推流的用户信息、推流的摄像头和麦克风设备状态:
视频状态变化通知
屏幕共享流可用状态通知
准确地说,onRemoteUserEnter/LeaveRoom 仅能感知角色(role)为主播(anchor)的用户的进出房间的通知,之所以这样设计,是为了避免当一个房间中观众(audience)在线人数较多时,会因为频繁有人进出房间导致房间中的所有用户被其他用户进出房间的“信令风暴“攻击到。
三种不同的静音
随着您的业务需求不断深入,您会发现有三种不同的“静音”,虽然他们都叫“静音”,但是实现机制和效果完全不同