human: 如何处理七牛云的实时音视频实现视频通话

gpt: [实时音视频](https://developer.qiniu.com/rtc) > 快速入门 > Windows >实现视频通话

#  实现视频通话

最近更新时间: 2022-03-24 16:34:11

## 初始化

首先配置 SDK 日志输出等级和存储位置：

    
    
    // 在程序初始化时调用此方法初始化 SDK log 配置，不调用 == 无输出
    QNRTC::SetLogFile(qiniu::kLogInfo, "rtc-log", "rtc.log");
    

> 注：SDK log 输出每次以覆盖的方式写入文件,超过 100M 覆盖，中途没有文件大小及磁盘剩余空间的检测。

  * 创建音视频通话核心类（全局唯一）：

    
    
    // 初始化全局参数，这里根据自己的需要设置相应参数
    QNRTCSetting setting;
    QNRTC::Init(setting, this);
    // 释放时调用 QNRTC::DestroyRtcClient 方法接口
    QNRTCClient* rtc_client_ptr_ = QNRTC::CreateClient(this);
    

## 创建 Track：

Track 代表了音视频通话过程中的一路音频或者一路视频，本文仅介绍一路音视频连麦的场景，创建方式如下：

    
    
     QNCameraVideoTrackConfig camera_info = {{width, height, 30, 2000},
                                                {width, height, 30},
                                                video_dev_id,
                                                CAMERA_TAG,
                                                enable_simulcast_};
     QNCameraVideoTrack* camera_track_ptr = QNRTC::CreateCameraVideoTrack(camera_info, this);
    
     QNMicrophoneAudioTrackConfig micro_info = {{0, 0, 0, 32}, MICROPHONE_TAG};
     QNMicrophoneAudioTrack*  microphone_audio_track_ptr =
            QNRTC::CreateMicrophoneAudioTrack(micro_info);
    

## 枚举视频采集设备

获取本地视频采集设备数量，以及其所支持的采集参数：

    
    
    // 获取本地视频采集设备数量
    int camera_count = QNRTC::GetCameraCount();
    // 枚举所有设备列表，及其所支持的采集参数,key:device id value:CameraDeviceInfo
    unordered_map<string, CameraDeviceInfo>   camera_dev_map_; 
    for (int i(0); i < camera_count; ++i) {
    	CameraDeviceInfo ci = QNRTC::GetCameraInfo(i);
    	camera_dev_map_[ci.id] = ci;
    }
    

## 加入房间

上文提到过，SDK 所有的功能都是从 `RoomToken` 开始的，所以加入房间只需要将 `RoomToken` 作为参数传给 SDK
就可以了。示例代码如下：

    
    
    rtc_client_ptr_->Join(_room_token);
    

加入房间成功后会触发
[QNClientEventListener.OnConnectionStateChanged](https://developer.qiniu.com/rtc/api/9407/QNClientEventListener#OnConnectionStateChanged)
回调 QNConnectionState.CONNECTED 状态。此时即可进行发布、订阅等操作。

在进入音视频通话房间之后，用户可以根据业务场景的需求在适当的时间调用离开房间的接口退出连麦，详情请见[房间管理](https://developer.qiniu.com/rtc/development_guidelines/9547/room-
management-windows)。

> 注：此处 `_room_token` 建议开发者的应用程序从自己的 Server 端获取，关于 Server 如何生成 token
> 可查阅[服务端开发文档](https://developer.qiniu.com/rtn/sdk/4538/server-api-
> reference#5)。

## 发布音/视频

成功加入房间后，即可在
[QNClientEventListener.OnConnectionStateChanged](https://developer.qiniu.com/rtc/api/9407/QNClientEventListener#OnConnectionStateChanged)
回调中调用以下代码进行本地 Track 的发布：

    
    
    void CRtcDemoV2::OnConnectionStateChanged(qiniu::QNConnectionState state, const qiniu::QNConnectionDisconnectedInfo& info)
    {
        if (state == CONNECTED) {
            StartPublish();
        }
    }
    

发布成功后，本地会收到
[QNPublishResultCallback.OnPublished](https://developer.qiniu.com/rtc/api/9435/QNPublishResultCallback#OnPublished)
回调。远端用户会收到
[QNClientEventListener.OnUserPublished](https://developer.qiniu.com/rtc/api/9407/QNClientEventListener#OnUserPublished)
回调。

## 订阅远端音/视频

SDK 收到远端发布
[QNClientEventListener.OnUserPublished](https://developer.qiniu.com/rtc/api/9407/QNClientEventListener#OnUserPublished)
的回调，在此回调内则可进行对 Track 的渲染窗口设置的操作，再进行订阅，如果用户默认设置了自动订阅，这里只需设置渲染窗口，不需要主动去订阅：

注：用于渲染视频的窗口句柄，在 MFC 中直接使用窗口类的 m_hWnd 成员变量获取，Qt 中通过窗口类的 winId() 方法进行获取,。

在成功订阅之后，用户可以根据业务场景的需求在适当的时间调用取消订阅的接口取消订阅相应的
Track，详情请见[发布与订阅](https://developer.qiniu.com/rtc/development_guidelines/9548/publish-
and-subscribe-windows)

## 离开房间

当音视频通话结束，调用以下代码离开房间：

    
    
        rtc_client_ptr_->Leave();
    

## 销毁

用户需要调用以下代码对资源进行释放，一般此操作建议在程序生命周期的 `OnDestroy()` 中进行，示例代码如下：

    
    
        if (rtc_client_ptr_) {
            rtc_client_ptr_->Leave();
        }
    
        if (camera_track_ptr_) {
            QNRTC::DestroyLocalTrack(camera_track_ptr_);
            camera_track_ptr_ = nullptr;
        }
    
        if (screen_track_ptr_) {
            QNRTC::DestroyLocalTrack(screen_track_ptr_);
            screen_track_ptr_ = nullptr;
        }
    
        if (custom_video_track_ptr_) {
            QNRTC::DestroyLocalTrack(custom_video_track_ptr_);
            custom_video_track_ptr_ = nullptr;
        }
    
        if (microphone_audio_track_ptr_) {
            QNRTC::DestroyLocalTrack(microphone_audio_track_ptr_);
            microphone_audio_track_ptr_ = nullptr;
        }
    
        if (custom_audio_track_ptr_) {
            QNRTC::DestroyLocalTrack(custom_audio_track_ptr_);
            custom_audio_track_ptr_ = nullptr;
        }
    
        if (rtc_client_ptr_) {
            QNRTC::DestroyClient(rtc_client_ptr_);
            rtc_client_ptr_ = nullptr;
        }
        QNRTC::DeInint();
    

以上内容是否对您有帮助？