客户端实现本文介绍如何使用声网灵隼纯呼叫版本的客户端示例项目在 Android 客户端实现呼叫和通话等功能。
信息纯呼叫版本的客户端示例项目提供呼叫、实时音视频等功能。你需要自行实现账号管理和设备管理相关逻辑。
如果你已有自研的设备管理等模块,声网建议你使用纯呼叫版本示例项目。
前提条件
开始前,请确保你已参考开通并配置声网灵隼物联网服务开通灵隼服务。
业务流程
在纯呼叫模式下,你需要自行实现账号系统与设备管理功能。基本流程如下:
环境准备
注册微信小程序账号并获取微信开发者工具
注册微信小程序企业账号。只有特定行业的认证企业账号才可以使用微信小程序的 live-pusher 和 live--player 组件。详见小程序官网文档。
下载并安装最新版本的微信开发者工具。
获取小程序组件权限
在微信公众平台的小程序开发选项中,切换到接口设置页签,打开实时播放音视频流和实时录制音视频流的开关。
配置服务器域名
你需要在 request 合法域名及 socket 合法域名中添加以下域名:
textwss://a1g2ouvmztk85d.ats.iot.cn-north-1.amazonaws.com.cn;wss://miniapp.agoraio.cn;https://ap-web-1.agoraio.cn;https://ap-web-2.agoraio.cn;https://ap-web-3.agoraio.cn;https://ap-web-4.agoraio.cn;https://apaas-iot.sd-rtn.com;https://iot-api-gateway.sh.agoralab.co;https://iot.sh.agoralab.co;https://miniapp.agoraio.cn;https://report-ad.agoralab.co;https://rest-argus-ad.agoralab.co;https://uap-ap-web-1.agora.io;https://uap-ap-web-2.agoraio.cn;https://uap-ap-web-3.agora.io;https://uap-ap-web-4.agoraio.cn;https://un2nfllop5.execute-api.cn-north-1.amazonaws.com.cn;https://uni-webcollector.agora.io;
跑通示例项目
下载示例项目并使用微信开发者工具打开项目。修改项目根目录下的 callkit.config.js 文件。参考开通并配置声网灵隼物联网服务从声网灵隼控制台的应用配置>>开发者选项页面获取所需参数。
JavaScriptmodule.exports = { DEBUG: true, // 声网灵隼控制台的应用配置>>开发者选项中的 App ID APPID: 'YOUR_APPID', // 声网灵隼控制台的应用配置>>开发者选项中的 Product Key PRODUCT_KEY: 'YOUR_PRODUCT_KEY', // 声网灵隼控制台的应用配置>>开发者选项中的 Project ID PROJECT_ID: 'YOUR_PROJECT_ID',}
在开发者工具中选择工具 >> 构建 npm。完成项目构建。
在登录页面输入你的账号名,进行登录。
登录完成后,输入需要呼叫的设备 ID 并点击呼叫设备。
实现客户端
创建小程序项目
参考如下步骤创建一个新的小程序。
打开微信开发者工具,然后按照屏幕提示扫码登录。
完成登录后,点击小程序界面的 +。
在弹出的新建项目界面中,依次填入小程序的项目名称、本地存储目录、小程序 AppID,然后点击新建。
成功创建小程序后,微信开发者工具的左侧会显示当前小程序的界面。你还可以点击真机调试,并扫描生成的二维码,在手机上进行体验。
引用 index.js 文件
下载示例项目。
使用 require 将 main/callkit/index.js 集成到项目中:
JavaScriptconst CallKitSDK = require('./callkit/index.js');
获取配置信息
通过灵隼控制台的应用配置页面中的开发者选项选项卡获取以下配置信息:
App ID:声网的 App ID。
Product Key:声网灵隼产品 ID。
本文将获取的配置定义为以下常量:
JavaScriptexport const appid = 'Your App ID'; export const PRODUCT_KEY = 'Your product key';
添加微信小程序组件
音视频通话页面的 .wxml 文件中需要使用微信的 live-player 组件和 live-pusher 组件。
JavaScript
初始化 SDK 并登录
JavaScript// 引入 callkit config 文件,在 init 项目的时候传入config文件const config = require('../../callkit.config.js');const username = 'agorauser'CallKitSDK.getAccountManager().initAndLogin(config, username) .then(this.onUserLoginSuccess) .catch(this.onLoginFail);
注册呼叫事件回调
JavaScriptonLoad() { // peer 呼叫请求事件 this.peerRequestEventCallbackUnsubscribe = CallKitSDK.getCallkitManager().peerRequestEventCallback((event) => { log.i('peerRequestEventCallback invoked'); const attachMsg = event.attachMsg || ''; // 调转到待接听界面 wx.navigateTo({ url: `/pages/answer/answer?attachMsg=${attachMsg}`, }); }); // peer 正在忙事件 this.peerBusyEventCallbackUnsubscribe = CallKitSDK.getCallkitManager().peerBusyEventCallback((event) => { log.i('peerBusyEventCallback invoked'); wx.showToast({ title: '对方正忙', icon: 'error', mask: true, }); }); // peer 接听事件 this.peerAnswerEventCallbackUnsubscribe = CallKitSDK.getCallkitManager().peerAnswerEventCallback((event) => { log.i('peerAnswerEventCallback invoked'); wx.hideLoading(); // peer 接听后跳转到 live 界面 wx.navigateTo({ url: '/pages/live/live', }); }); // peer 挂断事件 this.peerHangupEventCallbackUnsubscribe = CallKitSDK.getCallkitManager().peerHangupEventCallback((event) => { log.i('peerHangupEventCallback invoked'); wx.showToast({ title: '对方挂断', icon: 'error', mask: true, }); }); },
当退出小程序或者页面卸载时,可以调用返回的 unsubscribe 函数来删除订阅事件,节省资源。
JavaScriptonUnload() { // 退出界面时解除所有事件的绑定 this.peerRequestEventCallbackUnsubscribe(); this.peerBusyEventCallbackUnsubscribe(); this.peerAnswerEventCallbackUnsubscribe(); this.peerHangupEventCallbackUnsubscribe(); },
呼叫设备端
JavaScriptconst deviceId = 'mydoorbell' // 设备端IDconst attachMsg = 'Hello, stranger.' // optional,携带给设备端的消息CallKitSDK.getCallkitManager().callDevice(deviceId, attachMsg) .then((res) => { console.log('正在呼叫') }).catch((err) => { log.e(err); wx.showToast({ title: '呼叫设备失败', icon: 'error', }); });
当对方接听时,触发 peerAnswerEventCallback 回调。如果对方挂断,会收到 peerHangupEventCallback 的事件。如果对方忙,会收到 peerBusyEventCallback 的事件。如果此时设备端呼叫请求,那么 peerRequestEventCallback 会触发回调事件。
开始视频通话
通过 peerStreamAddedEventCallback 的回调获取拉流地址。然后调用 userPublishStream 接口来推送本地的推流地址。同时监听 peerHangupEventCallback 事件。
JavaScript/** * 生命周期函数--监听页面加载 */ onLoad(options) { wx.showLoading({ title: '正在拉取流', mask: true, }); // peer加入频道,获得播放地址 this.peerStreamAddedEventCallbackUnsubscribe = CallKitSDK.getCallkitManager().peerStreamAddedEventCallback((playUrl) => { log.i('peerStreamAddedEventCallback invoked'); wx.hideLoading(); this.setData({ playUrl, }); // 获得推流地址,开始推流 CallKitSDK.getCallkitManager().userPublishStream().then((pushUrl) => { this.setData({ pushUrl, }); }).catch((err) => { log.e(err); wx.switchTab({ url: '/pages/device/device' }); }); }); // 如果peer挂断呼叫,本地则返回主界面 this.peerHangupEventCallbackUnsubscribe = CallKitSDK.getCallkitManager().peerHangupEventCallback((event) => { log.i('peerHangupEventCallback invoked'); wx.showToast({ title: '对方已挂断', duration: 1500, }); setTimeout(() => { wx.switchTab({ url: '/pages/device/device' }); }, 1500); }); },
挂断通话
调用 hangupDevice 接口来挂断当前通话。
JavaScriptonHangup() { CallKitSDK.getCallkitManager().hangupDevice() .then((res) => { wx.switchTab({ url: '/pages/device/device' }); }).catch((err) => { wx.switchTab({ url: '/pages/device/device' }); }); },
通过注册的回调处理设备端呼叫。
JavaScriptonLoad(options) { this.setData({ name: options.name || '', attachMsg: options.attachMsg || '', }); // peer挂断事件,返回主界面 this.peerHangupEventCallbackUnsubscribe = CallKitSDK.getCallkitManager().peerHangupEventCallback((event) => { log.i('peerHangupEventCallback invoked'); wx.showToast({ title: '对方已挂断', icon: 'error', duration: 2000, }); setTimeout(() => { wx.switchTab({ url: '/pages/device/device' }); }, 2000); }); // 待接听时,可以显示peer的预览画面 this.peerStreamAddedEventCallbackUnsubscribe = CallKitSDK.getCallkitManager().peerStreamAddedEventCallback((playUrl) => { log.i('peerStreamAddedEventCallback invoked'); this.setData({ playUrl, }); }); }, onAccept() { CallKitSDK.getCallkitManager().answerDevice() .then((res) => { wx.navigateTo({ url: '/pages/live/live', }); }).catch((err) => { wx.switchTab({ url: '/pages/device/device' }); }); }, onHangup() { CallKitSDK.getCallkitManager().hangupDevice() .then((res) => { wx.switchTab({ url: '/pages/device/device' }); }).catch((err) => { wx.switchTab({ url: '/pages/device/device' }); }); },
参考信息
开发注意事项
声网推荐在 app.js 或者全局下订阅 userSessionEndEventCallback 事件,来监听用户登录状态的改变和 mqtt 连接状态的改变。如果发生改变,可以强制登出用户并且返回到登录界面。
JavaScriptonLaunch() { CallKitSDK.getInstanceManager().userSessionEndEventCallback((user) => { wx.showToast({ title: "登录超时", icon: 'error', }) wx.redirectTo({ url: '/pages/login/login', }) })}
API 参考
客户端纯呼叫 API 参考