快速入门音频通话

最近更新时间:2022-09-20 05:17:40

概述

本文主要介绍如何基于 anyRTC SDK 实现一个简单的音频通话功能。本文仅罗列最常用的几个接口,如果您希望了解更多的接口函数,请参见 API 文档

示例代码

Github地址

音频通话

1. 初始化 SDK

使用 anyRTC SDK 的第一步,是先通过 createARRtcEngine 创建一个 IRtcEngine 对象的指针 IRtcEngine*,并配置开发者信息和注册监听 SDK 事件的回调。

  • 继承 IRtcEngineEventHandler 事件回调接口类,重写关键事件的回调接口,包括本地用户进房/退房事件、远端用户加入/退出事件、错误事件和警告事件等。
  • 调用 initialize 接口配置开发者信息并注册监听 SDK 事件。
CArObject *CArObject::GetArObject(LPCTSTR lpAppId)
{
    if (m_lpArObject == NULL)
        m_lpArObject = new CArObject();
    if (m_lpArEngine == NULL)

        // 创建实例。
        m_lpArEngine = (IRtcEngine *)createARRtcEngine();
    if (lpAppId == NULL)
        return m_lpArObject;
    RtcEngineContext ctx;

    // 添加注册回调和事件。
    ctx.eventHandler = &m_EngineEventHandler;
#ifdef UNICODE
    char szAppId[128];
    ::WideCharToMultiByte(CP_ACP, 0, lpAppId, -1, szAppId, 128, NULL, NULL);

    // 输入你的 App ID。
    ctx.appId = szAppId;
#else
    ctx.appId = lpAppId;
#endif

    // 初始化 IRtcEngine。
    m_lpArEngine->initialize(ctx);
    return m_lpArObject;
}
// 继承 IRtcEngineEventHandler 类中的回调与事件。
class CAGEngineEventHandler :
    public IRtcEngineEventHandler
{
public:
    CAGEngineEventHandler(void);
    ~CAGEngineEventHandler(void);
    void SetMsgReceiver(HWND hWnd = NULL);
    HWND GetMsgReceiver() {return m_hMainWnd;};
 
    // 注册 onJoinChannelSuccess 回调。
    // 本地用户成功加入频道时,会触发该回调。
    virtual void onJoinChannelSuccess(const char* channel, uid_t uid, int elapsed);
 
    // 注册 onLeaveChannel 回调。
    // 本地用户成功离开频道时,会触发该回调。
    virtual void onLeaveChannel(const RtcStats& stat);
 
    // 注册 onUserOffline 回调。
    // 远端用户离开频道或掉线时,会触发该回调。
    virtual void onUserOffline(uid_t uid, USER_OFFLINE_REASON_TYPE reason);
private:
    HWND        m_hMainWnd;
};

2. 加入频道

调用 joinChannel 可以加入频道。 参数:

  • channelName:频道名称,只有输入相同的频道才能进行通信。
  • token:权限密钥,项目启动了权限密钥功能,加入房间必须使用Token。对安全要求高的用户,请开启该功能。
  • uid:用户本地ID,一般为业务用户的uid,请保持频道内该uid唯一。设置NULL,SDK会自动分配一个uid给该用户。
// 加入频道。
BOOL CArObject::JoinChannel(LPCTSTR lpChannelName, UINT nUID,LPCTSTR lpToken)
{
    int nRet = 0;
#ifdef UNICODE
    CHAR szChannelName[128];
    ::WideCharToMultiByte(CP_UTF8, 0, lpChannelName, -1, szChannelName, 128, NULL, NULL);
    char szToken[128];
    ::WideCharToMultiByte(CP_UTF8, 0, lpToken, -1, szToken, 128, NULL, NULL);
    if(0 == _tcslen(lpToken))
        nRet = m_lpArEngine->joinChannel(NULL, szChannelName, NULL, nUID);
    else
        nRet = m_lpArEngine->joinChannel(szToken, szChannelName, NULL, nUID);
#else
    if(0 == _tcslen(lpToken))
        nRet = m_lpArEngine->joinChannel(NULL, lpChannelName, NULL, nUID);
    else
        nRet = m_lpArEngine->joinChannel(lpToken, lpChannelName, NULL, nUID);
#endif
    if (nRet == 0)
        m_strChannelName = lpChannelName;
    return nRet == 0 ? TRUE : FALSE;
}

3. 收听远端音频流

anyRTC SDK 会默认接收远端的音频流,您无需为此编写额外的代码。如果您不希望收听某一个 uid 的音频流,可以使用 muteRemoteAudioStream 将其静音。

4. 开关本地声音采集

anyRTC SDK 在通信模式下进会会默认打开本地的麦克风采集,您无需为此编写额外的代码。如果您不希望发布自己的音频,可以使用 muteLocalAudioStream 将其禁止往网络发送本地音频流。

5. 退出频道

调用 leaveChannel 方法退出频道。不论当前是否还在通话中,调用该方法会把音频通话相关的所有资源释放掉。

BOOL CArObject::LeaveChannel()
{
    // 离开频道。
    int nRet = m_lpArEngine->leaveChannel();
    return nRet == 0 ? TRUE : FALSE;
}
 
 void CArObject::CloseArObject()
{
    if(m_lpArEngine != NULL)
        // 释放 IRtcEngine 对象。
        m_lpArEngine->release();
    if(m_lpArObject != NULL)
        delete m_lpArObject;
    m_lpArEngine = NULL;
    m_lpArObject = NULL;
}