CDN 转推
本文主要介绍 CDN 转推的使用姿势及其应用场景。
CDN 转推可实现直播场景的功能,实时音视频场景下的直播主要包括三个部分:单路流直播、多路流合流直播以及两者结合可切换的直播场景。
CDN 转推需要配置本地或者远端的音视频 Track,因此,调用转推接口前请务必保证加入了房间,并且已经发布或者订阅了相应的音视频 Track
下面将会就三种场景的使用姿势进行说明。
设置监听
在进行 CDN 转推之前,需要设置 CDN 转推流的状态监听:
mClient.setLiveStreamingListener(new QNLiveStreamingListener() {
@Override
public void onStarted(String streamID) {
// 转推任务创建成功时触发此回调
}
@Override
public void onStopped(String streamID) {
// 转推任务成功停止时触发此回调
}
@Override
public void onTranscodingTracksUpdated(String streamID) {
// 合流布局更新成功时触发此回调
}
@Override
public void onError(String streamID, QNLiveStreamingErrorInfo errorInfo) {
// 转推任务出错时触发此回调
}
});
其中,转推任务出错时的错误原因可参考 QNLiveStreamingErrorInfo。对应的错误码可参考 CDN 转推相关错误码
在设置好监听后,便可以基于业务场景进行单路转推任务
或者合流转推任务
的创建了。
单路流直播
单路流直播的场景,顾名思义,就是将一条音视频流直接转推到直播服务器,主要适用于不包含连麦的秀场直播
、连麦中需要将某一路流单独转推落存储
等场景。
场景示意图如下:
注意:如果主播有两路视频流(采集+录屏)需要合流转推,请参考多路流合流直播场景实现
单路流转推场景主要实现步骤如下:
创建单路转推任务
QNDirectLiveStreamingConfig 用于配置单路转推的相关信息,包括推流地址、参与 CDN 转推的音视频轨等。
创建转推任务的示例代码如下:
// 创建单路转推任务配置对象
QNDirectLiveStreamingConfig mDirectLiveStreamingConfig = new QNDirectLiveStreamingConfig();
// 设置 stream id,该 id 为转推任务的唯一标识符
mDirectLiveStreamingConfig.setStreamID(mRoomName);
// 设置推流地址
mDirectLiveStreamingConfig.setUrl("publish url");
// 设置单路流中的音频轨,仅支持一路音频的设置,重复设置会被覆盖
mDirectLiveStreamingConfig.setAudioTrack(mMicrophoneAudioTrack);
// 设置单路流中的视频轨,仅支持一路视频的设置,重复设置会被覆盖
mDirectLiveStreamingConfig.setVideoTrack(mCameraVideoTrack);
// 开始进行单路转推
mClient.startLiveStreaming(mDirectLiveStreamingConfig);
单路转推任务创建成功后,会触发上述 QNLiveStreamingListener.onStarted
回调接口,回调该接口即代表成功开启了单路流转推,可以通过相应的播放链接拉取直播流进行观看。
注意:
- QNDirectLiveStreamingConfig 仅支持配置一路视频轨和一路音频轨,重复设置会被覆盖
- 配置单路转推任务时,请务必保证待转推的音视频 Track 均已成功发布
- 单路转推场景下,需确保在创建视频 Track 时通过 QNVideoEncoderConfig 将视频降级模式 QNDegradationPreference 设置为
QNDegradationPreference.MAINTAIN_RESOLUTION
或者QNDegradationPreference.ADAPT_BITRATE_ONLY
,保证推流分辨率不会改变,否则可能会出现不可预期的问题!!!
停止单路转推任务
可以通过如下方式停止单路转推任务:
mClient.stopLiveStreaming(mDirectLiveStreamingConfig);
单路转推任务停止成功后,会触发上述 QNLiveStreamingListener.onStopped
回调接口。
多路流合流直播
多路流合流直播场景,主要适用于连麦互动直播
、PK 直播
以及单主播需要两路以上视频合流转推
等场景。简单来说,就是对连麦各方的视频画面进行合流,然后转推。这种场景相较于纯直播场景的单路流转推会复杂一些。
场景示意图如下:
为了实现该场景,首先,需要了解下相关配置类及其作用:
- QNTranscodingLiveStreamingConfig: 用于配置合流的基本参数,包括任务 id、推流地址、合流的宽高、码率等信息。
- QNTranscodingLiveStreamingTrack: 用于配置参与 CDN 合流的每一路媒体 Track 在合流画布中的位置、大小等信息。
了解上述概念后,该场景的主要实现步骤如下:
开启合流直播
创建 QNTranscodingLiveStreamingConfig
QNTranscodingLiveStreamingConfig mTranscodingLiveStreamingConfig = new QNTranscodingLiveStreamingConfig();
mTranscodingLiveStreamingConfig.setStreamID(streamID); // 设置 stream id,该 id 为合流任务的唯一标识符
mTranscodingLiveStreamingConfig.setUrl("publish url"); // 设置合流任务的推流地址
mTranscodingLiveStreamingConfig.setWidth(480); // 设置合流画布的宽度
mTranscodingLiveStreamingConfig.setHeight(848); // 设置合流画布的高度
mTranscodingLiveStreamingConfig.setVideoFrameRate(20); // 设置合流任务的视频帧率
mTranscodingLiveStreamingConfig.setRenderMode(QNRenderMode.ASPECT_FILL); // 设置合流任务的默认画面填充方式
mTranscodingLiveStreamingConfig.setBitrate(1000); // 设置合流任务的码率,单位: kbps
mTranscodingLiveStreamingConfig.setBackground(mBackgroundImage); // 设置合流画布的背景图片,仅支持 HTTP
mTranscodingLiveStreamingConfig.setWatermarks(Collections.singletonList(mWatermark)); // 设置合流任务的水印
mClient.startLiveStreaming(mTranscodingLiveStreamingConfig); // 开始转推
合流任务创建成功后,会触发上述 QNLiveStreamingListener.onStarted
回调接口。可以在该回调接口中设置合流布局
设置合流布局
合流任务创建成功之后,即可基于已发布的 Track 进行相应的合流布局配置。配置布局前,需要先了解 QNTranscodingLiveStreamingTrack 的概念。布局配置的示例代码如下:
// 配置待合流转推的视频 Track
QNTranscodingLiveStreamingTrack videoTranscodingTrack = new QNTranscodingLiveStreamingTrack();
videoTranscodingTrack.setTrackID(videoTrackID); // 设置待合流 Track id
videoTranscodingTrack.setX(x); // 设置 Track 画面在合流画面中位置的 x 轴坐标
videoTranscodingTrack.setY(y); // 设置 Track 画面在合流画面中位置的 y 轴坐标
videoTranscodingTrack.setZOrder(zOrder); // 设置 Track 画面在合流画面中的 zOrder 层级,zOrder 值越大,画面层级越高
videoTranscodingTrack.setWidth(width); // 设置 Track 画面在合流画面中位置宽度
videoTranscodingTrack.setHeight(height); // 设置 Track 画面在合流画面中位置高度
// 配置待合流转推的音频 Track
QNTranscodingLiveStreamingTrack audioTranscodingTrack = new QNTranscodingLiveStreamingTrack();
audioTranscodingTrack.setTrackID(audioTrackID); // 设置待合流 Track id
其中,远端用户的 trackID 可以通过 SDK 提供的相关回调返回的 QNRemoteAudioTrack 和 QNRemoteVideoTrack 获取:
public interface QNClientEventListener {
// 当成功订阅远端 Track 时会触发此回调
void onSubscribed(String remoteUserID, List<QNRemoteAudioTrack> remoteAudioTracks, List<QNRemoteVideoTrack> remoteVideoTracks);
}
通过上述代码创建或者更新已有的 QNTranscodingLiveStreamingTrack 布局配置后,即可调用如下方法使得相应的布局配置生效:
/**
* 新增、更新合流布局
*
* @param streamID 合流任务 id
* @param transcodingTracks 待配置布局的 QNTranscodingLiveStreamingTrack 的列表
*/
mClient.setTranscodingLiveStreamingTracks(String streamID, List<QNTranscodingLiveStreamingTrack> transcodingTracks);
当期望取消某路合流布局时,可以通过如下调用实现:
/**
* 设置取消合流布局
*
* @param streamID 合流任务 id
* @param transcodingTracks 待移除布局的 QNTranscodingLiveStreamingTrack 的列表
*/
mClient.removeTranscodingLiveStreamingTracks(String streamID, List<QNTranscodingLiveStreamingTrack> transcodingTracks);
注意:配置合流转推任务时,请务必保证待转推的音视频 Track 均已成功发布
停止合流直播
可以通过如下方式停止合流转推任务:
mClient.stopLiveStreaming(mTranscodingLiveStreamingConfig);
合流转推任务停止成功后,会触发上述 QNLiveStreamingListener.onStopped
回调接口。
单路、多路切换直播
单路流、多路流合流二者切换的场景,主要适用于有连麦需求的秀场直播
等场景,能够满足主播在自己单路流直播和连麦两路流合流直播二者间切换的需求。对于该场景的实现,需要注意的问题是,在两种场景切换的过程中,如何保证观看端不会断流黑屏。
为了避免切换过程中断流黑屏的问题,这里我们引入 serialnum
的概念以实现两路流的平滑切换:
- QNDirectLiveStreamingConfig 和 QNTranscodingLiveStreamingConfig 两种任务场景推流地址需要保持一致以避免播放端需要实现多余的切流操作
- 由于上述完全一致的地址可能会导致抢流的现象出现,所以需要在推流地址后面加上
serialnum
的参数,如 "rtmp://domain/app/streamName?serialnum=xxx",其中,serialnum 决定流的优先级,从 1 开始递增,值越大,优先级越高,优先级低的流会被停止掉,便可避免出现抢流的现象。也基于此,合流任务必须使用自定义合流任务,以便自定义推流地址。
综上,单路流、合流切换场景的实现步骤如下:
- 创建单路流转推任务,同时进行单路流直播
- 需要从单路转推任务切换到合流转推任务时,
创建自定义合流任务
,注意要使用自定义合流任务指定带有serialnum
参数的推流地址,在收到合流转推任务的onStarted
回调之后,在回调中执行mClient.stopLiveStreaming(mDirectLiveStreamingConfig)
来停止单路转推任务 - 需要从合流转推任务切换到单路转推任务时,创建单路转推任务,其推流地址需要带有
serialnum
参数,在收到单路转推任务的onStarted
回调之后,在回调中执行mClient.stopLiveStreaming(mTranscodingLiveStreamingConfig)
来停止合流转推任务
通过上述方式,即可实现单路流直播、多路流合流直播之间的切换,具体实现也可参照 demo 中的相关实现
发送 SEI
CDN 转推场景支持 SEI 信息的发送,设置方式如下:
String seiMsg = "SEI message";
// Camera 视频 Track 发送 SEI
mCameraVideoTrack.sendSEI(seiMsg.getBytes(StandardCharsets.UTF_8), 1);
// 屏幕录制视频 Track 发送 SEI
mScreenVideoTrack.sendSEI(seiMsg.getBytes(StandardCharsets.UTF_8), 1);
// 自定义视频 Track 发送 SEI
mCustomVideoTrack.sendSEI(seiMsg.getBytes(StandardCharsets.UTF_8), 1);
- 对于单路流直播的场景,调用上述接口后,播放端即可通过使用支持 SEI 解析的播放器获取到对应的 SEI 信息。
- 对于多路流合流直播的场景,调用上述接口后,还需在配置合流布局时,通过 QNTranscodingLiveStreamingTrack.setSEIEnabled 接口指定允许携带 SEI 信息的视频 Track,才可正常推送 SEI 信息。需要注意的是,一个合流任务中,仅支持一路视频 Track 携带 SEI 信息。
注意事项
- CDN 转推需要配置本地或者远端的音视频 Track,因此,调用转推接口前请务必保证加入了房间,并且已经发布或者订阅了相应的音视频 Track
- 单路流直播场景,一路流仅支持一路音频轨和一路视频轨的设置,重复设置会被覆盖
- 为保证单路流直播的质量,需确保在创建视频 Track 时通过 QNVideoEncoderConfig 将视频降级模式 QNDegradationPreference 设置为
QNDegradationPreference.MAINTAIN_RESOLUTION
或者QNDegradationPreference.ADAPT_BITRATE_ONLY
,保证推流分辨率不会改变 - 如果场景涉及到单路流直播、多路流合流直播之间的切换,那么合流任务务必使用自定义合流任务以指定带有
serialnum
的推流地址。其中,serialnum 决定流的优先级,从 1 开始递增,值越大,优先级越高
示例代码
CDN 转推场景的示例代码可参考 QNRTC-API-Examples。