互动白板
  • iOS
  • Android : Java
  • macOS
  • Windows
  • Web
  • Electron
  • 概述
  • 价格说明
  • 下载
  • 跑通示例源码
  • 接入指南
  • 快速开始
  • 场景实践
  • 客户端 API
  • 服务端 API
  • 常见错误码
  • 常见问题
  • 文档中心
  • 互动白板
  • 场景实践
  • 互动白板与文件共享的搭配使用

互动白板与文件共享的搭配使用

更新时间:2023-11-02 17:35

1 导读

1.1 简介

在实际业务开发过程中,互动白板 (ZegoWhiteboardView SDK)经常与文件共享 (ZegoDocsView SDK) 搭配使用。通常情况下,ZegoWhiteboardView 会覆盖在 ZegoDocsView 之上,然后通过一定的逻辑处理,就能实现在文件上绘制图元的业务需求。

1.2 概念解释

  • ZegoExpress-Video SDK:ZEGO 音视频互动 SDK,能够提供互动白板所需的实时信令传输的能力,其核心类为 ZegoExpressEngine。
  • ZegoWhiteboardView SDK:提供 ZEGO 互动白板服务的 SDK。
  • ZegoDocsView SDK:提供 ZEGO 文件共享服务 的 SDK。
  • ZegoWhiteboardView:在代码实现过程中,开发者直接使用的 ZegoWhiteboardView 视图。
  • ZegoDocsView:在代码实现过程中,开发者直接使用的 ZegoDocsView 视图。
  • 文件白板:ZegoWhiteboardView 覆盖在 ZegoDocsView 之上组成的视图。
  • 普通白板:ZegoWhiteboardView 视图。

2 前提条件

2.3.0 或以上 版本的 SDK 支持 Token 鉴权,若您需要升级鉴权方式,可参考 如何从 AppSign 鉴权升级为 Token 鉴权

3 实现流程

3.1 初始化 SDK

3.1.1 初始化 ZegoExpress-Video SDK

初始化 ZegoExpress-Video SDK,详情可参考实时音视频的 快速开始 - 实现流程

// 创建引擎,通用场景接入,并注册 self 为 eventHandler 回调
// 不需要注册回调的话,eventHandler 参数可以传 null,后续可调用 "setEventHandler:" 方法设置回调
ZegoEngineProfile profile = new ZegoEngineProfile();
profile.appID = ;  // 请通过官网注册获取,格式为:1234567890L
profile.appSign = ; // 请通过官网注册获取,格式为字符串
profile.scenario = ZegoScenario.DEFAULT;  // 通用场景接入
profile.application = getApplication();
engine = ZegoExpressEngine.createEngine(profile, null);

如果您需要切换鉴权方式,请参考 如何从 AppSign 鉴权升级为 Token 鉴权

3.1.2 初始化 ZegoWhiteboardView SDK

必须先保证 ZegoExpress-Video SDK 初始化成功,再初始化 ZegoWhiteboardView SDK

使用 ZegoWhiteboardManagerinit 方法初始化 ZegoWhiteboardView SDK。

如果回调 onInit 中的 “errorCode” 为 0,代表初始化成功,可进行更多操作。errorCode 可参考 常见错误码

ZegoWhiteboardManager.getInstance().init(context, new IZegoWhiteboardInitListener() {
    @Override
    public void onInit(int errorCode) {
        if (errorCode == 0) {
            /** 初始化成功 */
        } else {
            /** 初始化失败 */
        }
    }
});

3.1.3 初始化 ZegoDocsView SDK

详情可参考文件共享的 快速开始 - 实现流程

如果回调 onInit 中的 “errorCode” 为 0,代表初始化成功,可进行更多操作。errorCode 可参考 常见错误码

long appID = ;  /** 请通过官网注册获取,格式为 123456789L */
String appSign = ;  /** 请通过官网注册获取,格式为字符串*/
String logFolder = "";/** SDK 日志保存目录,需设置为与互动白板、express等其他sdk相同的log目录。默认目录为 /sdcard/Android/data/你的应用package名称/files/zegologs */

ZegoDocsViewConfig config = new ZegoDocsViewConfig();  
config.setAppID(appID);
config.setAppSign(appSign);
config.setLogFolder(logFolder);

ZegoDocsViewManager.getInstance().init(config, new IZegoDocsViewInitListener() {
    @Override
    public void onInit(int errorCode) {
        if (errorCode == 0) {
            /** 初始化成功 */
        } else {
            /** 初始化失败 */
        }
    }
});

3.2 登录房间

调用 ZegoExpressEngineloginRoom 接口登录房间,只有登录房间才能实现房间内所有成员的互通,详情可参考 快速开始 - 实现流程

//登录房间
void loginRoom() {
    // ZegoUser 的构造方法 public ZegoUser(String userID) 会将 “userName” 设为与传的参数 “userID” 一样。“userID” 与 “userName” 不能为 “null” 否则会导致登录房间失败。
    ZegoUser user = new ZegoUser("user2");

    ZegoRoomConfig roomConfig = new ZegoRoomConfig();

    // 只有传入 “isUserStatusNotify” 参数取值为 “true” 的 ZegoRoomConfig,才能收到 onRoomUserUpdate 回调。
    roomConfig.isUserStatusNotify = true;

    // roomID 由您本地生成,需保证 “roomID” 全局唯一。不同用户要登录同一个房间才能进行通话
    String roomID = "room1";

    // 登录房间
    engine.loginRoom(roomID, user, roomConfig, (int error, JSONObject extendedData)->{
        // 登录房间结果,如果仅关注登录结果,关注此回调即可
        if (error == 0) {
            // 登录成功
            Toast.makeText(this, "登录成功", Toast.LENGTH_LONG).show();
        } else {
            // 登录失败,请参考 errorCode 说明 https://doc-zh.zego.im/article/4378
            Toast.makeText(this, "登录失败,请参考 errorCode 说明 https://doc-zh.zego.im/article/4378", Toast.LENGTH_LONG).show();
        }
    });
}

3.3 创建并展示 ZegoDocsView 和 ZegoWhiteboardView

互动白板和文件共享一起使用时,需要把 ZegoWhiteboardView 和 ZegoDocsView 添加到同一个父容器中,并且 ZegoWhiteboardView 覆盖在 ZegoDocsView 之上。

3.3.1 创建 ZegoDocsView 并且加载文件

详情可参考文件共享的 快速开始 - 实现流程

ZegoDocsView zegoDocsView = new ZegoDocsView(context);
addView(zegoDocsView, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT))   // 添加到父容器中
String fileID = "";  // 上传文件得到fileID
String authKey = ""; //  用于鉴定权限,可以设置为""    
zegoDocsView.loadFile(fileID, authKey, new IZegoDocsViewLoadListener() {
     @Override
     public void onLoadFile(int errorCode) {
         if (errorCode == 0) {
         /** 加载成功 */
         } else {
         /** 加载失败 */
         }
     }
});

3.3.2 创建 ZegoWhiteboardView

在 ZegoDocsView 加载成功之后,开始创建 ZegoWhiteboardView。

ZegoDocsView docsView;    // 上面步骤中已经加载成功的 ZegoDocsView

//创建白板模型
ZegoWhiteboardViewModel model = new ZegoWhiteboardViewModel();
model.setAspectHeight(docsView.getContentSize.getHeight());  // 设置宽高比和文件的宽高比相同
model.setAspectWidth(docsView.getContentSize.getWidth());    // 设置宽高比和文件的宽高比相同
model.setName(docsView.getFileName());    // 把文件的名字设置给白板
model.setPageCount(docsView.getPageCount());    // 把文件的页数设置给白板
model.getFileInfo().setFileID(docsView.getFileID()) // 把文件的fileID设置给白板
model.getFileInfo().setFileType(docsView.getFileType())  // 把文件的fileType设置给白板
model.setRoomId("123");   // 房间号

ZegoWhiteboardManager.getInstance().createWhiteboardView(model, new IZegoWhiteboardCreateListener() {
    @Override
    public void onCreate(int errorCode, @Nullable ZegoWhiteboardView whiteboardView) {
        if (errorCode == 0) {
           /** 创建成功 */
            if (zegoWhiteboardView != null) {
                addView(zegoWhiteboardView, new LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT
                ))
            }
        } else {
          /** 创建失败 */
        }
    }
});

3.3.3 关联 ZegoDocsView 和 ZegoWhiteboardView

在上一步 ZegoWhiteboardView 创建成功并且添加到添加到父容器中后,ZegoDocsView 和 ZegoWhiteboardView 已经可以正常显示出来,需要把它们互相关联起来,以实现它们之间的互动。

ZegoDocsView docsView;    // 上面步骤中已经加载成功的 ZegoDocsView
ZegoWhiteboardView whiteboardView;  // 上面步骤中创建成功返回的 ZegoWhiteboardView

//设置白板可见区域和文件的可见区域大小一致,主要是用于小图片的显示
if (docsView.getVisibleSize().getHeight() != 0 || docsView.getVisibleSize().getWidth() != 0) {
  whiteboardView.setVisibleRegion(docsView.getVisibleSize());  
}

//设置文件监听白板的滚动,来达到文件和白板一起滚动的效果
whiteboardView.setScrollListener(new IZegoWhiteboardViewScrollListener() {
  @Override
  public void onScroll(float horizontalPercent, float verticalPercent) {
    docsView.scrollTo(verticalPercent, new IZegoDocsViewScrollCompleteListener() {
      @Override
      public void onScrollComplete(boolean b) {

      }
    });
  }
});

//设置文件监听白板的缩放,来达到文件和白板一起缩放的效果
whiteboardView.setScaleListener(new IZegoWhiteboardViewScaleListener() {
  @Override
  public void onScaleChanged(float scaleFactor,float transX, float transY) {
    docsView.scaleDocsView(scaleFactor, transX, transY);
  }
});

3.4 ZegoDocsView 与 ZegoWhiteboardView 之间的同步滚动与翻页

文件和白板搭配使用时,滚动分为以下两种情况:

  1. 指定页码滚动,通常用于滚动到文件的指定页,比如翻页场景。

    ZegoDocsView docsView;    // 上面步骤中已经加载成功的 ZegoDocsView
    ZegoWhiteboardView whiteboardView;  // 上面步骤中创建成功返回的 ZegoWhiteboardView
    int pageTarget ;   // 滚动的目标页码
    
    docsView.flipPage(pageTarget, new IZegoDocsViewScrollCompleteListener() {
      @Override
      public void onScrollComplete(boolean result) {
        if(result){
          whiteboardView.scrollTo(0f, docsView.getVerticalPercent());
        }
      }
    });
  2. 指定百分比滚动,如果需要滚动到白板的指定百分比位置,可以指定百分比滚动。

    ZegoDocsView docsView;    // 上面步骤中已经加载成功的 ZegoDocsView
    ZegoWhiteboardView whiteboardView;  // 上面步骤中创建成功返回的 ZegoWhiteboardView
    
    float scrollTargetXPercent ;   // 滚动的目标百分比
    float scrollTargetYPercent ;   // 滚动的目标百分比
    
    whiteboardView.scrollTo(scrollTargetXPercent, scrollTargetYPercent)

3.5 销毁文件白板

调用 ZegoWhiteboardViewdestroyWhiteboardView 接口可以销毁指定的白板,在收到 onDestroy 成功回调后再移除对应的文件白板。

ZegoDocsView docsView;    // 上面步骤中已经加载成功的 ZegoDocsView
ZegoWhiteboardView whiteboardView;  // 上面步骤中创建成功返回的 ZegoWhiteboardView

long whiteboardID = whiteboardView.getWhiteboardViewModel().getWhiteboardID()
ZegoWhiteboardManager.getInstance().destroyWhiteboardView(whiteboardID, new IZegoWhiteboardDestroyListener() {
  @Override
  public void onDestroy(int errorCode, long whiteboardID) {
    if(errorCode == 0){
       docsView.unloadFile();
       removeView(docsView)
       removeView(whiteboardView)
    }
  }
})

3.6 ZegoDocsView 和 ZegoWhiteboardView 的大小变更

如果 ZegoDocsView 的大小发生了变更(比如横竖屏切换),需要重新设置 ZegoWhiteboardView 的可见区域。

ZegoDocsView docsView;    // 上面步骤中已经加载成功的 ZegoDocsView
ZegoWhiteboardView whiteboardView;  // 上面步骤中创建成功返回的 ZegoWhiteboardView

docsView.reloadFile(new IZegoDocsViewLoadListener() {
  @Override
  public void onLoadFile(int errorCode) {
    whiteboardView.setVisibleRegion(docsView.getVisibleSize());
  }
});

3.7 (可选)Token 过期更新

此步骤介绍 Token 过期时如何处理;如果您未使用 Token 鉴权,可忽略此步。

监听 Token 过期通知,如果 Token 过期,需要主动更新 Token。

expressEngine.setEventHandler(new IZegoEventHandler() {
    @Override
    public void onRoomTokenWillExpire(String roomID, int remainTimeInSecond) {
        //token即将过期,去服务端获取新的token
        String token = getTokenFromServer();
        engine.renewToken(roomID, token);
        //这里需要同步更新文件token
        ZegoDocsViewManager.getInstance().renewToken(token);
    }
}

4 示例源码

以上介绍了互动白板和文件共享搭配使用的基本场景,更复杂的交互场景请查看完整的示例源码,详情请参考 下载示例源码

相关文档

本篇目录