核心原理:定制化开发的运作逻辑
互动课堂的各端界面(Web、Electron、Web 内核的 iOS/Android),底层都是基于网页(Web)实现的。
定制化开发的核心逻辑是:
不修改 SDK 内核源码,通过注入自定义 JS/CSS 文件,借助 SDK 开放的全局对象 TCIC.SDK.instance,在课堂生命周期的对应节点,实现界面样式修改、业务逻辑扩展、功能权限管控,最终实现全端统一的自定义效果。

通过定制化能实现什么?
通过注入自定义的 JS 和 CSS,您可以修改所有端的界面并补充业务逻辑。常见场景如下:
业务方向 | 具体场景举例 |
界面与样式 | 文案替换:将页面上的“课堂”字样全部替换为“会议”等行业专有词。 布局调整:修改摄像头/麦克风图标样式、调整弹窗按钮行为、自定义虚拟背景等。 |
功能与权限 | 屏蔽功能:隐藏头像区域、隐藏在线人数等无关业务。 权限配置:针对不同角色(老师/学生)配置白板权限、设置下课倒计时提醒等。 |
数据与事件 | 事件监听:当特定事件发生时(如进入房间、开关麦克风),触发业务弹窗,或将状态上报给您的业务后台。 |
快速开始:本地开发与调试
无论您是使用官方模板还是从零开发,调试的核心步骤都是启动本地服务 > 拼接课堂 URL > 注入代码。
步骤1:准备本地 JS/CSS 文件
您可以选择以下两种方式之一来准备代码:
我们提供了常用的自定义示例代码,开箱即用:
git clone https://github.com/InteractiveClassroom/tcic-custom-demo.gitpnpm icd ./demos/{SOME_DEMO} # 选择一个您需要的 demo 目录pnpm dev # 默认会在 localhost:3000 启动服务
如果您熟悉前端开发,可以直接在本地搭建一个静态服务器(假设运行在
8080 端口),并在根目录创建 test.js 和 test.css。注意:
如果使用 Vue/React 开发,请自行创建 div 节点插入 DOM,不要直接挂载到课堂原有的
#app 节点上。步骤2:在课堂中注入并调试
1. 进入 课堂演示登录页,依次单击创建课堂 > 立即进入。
2. 进入课堂后,复制浏览器地址栏中的 URL。
3. 在 URL 末尾拼接您的本地文件地址:
拼接 JS:
&debugjs=http://localhost:3000/custom.js拼接 CSS:
&debugcss=http://localhost:3000/custom.css完整示例:
https://class.qcloudclass.com/...&debugjs=http://localhost:3000/custom.js&debugcss=http://localhost:3000/custom.css4. 敲击回车键重新加载页面。打开开发者工具(F12)的 Network 面板,如果看到您的本地 JS/CSS 文件被成功加载,说明环境准备完毕,可以开始写代码了。

步骤3:发布到生产环境
当您在本地(
localhost)调试完毕,确认功能无误后,就可以发布上线了:1. 在本地项目中运行打包命令(如
npm run build),生成最终的 JS 和 CSS 文件,并发布到您的生产环境,使外网能访问到。2. 登录腾讯云控制台,进入自定义场景配置页面,详见 场景配置。
3. 配置您打包好的 JS 和 CSS URL,并生成一个“场景名称”。
4. 以后在进入课堂的时候,传入这个“场景名称”,该课堂就会自动加载您的定制化代码。
https://${课堂域名}/latest/class.html?scene=${scene}&schoolid=${schoolid}&classid=${classid}&userid=${userid}&token=${token}
// 1. 构建配置对象TCICClassConfig initConfig = new TCICClassConfig.Builder().schoolId(schoolId) // 应用 ID.classId(classId) // 课堂 ID.userId(userId) // 用户 ID.token(token) // 鉴权 Token.scene(scene) // 场景名称.build();
TCICClassConfig *roomConfig = [[TCICClassConfig alloc] init];// 必填参数roomConfig.schoolId = 123456; // 学校/应用 IDroomConfig.userId = "test_user"; // 用户 IDroomConfig.token = "test_token"; // 鉴权 TokenroomConfig.classId = 654321; // 课堂 ID// 可选参数配置[roomConfig setValue:@"en" forKey:@"language"]; // 设置语言[roomConfig setValue:@"scene_name" forKey:@"scene"]; // 设置场景
示例一:
URL 唤起方式,需要拼接 URL。
tcic://${课堂域名}/latest/class.html?scene=${scene}&classid=${classId}&userid=${userId}&token=${token}
示例二:
SDK 集成方式,在初始化时传入
scene。const TCIC = require('tcic-electron-sdk');TCIC.initialize({// 核心鉴权参数classId: '368507569',userId: '123456',token: 'yJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', // 务必动态获取// 可选:自定义参数 (透传至 Web 端)customParams: {key: 'value',scene: 'scene_name', //自定义场景名称},...})
基本概念与 API
在您的自定义 JS 文件中,主要通过操作状态(State)、事件(Event)和功能开关(Feature)来实现业务逻辑。
1. 课堂生命周期与状态
课堂的加载是一个按顺序进行的过程。绝大多数自定义逻辑,都必须等课堂加载到特定状态后才能执行,否则会报错。

关键状态节点:
含义 | 状态名 | 类型 | 备注 |
学校信息已获取 | TCIC.TMainState.School_Info_Ready | Boolean | 自定义 js/css 地址是从获取学校信息接口中获取,js/css 加载完成后,School_Info_Ready 状态会变成 true。 |
课堂信息已获取 | TCIC.TMainState.Class_Info_Ready | Boolean | 获取到课堂信息后,会处理布局和文案相关内容。 |
加入 TRTC 房间 | TCIC.TMainState.Joined_TRTC | Boolean | 在该状态改变后,用户才能使用 TRTC 房间相关功能,例如开启麦克风或者打开视频。 |
是否进行设备检测 | TCICUI.Constant.TStateDeviceDetect | Boolean | 需要连麦视频的用户完成设备检测再进入房间可以减少连麦异常的情况。 |
说明:
如何使用状态代码:
我们强烈推荐使用
promiseState 方法,它能确保当状态满足条件时,安全地执行您的代码。// 设置状态值TCIC.SDK.instance.setState(name ,val)// 示例:promiseState可以确保当前状态满足条件的时候立即执行一次。TCIC.SDK.instance.promiseState(name,val)// 示例:获取状态值TCIC.SDK.instance.getState(name)// 示例:当“学校信息已获取”时,打印学校信息TCIC.SDK.instance.promiseState(TCIC.TMainState.School_Info_Ready, true).then(() => {console.log("学校信息:", TCIC.SDK.instance.getSchoolInfo());});// 示例:强制关闭进入课堂前的“设备检测”环节TCIC.SDK.instance.setState(TCICUI.Constant.TStateDeviceDetect, false);
2. 课堂事件监听
除了状态,课堂还会不断抛出各种事件(例如有人进房、收到消息等)。您可以通过
on 和 off 来监听或取消监听。常用事件举例:
TCIC.TMainEvent.Show_Msg_Box:弹窗出现时触发,使用示例可以参考 修改下课按钮行为。TCIC.TMainEvent.Member_Join:有人加入课堂时触发。TCIC.TIMEvent.Recv_Msg:收到聊天消息时触发。事件可以在 TCIC.TMainEvent/TCIC.TIMEvent 里找到。
// 示例:监听事件TCIC.SDK.instance.on(eventname, callback);// 示例:取消监听事件TCIC.SDK.instance.off(eventname, callback);// 示例:监听收到消息事件TCIC.SDK.instance.on(TCIC.TIMEvent.Recv_Msg, (msg) => {console.log("收到新消息:", msg);});
说明:
在课堂控制台过滤
Tevent:: 可以观察到所有实时触发的事件行为。
3. 功能开关配置
针对不同的角色,您可能需要开启或关闭某些特定功能。这可以通过
setFeatureAvailable 来实现。此操作应在课堂信息加载完成 (Class_Status) 之后进行。常用白板开关:
WhiteBoardList:是否允许新增/切换白板(默认 true)。WhiteBoardPPT:是否允许课件翻页(默认 true)。WhiteBoardPPT.WheelPaging:是否支持用户使用鼠标滚轮对课件翻页(默认 false)。// 示例:如果是学生,则限制其白板操作权限TCIC.SDK.instance.promiseState(TCIC.TMainState.Class_Status, TCIC.TClassStatus.Already_Start).then(() => {if (TCIC.SDK.instance.isStudent()) {TCIC.SDK.instance.setFeatureAvailable("WhiteBoardList", true); // 允许添加白板TCIC.SDK.instance.setFeatureAvailable("WhiteBoardPPT", false); // 禁止翻页TCIC.SDK.instance.setFeatureAvailable("WhiteBoardPPT.WheelPaging", false); // 禁止滚轮翻页}});