快速实现 PK 直播
更新时间: 2024/08/23 14:52:55
本文介绍在单人直播的过程中,主播 A 邀请主播 B 进行PK直播实现流程。
flowchart LR
A("创建应用并获取 App Key") --> B(开通音视频通话 2.0 和直播服务)--> E("获取推拉流地址")--> C("集成 RTC SDK") --> D(实现 PK 直播)
click A "https://doc.yunxin.163.com/console/docs/TIzMDE4NTA?platform=console"
click B "https://doc.yunxin.163.com/live-streaming/docs/DM4MjYxODY?platform=android"
click C "https://doc.yunxin.163.com/nertc/docs/DcyNDc0ODI?platform=android"
click E "https://doc.yunxin.163.com/live-streaming/docs/DM4MjYxODY?platform=android#步骤3-获取推拉流地址"
style D fill:#337EFF,stroke:#337EFF,stroke-width:0px,color:#FFFFFF;
style A fill:#9DC3E6,stroke:#9DC3E6,stroke-width:0px,color:#FFFFFF;
style B fill:#9DC3E6,stroke:#9DC3E6,stroke-width:0px,color:#FFFFFF;
style C fill:#9DC3E6,stroke:#9DC3E6,stroke-width:0px,color:#FFFFFF;
style E fill:#9DC3E6,stroke:#9DC3E6,stroke-width:0px,color:#FFFFFF;
功能原理
PK 直播的架构原理如下图所示。
PK 直播的业务流程说明如下:
- 主播 A 发出 PK 邀请,主播 B 同意。
- 通过跨频道转发,主播 A 和主播 B 不需要退出原房间,直接将媒体流转发到房间 A 和房间 B 中,实现主播跨房间与其他主播实时互动。
- 互动直播服务器将主播 A 和主播 B 的音视频进行混屏转码后,推到 CDN 分发。
- 观众端使用 RTMP/HLS/FLV 协议进行拉流观看。
注意事项
- 只支持网易云信播放器 NELivePlayer 进行拉流,其他播放器暂不兼容。
- 单人直播切换到 PK 直播时,音频采样率必须保持一致。
API 时序图
sequenceDiagram
actor 主播A
participant NERtcSDK
participant 业务服务器
actor 主播B
%% 开始PK
主播A->>业务服务器: 邀请PK
Note right of 主播A: 邀请主播B进行PK(带上自己的uid、cname、Token等信息)
Note left of 主播B: 请自行实现邀请PK的相关业务逻辑
业务服务器->>主播B: 邀请PK(带上主播A的uid、cname、Token等信息)
主播B-->>业务服务器: 同意PK
业务服务器-->>主播A: 对端同意PK(带上主播B的uid、cname、Token等信息)
rect rgb(191, 223, 255)
主播A ->> NERtcSDK: startChannelMediaRelay 开启媒体转发
主播A ->> NERtcSDK: addLiveStream 开始旁路推流
NERtcSDK -->> 主播A: onLiveStreamState 监听旁路推流状态
主播A ->> NERtcSDK: stopPushStreaming 旁路推流成功后,停止推流
Note right of 主播A: 当主播B开始MediaRelay后,更新旁路推流,具体请根据实际业务进行调整
主播A ->> NERtcSDK: updateLiveStreamTask 更新旁路推流
Note right of 主播A: 根据回调确认mediaRelay是否成功
NERtcSDK -->> 主播A: onMediaRelayStatesChange 和 onMediaRelayReceiveEvent
end
NERtcSDK -->> 主播A: 监听房间中人员进入和音视频打开的回调
NERtcSDK -->> 主播B: 监听房间中人员进入和音视频打开的回调
主播A ->> 业务服务器: 结束PK
业务服务器 ->> 主播B: 结束PK
主播A ->> NERtcSDK: startPushStreaming 重新开始单人直播推流
NERtcSDK -->> 主播A: onStartPushStreaming
主播A ->> NERtcSDK: stopChannelMediaRelay 停止媒体转发
主播A ->> NERtcSDK: removeLiveStreamTask 移除旁路推流任务
主播B ->> NERtcSDK: stopChannelMediaRelay
主播B ->> NERtcSDK: removeLiveStreamTask 移除旁路推流任务
实现方法
开始 PK
-
开始 mediaRelay。
主播 A 调用
startChannelMediaRelay
方法开启媒体转发功能,将主播 A 的视频流推送到主播 B 房间。 -
开启旁路推流任务。
主播 A 调用
addLiveStreamTask
方法添加旁路推流任务,将主播 A 和主播 B 房间的音视频流推送到 CDN 上进行合流。 -
等待旁路推流结果。
通过
onLiveStreamState
回调监听旁路推流状态,如果状态为STATE_PUSHING
, 表示旁路推流成功。如果旁路推流失败,则根据实际情况进行失败回退,例如调用
stopChannelMediaRelay
方法停止媒体转发功能。 -
停止单人直播推流。
主播 A 调用
stopPushStreaming
方法停止单人直播推流。 -
等待主播 B 加入房间后更新旁路推流任务。
主播 A 调用
updateLiveStreamTask
方法更新旁路推流任务,保证主播房间和挑战者房间的音视频流能够同步播放。 -
确认 mediaRelay 是否成功。
通过
onMediaRelayStatesChange
和onMediaRelayReceiveEvent
回调监听媒体转发状态,确认媒体转发是否成功。如果媒体转发失败,则根据实际情况进行失败回退,例如调用
stopChannelMediaRelay
和removeLiveStreamTask
方法结束 PK。 -
设置画面布局。
结束PK
-
开始单人直播推流。
主播 A 调用
startPushStreaming
方法开始单人直播推流。 -
等待单人直播推流结果。
主播 A 通过
onStartPushStreaming
回调监听单人直播推流状态,如果推流成功,则执行下一步操作。 -
停止mediaRelay。
主播 A 和 主播 B 分别调用
stopChannelMediaRelay
方法停止媒体转发功能。 -
移除旁路推流任务。
主播 A 和 主播 B 分别调用
removeLiveStreamTask
方法移除旁路推流任务。
示例代码
网易云信为您提供实现CDN 推流的示例代码作为参考,您可以直接拷贝用于运行测试。
请单击下载CDN 推流最佳实践代码。
public void enterPK(String channelName, String token, long uid) {
//step1 开始mediaRelay(startMediaRelay)
NERtcMediaRelayParam mediaRelayParam = new NERtcMediaRelayParam();
NERtcMediaRelayParam.ChannelMediaRelayConfiguration config = mediaRelayParam.new ChannelMediaRelayConfiguration();
NERtcMediaRelayParam.ChannelMediaRelayInfo relayInfo = mediaRelayParam.new ChannelMediaRelayInfo(token, channelName, 0);
config.setDestChannelInfo(channelName, relayInfo);
NERtcEx.getInstance().startChannelMediaRelay(config);
//step2 开启旁路推流任务(addLiveStream)
NERtcEx.getInstance().addLiveStreamTask(taskInfo, (taskId, errCode) -> {});
//step3 等待旁路推流结果(onLiveStreamState), 如果state为STATE_PUSHING表示添加旁路任务成功,否则停止cdn推流(stopPushStreaming)
//step4 等待pk对方加入房间后更新旁路推流任务 updateLiveStreamTask
//step5 确认mediaRelay是否成功,如果失败根据实际情况做相应处理
//等待mediaRelay任务状态回调onMediaRelayStatesChange和onMediaRelayReceiveEvent确认mediaRelay是否成功
}
public void leavePK() {
//step1 开始cdn推流(startPushStreaming)
NERtcEx.getInstance().startPushStreaming(pushStreamingConfig);
//step2 等待cdn推流结果回调(onStartPushStreaming)
//成功后停止mediaRelay(stopMediaRelay)和移除旁路推流任务(removeLiveStreamTask)
//NERtcEx.getInstance().stopChannelMediaRelay();
//NERtcEx.getInstance().removeLiveStreamTask(taskId, (DeleteLiveTaskCallback) (taskId, errCode) -> {});
}
常用的回调
请在初始化时注册推流相关的回调,PK 场景需要关注的主要回调如下:
//开始推流startPushStreaming结果回调
void onStartPushStreaming(int result, long channelId);
//停止推流stopPushStreaming结果回调
void onStopPushStreaming(int result);
//推流过程中断开,变为重连状态回调
void onPushStreamingReconnecting(int reason);
//推流过程中重连成功回调
void onPushStreamingReconnectedSuccess();
//推流状态已改变回调
void onLiveStreamState(String taskId, String pushUrl, int liveState);
//跨房间媒体流转发状态发生改变回调
void onMediaRelayStatesChange(int state, String channelName);
//媒体流相关转发事件回调
void onMediaRelayReceiveEvent(int event, int code, String channelName);