功能描述
在实时音视频场景中,首帧时间(即用户从进入房间到看到/听到远端画面或声音的时间)是衡量用户体验的重要指标。首帧时间越短,用户等待时间越少,体验越流畅。
本文介绍四种优化首帧时间的方案:预连接(Preconnect)、快速拉流(Quick Start)、快速切房(switchRoom) 和 信令保活(keepAlive),帮助您根据业务场景选择合适的优化策略。
方案概述
| 方案 | 适用场景 | 优化原理 | 首帧提升 |
|---|---|---|---|
| 预连接 | 1v1 通话、连麦等进房前有可利用时间的场景 | 提前完成部分建连流程 | 明显 |
| 快速拉流 | 直播场景,观众拉单个主播的流 | SDK 内部优化拉流链路 | 明显 |
| 快速切房 | 直播 Feed 流等需要频繁切换房间的场景 | 复用已有连接,避免重复建连 | 明显 |
| 信令保活 | 需要频繁退房再进房的场景 | 退房后保持连接,再次进房时复用 | 明显 |
快速拉流和快速切房可以组合使用,实现直播 Feed 流场景下从页面首次进房到滑动切换的全链路秒开优化,详见直播 Feed 流最佳实践。
预连接(Preconnect)
前提条件
- 使用前需 提交工单 联系我们开通该功能。
适用场景
预连接适用于进房前存在可利用时间差的场景,例如:
- 1v1 通话:在用户按下「接听」按钮之前,可以利用来电等待的时间提前建立连接。
- 连麦场景:在用户点击「申请连麦」后、等待主播同意的过程中,可以提前建立连接。
实现步骤
1. 在进房前调用预连接
当存在可利用的时间窗口时(如收到来电邀请),调用预连接接口:
// 收到来电邀请时,立即调用预连接
await trtc.callExperimentalAPI('preconnect', {
sdkAppId: 1400000000, // 您的 sdkAppId
userId: 'user_123', // 当前用户 userId
userSig: 'xxx', // 当前用户的 userSig
roomId: 12345, // 房间号(数字类型)
});
roomId和strRoomId必须传入其中一个,与后续进房时使用的房间号保持一致。
2. 用户确认后正常进房
当用户点击「接听」或「同意」后,调用 trtc.enterRoom() 进房:
// 用户点击接听后,正常进房
await trtc.enterRoom({
sdkAppId: 1400000000,
userId: 'user_123',
userSig: 'xxx',
roomId: 12345, // 与预连接时的房间号保持一致
scene: 'rtc',
});
SDK 会自动复用预连接建立的连接,从而显著缩短进房时间。
注意事项
- 预连接成功后,连接有效期为 60 秒。
快速拉流(Quick Start)
适用场景
快速拉流适用于直播场景下,观众快速拉取单个主播的流:
- 直播间场景:观众进入直播间时,快速看到主播画面。
- 直播 Feed 流:与快速切房组合使用,页面首次进房时通过
quickStart快速拉流,后续滑动切换时通过switchRoom快速切房。
前提条件
- 使用前需 提交工单 联系我们开通该功能。
实现步骤
在 trtc.enterRoom() 时,传入 quickStart 参数:
// 进房前监听远端视频可用事件
trtc.on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, ({ userId, streamType }) => {
trtc.startRemoteVideo({
userId,
streamType,
view: 'video-container', // 播放视频的 DOM 元素 ID
});
});
await trtc.enterRoom({
sdkAppId: 1400000000,
userId: 'audience_123',
userSig: 'xxx',
roomId: 12345,
scene: 'live',
role: 'audience',
// 快速拉流参数
quickStart: {
remoteUserId: 'anchor_456', // 要拉取的主播 userId
}
});
进房前监听 TRTC.EVENT.REMOTE_VIDEO_AVAILABLE 事件,收到事件后调用 trtc.startRemoteVideo() 播放远端视频流。
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| remoteUserId | string | 是 | 要快速拉取的主播 userId |
| small | boolean | 否 | 是否拉小流,默认为 false |
| domain | string | 否 | 自定义拉流域名 |
拉取小流示例
如果主播开启了大小流,观众可以选择拉取小流:
await trtc.enterRoom({
sdkAppId: 1400000000,
userId: 'audience_123',
userSig: 'xxx',
roomId: 12345,
scene: 'live',
role: 'audience',
quickStart: {
remoteUserId: 'anchor_456',
small: true, // 拉取小流
}
});
注意事项
- 该功能仅支持直播场景(
scene: 'live')和观众角色(role: 'audience')。
快速切房(switchRoom)
前提条件
- 使用前需 提交工单 联系我们开通该功能。
适用场景
快速切房适用于需要频繁切换房间的场景,例如:
- 直播 Feed 流:用户上下滑动切换直播间时,快速切换到下一个主播的房间。
优化原理
传统的切换房间方式是先调用 trtc.exitRoom() 退房,再调用 trtc.enterRoom() 进入新房间。这种方式需要重新建立连接,耗时较长。
而 trtc.switchRoom() 通过复用已有连接,大大减少了切换房间的耗时。
实现步骤
// 1. 首先以观众身份进入直播间
await trtc.enterRoom({
sdkAppId: 1400000000,
userId: 'audience_123',
userSig: 'xxx',
roomId: 12345,
scene: 'live',
role: 'audience',
});
// 2. 用户滑动到下一个直播间时,调用 switchRoom 快速切换
await trtc.switchRoom({
userSig: 'xxx', // 新的 userSig(如果需要更新)
roomId: 12346, // 新的房间号
});
注意事项
- 切换前后的房间类型必须一致(都是数字房间号或都是字符串房间号)。
信令保活(keepAlive)
前提条件
- 使用前需 提交工单 联系我们开通该功能。
适用场景
信令保活适用于需要频繁退房再进房的场景,例如:
- 混合 Feed 流:Feed 流中同时存在 TRTC 直播间和非 TRTC 直播间,用户从 TRTC 房间滑动到非 TRTC 内容时需要退房,再次滑动到 TRTC 房间时需要重新进房。
- 监播巡查:运营或管理人员需要对多个直播间进行巡查监播,频繁进入不同房间查看内容后退出,再进入下一个房间。每次停留时间较短但进出频率很高,keepAlive 可以显著减少每次进房的等待时间。
- 直播列表浏览:用户在直播列表页浏览,点击某个直播间进入观看,退出后回到列表继续浏览,找到感兴趣的直播间后再次点击进入。这种「列表 → 进房 → 退房 → 列表 → 进房」的反复操作中,keepAlive 保持连接不断开,用户再次点击进入时可以更快看到画面。
- 多实例切换:同一用户使用多个 TRTC 实例,在不同实例间切换时可复用连接。
优化原理
正常退房后,SDK 会关闭与服务器之间的连接。下次进房时,需要重新建立连接,这一过程会带来额外的耗时。
开启 keepAlive 后,SDK 在退房时保持连接不断开,下次进房时直接复用已有连接,省去了重新建连的时间,从而加快进房速度。
注意事项
- 退房后,连接会保活一段时间。如果超时未重新进房,连接会自动断开。
- keepAlive 由后台云控开启,需要通过工单联系我们配置。
- 保活期间,如果网络断开,连接将自动关闭,下次进房会重新建立连接。
直播 Feed 流最佳实践
在直播 Feed 流场景中,用户首次进入直播间和后续滑动切换直播间的优化策略不同,可以将快速拉流和快速切房组合使用,实现全链路秒开:
- 页面首次进房:使用 trtc.enterRoom() +
quickStart,快速拉取主播流。 - 滑动切换(TRTC → TRTC):使用 trtc.switchRoom(),复用已有连接,快速切换房间。
混合 Feed 流场景
如果 Feed 流中同时存在 TRTC 直播间和非 TRTC 直播间,滑动切换时需要根据目标内容类型做不同处理:
- 页面首次进入 TRTC 房间: 调用
enterRoom并设置 quickStart 参数快速拉流 - TRTC → TRTC:调用
switchRoom快速切房。 - TRTC → 非 TRTC:调用
exitRoom退出 TRTC 房间。 - 非 TRTC → TRTC:调用
enterRoom重新进房并快速拉流。
let isInTRTCRoom = false;
let isFirstEnter = true;
// 用户滑动到下一个 Feed 项
async function onSlideToNext(nextItem) {
if (nextItem.type === 'trtc') {
if (isInTRTCRoom) {
// TRTC → TRTC:快速切房,复用已有连接
await trtc.switchRoom({
userSig: 'xxx',
roomId: nextItem.roomId,
});
} else {
// 页面首次进入 或 非 TRTC → TRTC:进房
const enterParams = {
sdkAppId: 1400000000,
userId: 'audience_123',
userSig: 'xxx',
roomId: nextItem.roomId,
scene: 'live',
role: 'audience',
};
// 页面首次进房时,使用 quickStart 快速拉流
if (isFirstEnter) {
enterParams.quickStart = {
remoteUserId: nextItem.anchorUserId,
};
isFirstEnter = false;
}
await trtc.enterRoom(enterParams);
isInTRTCRoom = true;
}
} else {
// TRTC → 非 TRTC:退出房间,释放连接
if (isInTRTCRoom) {
await trtc.exitRoom();
isInTRTCRoom = false;
}
// 加入非 TRTC 房间
}
}
- 页面首次进入 TRTC 房间时,在 trtc.enterRoom() 中加入
quickStart参数即可实现更快的秒开效果。- 连续切换 TRTC 房间时,使用 trtc.switchRoom() 复用连接,避免重建开销。
- 从非 TRTC 房间再次进入 TRTC 房间时,调用 trtc.enterRoom() 通过 keepAlive 复用连接进入房间即可。keepAlive 功能需 提交工单 联系我们开通。
方案选择建议
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 1v1 通话、连麦 | 预连接 | 进房前有明确的等待时间可利用 |
| 直播观看(首次进入) | 快速拉流 | 专为直播场景优化,观众可快速看到主播画面 |
| 直播 Feed 流(纯 TRTC) | 快速拉流 + 快速切房 | 页面首次进房用 quickStart 快速拉流,后续滑动用 switchRoom 快速切房 |
| 混合 Feed 流(TRTC + 非 TRTC) | 快速拉流 + 快速切房 + 信令保活 | TRTC 间用 switchRoom,退出 TRTC 后通过 keepAlive 保持连接,再次进房时复用 |
| 多人会议 | 预连接 | 进房前若有等待时间(如会议预约提醒),可利用预连接 |
常见问题
-
预连接失败会影响进房吗?
不会。预连接是可选的优化手段,即使预连接失败,后续调用 trtc.enterRoom() 仍会正常进房,只是无法享受首帧优化的效果。
-
快速拉流和预连接可以同时使用吗?
不可以。快速拉流是专门为直播场景设计的,预连接更适合通话场景。
-
如何判断首帧优化是否生效?
您可以通过 SDK 的首帧回调事件统计进房到首帧的时间差来验证优化效果。
-
开启 keepAlive 后,还需要使用 quickStart 吗?
quickStart只需要在页面首次进房时使用。开启 keepAlive 后,后续通过enterRoom重新进房时不需要再加入quickStart参数,即可享受 keepAlive 带来的连接复用效果。两者优化的环节不同:quickStart优化的是首次拉流速度,keepAlive优化的是退房后再次进房时的建连速度。 -
各秒开方案的进房速度对比?
从进房速度来看:
switchRoom>keepAlive+enterRoom>quickStart+enterRoom>enterRoom。