实现音视频通话

更新时间: 2023/09/22 15:31:19

网易云信音视频通话产品的基本功能包括高质量的实时音视频通话。当您成功初始化 SDK 之后,您可以简单体验本产品的基本业务流程。本文档为您展示音视频通话提供的基本业务流程。

前提条件

请确认您已完成以下操作:

操作流程

使用 NERTC SDK 实现音视频通话的主要流程如下图所示:

音视频通话流程图2

操作步骤

1. 引用头文件和动态库

在您的工程中对应的文件里引入 linux/api 目录下的头文件,并引用 lib 动态库。

2. 初始化

在操作 SDK 接口前,需要完成初始化。

  1. 调用 createNERtcEngine 方法创建一个 IRtcNERtcEngine 实例。
  2. 调用 initialize 方法完成初始化。
    // 创建 RTC 引擎对象并返回指针。
    nertc::IRtcEngineEx *rtc_engine_ = (IRtcEngineEx *)createNERtcEngine();
    // 设置已开通音视频功能的云信应用的AppKey。
    nertc::NERtcEngineContext context;
    rtc_engine_context_.app_key = app_key_.c_str();
    // 设置日志目录的完整路径,采用UTF-8 编码。可选。具体枚举值请参考 NERtcLogLevel。
    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
    }

3. 设置本地视图

初始化成功后,可以设置本地视图,来预览本地图像。您可以在加入房间之前预览,或在加入房间后预览。

  • 加入房间前预览。

    1. 通过 setupLocalVideoCanvasstartVideoPreview 方法,在加入房间前设置本地视图,预览本地图像。

      // 示例
      static void onYuvDataIncoming(
              nertc::uid_t uid,   /**< uid */
              void *data,         /**< 数据指针 */
              uint32_t type,      /**< NERtcVideoType */
              uint32_t width,     /**< 宽度 */
              uint32_t height,    /**< 高度 */
              uint32_t count,     /**< 数据类型个数,即offset及stride的数目 */
              uint32_t offset[4], /**< 每类数据偏移 */
              uint32_t stride[4], /**< 每类数据步进 */
              uint32_t rotation,  /**< NERtcVideoRotation */
              void *user_data     /**< 用户透传数据 */
      );
      NERtcVideoCanvas canvas;
      canvas.cb = onYuvDataIncoming;
      canvas.user_data = this;
      // Linux SDK 不支持内置渲染,因此需要用户拿到视频原始数据进行外部渲染,比如使用OpenGL。
      canvas.window = nullptr;
      canvas.scaling_mode = mode;
      // 设置本地视频画布
      rtc_engine_->setupLocalVideoCanvas(&canvas);
      // 开启本地预览
      rtc_engine_->startVideoPreview();
      
    2. 若要结束预览,或者准备加入房间时,调用 stopVideoPreview 停止预览。

  • 加入房间后预览。

    在成功加入房间后,通过 enableLocalVideo 方法进行视频的采集发送与预览。

    // 示例
    NERtcVideoCanvas canvas;
    canvas.cb = onYuvDataIncoming;
    canvas.user_data = this;
    // Linux SDK 不支持内置渲染,因此需要用户拿到视频原始数据进行外部渲染,比如使用OpenGL。
    canvas.window = nullptr;
    canvas.scaling_mode = mode;
    // 设置本地视频画布
    rtc_engine_->setupLocalVideoCanvas(&canvas);
    bool enabled = true;
    // 启动视频流
    rtc_engine_->enableLocalVideo(enabled);
    

4. 加入房间

加入房间前,请确保已完成初始化相关事项。若您的业务中涉及呼叫邀请等机制,建议通过信令实现。

通过 joinChannel 方法加入房间。

  // 示例
  rtc_engine_->joinChannel(token, channel_name, uid);

重要参数说明

参数 说明
token 安全认证签名(NERTC Token)。
  • 调试模式下:可设置为 null。产品默认为安全模式,您可以在网易云信控制台将鉴权模式修改为调试模式,具体请参见Token 鉴权
    调试模式的安全性不高,请在产品正式上线前修改为安全模式。
  • 产品正式上线后:请设置为已获取的NERTC Token。安全模式下必须设置为获取到的 Token 。若未传入正确的 Token 将无法进入房间。

    推荐使用安全模式

channel_name 房间名称,长度为 1 ~ 64 字节。目前支持以下 89 个字符:a-z, A-Z, 0-9, space, !#$%&()+-:;≤.,>? @[]^_{|}~"。
设置相同房间名称的用户会进入同一个通话房间。
您也可以在加入通道前,通过创建房间接口创建房间。加入房间时,若传入的 {channelName} 未事先创建,则云信服务器内部将为其自动创建一个名为 {channelName} 的通话房间。
uid 用户的唯一标识 id,房间内每个用户的 uid 必须是唯一的。此 uid 为用户在您应用中的 ID,请在您的业务服务器上自行管理并维护。

SDK 发起加入房间请求后,服务器会进行响应,开发者可以通过初始化时设置的 rtc_engine_context_.event_handleronJoinChannel 回调监听加入房间的结果,同时该回调会抛出当前通话房间的 channelId 与加入房间总耗时(毫秒);其中 channelId 即音视频通话的 ID,建议您在业务层保存该数据,以便于后续问题排查。

5. 设置远端视图

音视频通话过程中,除了要显示本地的视频画面,通常也要显示参与互动的其他连麦者/主播的远端视频画面。

  1. IRtcEngineEventHandler 通过以下回调获取相关信息:

    • onUserJoined:监听远端用户加入通话房间的事件,并抛出对方的 uid。当本端加入房间后,也会通过此回调抛出通话房间内已有的其他用户。

    • onUserVideoStart :监听远端用户发布视频流的事件,回调中携带对方的 uid 与发布的视频分辨率。

  2. 在监听到远端用户加入房间或发布视频流后,本方可以通过 setupRemoteVideoCanvas:forUserID: 方法设置远端用户视频画布,用于显示其视频画面。

    // 示例
    static void onYuvDataIncoming(
                nertc::uid_t uid,   /**< uid */
                void *data,         /**< 数据指针 */
                uint32_t type,      /**< NERtcVideoType */
                uint32_t width,     /**< 宽度 */
                uint32_t height,    /**< 高度 */
                uint32_t count,     /**< 数据类型个数,即offset及stride的数目 */
                uint32_t offset[4], /**< 每类数据偏移 */
                uint32_t stride[4], /**< 每类数据步进 */
                uint32_t rotation,  /**< NERtcVideoRotation */
                void *user_data     /**< 用户透传数据 */
    );
    NERtcVideoCanvas canvas;
    canvas.cb = onYuvDataIncoming;
    canvas.user_data = this;
    // Linux SDK 不支持内置渲染,因此需要用户拿到视频原始数据进行外部渲染,比如使用OpenGL。
    canvas.window = nullptr;
    canvas.scaling_mode = mode;
    rtc_engine_->setupRemoteVideoCanvas(uid, &canvas);
    
  3. 在监听到远端用户发布视频流后,本方可以通过 subscribeRemoteVideoStream 方法对其发起视频流的订阅,来将对方的视频流渲染到视频画布上。

    // 示例
    // 订阅指定用户的 kNERtcRemoteVideoStreamTypeHigh 类型的视频流
    void RtcEngine::subscribeRemoteUserVideoStream(nertc::uid_t uid) {
        int ret = rtc_engine_->subscribeRemoteVideoStream(uid, kNERtcRemoteVideoStreamTypeHigh, true);
        if (ret) {
            qDebug("[ERROR] can not subscribe remote video stream! ERROR CODE: %d", ret);
        }
    } 
    
  4. 监听远端用户离开房间或关闭视频功能。

6. 音频流

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

若您需要实现静音或关闭音频采集,请参考以下代码:

{
engine->enableLocalAudio(false);//静音本地音频
engine->muteLocalAudioStream(false);//关闭本地音频采集
}

7. 退出通话房间

通过 leaveChannel 接口退出通话房间。

  // 示例
  rtc_engine_->leaveChannel();

真正退出房间后,SDK 会走入初始化时设置的 rtc_engine_context_.event_handler 回调事件通知中的 onLeaveChannel

8. 销毁实例

当确定短期内不再使用音视频通话实例时,可以释放对应的对象资源。

  // 示例
  // 同步销毁 IRtcEngine 对象
  rtc_engine_->release(true);
  // 销毁 RTC 引擎对象
  destroyNERtcEngine((void*&)rtc_engine_);
  rtc_engine_ = nullptr;
此文档是否对你有帮助?
有帮助
我要吐槽
  • 前提条件
  • 操作流程
  • 操作步骤
  • 1. 引用头文件和动态库
  • 2. 初始化
  • 3. 设置本地视图
  • 4. 加入房间
  • 5. 设置远端视图
  • 6. 音频流
  • 7. 退出通话房间
  • 8. 销毁实例