Netless

Netless

  • 通用文档
  • 常见问题
  • JavaScript
  • Android
  • iOS
  • Server
  • GitHub
  • 🇬🇧 English

›进阶教程

接入准备

  • 前提条件
  • 开源项目
  • 快速调试
  • 版本历史

快速开始

  • 原生 JavaScript
  • React

进阶教程

  • 安装
  • 实时房间
  • 教具
  • PPT 与页面管理
  • 视角
  • 禁止操作
  • 自定义行为
  • 回放

初始化参数

  • SDK参数
  • 房间参数
  • 回放参数

功能介绍

  • 教具操作
  • 视角操作
  • 页面(场景)管理
  • 状态监听
  • 白板操作
  • 自定义事件
  • 鼠标位置同步
  • 文档转换
  • 回放功能
  • 大课只读
  • 撤回与重做
  • 集成白板插件

迁移与升级

  • 2.9.0 迁移指南
  • 2.8.0 迁移指南

回放

Netless 以记录信令的方式实现录制、回放功能。相较于传统的录屏模式,仅需少量带宽,回放时便输出高清的结果。只要调整好参数,Netless 云端就会自动录制实时房间的内容。

到此章为止,我们假设你已经将 Netless 互动白板 SDK 安装并引入了项目。如果没有,你可能跳过了之前的章节,强烈建议先阅读《安装》。

本章教程只会把房间状态管理的相关内容涉猎一遍。如果想深入了解相关内容,可以在阅读完本章后,进一步阅读《录制与回放》。

开启云端录制

在创建房间之初,可以开启云端录制功能。通过在调用 Netless 服务端 API 创建房间时,加入参数 isRecord: true 即可开启。

var url = "https://shunt-api.netless.link/v5/rooms";
var requestInit = {
    method: "POST",
    headers: {
        "content-type": "application/json",
        "token": sdkToken, // 签发的 SDK Token,需提前准备
    },
    body: JSON.stringify({
        isRecord: true, // 开启云端录制
    }),
};

window.fetch(url, requestInit).then(function(response) {
    return response.json();

}).then(function(roomJSON) {
    // 创建房间成功,获取描述房间信息的 roomJSON
    console.log(roomJSON);

}).catch(function(err) {
    // 失败了,打印出 Error 以便分析为何失败
    console.error(err);
});

建议在业务服务器上执行创建房间的操作,不要在前端或客户端上做。本章为了演示完整流程,用了前端的 window.fetch 方法调用 Netless 服务端 API。请勿在正式 Web 应用中效仿此行为。 SDK Token 是公司和团队的重要资产,原则上只能在业务服务器中产生并使用。绝对不能写死在前端!绝对不要通过网络传输给前端!否则,别人可以通过反编译、抓包等途径来窃取 SDK Token。SDK Token 一旦泄漏,会带来严重的安全问题。

开启之后,该房间的一切实时互动行为都会被 Netless 云端自动录制下来。更多关于创建房间 API 的内容,请参考《房间 | 服务端》。

在前端回放已录制好的内容

通过如下代码,可以创建一个用于回放的播放器实例。

var replayRoomParams = {
    room: "回放的房间 UUID",
    roomToken: "回放房间的 Room Token",
    beginTimestamp: new Date("2020-01-01 22:00:00").getTime(), // 回放开始时间
    duration: 10 * 60 * 1000, // 回放持续时间(ms),这里是 10 分钟
};
whiteWebSdk.replayRoom(replayRoomParams).then(function (player) {
    // 获取到回放数据,成功初始化播放器实例

}).catch(function(err) {
    // 获取回放数据失败
    console.error(err);
});

注意这里有 beginTimestamp 和 duration 两个参数。它们用于限定回放的范围。举个例子,假设你的产品是在线课堂,课程在上午 08:00 开始,08:45 结束。那么,你可以将这两个参数设为。

whiteWebSdk.replayRoom({
    ...otherReplayRoomParams,

    beginTimestamp: new Date("2020-01-01 08:00:00").getTime(),
    duration: 45 * 60 * 1000,
});

考虑到上课之前有人提前进场,下课后有人滞留,这些人都会产生互动行为,并被录制下来。限定范围会剔除 08:00 之前的内容和 08:45 之后的内容,让回放专注于课堂中的内容。

之后,我们需要把播放器在网页上展示出来。在此之前,还需要在网页的 Dom 树中准备白板占位符。

<div id="whiteboard" style="width: 100%; height: 100vh;"></div>

然后,通过如下代码,将回放的白板展示在网页上。

player.bindHtmlElement(document.getElementById("whiteboard"));

执行完如上代码后,你应该只能看见空空如也的网页,这是因为现在首帧还尚未加载。你需要执行如下代码开始播放。

player.play();

在 React 中展示白板回放内容

如果你使用 react 来管理网页视图,则无需设置白板占位符 <div> 。在拿到 player 对象之后,通过如下代码便可将白板回放页展示出来。

npm
TypeScript
import React from "react";
import { PlayerWhiteboard } from "white-react-sdk";

class App extends React.Component {

render() {
var style = {
width: "100%",
height: "100vh",
};
return <PlayerWhiteboard player={player} style={style}/>;
}
}
import * as React from "react";
import { PlayerWhiteboard } from "white-react-sdk";

class App extends React.Component {

public render(): React.ReactNode {
const style = {
width: "100%",
height: "100vh",
};
return <PlayerWhiteboard player={player} style={style}/>;
}
}

Netless 互动白板为 React 项目提供了专门的 SDK:white-react-sdk。该 SDK 是可完全代替 white-web-sdk 的超集。

适配占位符尺寸变化

当白板的边界尺寸(width、height)发生变化后,你必须调用如下代码,以让 White SDK 重新调整样式。

player.refreshViewSize();

一个典型场景是,用户会调整浏览器窗口大小,这会产生连锁反应,最终导致白板的尺寸发生改变。你可以监听窗口大小变化事件,及时调用该方法以保证白板样式始终能正确展示。

window.addEventListener("load", function() {
    player.refreshViewSize();
});

播放器操作

完成上一小节的阅读后,你终于可以在网页上看到回放录像了。但这个录像似乎只会从头播到尾,播完就结束了,不会再播了。而本小节,将教你如何实现播放、暂停、跳转、重复播放等功能。

可以通过如下代码播放、暂停。

// 播放
player.play();

// 暂停
player.pause();

可以通过如下代码跳转。指定的 timestamp 表示跳转到的时间戳,单位是毫秒,起点是 0,即这段回放内容的起点。

player.seekToScheduleTime(timestamp);

这三个方法虽然没有返回 Promise,但除了 pause 操作能立即起效外,其他操作不一定能立即起效。例如,当你调用 seekToScheduleTime 到一个较远的时间点,播放器可能发现这段内容尚未缓存,于是它必须通过网络请求预加载这段内容。此时,播放被阻塞,直到缓存到足够内容后才能开始播放。

考虑到播放缓存的问题,我们必须监听播放器状态的变化。我们可以通过在创建播放器实例的时候,添加监听回调函数来实现。

whiteWebSdk.replayRoom(replayRoomParams, {
    onPhaseChanged: function(phase) {
        case PlayerPhase.Playing: {
            // 正在播放
            break;
        }
        case PlayerPhase.Pause: {
            // 暂停了
            break;
        }
        case PlayerPhase.Buffering: {
            // 正在缓存
            break;
        }
    },
});

还可以修改播放倍率。

player.playbackSpeed = 1.5; // 切换为 1.5 倍播放

播放倍率默认是 1.0,因此可以通过如下代码把播放倍率恢复正常。

player.playbackSpeed = 1.0; // 恢复正常

在播放完之后,需要释放播放器实例。可以调用如下方法。

player.stop();

视角跟随

实时房间互动时,用户的视角变化信息也会被录制下来,在回放时会原样复现出来。因此,在回放时,观看者的视角会自动变化,以复现当时的情景。

用户也可以通过设备操作主动操作视角(平移、放缩),这时,用户会夺走视角控制权,白板不再复现录制中的视角变化信息。

如果不希望用户夺走视角控制权,可以通过如下代码禁止用户的设备操作。

player.disableCameraTransform = true;

如果用户已经夺走了视角控制权,可以通过如下代码收回用户的视角控制权,令白板重新复现录制的视角变化信息。

import { ObserverMode } from "white-web-sdk";

player.setObserverMode(ObserverMode.Directory);

服务端录制时延

Netless 云服务的录制功能并非一瞬间就可以出结果。因此,你有时可能会发现,某些刚刚创建的房间无法立即回放,并在 Console 中看到如下报错。

[White] Error: couldn't find any matching slices

这是因为房间创建不久,云端录制内容还未生成。稍微等一会,等到录制内容生成之后,就不会报错了。

你也可以在创建播放器之前,使用如下代码确认录制内容是否已生成。

var replayRange = {
    room: "回放房间的 UUID",
    roomToken: "回放房间的 Room Token",
    beginTimestamp: new Date("2020-01-01 08:00:00").getTime(),
    duration: 45 * 60 * 1000,
};
whiteWebSdk.isPlayable(replayRange).then(function(isPlayable) {
    // isPlayable === true 表示,这个时间段的录像已生成,可以播放

}).catch(fucntion(err) {
    // 获取失败
    console.error(err);
});

回朔自定义行为

实时房间中的 Global State 的变化,以及自定事件,都会被录制下来。你可以在回放时监听这些变化和事件,如果能妥善处理,这些由你自己实现的自定义行为也可以在回放时复现。

在创建播放器实例时,添加回调函数,以监听 Global State 的变化。

var replayRoomParams = {
    room: "回放的房间 UUID",
    roomToken: "回放房间的 Room Token",
    beginTimestamp: new Date("2020-01-01 22:00:00").getTime(), // 回放开始时间
    duration: 10 * 60 * 1000, // 回放持续时间(ms),这里是 10 分钟
};
whiteWebSdk.replayRoom(replayRoomParams, {
    onPlayerStateChanged: function(modifyState) {
        if (modifyState.globalState) {
            // 监听到 Global State 的变化
            var globalState = modifiyState.globalState;
        }
    },
});

通过如下代码可以监听自定义事件。

var event = "my-custom-event"; // 自定义事件名称

player.addMagixEventListener(event, function(event) {
    // 监听到自定义事件
    var payload = event.payload; // 事件荷载
});

回放音视频

如果你在实时房间中搭配实时音视频通讯,而音视频通讯的内容被录制了下来,那么,Netless 互动白板支持将它们连同白板内容一起被回放。

正确设计业务逻辑,你就可以回放一整个带音视频的互动白板房间了。你需要提前准备好音视频录制文件的 URL,在创建播放器实例时,传入参数。

whiteWebSdk.replayRoom({
    ...otherReplayRoomParams,
    mediaURL: "https://my-domain/assets/rtc-record.mp4",
});

异常流程处理

为了应用的稳定性,你需要处理播放器因为错误而终止的异常流程。在创建播放器之处,添加回调函数。

var replayRoomParams = {
    room: "回放的房间 UUID",
    roomToken: "回放房间的 Room Token",
    beginTimestamp: new Date("2020-01-01 22:00:00").getTime(), // 回放开始时间
    duration: 10 * 60 * 1000, // 回放持续时间(ms),这里是 10 分钟
};
whiteWebSdk.replayRoom(replayRoomParams, {
    onStoppedWithError: function(err) {
        // 播放器因为错误而终止。
        console.error(err);
    },
});
Last updated on 6/15/2020 by rick
← 自定义行为SDK参数 →
  • 开启云端录制
  • 在前端回放已录制好的内容
  • 在 React 中展示白板回放内容
  • 适配占位符尺寸变化
  • 播放器操作
  • 视角跟随
  • 服务端录制时延
  • 回朔自定义行为
  • 回放音视频
  • 异常流程处理
Netless
接入即互动
产品
管理控制台官网网站Demo 体验Github
公司
加入我们服务条款隐私协议
联系方式
support@netless.link社区
Copyright © 2020 Netless