EaseCallKit 是一套基于环信 IM 和声网音视频结合开发的音视频 UI 库,实现了一对一语音和视频通话以及多人音视频通话的功能。基于 EaseCallKit 可以快速实现通用音视频功能。
下面讲解用IM做信令的过程和效果示意
(一)演示样例(各端通用,本篇文章以iOS为例):
1、当iOS端息屏时,且杀死APP情况下,A向B发起视频,如下图:
1.发送方A【327648a965】给接收方B,发了一个视频通话申请,如下图中提示部分使用环信IM的文本消息发过来的,其中ext扩展字段携带rtc的channel id。该界面客户可以自己自定义解析。
2.上图中的接听和挂断,其实是环信IM有给发送方A【327648a965】发了一个CMD消息,通知发送方A,接收方B同意接听和挂断,对应的RTC部分还是调用RTC的对应创建、销毁相关接口和监听。下图中是发送方A【327648a965】的等待界面和拒绝的界面,是一个简单UI界面,客户自定义即可。
3.下图是整个rtc视频电话结束过程,再发送一条环信cmd消息,通知对方结束视频,并在UI上处理通知内容。
另外:针对自定义铃声这块信令分在线和离线,如果是在线的话,其实就是调用预存在app里的音频文件;但是离线的话,这个受制于各个厂商的限制,只是一个消息通知过来。点击后调起app完成视频弹出和接入。目前支持自定义铃声的厂家有:APNS、华为、小米。
具体代码参考:
1.发送方发起音视频:
发送方发送文本消息:
log: level: 0, area: 1, SEND:
{ verison : MSYNC_V1, compress_algorimth
: 0, command : SYNC, encrypt_type : [ 0 ], payload : { meta : { id :
17321550832330177, to : lp1, ns : CHAT, payload : { chattype : CHAT,
from : lp, to : lp1, contents : [ { contenttype : TEXT, text
:邀请您进行语音通话} ], exts : [ { key : action, type : 7, value : invite }, {
key : callId, type : 7, value : qguioygpiq }, { key : callerDevId,
type : 7, value : android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, {
key : channelName, type : 7, value : jfqzawdpbk }, { key : ext, type :
8, value : {} }, { key : msgType, type : 7, value : rtcCallWithAgora
}, { key : ts, type : 4, value : 1732155083234 }, { key : type, type :
2, value : 0 } ] } } } }
2.接收方收到发送方发送的文本消息后给发起方发送COMMAND 消息
接收方接收到消息
[2024/11/21 10:12:04:905]: log: level: 0, area:1, RECV: { verison :
MSYNC_V1, command : SYNC, payload : { status : { error_code :0 },
metas : [ { id : 1351155153809442540, from :
easemob-demo#support_lp1@eas********/c6c02a96-495c-4780-82a7-cfb8ced96b31, to : easemob-demo#su@********com, timestamp :1732155124141, ns
: CHAT, payload : { chattype : CHAT, from : lp1, to : lp, contents : [
{ contenttype : TEXT, text :邀请您进行语音通话 } ], exts : [ { key : action,
type : 7, value : invite }, { key : callId, type : 7, value :
hunzyeqdtt }, { key : callerDevId, type : 7, value :
android_aid63a35073-8403-4495-9772-88021c27a40d}, { key : channelName,
type :7, value : exjwllhwdd }, { key : ext, type :8, value : {} }, {
key : msgType, type :7, value : rtcCallWithAgora }, { key : ts, type
:4, value : 1732155126762}, { key : type, type :2, value : 0} ], meta
: {} }, exts : [ { key : client_id, type :4, value :
17321551267620308} ], meta : {“is_online”:1} } ], next_key
:1351155153809442540, queue : lp1, timestamp :1732155124274 } }
接收方发送消息COMMAND消息
log: level: 0, area: 1, SEND:
{ verison : MSYNC_V1, compress_algorimth
: 0, command : SYNC, encrypt_type : [ 0 ], payload : { meta : { id :
17321551249410208, to : lp1, ns : CHAT, payload : { chattype : CHAT,
from : lp, to : lp1, contents : [ { contenttype : COMMAND, action :
rtcCall } ], exts : [ { key : action, type : 7, value : alert }, { key
: callId, type : 7, value : hunzyeqdtt }, { key : calleeDevId, type :
7, value : android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, { key :
callerDevId, type : 7, value :
android_aid63a35073-8403-4495-9772-88021c27a40d }, { key : msgType,
type : 7, value : rtcCallWithAgora }, { key : ts, type : 4, value :
1732155124942 } ] } } } }
3.发起方收到接收方的COMMAND 消息后给接收方发送COMMAND消息
发起方收到接收方COMMAND消息
log: level: 0, area: 1, RECV: { verison : MSYNC_V1, command : SYNC,
payload : { status : { error_code : 0 }, metas : [ { id :
1351154975949981420, from :
easemob-demo#support_lp1@easemob.com/android_c6c02a96-495c-4780-82a7-cfb8ced96b31, to : easemob-demo#support_lp@easemob.com, timestamp : 1732155082744,
ns : CHAT, payload : { chattype : CHAT, from : lp1, to : lp, contents
: [ { contenttype : COMMAND, action : rtcCall } ], exts : [ { key :
action, type : 7, value : alert }, { key : callId, type : 7, value :
qguioygpiq }, { key : calleeDevId, type : 7, value :
android_aid63a35073-8403-4495-9772-88021c27a40d }, { key :
callerDevId, type : 7, value :
android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, { key : msgType,
type : 7, value : rtcCallWithAgora }, { key : ts, type : 4, value :
1732155085378 } ], meta : {} }, exts : [ { key : client_id, type : 4,
value : 17321550853770289 } ], meta : {“is_online”:1} } ], next_key :
1351154975949981420, queue : lp1, timestamp : 1732155082771 } }
发起方给接收方发送COMMAND消息:
log: level: 0, area: 1, SEND:
{ verison : MSYNC_V1, compress_algorimth
: 0, command : SYNC, encrypt_type : [ 0 ], payload : { meta : { id :
17321550834090180, to : lp1, ns : CHAT, payload : { chattype : CHAT,
from : lp, to : lp1, contents : [ { contenttype : COMMAND, action :
rtcCall } ], exts : [ { key : action, type : 7, value : confirmRing },
{ key : callId, type : 7, value : qguioygpiq }, { key : calleeDevId,
type : 7, value : android_aid63a35073-8403-4495-9772-88021c27a40d }, {
key : callerDevId, type : 7, value :
android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, { key : msgType,
type : 7, value : rtcCallWithAgora }, { key : status, type : 1, value
: 1 }, { key : ts, type : 4, value : 1732155083409 } ] }, routeType :
1 } } }
接收方收到发起方发送的COMMAND消息
[2024/11/21 10:12:05:044]: log: level: 0, area:1, RECV: { verison :
MSYNC_V1, command : SYNC, payload : { status : { error_code :0 },
metas : [ { id : 1351155154967070444, from :
easemob-demo#support_lp1@eas********/c6c02a96-495c-4780-82a7-cfb8ced96b31, to : easemob-demo#su@********com, timestamp :1732155124417, ns
: CHAT, payload : { chattype : CHAT, from : lp1, to : lp, contents : [
{ contenttype : COMMAND, action : rtcCall } ], exts : [ { key :
action, type :7, value : confirmRing }, { key : callId, type :7, value
: hunzyeqdtt }, { key : calleeDevId, type :7, value :
android_aidf3729974-5566-46ea-b93a-10897064ccd6}, { key : callerDevId,
type :7, value : android_aid63a35073-8403-4495-9772-88021c27a40d}, {
key : msgType, type :7, value : rtcCallWithAgora }, { key : status,
type :1, value :1 }, { key : ts, type : 4, value : 1732155127038 } ],
meta : {} }, routeType : 1, exts : [ { key : msg_type, type : 7, value
: command }, { key : write_channel, type : 1, value : 1 }, { key :
chat_type, type : 7, value : chat:user }, { key : route_type, type :7,
value : route_online }, { key : chat_route, type : 7, value :
route_online:chat:user:command }, { key : client_id, type :4, value :
17321551270370316 } ] } ], queue : lp1, is_last : true } }
4.发起方挂断
发起方挂断给接收方发送COMMAND消息
log: level: 0, area: 1, SEND:
{ verison : MSYNC_V1, compress_algorimth
: 0, command : SYNC, encrypt_type : [ 0 ], payload : { meta : { id :
17321599975870322, to : lp1, ns : CHAT, payload : { chattype : CHAT,
from : lp, to : lp1, contents : [ { contenttype : COMMAND, action :
rtcCall } ], exts : [ { key : action, type : 7, value : cancelCall },
{ key : callId, type : 7, value : vkmqhzojtm }, { key : callerDevId,
type : 7, value : android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, {
key : msgType, type : 7, value : rtcCallWithAgora }, { key : ts, type
: 4, value : 1732159997588 } ] } } } }
接收方收到COMMAND消息
log: level: 0, area: 1, RECV: { verison : MSYNC_V1, command : SYNC,
payload : { status : { error_code : 0 }, metas : [ { id :
1351176082597873092, from :
easemob-demo#support_lp@eas********/03aa476f-2451-4f12-89f9-c1f0767b8fe0,
to : easemob-demo#sup@********com, timestamp : 1732159997001,
ns : CHAT, payload : { chattype : CHAT, from : lp, to : lp1, contents
: [ { contenttype : COMMAND, action : rtcCall } ], exts : [ { key :
action, type : 7, value : cancelCall }, { key : callId, type : 7,
value : vkmqhzojtm }, { key : callerDevId, type : 7, value :
android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, { key : msgType,
type : 7, value : rtcCallWithAgora }, { key : ts, type : 4, value :
1732159997588 } ], meta : {} }, exts : [ { key : client_id, type : 4,
value : 17321599975870322 } ], meta : {“is_online”:1} } ], next_key :
1351176082597873092, queue : lp, timestamp : 1732159997034 } }
5.接收方接听
接收方接通时给发起方发送COMMAND消息
log: level: 0, area: 1, SEND:
{ verison : MSYNC_V1, compress_algorimth
: 0, command : SYNC, encrypt_type : [ 0 ], payload : { meta : { id :
17321560242720224, to : lp1, ns : CHAT, payload : { chattype : CHAT,
from : lp, to : lp1, contents : [ { contenttype : COMMAND, action :
rtcCall } ], exts : [ { key : action, type : 7, value : answerCall },
{ key : callId, type : 7, value : bryryludvk }, { key : calleeDevId,
type : 7, value : android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, {
key : callerDevId, type : 7, value :
android_aid63a35073-8403-4495-9772-88021c27a40d }, { key : msgType,
type : 7, value : rtcCallWithAgora }, { key : result, type : 7, value
: accept }, { key : ts, type : 4, value : 1732156024272 }, { key :
videoToVoice, type : 1, value : 0 } ] }, routeType : 1 } } }
发起方收到接听方COMMAND消息后给接听方发送COMMAND消息
log: level: 0, area: 1, RECV: { verison : MSYNC_V1, command : SYNC,
payload : { status : { error_code : 0 }, metas : [ { id :
1351159017233188292, from :
easemob-demo#support_lp@eas********/03aa476f-2451-4f12-89f9-c1f0767b8fe0,
to : easemob-demo#sup@********com, timestamp : 1732156023677,
ns : CHAT, payload : { chattype : CHAT, from : lp, to : lp1, contents
: [ { contenttype : COMMAND, action : rtcCall } ], exts : [ { key :
action, type : 7, value : answerCall }, { key : callId, type : 7,
value : bryryludvk }, { key : calleeDevId, type : 7, value :
android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, { key :
callerDevId, type : 7, value :
android_aid63a35073-8403-4495-9772-88021c27a40d }, { key : msgType,
type : 7, value : rtcCallWithAgora }, { key : result, type : 7, value
: accept }, { key : ts, type : 4, value : 1732156024272 }, { key :
videoToVoice, type : 1, value : 0 } ], meta : {} }, routeType : 1,
exts : [ { key : msg_type, type : 7, value : command }, { key :
write_channel, type : 1, value : 1 }, { key : chat_type, type : 7,
value : chat:user }, { key : route_type, type : 7, value :
route_online }, { key : chat_route, type : 7, value :
route_online:chat:user:command }, { key : client_id, type : 4, value :
17321560242720224 } ] } ], queue : lp, is_last : true } }
发起方给接听方发送COMMAND消息
log: level: 0, area: 1, SEND:
{ verison : MSYNC_V1, compress_algorimth
: 0, command : SYNC, encrypt_type : [ 0 ], payload : { meta : { id :
17321560263460351, to : lp, ns : CHAT, payload : { chattype : CHAT,
from : lp1, to : lp, contents : [ { contenttype : COMMAND, action :
rtcCall } ], exts : [ { key : action, type : 7, value : confirmCallee
}, { key : callId, type : 7, value : bryryludvk }, { key :
calleeDevId, type : 7, value :
android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, { key :
callerDevId, type : 7, value :
android_aid63a35073-8403-4495-9772-88021c27a40d }, { key : msgType,
type : 7, value : rtcCallWithAgora }, { key : result, type : 7, value
: accept }, { key : ts, type : 4, value : 1732156026348 } ] },
routeType : 1 } } }
接听方收到发送方回的COMMAND消息
log: level: 0, area: 1, RECV: { verison : MSYNC_V1, command : SYNC,
payload : { status : { error_code :0 }, metas : [ { id :
1351159017375794924, from :
easemob-demo#support_lp1@eas********/c6c02a96-495c-4780-82a7-cfb8ced96b31, to : easemob-demo#su@********com, timestamp :1732156023711, ns
: CHAT, payload : { chattype : CHAT, from : lp1, to : lp, contents : [
{ contenttype : COMMAND, action : rtcCall } ], exts : [ { key :
action, type :7, value : confirmCallee }, { key : callId, type :7,
value : bryryludvk }, { key : calleeDevId, type :7, value :
android_aidf3729974-5566-46ea-b93a-10897064ccd6}, { key : callerDevId,
type :7, value : android_aid63a35073-8403-4495-9772-88021c27a40d}, {
key : msgType, type :7, value : rtcCallWithAgora }, { key : result,
type :7, value : accept }, { key : ts, type :4, value :1732156026348}
], meta : {} }, routeType :1, exts : [ { key : msg_type, type :7,
value : command }, { key : write_channel, type :1, value :1}, { key :
chat_type, type :7, value : chat:user }, { key : route_type, type :7,
value : route_online }, { key : chat_route, type :7, value :
route_online:chat:user:command }, { key : client_id, type :4, value :
17321560263460351 } ] } ], queue : lp1, is_last : true } }
6.接收方拒绝
接收方拒绝时给发起方发送COMMAND消息
log: level: 0, area: 1, SEND:
{ verison : MSYNC_V1, compress_algorimth
: 0, command : SYNC, encrypt_type : [ 0 ], payload : { meta : { id :
17321571891340242, to : lp1, ns : CHAT, payload : { chattype : CHAT,
from : lp, to : lp1, contents : [ { contenttype : COMMAND, action :
rtcCall } ], exts : [ { key : action, type : 7, value : answerCall },
{ key : callId, type : 7, value : vljrkwyhqb }, { key : calleeDevId,
type : 7, value : android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, {
key : callerDevId, type : 7, value :
android_aid63a35073-8403-4495-9772-88021c27a40d }, { key : msgType,
type : 7, value : rtcCallWithAgora }, { key : result, type : 7, value
: refuse }, { key : ts, type : 4, value : 1732157189135 }, { key :
videoToVoice, type : 1, value : 0 } ] }, routeType : 1 } } }
发起方收到接收方COMMAND消息给接收方发送COMMAND消息
发起方收到接收方COMMAND
log: level: 0, area: 1, RECV: { verison : MSYNC_V1, command : SYNC,
payload : { status : { error_code : 0 }, metas : [ { id :
1351164020316440004, from :
easemob-demo#support_lp@eas********/03aa476f-2451-4f12-89f9-c1f0767b8fe0,
to : easemob-demo#sup@********com, timestamp : 1732157188545,
ns : CHAT, payload : { chattype : CHAT, from : lp, to : lp1, contents
: [ { contenttype : COMMAND, action : rtcCall } ], exts : [ { key :
action, type : 7, value : answerCall }, { key : callId, type : 7,
value : vljrkwyhqb }, { key : calleeDevId, type : 7, value :
android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, { key :
callerDevId, type : 7, value :
android_aid63a35073-8403-4495-9772-88021c27a40d }, { key : msgType,
type : 7, value : rtcCallWithAgora }, { key : result, type : 7, value
: refuse }, { key : ts, type : 4, value : 1732157189135 }, { key :
videoToVoice, type : 1, value : 0 } ], meta : {} }, routeType : 1,
exts : [ { key : msg_type, type : 7, value : command }, { key :
write_channel, type : 1, value : 1 }, { key : chat_type, type : 7,
value : chat:user }, { key : route_type, type : 7, value :
route_online }, { key : chat_route, type : 7, value :
route_online:chat:user:command }, { key : client_id, type : 4, value :
17321571891340242 } ] } ], queue : lp, is_last : true } }
发起方给接收方发送COMMAND消息
log: level: 0, area: 1, SEND:
{ verison : MSYNC_V1, compress_algorimth
: 0, command : SYNC, encrypt_type : [ 0 ], payload : { meta : { id :
17321571912110022, to : lp, ns : CHAT, payload : { chattype : CHAT,
from : lp1, to : lp, contents : [ { contenttype : COMMAND, action :
rtcCall } ], exts : [ { key : action, type : 7, value : confirmCallee
}, { key : callId, type : 7, value : vljrkwyhqb }, { key :
calleeDevId, type : 7, value :
android_aidf3729974-5566-46ea-b93a-10897064ccd6 }, { key :
callerDevId, type : 7, value :
android_aid63a35073-8403-4495-9772-88021c27a40d }, { key : msgType,
type : 7, value : rtcCallWithAgora }, { key : result, type : 7, value
: refuse }, { key : ts, type : 4, value : 1732157191211 } ] },
routeType : 1 } } }
接收方收到发送方COMMAND消息
log: level: 0, area: 1, RECV: { verison : MSYNC_V1, command : SYNC,
payload : { status : { error_code :0 }, metas : [ { id :
1351164020429690280, from :
easemob-demo#support_lp1@eas********/c6c02a96-495c-4780-82a7-cfb8ced96b31, to : easemob-demo#su@********com, timestamp :1732157188573, ns
: CHAT, payload : { chattype : CHAT, from : lp1, to : lp, contents : [
{ contenttype : COMMAND, action : rtcCall } ], exts : [ { key :
action, type :7, value : confirmCallee }, { key : callId, type :7,
value : vljrkwyhqb }, { key : calleeDevId, type :7, value :
android_aidf3729974-5566-46ea-b93a-10897064ccd6}, { key : callerDevId,
type :7, value : android_aid63a35073-8403-4495-9772-88021c27a40d}, {
key : msgType, type :7, value : rtcCallWithAgora }, { key : result,
type :7, value : refuse }, { key : ts, type :4, value :1732157191211}
], meta : {} }, routeType :1, exts : [ { key : msg_type, type :7,
value : command }, { key : write_channel, type :1, value :1}, { key :
chat_type, type :7, value : chat:user }, { key : route_type, type :7,
value : route_online }, { key : chat_route, type :7, value :
route_online:chat:user:command }, { key : client_id, type :4, value :
17321571912110022 } ] } ], queue : lp1, is_last : true } }
7. 接听后挂断:
接听后发送方挂断或者接收方挂断都是一样的逻辑
调用声网的RtcEngine#leaveChannel
通过IRtcEngineEventHandler#onUserOffline
监听对方 退出后离开
参考文档:
-
注册环信IM:https://console.easemob.com/user/register
-
环信EaseCallKit源码:https://github.com/easemob/ease_call_kit
-
EaseCallKit集成文档:点此链接后各个端自行切换