实时音视频

  • 实时音视频 > 快速入门 > Windows >实现视频通话

    实现视频通话

    最近更新时间:2021-11-19 11:13:59

    初始化

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

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

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

    • 创建音视频通话核心类(全局唯一):
    // 释放时调用 QNRTC::DestroyRtcClient 方法接口
    QNRTCClient* _rtc_client_ptr = QNRTC::CreateClient();
    

    创建 Track:

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

     QNCameraVideoTrackConfig camera_info = { width,height,30,2000000,video_dev_id,CAMERA_TAG,m_hWnd,_enable_simulcast};
     QNCameraVideoTrack* _camera_track_ptr = QNRTC::CreateCameraVideoTrack(camera_info);
    
     QNMicrophoneAudioTrackConfig micro_info = { 32000,MICROPHONE_TAG };
     QNMicrophoneAudioTrack* = _microphone_audio_track_ptr = QNRTC::CreateMicrophoneAudioTrack(micro_info);
    

    为各模块设置其监听接口:

    // this 为实现了所有回调接口类的对象指针
    _rtc_client_ptr->SetQNClientEventListener(this);
    _rtc_client_ptr->SetQNPublishResultCallback(this);
    _rtc_client_ptr->SetLiveStreamingListener(this);
    

    枚举视频采集设备

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

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

    驱动 SDK 内部引擎

    需要开发者在上层开启定时器,并定时调用(比如:20ms 触发一次) _rtc_client_ptr->Loop(); 方法,以保证 SDK 的事件及时通知给用户,否则 SDK 内部回调不会触发;

    注:Loop 方法实际是用于处理 SDK 内部通知给开发者的消息; 此处建议开发者在自己的主线程(UI 线程)中开启定时器,以定时调用 Loop 方法,保证 SDK 回调均在上层主线程中触发,可方便开发者的 UI 操作。

    加入房间

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

    _rtc_client_ptr->Join(_room_token);
    

    加入房间成功后会触发 QNClientEventListener.OnConnectionStateChanged 回调 QNConnectionState.CONNECTED 状态。此时即可进行发布、订阅等操作。

    在进入音视频通话房间之后,用户可以根据业务场景的需求在适当的时间调用离开房间的接口退出连麦,详情请见房间管理

    注:此处 _room_token 建议开发者的应用程序从自己的 Server 端获取,关于 Server 如何生成 token 可查阅服务端开发文档

    发布音/视频

    成功加入房间后,即可在 QNClientEventListener.OnConnectionStateChanged 回调中调用以下代码进行本地 Track 的发布:

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

    发布成功后,本地会收到 QNPublishResultCallback.OnPublished 回调。远端用户会收到 QNClientEventListener.OnUserPublished 回调。

    订阅远端音/视频

    SDK 收到远端发布 QNClientEventListener.OnUserPublished 的回调,在此回调内则可进行对 Track 的渲染窗口设置的操作,再进行订阅,如果用户默认设置了自动订阅,这里只需设置渲染窗口,不需要主动去订阅:

    void CRtcDemoV2::OnUserPublished(const std::string& remoteUserID, const qiniu::RemoteTrackList& trackList)
    {
        for (auto&& itor : trackList) {
            shared_ptr<TrackInfoUI> tiu(new TrackInfoUI(this, itor));
            if (tiu->render_wnd_ptr) {
                itor->SetRenderHwnd((void*)tiu->render_wnd_ptr->m_hWnd);
            }
            _remote_tracks_map.insert_or_assign(itor->GetTrackID(), tiu);
        }
        if (_rtc_client_ptr) {
            _rtc_client_ptr->Subscribe(static_cast<qiniu::RemoteTrackList>(trackList));
        }
    }
    

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

    在成功订阅之后,用户可以根据业务场景的需求在适当的时间调用取消订阅的接口取消订阅相应的 Track,详情请见发布与订阅

    离开房间

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

        _rtc_client_ptr->Leave();
    

    销毁

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

        if (_camera_track_ptr) {
            QNRTC::DestroyCameraVideoTrack(_camera_track_ptr);
            _camera_track_ptr = nullptr;
        }
        if (_screen_track_ptr) {
            QNRTC::DestroyScreenVideoTrack(_screen_track_ptr);
            _screen_track_ptr = nullptr;
        }
        if (_custom_video_track_ptr) {
            QNRTC::DestroyCustomVideoTrack(_custom_video_track_ptr);
            _custom_video_track_ptr = nullptr;
        }
        if (_microphone_audio_track_ptr) {
            QNRTC::DestroyMicrophoneAudioTrack(_microphone_audio_track_ptr);
            _microphone_audio_track_ptr = nullptr;
        }
        if (_custom_audio_track_ptr) {
            QNRTC::DestroyCustomAudioTrack(_custom_audio_track_ptr);
            _custom_audio_track_ptr = nullptr;
        }
    
    以上内容是否对您有帮助?
  • Qvm free helper
    Close