阿里云视频直播支持Web端主播与观众的连麦互动,用户无需安装额外的应用程序即可直接在Web页面上与他人进行连麦互动。本文为您介绍Web端连麦互动的操作步骤和相关示例代码,帮助用户快速接入连麦互动场景。
接入RTC连麦互动方案介绍
直播SDK基于实时音视频RTC来实现连麦方案,帮助客户实现超低延时、更多人数的直播实时互动,一般流程如下:
连麦前:主播使用RTC连麦推流地址进行推流,观众拉取CDN流进行观看。
连麦中:观众从普通观众切换为连麦观众,使用RTC连麦推流地址进行推流,使用RTC连麦拉流地址拉取主播的超低延时流;主播使用RTC连麦拉流地址进行拉取连麦观众的超低延时流。
结束连麦:连麦观众切换为普通观众,停止RTC推流和RTC拉流,切换为拉取CDN流进行观看。
注意事项
互动模式下主播或者连麦观众的超低延时流,只能使用AlivcLivePlayer对象。AlivcLivePlayer目前只支持播放
artc://live.aliyun.com/play/
前缀的超低延时流。本文介绍Web端连麦功能使用,Web连麦互动SDK的集成方法,请参见Web连麦互动SDK集成。
重要为了兼容新版Chrome,Web连麦互动SDK于2024年3月15日已升级,请已接入旧版Web连麦互动SDK的用户尽快完成SDK升级,避免出现无法使用的问题。接入新版SDK的详细信息,请参见Web连麦互动SDK集成。
步骤一:开通直播连麦服务
使用直播连麦功能时,您需要先创建连麦应用,并配置观众播放域名。具体操作方法,请参见直播连麦快速入门。
步骤二:生成连麦互动推拉流地址
您可以通过控制台生成或通过自定义拼接主播和连麦观众的推拉流地址,及普通观众(非连麦观众)的CDN播放地址。
方法一:控制台生成
若您希望快速生成主播和连麦观众的推拉流地址,及普通观众(非连麦观众)的CDN播放地址进行体验,可以借助控制台工具进行生成。具体操作,请参见连麦地址生成器。
方法二:自定义拼接
通过控制台生成主播和连麦观众的推拉流地址URL中,Token为临时Token,一般用于测试使用。如果需要正式使用,为了安全起见,请使用自定义拼接的推拉流地址。自定义拼接地址中Token是基于您的SdkAppID、 AppKey、房间ID、UserID和Timestamp通过SHA256加密算法计算得到,攻击者很难通过伪造Token盗用您的云服务流量。自定义拼接详情请参见连麦互动场景主播端和连麦观众端推拉流地址和普通观众的CDN播放地址。
步骤三:创建推流对象
主播端和连麦观众端都需要执行该操作。
创建AlivcLivePusher推流对象
创建推流引擎对象 AlivcLivePusher,设置相应的回调:
const pusher = new window.AlivcLivePush.AlivcLivePusher();
await pusher.init({
resolution: window.AlivcLivePush.AlivcResolutionEnum.RESOLUTION_540P,
fps: window.AlivcLivePush.AlivcFpsEnum.FPS_30,
// audioOnly: true, 针对纯音频推流场景,非纯音频推流场景不需要。
});
pusher.info.on('pushstatistics', _stat => {
// TODO... 推流统计信息处理
// console.log(_stat);
});
pusher.error.on('system', error => {
console.log(error);
});
pusher.network.on('connectionlost', () => {
console.log('connectionlost');
});
连麦互动模式下推流
使用连麦互动模式下推流地址URL进行推流。
await pusher.startPreview(videoElement);
await pusher.startPush("artc://live.aliyun.com/push/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX"); //主播或连麦观众的推流地址
startPreview和startPush均为异步方法,为了保证调用顺序,需要通过await执行,或通过Promise处理。
如果使用场景为Native与Web连麦互通,则Native端(Android/iOS)必须使用H5兼容模式。否则,Web用户查看Native用户将是黑屏。请在Native端调用AlivcLivePushConfig#setH5CompatibleMode接口,接口详细说明请参考Native SDK API文档。
步骤四:创建AliPlayer CDN播放
普通观众端(非连麦观众)需要执行该操作。
如果播放端需要使用AliPlayer进行CDN播放,需要先获取普通观众(非连麦观众)的CDN播放地址。具体操作,请参见步骤二:生成连麦互动推拉流地址。
建议将下述RTMP格式的播放地址换成HTTP-FLV格式的形式。在阿里云视频直播控制台生成地址时,会同时生成RTMP与HTTP-FLV的地址,这两个协议里包含的数据内容是一致的,只是网络协议通道不一样。HTTP协议是互联网主要协议,CDN、运营商、中间网络设备等链路中都对HTTP有很长时间的网络优化,HTTP的默认80/443端口号也是常见白名单端口,不容易被禁用,而RTMP协议比较老,其默认端口号是1935有可能被防火墙等设备禁用,导致异常。因此在综合网络环境下,HTTP-FLV的稳定性、性能(卡顿、延时)会比RTMP更好。
const player = new window.Aliplayer(
{
id: videoId, // video element ID
source: url, //播放地址,可以是第三方直播地址,或阿里云直播服务中的拉流地址。
isLive: true, //是否为直播播放。
},
function (player: any) {
console.log('The player is created.', player);
}
);
步骤五:观众连麦
主播A RTC推流
主播A开始推流,调用AlivcLivePusher推流引擎开始主播A的推流。代码示例:
await pusher.startPreview(videoElement); // videoElement 可以通过 Document 相关 API 获得
await pusher.startPush("artc://live.aliyun.com/push/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX"); //主播或连麦观众的推流地址
普通观众(非连麦观众)的CDN播放主播A的流
所有观众观看主播A的直播,调用AliPlayer开始播放主播A的流。示例代码:
const player = new window.Aliplayer(
{
id: videoId, // video element ID
source: 'rtmp://test.alivecdn.com/live/streamId?auth_key=XXX', //播放地址,可以是第三方直播地址,或阿里云直播服务中的拉流地址。
isLive: true, //是否为直播播放。
},
function (player: any) {
console.log('The player is created.', player);
}
);
观众D发起连麦
观众D创建AlivcLivePusher对象,使用D的互动推流地址开始推流。示例代码:
const pusher = new window.AlivcLivePush.AlivcLivePusher(); pusher.init({ resolution: window.AlivcLivePush.AlivcResolutionEnum.RESOLUTION_540P, fps: window.AlivcLivePush.AlivcFpsEnum.FPS_30, // audioOnly: true, 针对纯音频推流场景,非纯音频推流场景不需要。 }); pusher.info.on('pushstatistics', _stat => { // TODO... 推流统计信息处理 // console.log(_stat); }); pusher.error.on('system', error => { console.log(error); }); pusher.network.on('connectionlost', () => { console.log('connectionlost'); }); await pusher.startPreview(videoElement); // videoElement 可以通过 Document 相关 API 获得 await pusher.startPush("artc://live.aliyun.com/push/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX"); //主播或连麦观众的推流地址
主播A获取连麦观众D的互动模式直播拉流地址,创建AlivcLivePlayer对象拉取连麦观众D的实时流。示例代码:
const player = new window.AlivcLivePush.AlivcLivePlayer(); // artc:// 链接为观众D的直播拉流地址 const playInfo = await player.startPlay("artc://live.aliyun.com/play/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX", videoElement); playInfo.on('userleft', () => { // 处理观众D离开的事件 }); playInfo.on('canplay', () => { // 处理视频可播放事件 }
同时,连麦观众D获取主播A的互动模式直播拉流地址创建AlivcLivePlayer对象拉取主播A的实时流。示例代码:
const player = new window.AlivcLivePush.AlivcLivePlayer(); // artc:// 链接为主播A的直播拉流地址 const playInfo = await player.startPlay("artc://live.aliyun.com/play/6375?timestamp=1661596947&token=XXX&userId=7135&sdkAppId=XXX", videoElement); playInfo.on('userleft', () => { // 处理主播A离开的事件 }); playInfo.on('canplay', () => { // 处理视频可播放事件 }
连麦成功后更新混流
为了保证普通观众B和C(非连麦观众)可以看到连麦观众D的画面,主播A此时需要发起一次混流操作,即将主播A和连麦观众D的画面,混合成一路流给到CDN观众播放。
主播A调用setLiveMixTranscodingConfig接口启动云端混流(转码)任务,设置需要混流的对象。混流出来的视频画面的分辨率、帧率等使用的是主播A创建AlivcLivePusher引擎时指定的AlivcLivePushConfig中的配置。即如果主播A创建AlivcLivePusher引擎时AlivcLivePushConfig中配置分辨率为720P,则混流出来的视频画面的分辨率也是720P。
const resolution = pusher.getResolution();
const width = window.AlivcLivePush.AlivcResolution.GetResolutionWidth(resolution);
const height = window.AlivcLivePush.AlivcResolution.GetResolutionHeight(resolution);
const mixStreams = [];
const transcodingConfig = new window.AlivcLivePush.AlivcLiveTranscodingConfig();
const anchorMixStream = new window.AlivcLivePush.AlivcLiveMixStream(
userA, // 修改为主播A的用户ID
0,
0,
width,
height,
1
);
// 将主播A的流添加到混流列表
mixStreams.push(anchorMixStream);
const audienceMixStream = new window.AlivcLivePush.AlivcLiveMixStream(
userD, // 修改为连麦观众D的用户ID
100,
200,
200,
300,
2
);
// 将连麦观众D的流添加到混流列表
mixStreams.push(audienceMixStream);
transcodingConfig.mixStreams = mixStreams;
await pusher.setLiveMixTranscodingConfig(transcodingConfig);
这样,普通观众就可以看到主播A和连麦观众D的连麦互动。
连麦观众D结束连麦
连麦观众D结束连麦,需要调用AlivcLivePusher推流引擎的结束推流接口,并将AlivcLivePusher推流引擎销毁。示例代码:
await pusher.destroy(); pusher = null;
同时,连麦观众D需要调用AlivcLivePlayer拉流引擎的结束播放接口,并将AlivcLivePlayer拉流引擎销毁。示例代码:
await player.destroy(); player = null;
连麦观众D切换为普通观众,通过步骤四:创建AliPlayer CDN播放进行CDN播放。
主播A需要调用AlivcLivePlayer拉流引擎的结束播放接口,并将AlivcLivePlayer拉流引擎销毁。示例代码:
await player.destroy(); player = null;
同时,当主播A不再需要混流,普通观众只需观看主播A的画面时,可以调用setLiveMixTranscodingConfig接口,将参数传入空值,即可切换为旁路模式。
警告若主播还在房间中但不再需要混流,请务必传入空值进行取消。因为当发起混流后,云端混流模块就会开始工作,不及时取消混流可能会引起不必要的计费损失。
pusher.setLiveMixTranscodingConfig();