快速入门

本文为您介绍如何使用 NERTC SDK 快速实现音视频通话功能。

前提条件

在开始运行工程之前,需要准备好如下材料:

快速跑通Sample Code

注意:在运行前,请联系商务经理开通非安全模式。非安全模式建议只在集成开发阶段使用,正式上线前请改回安全模式。

下载完 Sample Code 源码工程后,打开 nrtc_engine.h 文件,在以下位置填入您的AppKey。

#define APP_KEY ""

然后使用 Qt creator 打开 nertc_with_Qt.pro 文件,重新构建后即可运行程序。

集成SDK

至此, NERtc SDK 已经导入完成。

实现音视频通话

本节主要介绍如何使用 NERTC SDK 实现音视频通话,主要流程如下图所示:

音视频通话流程图1

音视频通话流程图2

初始化

进入频道之前,调用 createNERtcEngine 方法创建一个 NERtcEngine 实例,并调用 initialize 方法完成初始化。

// 创建 RTC 引擎对象并返回指针。
nertc::IRtcEngineEx *rtc_engine_ = (IRtcEngineEx *)createNERtcEngine();
// 设置已开通音视频功能的云信应用的AppKey。
rtc_engine_context_.app_key = app_key_.c_str();
// 设置日志目录的完整路径,采用UTF-8 编码。可选。
rtc_engine_context_.log_dir_path = log_dir_path_.c_str();
// 设置日志级别,默认级别为 kNERtcLogLevelInfo。
rtc_engine_context_.log_level = log_level;
// 指定 SDK 输出日志文件的大小上限,单位为 KB。如果设置为 0,则默认为 20 M。
rtc_engine_context_.log_file_max_size_KBytes = log_file_max_size_KBytes;
// 设置SDK向应用发送回调事件的通知。
rtc_engine_context_.event_handler = this;
// 初始化 NERTC SDK 服务。
if (kNERtcNoError != rtc_engine_->initialize(rtc_engine_context_))
{
    //TODO
}

设置本地视图

设置本地视频画布

调用 setupLocalVideoCanvas 方法,使应用程序绑定本地视频流的显示视窗,并设置本地视频视图。

NERtcVideoCanvas canvas;
canvas.cb = nullptr;
canvas.user_data = nullptr;
canvas.window = window;
// 设置视频缩放模式。
canvas.scaling_mode = mode;
rtc_engine_->setupLocalVideoCanvas(&canvas);

本地视频预览

若要在进入频道前启动本地视频预览,需要调用 startVideoPreview 方法启动本地视频预览。

int ret = rtc_engine_->startVideoPreview();

启动本地视频预览后,本地视频画面会显示在 setupLocalVideoCanvas 方法设置的画布中。

注意:正式执行加入频道操作前,需要先关闭本地视频预览。

int ret = rtc_engine_->stopVideoPreview();

启动视频流

在加入频道前或加入后需要调用 enableLocalVideo 启动本地视频流,以便可以将本地视频流发布到云信服务器。

bool enabled = true;
int ret = rtc_engine_->enableLocalVideo( enabled );

启动视频流后,本地视频画面会显示在 setupLocalVideoCanvas 方法设置的画布中。

请注意与 startVideoPreview 方法区分:

加入频道

加入频道前,请确保已完成初始化相关事项。若您的业务中涉及呼叫邀请等机制,可以使用信令

int ret = rtc_engine_->joinChannel(token, channel_name, uid);

当加入频道成功后,会走入初始化时设置的 rtc_engine_context_.event_handler 回调事件通知中的 onJoinChannel

/** 加入频道回调

     @param cid  频道 ID。
     @param uid  用户 ID。
     @param result  返回结果。
     @param elapsed 从 joinChannel 开始到发生此事件过去的时间(毫秒)。
     */
    virtual void onJoinChannel(channel_id_t cid, uid_t uid, NERtcErrorCode result, uint64_t elapsed) {
        (void)cid;
        (void)uid;
        (void)result;
        (void)elapsed;
    }

设置远端视图

视频通话过程中,除了要显示本地的视频画面,通常也要显示参与通话的其他用户的远端视频画面。

监听远端用户进出频道

当有远端用户进出频道时,会走入初始化时设置的 rtc_engine_context_.event_handler 回调事件通知中的:

通信模式下,该回调提示有远端用户加入了频道,并返回新加入用户的 uid;如果本端加入频道之前,频道内已经有其他用户了,在本端加入成功时,也会收到这些已有用户加入频道的回调。

    /** 远端用户加入当前频道回调。

     @param uid 新加入频道的远端用户ID。
     @param user_name 新加入频道的远端用户名。
     */
    virtual void onUserJoined(uid_t uid, const char * user_name) {
        (void)uid;
        (void)user_name;
    }
    /** 远端用户离开当前频道回调。

     提示有远端用户离开了频道(或掉线)。

     @param uid 远端用户ID。
     @param reason 远端用户离开原因。
     */
    virtual void onUserLeft(uid_t uid, NERtcSessionLeaveReason reason) {
        (void)uid;
        (void)reason;
    }

设置远端视频画布

监听到远端用户加入频道后,可以调用 setupRemoteVideoCanvas 方法设置远端视频画布,用来显示远端用户的视频画面。

NERtcVideoCanvas canvas;
canvas.cb = nullptr;
canvas.user_data = nullptr;
canvas.window = window;
// 设置视频缩放模式。
canvas.scaling_mode = mode;
rtc_engine_->setupRemoteVideoCanvas(uid, &canvas);

监听远端视频流发布

当频道中的其他用户有视频流发出/关闭时,分别会走入初始化时设置的 rtc_engine_context_.event_handler 回调事件通知中的以下回调:

/** 远端用户开启视频回调。

     @param uid 远端用户ID。
     @param max_profile 最大分辨率。
     */
    virtual void onUserVideoStart(uid_t uid, NERtcVideoProfileType max_profile) {
        (void)uid;
        (void)max_profile;
    }
    /** 远端用户停用视频回调。

     @param uid 远端用户ID。
     */
    virtual void onUserVideoStop(uid_t uid) {
        (void)uid;
    }

订阅远端视频流

在设置完远端视频画布后,且监听到远端用户有视频发布时,可以订阅远端用户的视频流。

/** 订阅/取消订阅 指定远端用户的视频流。对方打开视频后需要主动订阅。

    @param[in] uid 指定用户的用户 ID。
    @param[in] type 流类型。 #NERtcRemoteVideoStreamType
    @param[in] subscribe
    - true: 订阅指定远端用户的视频流;
    - false: 取消订阅指定远端用户的视频流。

    @return
    - 0: 方法调用成功;
    - 其他: 方法调用失败。
    */
    virtual int subscribeRemoteVideoStream(uid_t uid, NERtcRemoteVideoStreamType type, bool subscribe) = 0;
// 订阅指定用户的 kNERtcRemoteVideoStreamTypeHigh 类型的视频流
void NRTCEngine::subscribeRemoteUserVideoStream(nertc::uid_t uid) {
    int ret_temp = rtc_engine_->subscribeRemoteVideoStream(uid, kNERtcRemoteVideoStreamTypeHigh, true);
    if (ret_temp) {
        qDebug("[ERROR] can not subscribe remote video stream! ERROR CODE: %d", ret_temp);
    }
}

订阅成功后,即可显示远端的视频画面。

音频流

在 NERtc SDK 中,本地音频的采集发布和远端音频订阅播放是默认启动的,正常情况下无需开发者主动干预。

离开频道

当通话结束,需要离开频道,可以调用以下接口:

int ret = rtc_engine_->leaveChannel();

不论当前是否还在通话中,调用该方法会把相关的所有资源释放掉。真正退出频道后,SDK 会走入初始化时设置的 rtc_engine_context_.event_handler 回调事件通知中的 onLeaveChannel

/** 离开频道回调。

     App 调用  IRtcEngine::leaveChannel "leaveChannel" 方法时,SDK提示 App 离开频道是否成功。

     @param result 返回结果。
     */
    virtual void onLeaveChannel(NERtcErrorCode result) {
        (void)result;
    }

销毁音视频实例

释放当前的音视频实例,建议在应用确定不再需要使用音视频时,通过该接口释放对象资源。

void NRTCEngine::Uninit() {
    if (rtc_engine_) {
        ...

        //同步销毁 IRtcEngine 对象
        rtc_engine_->release(true);
        // 销毁 RTC 引擎对象
        destroyNERtcEngine((void*&)rtc_engine_);
        rtc_engine_ = nullptr;
    }
}