Agroa(声网)关于音视频通话的实现

前言

鉴于公司项目接入的极光IM的音视频聊天无法实现视频会议及踢人的相关功能。因此更换了音视频的相关第三方库。而环信提供了音视频会议的功能且环信的音视频功能就是基于Agroa的功能进行了二次封装。然后在此总结一下自己使用Agroa集成的一些流程及问题。

需要用到的技术文档

Agroa的音视频聊天主要用到了三部分的技术支持。

  • 语音通话
  • 视频通话
  • 云信令(原实时消息)

实现视频通话

做过音视频通话的应该都很清楚视频语音通话唯一的区别就是在于是否显示对方的实时视频流。因此本文档只提供一下关于视频通话的实现流程。

在Agroa官网创建一个新的项目
  • 注册一个Agroa的账号
  • 创建一个新的项目
  1. 去到项目管理页面
    创建项目.png
  2. 创建一个新的项目
    新建一个项目.png

    项目名称使用场景可以自行的去填写和选择一下。鉴权机制直接选择默认的下面的这种模式就可以了。关于鉴权机制具体的相关内容会随着后面的使用过程中慢慢的了解到的。在此就不在过多的说明了
  3. 配置项目信息(申请语音视频的通话频道)
    在完成第二步的项目创建后实际是我们在自己测试的过程中还是无法实现语音、视频通话的即使是配置了相关的语音视频协议也是不行的。这是因为我们使用了调试模式如果需要去做语音和视频通话的功能需要先去申请一个频道
    启用主要证书.png

    此处我们需要开启主要证书。
  4. 删除“无证书”(也可以选择不删除)
    无证书删除后用户就无法直接登录,项目正式上线后需要删除掉无证书。而我个人在使用过程中是直接将无证书给删除掉了的。
    删除无证书的信息.png

    此处我已经将无证书给删除掉了。而上面的次要证书是在你开启主要证书后自动生成的。
  5. 申请音视频的临时通话频道
    通过主要证书下的生成临时音视频token进行申请
    生成测试频道.png

    此处需要保留的信息是频道名临时Token
    到此关于项目需要的一些前置的准备信息已经完成了
集成云信令的SDK
  • 通过pod导入AgoraRtm_iOS的库文件
  • 下载官方项目然后将项目中的SDK导入到项目中
    导入云信令SDK.png

    Agora RTM iOS SDK
登录云信令账号

云信令的账号不存在注册的情况。用户名可以自己随便填写

let kit = AgoraRtmKit(appId: "项目appId", delegate: self)
kit.login(byToken: "生成的byToken", user: "下面生成token使用到的uid", completion: {[weak self] code in
   if code == .ok{
        print("登录成功")
   }
})

此处的kit使用的是一个局部变量。在正常的使用过程中要将kit设置成全局变量,因为这个属性在后续发起音视频聊天的时候需要用到这个kit
关于byToken因为已经删除掉了项目中的无证书,如果此处不填写byToken是无法登录的,不删除无证书可以不去填写此处的东西。
byToken的生成网址

token生成.png

  • appID
  • appCertificate 项目主要证书的key
  • uid 要用来登录的用户名
发起视频邀请
  • 导入视频通话的sdk
  1. pod 'AgoraRtcEngine_iOS'
  2. 官网下载SDK
    SDK下载.png

    AgoraRtcEngine_iOS下载地址
  • 发起视频通话
    视频通话流程图.png

    1.创建用户界面
  • 本地视频窗口
  • 远端视频窗口
    2.导入类
    在调用 Agora API 前,你需要在项目中导入 AgoraRtcKit 类,并定义一个 agoraKit 变量。
import AgoraRtcKit
class ViewController: UIViewController {
    ...
    // 定义 agoraKit 变量
    var agoraKit: AgoraRtcEngineKit?
}

3. 初始化 AgoraRtcEngineKit 对象
调用 sharedEngineWithAppId 创建并初始化 AgoraRtcEngineKit 对象。你需要将 YourAppID 替换为你的 Agora 项目的 App ID。

func initializeAgoraEngine() {
       agoraKit = AgoraRtcEngineKit.sharedEngine(withAppId: "YourAPPID", delegate: self)
    }

4. 设置本地视图
在加入频道前设置本地视图,以便在通话中看到本地图像

func setupLocalVideo() {
    // 启用视频模块
    agoraKit?.enableVideo()
    let videoCanvas = AgoraRtcVideoCanvas()
    videoCanvas.uid = 0
    videoCanvas.renderMode = .hidden
    videoCanvas.view = localView
    // 设置本地视图
    agoraKit?.setupLocalVideo(videoCanvas)
    }

5. 加入频道

func joinChannel(){
        // 频道内每个用户的 uid 必须是唯一的
        agoraKit?.joinChannel(byToken: "YourToken", channelId: "YourChannelName", info: nil, uid: 0, joinSuccess: { (channel, uid, elapsed) in
    })
}

此处channelId使用的是申请音视频的临时通话频道添加的频道id
给远端用户发送邀请

let localInvitation = AgoraRtmLocalInvitation.init(calleeId: "要邀请的用户uid")
localInvitation.channelId = "频道id"
        localInvitation.content = "语音通话"
        self.kit?.getRtmCall()?.send(localInvitation, completion: { code in
            if code == .ok{
                print("userb邀请成功")
            }
        })

//如果需要邀请多个人的话可以如下这样继续添加
let localInvitation1 = AgoraRtmLocalInvitation.init(calleeId: "要邀请的用户uid")
localInvitation1.channelId = "1234"
        localInvitation1.content = "语音通话"
        self.kit?.getRtmCall()?.send(localInvitation1, completion: { code in
            if code == .ok{
                print("userb邀请成功")
            }
        })
远端用户加入频道
  • 远端用户收到通话邀请的监听
var invitaCallKit : AgoraRtmCallKit?
var invitaAgoraRtm : AgoraRtmRemoteInvitation?
/// 收到通话邀请
    /// - Parameters:
    ///   - callKit: <#callKit description#>
    ///   - remoteInvitation: <#remoteInvitation description#>
    func rtmCallKit(_ callKit: AgoraRtmCallKit, remoteInvitationReceived remoteInvitation: AgoraRtmRemoteInvitation) {
        print("收到通话邀请")
        self.invitaCallKit = callKit
        self.invitaAgoraRtm = remoteInvitation
        acceptBtn.isHidden = false
    }
var invitaCallKit : AgoraRtmCallKit?
var invitaAgoraRtm : AgoraRtmRemoteInvitation?
self.invitaCallKit!.accept(self.invitaAgoraRtm!) { code in
            print("点击了接收邀请")
        }
本地端收到用户加入频道
// 监听 didJoinedOfUid 回调
    // 远端用户加入频道时,会触发该回调
    func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
        let videoCanvas = AgoraRtcVideoCanvas()
        videoCanvas.uid = uid
        videoCanvas.renderMode = .hidden
        videoCanvas.view = remoteView
        // 设置远端视图
        agoraKit?.setupRemoteVideo(videoCanvas)
    }
关于云信令需要用到的相关代理方法

云信令主要是实现呼叫邀请相关的代理

  • iOS


    呼叫邀请.png
  • Android


    安卓邀请.png
/// 收到通话邀请
    /// - Parameters:
    ///   - callKit: <#callKit description#>
    ///   - remoteInvitation: <#remoteInvitation description#>
    func rtmCallKit(_ callKit: AgoraRtmCallKit, remoteInvitationReceived remoteInvitation: AgoraRtmRemoteInvitation) {
        print("收到通话邀请")
        self.invitaCallKit = callKit
        self.invitaAgoraRtm = remoteInvitation
        acceptBtn.isHidden = false
    }
    
    func rtmCallKit(_ callKit: AgoraRtmCallKit, remoteInvitationFailure remoteInvitation: AgoraRtmRemoteInvitation, errorCode: AgoraRtmRemoteInvitationErrorCode) {
        print("对端呼叫邀请失败")
    }
    
    //被叫方收到被叫接收邀请 ->  被叫方自己接收到自己加入频道的
    func rtmCallKit(_ callKit: AgoraRtmCallKit, remoteInvitationAccepted remoteInvitation: AgoraRtmRemoteInvitation) {
        self.agoraKit?.enableVideo()
        let videoCanvas = AgoraRtcVideoCanvas()
        videoCanvas.uid = 0
        videoCanvas.renderMode = .hidden
        videoCanvas.view = localView
        agoraKit?.setupLocalVideo(videoCanvas)
        self.agoraKit?.joinChannel(byToken: "006f5765e0372174c99a6cf50e93d0bd85cIAB6NOUbAUcVpaztm68yf76LAZ/S2iOiUYeik7SJ0SJK2KPg45sAAAAAEAAxc9bWck4HYgEAAQBxTgdi", channelId: "1234", info: nil, uid: UInt(arc4random()) % 100, joinSuccess: { channel, uid, elapsed in
            print("被叫加入语音通话")
        })
        
    }
    //主叫收到被叫接收邀请
    func rtmCallKit(_ callKit: AgoraRtmCallKit, localInvitationAccepted localInvitation: AgoraRtmLocalInvitation, withResponse response: String?) {
        print("被叫已接收邀请")
        if joinNumber == 0 {
            
            self.agoraKit?.joinChannel(byToken: "006f5765e0372174c99a6cf50e93d0bd85cIAB6NOUbAUcVpaztm68yf76LAZ/S2iOiUYeik7SJ0SJK2KPg45sAAAAAEAAxc9bWck4HYgEAAQBxTgdi", channelId: "1234", info: nil, uid: 0, joinSuccess: { [weak self] channel, uid, elapsed in
                print("被叫加入语音通话")
                self?.joinNumber = 1
            })
        }
// 发送取消邀请的功能
        kit?.getRtmCall()?.cancel(localInvitation1, completion: { code in
            print("userc 已经被我干掉了")
        })
    }
    
    
    func rtmCallKit(_ callKit: AgoraRtmCallKit, remoteInvitationCanceled remoteInvitation: AgoraRtmRemoteInvitation) {
        self.acceptBtn.isHidden = true
    }
关于音视频中语音和视频流的开关装填设置

音视频流的相关设置参数主要是通过AgoraRtcEngineKit 类实现的。

音频管理.png

视频管理.png

退出频道

agoraKit?.leaveChannel(nil)

销毁 AgoraRtcEngineKit 对象

AgoraRtcEngineKit.destroy()

后端生成token

token鉴权

你可能感兴趣的:(Agroa(声网)关于音视频通话的实现)