2025/11/17 18:27:18
录制与回放
声网 Fastboard SDK 提供录制与回放功能,支持将实时房间中的所有互动行为录制下来,并支持高质量回放。相较于传统的录屏模式,白板录制和回放具有以下优势:
- 高效录制:采用信令记录方式,相比传统录屏模式占用带宽更少、存储空间更小
- 高质量回放:回放时还原现场效果,画质清晰、动画流畅
- 服务端录制:录制在服务端自动进行,无需客户端额外处理
- 灵活回放:支持指定时间范围回放、播放控制、视角跟随等功能
- 完整记录:录制白板操作、自定义事件、视角变化、多窗口应用等所有互动行为
- 内置 UI:提供开箱即用的回放 UI 组件,支持主题和语言自定义
本文介绍如何开启白板录制功能以及如何使用 Fastboard SDK 实现白板内容回放。
技术原理
白板录制
声网互动白板录制不是屏幕录制,而是记录信令与数据增量构成的私有二进制数据。录制过程完全在服务端进行,具有以下优势:
- 自动录制:只需在创建房间时开启录制功能,服务端会自动录制房间内的所有互动行为
- 智能管理:只有在房间活跃时才会生成录制信息,房间无活动时录制会自动停止
- 数据紧凑:录制生成的数据相比传统音视频格式更紧凑,占用存储空间更小
- 多窗口支持:完整记录 Fastboard 多窗口模式下的所有应用和操作
白板回放
Fastboard SDK 基于底层 Whiteboard SDK 的回放能力,提供了更易用的 API 和内置 UI 组件。回放时,SDK 会依照录制的信令与数据增量还原现场,得到的效果和实时互动时一模一样。回放支持:
- 指定时间范围回放
- 播放、暂停、跳转等播放控制
- 播放速度调节
- 视角跟随和自由视角切换
- 自定义事件和全局状态变化的回放
- 多窗口应用的完整回放
前提条件
开始前,请确保:
- 已在项目中集成声网 Fastboard SDK。详见快速开始。
- 已获取有效的 App Identifier 和 Room Token。详见获取互动白板项目的安全密钥。
- 如需在业务服务器上创建房间,请参考房间管理服务端 API。
实现录制功能
开启录制
要开启白板录制功能,需要在创建房间时设置 isRecord: true 参数。通过服务端 API POST 创建房间创建支持录制的房间:
JavaScript
var url = "https://api.netless.link/v5/rooms";
var requestInit = {
method: "POST",
headers: {
"content-type": "application/json",
"token": "NETLESSSDK_YWs9xxxxxxM2MjRi", // 替换为你的 SDK Token
"region": "cn-hz", // 替换为你的数据中心
},
body: JSON.stringify({
name: "我的 Fastboard 录制房间",
isRecord: true, // 开启录制功能
}),
};
fetch(url, requestInit).then(function(response) {
return response.json();
}).then(function(roomJSON) {
// 创建房间成功,获取房间信息
console.log("房间 UUID:", roomJSON.uuid);
console.log("房间已开启录制功能");
}).catch(function(err) {
console.error("创建房间失败:", err);
});
注意
- SDK Token 是重要的安全凭证,建议在业务服务器中使用,不要写死在前端代码中。
- 开启录制功能后,该房间内的所有互动行为都会被自动录制。
录制内容
开启录制功能后,以下内容会被自动录制:
- 白板绘制操作(画笔、图形、文字等)
- 场景切换和内容变化
- 图片、音视频、课件(PPT、DOC)的展示和操作
- 多窗口应用的所有操作和状态变化
- 用户视角变化
- 自定义事件(通过
dispatchMagixEvent发送的事件) - 全局状态变化(
GlobalState的修改)
实现回放功能
方法一:使用 replayFastboard 和 createReplayUI
这是推荐的方法,提供完整的回放 UI 组件:
JavaScript
import { replayFastboard, createReplayUI } from "@netless/fastboard";
// 创建回放播放器
const player = await replayFastboard({
sdkConfig: {
appIdentifier: "RMxxxAQ", // 替换为你的 App Identifier
region: "cn-hz", // 替换为你的数据中心
},
replayRoom: {
room: "a7xxx69", // 房间 UUID
roomToken: "NETLESSROOM_YWxxxjk", // Room Token
beginTimestamp: new Date("2023-01-01 08:00:00").getTime(), // 回放开始时间
duration: 45 * 60 * 1000, // 回放持续时间(毫秒)
},
managerConfig: {
cursor: true, // 显示光标
},
});
// 创建并挂载回放 UI
const ui = createReplayUI(player, document.getElementById("whiteboard"));
// 可选:更新 UI 配置
ui.update({
theme: "dark",
language: "zh-CN"
});
// 使用完毕后销毁
// ui.destroy();
方法二:使用 React Hook
如果你使用 React 框架,可以使用 useReplayFastboard Hook:
React JSX
import React from "react";
import { useReplayFastboard, ReplayFastboard } from "@netless/fastboard-react";
function ReplayComponent() {
const player = useReplayFastboard(() => ({
sdkConfig: {
appIdentifier: "RMxxxAQ", // 替换为你的 App Identifier
region: "cn-hz",
},
replayRoom: {
room: "a7xxx69", // 房间 UUID
roomToken: "NETLESSROOM_YWxxxjk", // Room Token
beginTimestamp: new Date("2023-01-01 08:00:00").getTime(),
duration: 45 * 60 * 1000,
},
managerConfig: {
cursor: true,
},
}));
return (
<ReplayFastboard
player={player}
theme="light"
language="zh-CN"
/>
);
}
插件配置
如果在创建实时房间时启用了插件(如 AppliancePlugin 或 AppInMainViewPlugin),在回放时也需要配置相同的插件:
JavaScript
const player = await replayFastboard({
sdkConfig: {
appIdentifier: "RMxxxAQ",
region: "cn-hz",
},
replayRoom: {
room: "a7xxx69",
roomToken: "NETLESSROOM_YWxxxjk",
beginTimestamp: new Date("2023-01-01 08:00:00").getTime(),
duration: 45 * 60 * 1000,
},
// 如果实时房间启用了 AppliancePlugin,回放时也需要配置
enableAppliancePlugin: {
cdn: {
fullWorkerUrl: "path/to/fullWorker.js",
subWorkerUrl: "path/to/subWorker.js",
},
strokeWidth: {
min: 1,
max: 32
},
syncOpt: {
interval: 200
},
},
// 如果实时房间启用了 AppInMainViewPlugin,回放时也需要配置
enableAppInMainViewPlugin: true,
});
播放器控制
FastboardPlayer 提供了丰富的播放控制功能:
JavaScript
// 播放控制
player.play(); // 开始播放
player.pause(); // 暂停播放
player.stop(); // 停止播放
// 跳转到指定位置(单位:毫秒,相对于回放开始时间)
player.seek(10 * 60 * 1000); // 跳转到第 10 分钟
// 设置播放倍速
player.setPlaybackRate(1.5); // 1.5 倍速播放
player.setPlaybackRate(1.0); // 恢复正常速度
// 获取播放状态信息
console.log("当前播放进度:", player.currentTime.value); // 当前播放位置(毫秒)
console.log("总时长:", player.duration.value); // 回放总时长(毫秒)
console.log("播放状态:", player.phase.value); // 播放状态
console.log("播放速度:", player.playbackRate.value); // 当前播放速度
console.log("是否可播放:", player.canplay.value); // 是否准备好播放
监听播放器状态变化
可以通过订阅可观察属性来监听播放器状态的变化:
JavaScript
// 监听播放进度变化
const unsubscribeProgress = player.currentTime.subscribe(time => {
console.log("当前播放进度:", time + "ms");
});
// 监听播放状态变化
const unsubscribePhase = player.phase.subscribe(phase => {
switch(phase) {
case "playing":
console.log("正在播放");
break;
case "pause":
console.log("已暂停");
break;
case "buffering":
console.log("正在缓冲");
break;
case "ended":
console.log("播放结束");
break;
case "waitingFirstFrame":
console.log("等待首帧");
break;
}
});
// 监听播放速度变化
const unsubscribeRate = player.playbackRate.subscribe(rate => {
console.log("播放速度:", rate + "x");
});
// 取消订阅
// unsubscribeProgress();
// unsubscribePhase();
// unsubscribeRate();
自定义渲染
如果需要自定义渲染,可以使用 bindContainer 方法:
JavaScript
// 只渲染白板内容,不包含控制 UI
player.bindContainer(document.getElementById("whiteboard"));
// 可选:移动 collector 到指定位置
player.bindCollector(document.getElementById("collector"));
参考信息
开发注意事项
在使用 Fastboard 录制与回放功能时,需要注意以下几点:
- 录制延时:录制内容不是实时生成的,新创建的房间可能需要等待一段时间才能获得录制内容
- 插件一致性:如果实时房间启用了插件,回放时必须配置相同的插件,否则可能导致回放异常
- 时间范围:建议根据实际使用场景设置合适的回放时间范围,避免回放过长的无效内容
- 网络缓冲:回放时可能需要网络缓冲,特别是跳转到较远时间点时
- 存储成本:长期开启录制功能会产生存储成本,建议根据业务需要合理使用
- 资源释放:使用完毕后记得调用
ui.destroy()和player.destroy()释放资源
API 参考
replayFastboard- 创建回放播放器createReplayUI- 创建回放 UI- POST 创建房间