XCC API

Agora

XSwitch 支持与 Agora 互联互通。


Agora 是一个 RTC 服务,提供各种终端(iOS、Android、macOS、Windows、Linux 等)的 SDK,可以用于快速开发 RTC 应用。

本质上,两个 Agora SDK,使用同一个 appid,加入同一个 channel 后,就可以相互通话(或视频)。

本文档假定读者已经熟悉 Agora 的功能和终端 SDK 使用方法。如果不熟悉,可以参考以下链接:

Agora 需要以下参数:

  • appid: Agora App ID,字符串,同一个 ID 下的媒体才有可能互通
  • token: App ID 泄漏后后果严重,因此使用 Token 来代替 App ID
  • channel: Agora Channel(频道),字符串,加入同一个 Channel 中的所有成员都可以媒体互通

Agora 在 XSwitch 内也是一个 Endpoint,与 SIP 类似,呼叫字符串格式为:agora/$appid-or-token/$channel/$dest_number

目前仅支持一个 SIP Channel 加入一个 Agora Channel,不支持多个 SIP 端加入同一个 Agora Channel(会议模式)。

在 XSwitch 中,也有 Channel 概念,一个 Channel 代表一个通道,也就是一路通话,与 Agora 概念区分,我们把 XSwitch 中的 Channel 叫通道,Agora 中的 Channel 叫频道。

Agora 呼叫 SIP

  • Android/iOS 客户端加入appid/channel
  • Agora 加入appid/channel,在 XSwitch 中生成一个 Channel(注意,与 Agora Channel 字符串不同)
  • Bridge 到 SIP

有以下两种方式:

{
  "jsonrpc": "2.0",
  "id": "0",
  "method": "XNode.NativeAPI",
  "params": {
    "ctrl_uuid": "ctrl_uuid",
    "cmd": "agora",
    "args": "call $key $channel $dest_number $cid_name $cid_number"
  }
}

其中:

  • key:Agora App ID 或 Token,必选
  • channel:Agora Channel,必选
  • dest_nubmer:被叫号码,必选
  • cid_name:主叫名称,可选
  • cid_number:主叫号码,可选

该方法使用 Native API 发起呼叫,会到系统 Dialplan 中查找$dest_number,具体的 Context 可以在模块配置文件中配置。

此外,也可以直接使用 Dial 发起外呼:

{
  "jsonrpc": "2.0",
  "id": "0",
  "method": "XNode.Dial",
  "params": {
    "ctrl_uuid": "ctrl_uuid",
    "destination": {
      "global_params": {},
      "call_params": [
        {
          "uuid": "uuid",
          "dial_string": "agora/$key/$channel/$dest_number",
          "params": {
            "agora_token": "token",
            "area_code": "2",
            "encrypt_mode": "2",
            "encrypt_key": "key",
            "encrypt_salt": "salt"
          }
        }
      ]
    }
  }
}

其中:

  • dest_nubmer:被叫号码,如果指定为auto_answer,则 Agora channel 会自动应答
  • agora_token:Agora Token,注意,key 可以为 App ID 或者 Token,但是 dial_string 是以 / 分割的,如果 Token 中含有 / 需要转义,另外私有化部署或者其他一些场景中,App ID 和 Token 是同时需要的,所以 Token 尽量放到该字段中
  • area_code:可选,区域码对应的 INT 值
  • encrypt_mode:可选,加密模式对应的 INT 值
  • encrypt_key:可选,加密 key
  • encrypt_salt:可选,加密 salt

呼通后,Agora Channel 将会自动接听,然后就可以调用XNode.Bridge去 Bridge SIP 侧的 Channel 了。

上述两种方式都需要先将 Agora SDK 加入 Channel,如果想省钱,可以先呼叫 SIP,等 SIP 接通后再加入 Agora Channel,如果 SIP 侧呼不通,就无需加入 Agora Channel。呼叫流程如下:

  • XSwitch Dial SIP
  • XSwitch 执行agora App 加入 Agora Channel,或通过 Bridge 加入 Agora Channel
  • 客户端 SDK 加入同一个 Channel

SIP 呼叫 Agora

SIP 呼叫 Agora 也有两种方式,当 SIP Channel 到来后,可以先 Accept,然后 Bridge 到agora/$key/$channel/$dest_number即可。

另一种方式是直接调用一个NativeApp,如:

{
  "jsonrpc": "2.0",
  "id": "0",
  "method": "XNode.NativeApp",
  "params": {
    "ctrl_uuid": "ctrl_uuid",
    "cmd": "agora",
    "args": "$key $channel"
  }
}

注意:不管从哪个方向呼,Agora 只有媒体层的协议支持,没有信令,因此,具体的信令由开发者自行实现,如:

  • 对于 SIP 来话,可以在 Accept 后,Bridge 到 Agora Channel,并通过 Push Notification 通知移动客户端 SDK 加入某个appid/channel(具体先后顺序可以自行决定)。
  • 对于 Agora 呼 SIP 的场景,移动客户端可以通过 REST API 或 Websocket 等方式通知 Ctrl 侧加个 Agora Channel 并呼叫 SIP。

Agora Channel 与 agora App

在 XSwitch 中,一个 Channel 指一路通话,典型地,SIP 呼 Agora 以及 Agora 呼 SIP 都有两个 Channel 组成,一个 SIP Channel 和一个 Agora Channel,它们之间使用 Bridge 进行桥接,组成一个桥接的呼叫。

在 XSwitch 中,SIP 与 Agora 通信的另一种实现方式是使用agora App,该 App 会执行join操作调用 Agora Linux SDK 加入一个 Agora 频道,但不会产生一个 Agora 通道,在 XSwitch 中,它是一个单腿呼叫。

音视频订阅

与 SIP 互通中,如果使用 Agora Endpoint 时,会在 XSwitch 中生成一个 Agora 的通道,也就是我们常说的腿。这条腿负责与声网交互,因此我们可以通过这条腿来进行音视频的订阅。

可以通过 agora sub|unsub API 进行控制,如:

{
  "jsonrpc": "2.0",
  "id": "0",
  "method": "XNode.NativeAPI",
  "params": {
    "ctrl_uuid": "ctrl_uuid",
    "cmd": "agora",
    "args": "sub $uuid $uid $type"
  }
}

其中:

  • uuid:XSwitch 中的 Agora 通道的 uuid,必选
  • uid:声网频道内其他成员的 uid,all 表示所有成员,必选
  • type:媒体类型,audiovideoall,必选。媒体类型如果为 audio,表示只订阅或者取消订阅音频,视频保持旧状态不变,为 video 时同理。

另外,在使用 Agora Endpoint 加入声网时,可以选择默认不订阅任何音视频,呼叫字符串如:

{agora_disable_sub=true}agora/$key/$channel/$dest_number

注意:由于是 Bridge 模式,如果是视频呼叫,同一时间只允许订阅一路视频,需要调用方做好控制。

会议

当有多个 SIP Channel 需要加入 Agora Channel 时,就形成一个会议,可以使用agora Application 实现。

agora Application 有一个全局的 Agora Channel 引用计数,多个 SIP Channel 可以加入同一个 Agora Channel(增加一个uid)。

其它

下面是一个示例:

更多示例可以参考xswitch/xcc-examples中的例子。

WebRTC