互动视频
  • iOS
  • Android
  • macOS
  • Windows : C++
  • Linux
  • Web
  • 小程序
  • Electron
  • 概述
  • 限制说明
  • SDK 下载
  • 快速开始
  • 设备管理
  • 常用功能
  • 推拉流进阶
  • 视频进阶
  • 音频进阶
  • 其他功能
  • 废弃接口
  • API 文档
  • 常见错误码
  • 常见问题
  • 视频直播
  • 视频通话
  • 文档中心
  • 互动视频
  • 视频通话
  • 功能实现流程

功能实现流程

更新时间:2021-04-25 20:25

实时视频场景的典型使用之一是,同一会话中的多用户进行视频实时通话。

以 2 人间的实时视频为例,主要流程如下:

请注意:

  1. 上面流程中以 2 名房间成员间的实时视频为例,实际上 Zego SDK 支持多人实时视频。建议开发者按需设计。

  2. 为了便于开发者更快理解 VideoTalk 中的逻辑,下述每节会将功能核心源码片段挑出来并加以讲解。开发者亦可直接阅读 VideoTalk 源码,两者是一致的。

如果想了解更详细的 API 调用时序,请参考第六节中的 API 调用时序图。

1 登录房间

用户间进行实时视频对话前,需要先登录到同一个房间。

VideoTalk 中登录相关源码片段演示如下,仅供参考:

ZegoVideoTalkDialog.cpp

// 执行登录房间操作,成功后将在回调中发布直播
if (!LIVEROOM::LoginRoom(m_pChatRoom->getRoomId().toStdString().c_str(), role))
{
    QMessageBox::information(NULL, tr("提示"), tr("进入房间失败"));
}

//LoginRoom 的回调函数 OnLoginRoom
void ZegoVideoTalkDialog::OnLoginRoom(int errorCode, const QString& strRoomID, QVector<StreamPtr> vStreamList)
{

    if (errorCode != 0)
    {
        addLogString(tr(登录房间失败. error: %1").arg(errorCode));
        QMessageBox::information(NULL, tr("提示"), tr("登录房间失败. error: %1").arg(errorCode));
        this->close();
        return;
    }

    addLogString(tr("登录房间成功. roomID: %1").arg(strRoomID));

    //加入房间列表
    roomMemberAdd(m_strCurUserName);
    //登录房间成功即推流以及拉流
    StartPublishStream();

    for (auto& stream : vStreamList)
    {
        StartPlayStream(stream);
    }

}

2 开始视频通话

登录房间成功后,即可开始走推流、拉流流程,以推送己方画面和观看对方画面。

推流流程请参考:快速集成-推流
拉流流程请参考:快速集成-拉流

VideoTalk 中开始视频通话(即推流、拉流)相关源码片段演示如下,仅供参考:

ZegoVideoTalkDialog.cpp

// 同意视频通话,房间成员开始推流
void ZegoVideoTalkDialog::StartPublishStream()
{
    QTime currentTime = QTime::currentTime();
    //获取当前时间的毫秒
    int ms = currentTime.msec();
    QString strStreamId;
#ifdef Q_OS_WIN
    strStreamId = QString("s-windows-%1-%2").arg(m_strCurUserID).arg(ms);
#else
    strStreamId = QString("s-mac-%1-%2").arg(m_strCurUserID).arg(ms);
#endif
    m_strPublishStreamID = strStreamId;

    StreamPtr pPublishStream(new QZegoStreamModel(m_strPublishStreamID, m_strCurUserID, m_strCurUserName, "", true));

    m_pChatRoom->addStream(pPublishStream);

    //推流前调用双声道
    LIVEROOM::SetAudioChannelCount(2);

    if (m_avaliableView.size() > 0)
    {

        int nIndex = takeLeastAvaliableViewIndex();
        pPublishStream->setPlayView(nIndex);
        addAVView(nIndex);

        if (theApp.GetBase().getUseSurfaceMerge())
        {
#if (defined Q_OS_WIN) && (defined USE_SURFACE_MERGE) 
            StartSurfaceMerge();
#endif
        }
        else
        {
            LIVEROOM::SetVideoFPS(m_pAVSettings->GetFps());
            LIVEROOM::SetVideoBitrate(m_pAVSettings->GetBitrate());
            LIVEROOM::SetVideoCaptureResolution(m_pAVSettings->GetResolution().cx, m_pAVSettings->GetResolution().cy);
            LIVEROOM::SetVideoEncodeResolution(m_pAVSettings->GetResolution().cx, m_pAVSettings->GetResolution().cy);

            //配置View
            LIVEROOM::SetPreviewView((void *)AVViews.last()->winId());
            LIVEROOM::SetPreviewViewMode(LIVEROOM::ZegoVideoViewModeScaleAspectFill);
            LIVEROOM::StartPreview();
        }

        QString streamID = m_strPublishStreamID;
        m_anchorStreamInfo = pPublishStream;

        addLogString(tr("创建流成功, streamID: %1").arg(streamID));
        if (LIVEROOM::StartPublishing(m_pChatRoom->getRoomName().toStdString().c_str(), streamID.toStdString().c_str(), LIVEROOM::ZEGO_JOIN_PUBLISH, ""))
        {
            m_bIsPublishing = true;
            addLogString(tr("开始直播,流ID: %1").arg(streamID));
        }
    }
}

// 推流成功,开始拉流,观看房间其他成员画面
void ZegoVideoTalkDialog::StartPlayStream(StreamPtr stream)
{
    if (stream == nullptr) { return; }

    m_pChatRoom->addStream(stream);

    if (m_avaliableView.size() > 0)
    {
        int nIndex = takeLeastAvaliableViewIndex();
        qDebug() << "playStream nIndex = " << nIndex << " play stream id is " << stream->getStreamId();
        stream->setPlayView(nIndex);
        addAVView(nIndex);
        //配置View
        LIVEROOM::SetViewMode(LIVEROOM::ZegoVideoViewModeScaleAspectFill, stream->getStreamId().toStdString().c_str());
        LIVEROOM::StartPlayingStream(stream->getStreamId().toStdString().c_str(), (void *)AVViews.last()->winId());
    }
}

3 结束视频通话

视频通话结束后的操作主要是停止推流、停止拉流、清理视图、登出房间等,开发者可按需调用。

VideoTalk 中结束视频通话相关源码片段演示如下,仅供参考:

ZegoVideoTalkDialog.cpp

// 停止预览,停止推拉流,清理 view
void ZegoVideoTalkDialog::cleanBeforeGetOut()
{
    //离开房间时先把混音功能和声卡采集关闭
#ifdef Q_OS_WIN
    if (m_isUseDefaultAux)
        EndAux();
    else
    {
        AUDIOHOOK::StopAudioRecord();
        LIVEROOM::EnableAux(false);
        AUDIOHOOK::UnInitAudioHook();

    }
#else
    EndAux();
#endif

    if (ui.m_bCapture->text() == tr("停止采集"))
#ifdef Q_OS_WIN
        LIVEROOM::EnableMixSystemPlayout(false);
#endif

    for (auto& stream : m_pChatRoom->getStreamList())
    {
        if (stream != nullptr){
            if (stream->isCurUserCreated())
            {
                StopPublishStream(stream->getStreamId());
            }
            else
            {
                StopPlayStream(stream->getStreamId());
            }
        }
    }

    roomMemberDelete(m_strCurUserName);
    LIVEROOM::LogoutRoom();
    if (timer != nullptr)
        timer->stop();

    //释放堆内存
    delete m_cbMircoPhoneListView;
    delete m_cbCameraListView;
    delete m_memberModel;
    delete m_cbMircoPhoneModel;
    delete m_cbCameraModel;
    delete timer;
    delete gridLayout;
    //指针置为空
    m_cbMircoPhoneListView = nullptr;
    m_cbCameraListView = nullptr;
    m_memberModel = nullptr;
    m_cbMircoPhoneModel = nullptr;
    m_cbCameraModel = nullptr;
    timer = nullptr;
    gridLayout = nullptr;
}

4 API 调用时序图

实时视频 API 调用时序图如下:

本篇目录