白板初始化

互动白板的接入需要依赖IM的账号系统,所以音视频的初始化需要依赖IM实例,这里需要首先初始化IM,再初始化音视频

初始化IM

初始化IM, 完成IM的登录连接操作 请参照IM初始化章节

请注意IM连接成功后方可进行白板互动,否则发起白板互动失败

初始化白板

以下是示例代码

// 初始化NIM ...
NIM.use(WhiteBoard)

const nim = NIM.getInstance({
  // ...
})

const whiteboard = WhiteBoard.getInstance({
  nim: nim,
  debug: true
})
参数名 类型 说明
nim object 互动白板是基于 IM 的, 需要传入 NIM 初始化后的实例
isCustom bool (可选)是否自定义裸数据,默认是
container dom (可选)绘图容器,如果走完全的自定义裸数据通道,则不必传该参数
debug bool 是否开启日志打印,默认 false

如果要同时开启音频功能,请初始化音视频

初始白板注册事件监听

在初始化白板之后, 在进行互动白板之前, 请先注册监听一些音白板通知事件。

被叫收到白板请求的通知

// 是否被叫中
let beCalling = false
// 呼叫类型
let type = null
// 被叫信息
let beCalledInfo = null
// 是否正忙
let busy = false
// 开启监听
whiteboard.on('beCalling', function(obj) {
  console.log('on beCalling', obj)
  const channelId = obj.channelId
  // 被叫回应主叫自己已经收到了通话请求
  whiteboard.control({
    channelId,
    command: WhiteBoard.NETCALL_CONTROL_COMMAND_START_NOTIFY_RECEIVED
  })
  // 只有在没有通话并且没有被叫的时候才记录被叫信息, 否则通知对方忙并拒绝通话
  if (!whiteboard.calling && !beCalling) {
    type = obj.type
    beCalling = true
    beCalledInfo = obj
  } else {
    if (whiteboard.calling) {
      busy = whiteboard.notCurrentChannelId(obj)
    } else if (beCalling) {
      busy = beCalledInfo.channelId !== channelId
    }
    if (busy) {
      whiteboard.control({
        channelId,
        command: WhiteBoard.NETCALL_CONTROL_COMMAND_BUSY
      })
      // 拒绝通话
      whiteboard.response({
        accepted: false,
        beCalledInfo: obj
      })
    }
  }
})
obj属性 类型 说明
account string 主叫account
type number 主叫发起的通话类型(音频还是视频)
channelId string 该通呼叫会话的唯一id值,开发者可用于判断是否是同一通呼叫

主叫收到被叫接受的通知

// 被叫接受的通知
whiteboard.on('callAccepted', function(obj) {
  console.log('on callAccepted', obj)
  // 取消呼叫倒计时
  clearCallTimer()
  // 可以开启音视频连接操作。。。
})

obj 为呼叫应答的回调通知对象

obj属性 类型 说明
account string 被叫账号
type number 音视频呼叫类型:音频、视频

主叫收到被叫拒绝的通知

// 被叫拒绝的通知
whiteboard.on('callRejected', function(obj) {
  console.log('on callRejected', obj)
  // 取消呼叫倒计时
  clearCallTimer()
  // 挂断
  hangup()
  // 做清理工作
  resetWhenHangup()
})

obj 为呼叫应答的回调通知对象

obj属性 类型 说明
account string 被叫账号
type number 音视频呼叫类型:音频、视频

通话中收到远端的控制指令

whiteboard.on('control', function(obj) {
  console.log('收到指令', obj)
})

obj 为指令通知对象

param属性 类型 说明
channelId number 需要发送指令的房间id
command number 指令类型,具体值请参照这里

收到白板结束通知

whiteboard.on('hangup', function(obj) {
  console.log('on hangup', obj)
  // 判断需要挂断的通话是否是当前正在进行中的通话
  if (!beCalledInfo || beCalledInfo.channelId === obj.channelId) {
    // 清理工作
    resetWhenHangup()
  }
})

obj 收到的挂断通知对象

obj属性 类型 说明
timetag string 时间戳
channelId string 当前通话的唯一id值
account string 对方账号
type number 挂断类型:0 为正常挂断,-1位异常挂断(超时等)

其他端已处理的通知

whiteboard.on('callerAckSync', function(obj) {
  console.log('其他端已经做了处理', obj)
})

obj 为其他端已处理的回调对象

obj属性 类型 说明
timetag string 时间戳
channelId string 当前通话的唯一id值
type number 通话类型:音频、视频
accepted bool 其他端做出的应答:接受、拒绝
fromClientType string 从什么类型的终端做出的应答:IOS、Android等

监听接收自定义裸数据

whiteboard.on('data', function(obj) { 
  console.log('收到裸数据:', obj)
})

obj 为收到的裸数据对象

obj属性 类型 说明
account string 裸数据的发送者(多人房间中用于区分)
data string 对方发送的裸数据(请自己做好解析)

DrawPlugin插件的使用

  // 初始化白板插件
  function initDrawPlugin () {
    this.drawPlugin = new DrawPlugin(this.$refs.container, {
      UID: whiteboard.getAccount(),
      nim: nim,
      width: 640,
      height: 480,
      isP2P: true  // 开启p2p模式,则不发送颜色
    })
    this.drawPlugin.enableDraw(true)
    var that = this
    this.drawPlugin.on('data', function (obj) {
      var toAccount = obj.toAccount
      var data = obj.data
      if (!data || !whiteboard.isChannelConnected()) return
      whiteboard.sendData({
        toAccount: toAccount,
        data: data
      })
    })
  }
  // 接收白板sdk的数据
  function onData (obj) {
    this.drawPlugin && this.drawPlugin.act({ account: obj.account, data: obj.data })
  }

  // 撤销
  function undo () {
    this.drawPlugin.undo();
  }
  // 清空
  function clear () {
    this.drawPlugin.clear();
  }