客户端实现
更新时间: 2022/08/04 14:36:21
本文档为您展示通过 SDK 实现 PK 连麦场景的相关步骤,帮助您在业务中实时音视频通话、互动直播、连麦 PK、文字聊天、收发礼物等 IM、音视频通话 2.0 和互动直播 2.0 在 PK 连麦场景下的相关能力。
前提条件
-
已在控制台创建应用,并获取了应用对应的 App Key。
详细操作请参考创建应用。
-
已成功开通 IM 即时通讯产品的聊天室功能、开通信令、音视频通话 2.0 产品。
详细操作请参考开通服务。聊天室功能需单独开通,若有需要,请联系商务经理或技术支持。
集成 SDK
请参考下表,将相应的 SDK 或服务集成到您的项目中。
产品 | SDK 下载 | 集成文档 |
---|---|---|
IM 即时通讯 | IM SDK | 集成 SDK |
音视频通话 2.0 | NERTC SDK | 集成 SDK |
信令 | 信令 SDK | 集成信令 SDK |
实现 PK 连麦
步骤1 初始化配置
-
业务应用服务器配置。
正式开始业务流程之前,您需要通过业务应用服务器完成以下步骤。
-
初始化并登陆 IM。
初始化的详细说明请参考初始化 IM SDK。
-
设置音频参数和属性。
您可以根据对音质、声道、场景等的不同需求,通过 setAudioProfile 方法灵活设置音频属性,获得最佳实时互动效果。
-
初始化 NERTC SDK 并注册监听。
初始化的详细说明请参考初始化 NERTC SDK。
示例代码:
//1. 初始化并登陆 IM。
//2. 设置音频参数和属性。
NERtcEx.getInstance().setParameters(mRtcParameters); //先设置参数,后初始化NERtcEx.getInstance().setAudioProfile(mAudioProfile,mAudioScenario);//初始化前设置音频场景
//3. 初始化 SDK 并注册监听。
NERtcEx.getInstance().init(getApplicationContext(),Config.APP_KEY,callback,null);
步骤2 主播端开播
经过一系列初始化配置之后,主播端可以开启单人直播。
-
启动视频流。
调用 enableLocalVideo 开启本地视频采集和发送。
-
设置本地视频画布并预览。
通过 setupLocalVideoCanvas 设置本地视频画布,确定本地采集的视频画面。并通过 startVideoPreview 方法在加入房间之前预览本地画面。
-
设置直播模式,并打开推流开关。
在互动直播的场景中,建议在加入房间前,通过 setChannelProfile 接口设置房间模式为直播模式。并 setParameters 打开推流开关。
注意:开启推流开关之后,主播或管理员创建推流任务之后才正式启动旁路推流。
-
设置角色为主播。
NERTC SDK V3.9.0 及后续版本支持直播场景下的用户角色管理,角色包括主播和观众。加入房间前可以通过 setClientRole 设置用户角色为主播。
-
加入音视频房间和 IM 聊天室。
- 客户端可以直接通过 joinChannel 加入音视频房间,您也可以通过服务端 API 创建房间之后,客户端通过参数 ChannelName 加入指定房间。
- 安全模式下加入房间需要填写获取到的 Token;调试模式下,Token 请设置为 null。
-
配置推流状态监听。
主播或连麦者参与互动直播的过程中,可以通过 NERtcCallback 的 onLiveStreamState 来监听推流状态。
-
新增并维护推流任务。
在成功加入房间后,通过 addLiveStreamTask 创建推流任务,将通话房间内的多媒体数据推至 CDN。常见的推流状态请参考互动直播推流状态。
您也可以通过服务端 API 创建推流任务。
示例代码:
//1. 启动视频流。
* @param enable true: 开启,false : 关闭
ublic abstract int enableLocalVideo(boolean enable);
//2. 设置本地视频画布并预览。
public abstract int setupLocalVideoCanvas(com.netease.lava.api.IVideoRender render);
NERtcEx.getInstance().startVideoPreview();
//3. 设置直播模式,并打开推流开关。
// 0 - COMMUNICATION(通信模式), 1 - LIVE_BROADCASTING(直播模式)
NERtcEx.getInstance().setChannelProfile(1);
mRtcParameters.set(NERtcParameters.KEY_PUBLISH_SELF_STREAM, true);
NERtcEx.getInstance().setParameters(mRtcParameters);
//4. 加入音视频房间和 IM 聊天室。
public abstract int joinChannel(java.lang.String token,
java.lang.String channelName,
long uid);
NIMClient.getService(ChatRoomService.class).enterChatRoomEx(data, 1).setCallback(new RequestCallback<EnterChatRoomResultData>()
//5. 配置推流状态监听。
public void onLiveStreamState(String taskId, String pushUrl, int liveState);
//6. 新增并维护推流任务。
// 示例
// 初始化推流任务
NERtcLiveStreamTaskInfo liveTask1 = new NERtcLiveStreamTaskInfo();
//taskID 可选字母、数字,下划线,不超过64位
liveTask1.taskId = String.valueOf(Math.abs(pushUlr.hashCode()));
// 设置推互动直播推流地址,一个推流任务对应一个推流房间
liveTask1.url = pushUlr;
// 设置是否进行互动直播录制,请注意与音视频通话录制区分。
liveTask1.serverRecordEnabled = false;
// 设置推音视频流还是纯音频流
liveTask1.liveMode = enableVideo? NERtcLiveStreamTaskInfo.NERtcLiveStreamMode.kNERtcLsModeVideo : NERtcLiveStreamTaskInfo.NERtcLiveStreamMode.kNERtcLsModeAudio;
//设置整体布局
NERtcLiveStreamLayout layout = new NERtcLiveStreamLayout();
layout.userTranscodingList = new ArrayList<>();
layout.width = 720;//整体布局宽度
layout.height = 1280;//整体布局高度
layout.backgroundColor = Color.parseColor("#3399ff"); // 整体背景色
liveTask1.layout = layout;
// 设置直播成员布局
NERtcLiveStreamUserTranscoding user1 = new NERtcLiveStreamUserTranscoding();
user1.uid = uid1; // 用户id
user1.audioPush = true; // 推流是否发布user1 的音频
user1.videoPush = enableVideo; // 推流是否发布user1的视频
if (user1.videoPush) {// 如果发布视频,需要设置一下视频布局参数
// user1 视频的缩放模式, 详情参考NERtcLiveStreamUserTranscoding 的API 文档
user1.adaption = NERtcLiveStreamUserTranscoding.NERtcLiveStreamVideoScaleMode.kNERtcLsModeVideoScaleCropFill;
user1.x = 10; // user1 的视频布局x偏移,相对整体布局的左上角
user1.y = 10; // user1 的视频布局y偏移,相对整体布局的左上角
user1.width = 180; // user1 的视频布局宽度
user1.height = 320; //user1 的视频布局高度
}
layout.userTranscodingList.add(user1);
...
// 设置第n位直播成员布局
NERtcLiveStreamUserTranscoding usern = new NERtcLiveStreamUserTranscoding();
usern.uid = uidn;
usern.audioPush = true;
usern.videoPush = enableVideo;
if (usern.videoPush) {
usern.adaption = NERtcLiveStreamUserTranscoding.NERtcLiveStreamVideoScaleMode.kNERtcLsModeVideoScaleCropFill;
usern.x = user1.x + user1.width + 10;
usern.y = user1.y + user1.height + 10;
usern.width = 320;
usern.height = 640;
}
layout.userTranscodingList.add(usern);
// 调用 addLiveStreamTask 接口添加推流任务
int ret = NERtcEx.getInstance().addLiveStreamTask(liveTask1, addLiveTaskCallback);
if (ret != 0) {
showToast("调用添加推流任务接口执行失败 , ret : " + ret);
}
// 添加推流任务的异步callback
private AddLiveTaskCallback addLiveTaskCallback = new AddLiveTaskCallback(){
void onAddLiveStreamTask(String taskId, int errCode){
if (code == RtcCode.LiveCode.OK) {
showToast("添加推流任务成功 : taskId " + taskId);
} else {
showToast("添加推流任务失败 : taskId " + taskId + " , code : " + code);
}
}
};
步骤3 观众端观看
-
观众端加入聊天室。
观众端加入聊天室之后可以进行文字互动、打赏等操作。
-
观众端通过拉流地址拉流观看直播。
观众端通过播放器实现拉流收听,您可以使用网易云信提供的播放器 SDK 实现,详细操作请参考播放器 SDK 快速入门。
步骤4 主播连麦 PK
在 PK 连麦场景 Demo 中,主播 A 邀请主播 B 进行连麦 PK,主播 B 同意 PK 申请后,主播 A 和 B 删除推流任务、退出原有互动直播房间,并且请求服务器创建一个新的互动直播房间用于连麦 PK。主播 A 和 B 重新加入新房间之后,使用原有的推流地址重新推流,在新的互动直播房间中进行连麦 PK 即可。
注意:
- 主播退出原直播房间之前,需要先删除推流任务,并在加入新房间后使用原推拉流地址重新推流,否则会因为重复推流造成推流失败。
- 观众端不需要切换推拉流地址,拉流出现断流时可以重新拉流解决问题。
操作步骤:
-
主播 A 通过信令发起 PK 邀请,并创建信令房间。
通过信令可以直接呼叫并创建信令房间,用于邀请其他主播进行 PK。
-
主播 B 接受 PK 邀请,并自动加入信令房间。
主播 B 也可以拒绝邀请,详细操作请查看示例代码。
-
主播 A 和主播 B 删除推流任务、退出原房间并加入新的直播房间。
主播 A 和主播 B 加入新直播房间的详细流程,请参考步骤2。
-
主播端设置远端画布。
- 监听远端用户加入房间与监听远端视频流发布。
- 设置远端画布、订阅远端视频流。
-
新增推流任务,观众端重新拉流。
新的推流任务中需要添加两个主播的原推流地址,观众端拉流时无需切换拉流地址。
示例代码:
//1. 主播 A 通过信令发起 PK 邀请,并创建信令房间。
NIMClient.getService(SignallingService.class).call(CallParamBuilder callParamBuilder)
//2. 主播 B 接受 PK 邀请,并自动加入信令房间。
// 接受对方邀请并自动加入房间
NIMClient.getService(SignallingService.class).acceptInviteAndJoin(inviteParam, selfUid).setCallback
// 拒绝邀请
NIMClient.getService(SignallingService.class).rejectInvite(inviteParam);
//3. 主播 A 和主播 B 删除推流任务、退出原房间并加入新的直播房间。
NERtcEx.getInstance().leaveChannel(); 离开房间
public abstract int joinChannel(java.lang.String token,
java.lang.String channelName,
long uid); 加入房间
//4. 主播端设置远端画布。
//监听远端用户加入房间与监听远端视频流发布。
- void onUserJoined(long uid);
- void onUserVideoStart(long uid, int maxProfile);
//设置远端画布、订阅远端视频流。
public abstract int setupRemoteVideoCanvas(com.netease.lava.api.IVideoRender render, long uid);
public abstract int subscribeRemoteVideoStream(long uid,
NERtcRemoteVideoStreamType streamType,
boolean subscribe);
//5. 新增推流任务,观众端重新拉流。
步骤5 结束直播
- 调用接口 leaveChannel 离开房间。
- 调用接口 release 销毁音视频实例。
示例代码:
//1. 离开房间。
NERtcEx.getInstance().leaveChannel();
//2. 销毁音视频实例。
NERtcEx.getInstance().release();
常见问题
如何实现在 PK 直播过程中,一方异常退出后,自动停止 PK?
可以开通实时音视频抄送,获取用户离开房间回调,或者开通 IM 登出事件消息抄送。您的业务层可以根据抄送,判断退出的一方失败,并结束 PK、删除推流任务。