设备通话解决方案-voip小程序音视频通话

前言

设备通话解决方案通常涉及到音频和视频通信技术,包括语音通话、视频通话、实时消息传输等。这些解决方案可以被用于各种应用场景,包括在线教育、远程会议、在线医疗咨询。像这些都是设备通话的一些方案,后面会详细说说。但是这些通话都有一个困难点,那就是如何唤醒。否则只有这个应用内进行呼叫,不然就是再它还没后台杀死中才能进行呼叫,这样用户的体验特别不好。因为你呼叫了,没办法唤醒弹出来。对于这个唤醒,基本上是无解的。因为这跟系统的调度机制有关,与技术无关。目前看到就是,大公司与手机厂商进行合作,加入白名单,才可以做到,或者自己重写安卓系统某些机制,如电话手表这些。还有一种方案就是设备可以支持手机插卡,但这个也是极其不方便的,因为一台设备可以多个人使用。

开头

之前采用的通话方案是腾讯云实时音视频,这个安卓去调对应的SDK就行,但是遇到了开头说的问题,就是没办法通知唤醒用户进行接听通话,遭到了用户的投诉。体验非常不好。也有其它方案,列如采用离线推送,个推,提醒用户进入app。但效果还是不太好。

为此我们调研到了一款不错的解决方案,微信推出的,借助微信小程序音视频通话(for 硬件)能力,硬件开发者可以通过小程序硬件框架(WMPF),实现智能设备和手机微信端的一对一音视频通话,满足实时触达场景,提升通话体验。

介绍

1、主要原理:

借助安卓系统设备运行小程序硬件框架(WMPF),而WMPF中可以运行小程序,与用户手机微信内的小程序进行通话。
请添加图片描述

2、合作角色

(技术原理,WMPF 技术原理 | 微信开放文档 (qq.com)

作为小程序开发者的角度而言,将开发的小程序通过WMPF硬件展示出来,实现硬件的特殊需求,需要开发者再微信开放平台(微信开放平台 (qq.com))开启相关功能才能授权给WMPF使用(关闭则WMPF无法使用小程序)。

我们基于WMPF硬件开发时,小程序开发者可以通过调用与wx.xxx相似的wmpf.xxx接口,完成与WMPF Client端的通信,实现WMPF小程序下特有的功能(微信开放文档 (qq.com))。

3、WMPF支持的能力

WMPF支持很多的小程序接口,也有一些特有的能力,比如消息推送能力(无条件限制,但一个月内至少启动一次小程序)等等。先由WMPF拉起指定路径的小程序(LaunchWxaApp | 微信开放文档 (qq.com)),其中也有用二维码拉起方式,还可以关闭和预加载小程序的接口api;然后就可以达到硬件依靠利用小程序的能力与移动应用(WMPF Client)通信;其中接口分为两种形式,可以是 WMPF 提供的特有能力接口(例如刷脸支付、消息推送、打印机、设备 SN 码等),也可以是开发者自定义的在小程序与 WMPF Client 之间进行数据通信(Invoke Channel)。

4、VOIP插件

为了方便开发者接入WMPF-VoIP通话,保证设备侧和手机侧通话场景的用户体验,平台提供了小程序VOIP插件(VOIP通话 | 小程序插件 | 微信公众平台 (qq.com))。这个插件只能提供「小程序音视频通话(for 硬件)」的部分基础能力和统一的通话界面,插件提供了一些基本的api接口,比如发起接起通话、自定义通话设置、监听通话事件、硬件设备查询以及其它接口等等。

5、腾讯云实时音视频(TRTC)

TRTC(实时音视频 产品概述-产品简介-文档中心-腾讯云 (tencent.com))主打全平台互通的多人音视频通话和低延时互动直播解决方案,提供小程序、Web、Android、iOS、Electron、Windows、macOS 等平台的 SDK(Software Development Kit–软件开发工具包) 便于开发者快速集成并与实时音视频 TRTC 云服务后台连通TRTC提供包月免费体验TRTC旗舰版中的所有产品以及10000分钟的免费音视频时长包(实时音视频 计费概述-购买指南-文档中心-腾讯云 (tencent.com))。

6、TRTC与微信VOIP的对比

前者依赖于腾讯云平台提供的技术,主打全平台互通的多人音视频通话和低延时互动直播解决方案,适配于很多的场景和平台,而且也可集成其内部提供的TUICALLKIT UI组件,也可以快速地接入demo体验;后者依靠微信小程序内部自身的插件和音视频通话能力,引入插件并申请到音视频通话权限后即可同调用微信api一样调用wmpfVoip接口。

总得来说

像WebRTC,云通讯平台,一些公司如腾讯云、阿里云、环信等提供了完整的云通讯平台,这些平台提供了音视频通话、实时消息传输、文件共享等功能,开发者可以通过使用这些平台提供的SDK和API,快速在自己的应用中集成音视频通话功能。这些其实都跟TRTC是差不多的,能做到音视频通话,但都有相同的痛点就是唤醒。

使用

对于WMPF (安卓工程师需要做的事情)

1.「微信终端合作平台」微信开放平台」均注册相关所需硬件和移动应用,且绑定指定小程序。

2.下载WMPF Service Apk,安装到安卓硬件上【主要区分64和32的版本】,到 WMPF 发布页面下载。

3.设备认证【安卓】,需要设备厂商内置一个 RPMB 分区读写及通信的服务。(需厂商实现)

4.设备注册【一个个的硬件注册】:(有示例辅助工具代码,需要服务端协助对接实现)

A:公钥(wmpfPublicKeyPath.key)和 私钥(wmpfPrivateKeyPath.key),存放在服务端,已生成,需要和微信终端合作平台登记设备的公钥一致;

B: 获取设备签名signature,需要参数productId、deviceId(安卓设备序列号或唯一标识)、私钥;

C: 获取accessToken,需要参数微信开放平台注册的移动应用appId,移动应用appSecret;

D: 添加设备信息到微信后台,接口:adddevice,所需参数model_name(在微信终端合作平台登记的型号),productId、deviceId(安卓设备序列号或唯一标识)、accessToken;

E:校验结果和签名,需要参数productId、deviceId(安卓设备序列号或唯一标识)、公钥、设备签名signature;

5.WMPF Client 开发:(安卓Apk开发【宿主】,拉起小程序的)

  1. 初始化:WMPFBoot.init(),所需参数移动应用appId、productId、keyVersion(微信终端合作平台的公钥版本号,一般是1)、deviceId(安卓设备序列号或唯一标识)、设备签名signature;(需服务端协助)

  2. 设备激活:activateDevice()方法;

  3. 设备注册(不可逆): 执行一次成功即可,无需重复(需服务端协助)

a) 获取access_token:Cgi.getAccessToken,所需参数微信小程序appId、微信小程序的secret;

b) 获取snTicket:Cgi.getSnTicket,所需参数access_token、deviceId(安卓设备序列号或唯一标识)、modelId(微信公众平台获取的 model_id);

c) registerMiniProgramDevice,需参数微信小程序appId、modelId、deviceId(安卓设备序列号或唯一标识)、snTicket。

  1. 需要知道当前用户信息、还有拨打给谁的信息。

  2. 激活license,费用问题:接口是https://api.weixin.qq.com/wxa/business/license/activedevice?access_token= 所需参数pkg_type、device_list[ model_id, sn, acitive_number ]

6)启动小程序:launchMiniProgram。

特点注意:

1.设备需要满足下列条件之一:

  • 设备 EMMC/UFS 存储上的 RPMB(Replay Protected Memory Block) 分区未被使用;
  • 设备支持 TEE,并能按照《设备认证 TEE 规范》开发 TA 并提交验收。

此外,设备厂商需要内置一个 RPMB 分区读写及通信的 RPMBD 服务,并保证服务能够开机正常启动。

这个由你你的设备厂商决定了你能不能用这个小程序音视频通话。一定要有 RPMBD 服务。

2.每一颗 EMMC/UFS 存储芯片的 RPMB KEY 只能被写一次,不能修改。如果被写入错误的值 (非注册时的 model_id 和 sn),那么这颗芯片就无法继续使用。如果第一次注册时写错了这个参数,不好意思,基本只能换一台了。

3.开发版跟体验版调试进行开发时需要做扫码登陆。

对于小程序(前端)

1.授权需要:

  authVoIP() {
    wx.requestDeviceVoIP({
      sn: '', // Todo 向用户发起通话的设备 sn(需要与设备注册时一致),需要提前准备
      snTicket: '', // 获取的 snTicket
      modelId: '', // 「设备接入」从微信公众平台获取的 model_id
      deviceName: '', // 设备名称,用于授权时显示给用户
      success(res) {
        console.log(`requestDeviceVoIP success:`, res)
      },
      fail(err) {
        console.error(`requestDeviceVoIP fail:`, err)
      }
    })
  }

2.设备呼叫手机需要:

const wmpfVoip = requirePlugin('wmpf-voip').default

try {
  // 2.4.0 以下版本 roomId 为 groupId
  const { roomId, isSuccess } = await wmpfVoip.initByCaller({
    caller: {
      id: 'sn', // 设备 SN
      // 不支持传 name,显示的是授权时「deviceName」+「modelId 对应设备型号」
    },
    listener: {
      // 参见 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 获取
      id: 'openId' // 接听方 用户 openId
      name: 'xxxxxx', // 接听方名字,仅显示用
    },
    roomType: 'video', // 房间类型。voice: 音频房间;video: 视频房间
    businessType: 1, // 1 为设备呼叫手机微信
    voipToken: 'xxxxxxxxxx', // 使用设备认证 SDK 注册的设备传入 deviceToken,使用 WMPF RegisterMiniProgramDevice 接口注册的设备无需传入(插件 2.3.0 支持)
    miniprogramState: 'formal', // 指定接听方使用的小程序版本
  })

  if (isSuccess) {
    // 如果小程序启动直接进入插件页面,则不要调用 wx.redirectTo
    wx.redirectTo({
      url: wmpfVoip.CALL_PAGE_PATH,
      // 插件 2.3.9 开始支持 CALL_PAGE_PATH, 低版本请传入 'plugin-private://wxf830863afde621eb/pages/call-page-plugin/call-page-plugin',
    })
  } else {
    wx.showToast({
      title: '呼叫失败',
      icon: 'error',
    })
  }
} catch (e) {
  // 参数错误的情况会通过异常抛出
  wx.showToast({
    title: '呼叫失败',
    icon: 'error',
  })
}

3.手机呼叫设备:【场景不需要此功能】

const wmpfVoip = requirePlugin('wmpf-voip').default
const roomType = 'video'
try {
  const { roomId, isSuccess } = await wmpfVoip.callWMPF({
    roomType: 'video', // 房间类型。voice: 音频房间;video: 视频房间
    sn: '设备 SN',
    modelId: '设备 modelId',
    pushToken: '从设备获取的 pushToken',
    nickName: '设备端显示的微信用户名称',
    deviceName: '我的学习机',
    envVersion: 'release', // 指定接听方使用的小程序版本,开发过程可以使用 develop
  })

  if (/* 当前不在插件页面 */) {
    // 跳转到插件的通话页面
    wx.redirectTo({
      url: wmpfVoip.CALL_PAGE_PATH,
      // 插件 2.3.9 开始支持 CALL_PAGE_PATH, 低版本请传入 'plugin-private://wxf830863afde621eb/pages/call-page-plugin/call-page-plugin',
    })
  }
} catch (e) {
  console.error('callWMPF failed:', e)
  // 参数错误的情况会通过异常抛出
  wx.showToast({
    title: '呼叫失败',
    icon: 'error',
  })
}
总体流程

微信相关后台有固定的小程序appid、小程序secret、移动应用APPID、移动应用secret、model_id、productId、model_name… ——> 创建设备组 ——> 注册设备到微信后台 ——> 将设备添加到设备组 ——> 设备认证(不可逆)——> 设备激活license付费 ——>小程序授权设备组 ——> 拨打电话

微信接口文档

1.微信终端

https://wecooper.weixin.qq.com

2.WMPF

https://developers.weixin.qq.com/miniprogram/dev/framework/device/device-register-wmpf.html

3.小程序后台

https://mp.weixin.qq.com

4.voip

https://developers.weixin.qq.com/miniprogram/dev/framework/device/device-voip.html

1.model_id:(微信后台设备申请提供)

2.SN:安卓提供

appid:(微信后台)

scret:(微信后台)

3.获取access_token

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=&secret=

4.获取openId(一进来就能获取)

https://api.weixin.qq.com/sns/jscode2session?appid=&secret=&js_code=&grant_type=authorization_code

5.获取sn_ticket

https://api.weixin.qq.com/wxa/getsnticket?access_token=
{
  "model_id": "",
  "sn": ""
}
raw jSON

安卓效果

请添加图片描述

请添加图片描述

请添加图片描述

代码示例

就两步,一是用户授权,二是设备点击拨号。其它参数可以通过postman调取。去测试运行。

wskang12138/voip-demo: 小程序音视频通话示例 (github.com)

总结

不过是安卓还是ios 它都是跟你微信语音通话的效果是一样的,测试过程中也发现,IOS似乎还是有问题存在的,当通话过程中特别网卡时,一边断开了,另外一边还在继续。同时,安卓跟ios效果是不一样的,安卓是把微信小程序整个唤起,再全屏覆盖,弹出通话接听框,而ios只是通知,当然也有震动跟铃声,没有达到全屏覆盖这个效果,微信对微信发起音视频也是如此效果。

  • 20
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值