跳到主要内容

实现音视频通话

前置条件

配置云厂商音视频服务
下载和集成GRTC SDK和Uniapp原生插件

Demo体验

GoEasy音视频通话开源示例下载

初始化GRTC

为了使用 GRTC,必须在main.js 中进行 GRTC 的初始化,并将其挂载为全局对象,以便其他页面能够轻松引用。

GRTC的正常工作必须依赖GoEasy,在初始化 GRTC 之前,务必先完成 GoEasy 的初始化。


import GoEasy from 'goeasy.esm.min.js'
import GRTC from 'goeasy-rtc.esm.min.js' //引入GRTC SDK

//初始化GoEasy,GRTC依赖GoEasy
GoEasy.init({
host: 'hangzhou.goeasy.io', //若是新加坡区域:singapore.goeasy.io
appkey: 'BC-xxxx', // common key,
modules: ['im'],
// true表示支持通知栏提醒,false则表示不需要通知栏提醒
allowNotification: true //仅有效于app,小程序和H5将会被自动忽略
});

//初始化GRTC
GRTC.init(GoEasy);

//挂载为全局对象,便于在其他页面使用
uni.$GoEasy = GoEasy;
uni.$GRTC = GRTC;

建立GoEasy连接

由于 GRTC 通过 GoEasy 底层的 WebSocket 通道进行信号交互,因此在拨打/发起单聊通话之前,务必确保建立 GoEasy 连接。否则将无法成功发起通话,也无法监听到来电的响铃事件。

需要特别注意:

  • GRTC 的初始化必须在建立连接之前完成,否则GRTC将无法正常工作。
  • 在建立连接时,务必传入当前用户的ID和数据。缺少用户ID将无法作为发起拨打的用户,也无法作为明确的用户接收来电。

GoEasy.connect({
id:"001", //用户id,必填
data:{"avatar":"/www/xxx.png","nickname":"Neo"}, //必须是一个对象,im必填,最大长度300字符,显示拨打、响铃和通话界面
onSuccess: function () { //连接成功
console.log("GoEasy connect successfully.") //连接成功
},
onFailed: function (error) { //连接失败
console.log("Failed to connect GoEasy, code:"+error.code+ ",error:"+error.content);
},
onProgress:function(attempts) { //连接或自动重连中
console.log("GoEasy is connecting", attempts);
}
});

拨打/发起通话

发起一对一通话


let promise = GRTC.call({
calleeId: 'user001', //接听方用户id
mediaType: 1, // 0:音频通话 1:视频通话
})

promise.then(() => {
console.log("拨打成功.");
}).catch((error)=>{
console.log("拨打失败:", error);
})

发起多人通话

GRTC多人通话功能支持最多9人同时进行通话,其中包括一个发起通话的拨打方和最多8个同时参与通话的接听方。


let promise = GRTC.groupCall({
calleeIds: ['user001','user002','user003'], //接听方用户id数组,最多不可以超过8个
mediaType: 1, // 0:音频通话 1:视频通话
groupId: 'group001' //群id
})

promise.then(() => {
console.log("拨打成功.");
}).catch((error)=>{
console.log("拨打失败:", error);
})

页面渲染

获取当前通话对象

在音视频通话的实现过程中,通常需要设计拨打页面、响铃页面和通话页面。在渲染这些页面时,可通过调用 GRTC.currentCall() 获取当前通话对象,以便在页面上呈现拨打方、接听方的信息、通话时长以及视频图像。

需要注意的是,只有在拨打成功或者有新的来电,即监听到响铃事件时,才能通过该方法获取到当前通话对象。


let currentCall = GRTC.currentCall();

// currentCall 对象的属性说明:
// - id: 通话ID
// - time: 拨打时间
// - speakerOn: 扬声器开关状态(true: 打开,false: 关闭)
// - caller: 主叫用户信息
// - id: 用户ID
// - data: 用户数据
// - status: 用户状态('Dialing': 呼叫中,'Ringing': 响铃中,'InCall': 通话中,'Quit': 离开)
// - micMuted: 麦克风静音状态(true: 静音,false: 未静音)
// - cameraMuted: 摄像头启用状态(true: 关闭,false: 打开)
// - callees: 被叫用户数组,属性与 caller 一致
// - status: 通话状态 ('Dialing': 呼叫中, 'Ringing': 响铃中, 'InCall': 通话中)
// - groupId: 群ID(可选)
// - mediaType: 媒体类型(0: 音频, 1: 视频)
// - getDuration(): 通话时长(秒)

用户信息展示

对于已经连接过 GoEasy 的用户,在拨打成功或者有新的来电时,您可以通过 currentCall.callees 返回的数组中的对象获取到被拨打方的 id 和 data。对于没有连接过的用户,则只有 id 而没有 data。

为了确保在 currentCall.callees 中能够获取成员 data,您可以调用 REST 接口注册成员 data:

  • 方法: POST
  • URL: http://rest-hz.goeasy.io/v2/memberdata
  • 请求头: Content-Type: application/json
  • 请求体:
{
"appkey": "bc-xxx", // 应用appkey
"id": "user001", // 成员id
"data": {"name": "Wallace", "avatar": "/images/Avatar-2.png"} //成员数据对象,可以任意定义属性
}

实时视频显示

在实现实时视频通话时,通过使用<grtc-video>标签,您可以在页面中实时展示视频图像。只需传入相应用户的userId,即可方便地呈现该用户的实时视频。

由于<grtc-video>标签是基于Uniapp原生插件实现的,因此仅限于在nvue页面中使用,无法在vue页面中应用。

拨打、响铃和通话等界面通常都要求实时展示视频图像,因此建议相关页面统一采用nvue页面。

    <grtc-video v-if="call.mediaType === 1" :userId="userid" ></grtc-video>

来电响铃

开发者可通过监听 GRTC.EVENT.RING 事件实现来电响铃功能。在监听到该事件时,即可触发页面跳转至响铃页面,实现来电响铃的功能。

为确保不错过任何来电,务必在 APP 默认首页实现响铃事件的监听。这样可以确保 APP 启动后立即执行监听代码,无论用户在访问任何页面时,只要有来电,都能及时监听到响铃事件并成功跳转至响铃页面。

    
function onRing() {
const currentCall = GRTC.currentCall()
console.log('onRing', currentCall);
//TODO: 跳转到响铃页面
}

GRTC.on(GRTC.EVENT.RING, onRing);

接听通话

在监听到来电响铃事件后,可通过调用 GRTC.accept() 方法来接听通话。在接听成功后,可跳转至通话页面,实现通话功能。没有来电时,调用该方法将无效。


let promise = GRTC.accept();

promise.then(() => {
console.log("接听成功")
//跳转到通话页面
}).catch((e) => {
console.log('接听失败', e);
})


结束通话

若当前存在进行中的通话,随时可通过调用 GRTC.end() 方法来结束通话。在通话拨打时调用,表示取消通话;来电响铃时调用,则是拒接来电;而在通话中调用,则意味着挂断通话。

    GRTC.end();

监听其他事件

通话结束事件


function onCallEnded() {
console.log('通话结束');
}
GRTC.on(GRTC.EVENT.CALL_ENDED, onCallEnded);

用户退出事件

用户退出事件在通话过程中的多个场景下被触发,包括用户主动取消拨打、拒绝来电、或结束正在进行的通话,同时也可能由于网络异常导致通话中断。此外,响铃超时和多设备同步同样会引发该事件。

在多人通话中,每当有用户退出,该事件会被触发,可用于展示具体的退出原因或更新页面上的用户列表。

对于一对一通话,任何一方的退出都意味着通话的结束。由于用户退出事件对象包含退出的具体原因,因此在实现一对一通话时,建议直接使用用户退出事件代替通话结束事件,无需再额外监听通话结束事件。

    
function onUserQuit(event) {
// event属性说明:
// - user:
// - id: 用户ID
// - data: 用户data
// - reason: 退出原因,可能的取值包括:
// - NO_ANSWER: 本端响铃达到XX秒,本方未接听
// - CANCELLED: 本端取消
// - REJECTED: 本端拒绝
// - HUNG_UP: 本端挂断
// - RTC_DISCONNECTED: 本端RTC网络断开
// - GOEASY_DISCONNECTED: 本端GoEasy网络断开
// - HANDLED_ON_ANOTHER_DEVICE: 已经被同一个用户在其他设备接听或者拒绝
console.log('onUserQuit', event);
}


GRTC.on(GRTC.EVENT.USER_QUIT, onUserQuit);

用户已响铃事件

在发起通话时,若对方已成功接收来电并开始响铃,将触发该事件。在多人通话场景下,此事件将被多次触发,每当有用户响铃时都会被触发。

该事件可用于模拟传统电话中不同声音代表不同拨打状态的效果,同时还可通过页面展示每个用户的响铃状态,


function onUserRang(event) {
// event属性说明:
// - user:
// - id: 用户ID
// - data: 用户data
console.log('onUserRang', event);
}

GRTC.on(GRTC.EVENT.USER_RANG, onUserRang);

用户接听成功事件

不论是多人通话还是一对一通话,只要有用户接听成功,该事件都会被触发。在多人通话场景下,此事件将被多次触发,每当有用户接听成功时都会触发。

    
function onUserAccepted(event) {
// event属性说明:
// - user:
// - id: 用户ID
// - data: 用户data
console.log('onUserAccepted', event);
}

GRTC.on(GRTC.EVENT.USER_ACCEPTED, onUserAccepted);

取消事件监听

    GRTC.off(GRTC.EVENT.USER_ACCEPTED, onUserAccepted);