更新记录

2.6.0(2024-09-30) 下载此版本

更新iOS插件

0.0.2(2024-09-20) 下载此版本

更新文件和白板,接入更简单

0.1.0(2021-01-21) 下载此版本

支持涂鸦、文本、直线、矩形、椭圆、橡皮、激光笔等功能 音画同步 实时协作

查看更多

平台兼容性

Android Android CPU类型 iOS
适用版本区间:5.0 - 14.0 armeabi-v7a:支持,arm64-v8a:支持,x86:未测试 适用版本区间:9 - 17

原生插件通用使用流程:

  1. 购买插件,选择该插件绑定的项目。
  2. 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块,如需要填写参数则参考插件作者的文档添加。
  3. 根据插件作者的提供的文档开发代码,在代码中引用插件,调用插件功能。
  4. 打包自定义基座,选择插件,得到自定义基座,然后运行时选择自定义基座,进行log输出测试。
  5. 开发完毕后正式云打包

付费原生插件目前不支持离线打包。
Android 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/android
iOS 离线打包原生插件另见文档 https://nativesupport.dcloud.net.cn/NativePlugin/offline_package/ios

注意事项:使用HBuilderX2.7.14以下版本,如果同一插件且同一appid下购买并绑定了多个包名,提交云打包界面提示包名绑定不一致时,需要在HBuilderX项目中manifest.json->“App原生插件配置”->”云端插件“列表中删除该插件重新选择


快速开始

这份文档将指导您如何在 uni-app 项目集成 超级白板 uniapp SDK 并快速开始创建一个纯白板。

准备环境

在开始集成超级白板 SDK 前,请确保开发环境满足以下要求:

  • 参考 uni-app 文档创建项目。
  • HBuilderX 3.0.0 或以上版本。
  • IOS
    • Xcode 15.0 或以上版本。
    • iOS 12.0 或以上版本且支持音视频的 iOS 设备。
  • Android
    • Android Studio 2020.3.1 或以上版本。
    • Android SDK 25、Android SDK Build-Tools 25.0.2、Android SDK Platform-Tools 25.x.x 或以上版本。
    • Android 4.4 或以上版本,且支持音视频的 Android 设备。
  • 设备已经连接到 Internet。

前提条件

  • 已在 ZEGO 控制台 创建项目,并申请有效的 AppID 和 AppSign,详情请参考 控制台 - 项目信息。
  • 联系 ZEGO 技术支持,开通文件相关服务。 填写配置文件 在 “common/KeyCenter.js.example” 文件中,填入本文 前提条件 已获取的 AppID 和 appSign。 实现流程 引入SDK
    1. 使用 HBuilderX 打开 manifest.json,重新生成一个 uni-app 应用标识。
    2. 创建自定义基座,填入 AppID。

[图片]

[图片] 注意:IOS 需要苹果开发者证书。为方便测试,可以暂时只勾选安卓端。

  1. 将插件市场的 ZEGO 即构实时音视频 SDK SDK 引入到项目中,并找到 manifest.json 中的 App 原生插件配置。

[图片]

[图片]

勾选上面购买的 ZEGO 即构实时音视频 SDK 并确认。 [图片]

  1. 将插件市场的 ZEGO superboard sdk 下载并导入 HBuilderX。 插件未发布,todo @马军福 @章聪 按照 rtc 流程截图补充 基本实现 引入白板 view 组件 在 vue 的 template 中使用 ZegoSuperboardContainerView 组件

    引入 SDK 并初始化 引入 sdk 路径待更新,todo @马军福 @章聪 // 引入 sdk 路径待更新 import ZegoSuperBoardApp from "@/components/zego-ZegoSuperBoardUniApp-JS/lib/ZegoSuperBoardApp"; import ZegoExpressEngine from '@/uni_modules/zego-ZegoExpressUniApp-JS/components/zego-ZegoExpressUniApp-JS/lib/ZegoExpressEngine'; const appID = keyCenter.getAppID(); const appSign = keyCenter.getAppSign(); const userID = keyCenter.getUserID(); const userName = keyCenter.getUserName(); const roomID = keyCenter.getRoomID();

// 初始化 Express RTC SDK // 使用从 ZEGO 控制台申请到的 appID 用于初始化 const profile = { appID : xxx, // AppSign 仅满足简单的鉴权需求,如果需要升级为更加安全的鉴权方式,请参考如何从 AppSign 鉴权升级为 Token 鉴权// AppSign 可通过控制台获取,格式为 @"39011cbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" appSign: '39011cbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', scenario : 0 };

ZegoExpressEngine.createEngineWithProfile(profile)

let roomConfig = {}; // 只有传入 “isUserStatusNotify” 参数取值为 “true” 的 ZegoRoomConfig,才能收到 onRoomUserUpdate 回调。 roomConfig.isUserStatusNotify = true; // 登录房间 ZegoExpressEngine.instance().loginRoom(roomID, {'userID': userID, 'userName': userName}, roomConfig);

// 初始化超级白板 SDK ZegoSuperBoardApp.init({ appID, appSign, userID, });

// 设置白板容器 ZegoSuperBoardApp.setContainerView();

创建白板 var zegoSuperBoardSubView = ZegoSuperBoardApp.getInstance() .getSuperBoardView() .getCurrentSuperBoardSubView();

// 监听远端新增白板 ZegoSuperBoardApp.getInstance().on( "remoteSuperBoardSubViewAdded", function (name, createTime, fileID, fileType, uniqueID, whiteboardIDList) {} );

// 创建白板 let params = { perPageWidth: 640, perPageHeight: 360, pageCount: 10, name: "白板名" + new Date().getTime(), };

ZegoSuperBoardApp.getInstance().createWhiteboardView(params);

完整代码

import { ref, onMounted, computed, onBeforeMount } from "vue"; import keyCenter from "@/common/KeyCenter.ts"; // 引入 sdk 路径待更新 import ZegoSuperBoardApp from "@/components/zego-ZegoSuperBoardUniApp-JS/lib/ZegoSuperBoardApp"; import ZegoExpressEngine from "@/components/zego-express-video-uniapp/lib/ZegoExpressEngine.js"; const appID = keyCenter.getAppID(); const appSign = keyCenter.getAppSign(); const userID = keyCenter.getUserID(); const userName = keyCenter.getUserName(); const roomID = keyCenter.getRoomID(); const containerview = ref(null); const engine = ref(null); const superboard = ref(null); const curView = ref(null); const currentPage = ref(0); const pageCount = ref(0); const options = ref([]); const selectedOptionId = ref(""); const selectedOptionName = ref(""); const initRTC = async () => { let profile = { appID, appSign, scenario: 0, }; engine.value = await ZegoExpressEngine.createEngineWithProfile(profile); }; const loginRTCRoom = async () => { let user = { userID, userName, }; let config = { isUserStatusNotify: true, }; const result = await ZegoExpressEngine.instance().loginRoom( roomID, user, config ); }; const initSuperboad = async () => { const superboard_init_res = await ZegoSuperBoardApp.init({ appID, appSign, userID, }); console.log("init=", superboard_init_res); superboard.value = ZegoSuperBoardApp.getInstance(); }; const setContainerView = async () => { containerview.value.addSuperboardView(); // await ZegoSuperBoardApp.setContainerView(); }; // 窗口尺寸发生变化才需要调用 const updateContainerFrame = () => { ZegoSuperBoardApp.updateContainerViewFrame(); }; const superboardEvent = () => { // 监听白板翻页、滚动 var zegoSuperBoardSubView = superboard.value .getSuperBoardView() .getCurrentSuperBoardSubView(); superboard.value.on( "scrollChange", function ( name, createTime, fileID, fileType, uniqueID, whiteboardIDList, currentPage, pageCount ) { console.log("scrollChange", currentPage); // SuperBoardView 每次滚动后都会回调这个方法 // 业务层可在这里更新界面的 页码/总页数 等信息 } ); // 监听远端切换白板 superboard.value.on("remoteSuperBoardSubViewSwitched", function (uniqueID) { // 收到远端切换白板文件。 // 可以根据当前 ZegoSuperBoardManager.getInstance().getSuperBoardView().getCurrentSuperBoardSubView() 的信息更新UI,如更新当前显示白板/文件名称。 }); // 监听远端新增白板 superboard.value.on( "remoteSuperBoardSubViewAdded", function (name, createTime, fileID, fileType, uniqueID, whiteboardIDList) {} ); }; const logout = async () => { await superboard.value.unInit() await engine.value.logoutRoom(roomID); uni.navigateTo({ url: "/pages/login/index" }); }; // 创建白板 const createSuperBoardView = async () => { let params = { perPageWidth: 640, perPageHeight: 360, pageCount: 10, name: "白板名" + new Date().getTime(), }; const res = await superboard.value.createWhiteboardView(params); if (res.errorCode === 0) { uni.showToast({ title: "创建白板成功", icon: "success", duration: 2000, }); options.value.push({ uniqueID: res.uniqueID, name: res.name }); } else { uni.showToast({ title: "创建白板失败:" + res.code, icon: "none", duration: 2000, }); } }; // 设置白板样式 const setSuperBoardViewStyle = async () => { var zegoSuperBoardSubView = superboard.value .getSuperBoardView() .getCurrentSuperBoardSubView(); console.log("setSuperBoardViewStyle", !!zegoSuperBoardSubView); if (zegoSuperBoardSubView) { superboard.value.enableHandwriting(true); // 画笔颜色,默认为红色 superboard.value.setBrushColor('#1016ff'); // 画笔粗细,默认为 6 superboard.value.setBrushSize(12); // 设置白板背景颜色 zegoSuperBoardSubView.setWhiteboardBackgroundColor('#1016ff'); } }; // 销毁白板 const destroySuperBoardSubView = async (uniqueID: string) => { console.log("uniqueID", uniqueID); try { const res = await superboard.value.destroySuperBoardSubView(uniqueID); if (res.errorCode === 0) { uni.showToast({ title: "删除白板成功", icon: "success", duration: 2000, }); updateList('delete', {uniqueID}) } else { uni.showToast({ title: "删除白板失败:" + res.code, icon: "none", duration: 2000, }); } } catch (e) { console.log("destroySuperBoardSubView:", e); } }; //翻上一页 const flipToPrePage = async () => { var zegoSuperBoardSubView = superboard.value .getSuperBoardView() .getCurrentSuperBoardSubView(); if (zegoSuperBoardSubView) { // 这里可以调用subView对应的接口进行翻页,以下是简单的示例 // 跳转上一页 zegoSuperBoardSubView.flipToPrePage(); } }; // 翻下一页 const flipToNextPage = async () => { var zegoSuperBoardSubView = superboard.value .getSuperBoardView() .getCurrentSuperBoardSubView(); if (zegoSuperBoardSubView) { // 这里可以调用subView对应的接口进行翻页,以下是简单的示例 // 跳转下一页 zegoSuperBoardSubView.flipToNextPage(); } }; // 撤销 const undo = async () => { var zegoSuperBoardSubView = superboard.value .getSuperBoardView() .getCurrentSuperBoardSubView(); if (zegoSuperBoardSubView) { zegoSuperBoardSubView.undo(); } }; // 重做 const redo = async () => { var zegoSuperBoardSubView = superboard.value .getSuperBoardView() .getCurrentSuperBoardSubView(); if (zegoSuperBoardSubView) { zegoSuperBoardSubView.redo(); } }; // 切换白板 const onWhitebopardChange = async (e) => { try { const index = e.detail.value; // 根据索引值从选项数组中获取对应的选项 const selected = options.value[index]; selectedOptionId.value = selected.uniqueID; // 记录选中的id selectedOptionName.value = selected.name; // 显示选中的name var superBoardView = superboard.value.getSuperBoardView(); // 切换白板 superBoardView.switchSuperBoardSubView(selected.uniqueID) } catch (errorData) { console.error(errorData) } }; // 更新当前 view 相关数据 const updateCurView = async () => { var zegoSuperBoardSubView = superboard.value .getSuperBoardView() .getCurrentSuperBoardSubView(); if (zegoSuperBoardSubView) { curView.value = zegoSuperBoardSubView; currentPage.value = await zegoSuperBoardSubView.getCurrentPage(); pageCount.value = await zegoSuperBoardSubView.getPageCount(); } }; const updateList = (type: any, data?: any) => { if (type === "add") { options.value.push({ uniqueID: data.uniqueID, name: data.name }); } else { options.value = options.value.filter( (item) => item.uniqueID !== data.uniqueID ); } }; // 获取列表 const getList = async () => { const list = await superboard.value.getSuperBoardSubViewModelList(); // 遍历 list 并更新 options 的数据 list.forEach((res: { uniqueID: any; name: any }) => { updateList("add", res); }); if (list.length !== 0) { var zegoSuperBoardSubView = superboard.value .getSuperBoardView() .getCurrentSuperBoardSubView(); let view = await zegoSuperBoardSubView.getCurrentSuperBoardSubViewModel(); selectedOptionName.value = view.name; selectedOptionId.value = view.uniqueID; } }; onMounted(async () => { try { await initRTC(); await loginRTCRoom(); await initSuperboad(); await setContainerView(); updateContainerFrame(); await getList(); await updateCurView(); superboardEvent(); } catch (e) { console.error("demo error=", e); } }); <style> .content { } .flex { display: flex; flex-wrap: wrap; flex-direction: row; align-items: center; justify-content: space-between; } .flex-start { justify-content: flex-start; } .containerview { width: 750rpx; height: 500rpx; /* background-color: #ccc; */ } .picker { padding: 10px; background-color: #f3f3f3; text-align: center; border: 1px solid #ddd; border-radius: 5px; } </style>
  1. 配置入口与页面路由

根据业务场景为通话页配置入口。

import { ref } from 'vue'; import keyCenter from '@/common/KeyCenter.ts'; const appID = ref(keyCenter.getAppID()); const userID = ref(keyCenter.getUserID()); const appSign = ref(keyCenter.getAppSign()); const roomID = ref(keyCenter.getRoomID()); const userName = ref(keyCenter.getUserName()); const bindAppIDChange = (e) => { keyCenter.setAppID(e.detail.value); }; const bindUserIDChange = (e) => { keyCenter.setUserID(e.detail.value); }; const bindAppsignChange = (e) => { keyCenter.setAppSign(e.detail.value) }; const bindRoomIDChange = (e) => { keyCenter.setRoomID(e.detail.value); }; const bindUserNameChange = (e)=>{ keyCenter.setUserName(e.detail.value); } const login = ()=>{ uni.navigateTo({ url: "/pages/index/index" }) } <style lang="scss" scoped> .zego-container { background-color: #F4F4F4; } .zego-row-area { flex-direction: row; margin-left: 36.53rpx; margin-right: 36.53rpx; margin-top: 17.3rpx; margin-bottom: 17.3rpx; align-items: center; justify-content: space-between; } .zego-row-area-2 { margin-left: 36.53rpx; margin-right: 36.53rpx; margin-top: 17.3rpx; margin-bottom: 17.3rpx; } .zego-input { background-color: #FFFFFF; border-radius: 9.61rpx; border-color: #BBBBBB; border-width: 1.92rpx; border-style: solid; color: #101010; font-size: 26.92rpx; height: 46.15rpx; padding-left: 9.61rpx; } .zego-title-text { color: #101010; font-size: 26.92rpx; } </style>

打开 pages.json,添加 pages 配置 { "pages": [ { "path": "pages/login/index", "style": { "navigationBarTitleText": "login" } }, { "path": "pages/index/index", "style": { "navigationBarTitleText": "uni-app" } } ], }

运行和测试

至此,您已经完成了所有步骤!

只需在 HBuilderX 中点击 运行到手机或模拟器 ,选择需要运行的端侧与基座,即可在设备上运行和测试您的应用程序。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

读取文件,写入文件

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

此插件需配合插件 ZegoExpress音视频SDK(白板)使用,该插件会采集摄像头、录音数据,详情可参考 https://doc-zh.zego.im/zh/5416.html

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT License

Copyright (c) 2020 ZEGO

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问