基於 Agora SDK 實現 Windows 端的多人視頻互動

本文介紹如何通過 Agora SDK 在 Windows 平臺快速實現互動直播。互動直播和實時通話的區別就在於,直播頻道的用戶有角色之分。你可以將角色設置爲主播或者觀衆,其中主播可以收、發流,觀衆只能收流。

Demo 體驗

Agora 在 GitHub 上提供一個開源的實時音視頻通話示例項目 OpenLive-Windows。在實現相關功能前,你可以下載並查看源代碼:https://github.com/AgoraIO/Basic-Video-Broadcasting/tree/master/OpenLive-Windows

前提條件

  • Microsoft Visual Studio 2017 或以上版本

  • 支持 Windows 7 或以上版本的 Windows 設備

  • 有效的 Agora 賬戶(免費註冊)

如果你的網絡環境部署了防火牆,請根據聲網文檔中心的「應用企業防火牆限制」打開相關端口。

設置開發環境

本節介紹如何創建項目,並將 Agora SDK 集成至你的項目中。

創建 Windows 項目

參考以下步驟創建一個 Windows 項目。若已有 Windows 項目,直接查看集成 SDK。

1. 打開 Microsoft Visual Studio 並點擊新建項目。

2. 進入新建項目窗口,選擇項目類型爲 MFC 應用程序,輸入項目名稱,選擇項目存儲路徑,並點擊確認

3. 進入MFC 應用程序窗口,選擇應用程序類型爲基於對話框,並點擊完成。

集成 SDK

參考以下步驟將 Agora SDK 集成到你的項目中。

1. 配置項目文件

  • 根據應用場景,從 SDK 下載獲取最新 SDK,解壓並打開。

  • 打開已下載的 SDK 文件,並將其中的 sdk 文件夾複製到你的項目文件夾下。

2. 配置項目屬性

解決方案資源管理器窗口中,右擊項目名稱並點擊屬性進行以下配置,配置完成後點擊確定

  • 進入 C/C++ > 常規 > 附加包含目錄菜單,點擊編輯,並在彈出窗口中輸入 $(SolutionDir)include

  • 進入鏈接器 > 常規 > 附加庫目錄菜單,點擊編輯,並在彈出窗口中輸入 $(SolutionDir)

  • 進入鏈接器 > 輸入 > 附加依賴項菜單,點擊編輯,並在彈出窗口中輸入 agora_rtc_sdk.lib

實現音視頻直播

本節介紹如何實現音視頻直播。視頻直播的 API 使用時序見下圖:

1. 創建用戶界面

爲直觀地體驗音視頻通話,需根據應用場景創建用戶界面(UI)。若項目中已有用戶界面,直接查看初始化 IRtcEngine。

如果你想實現一個視頻直播,推薦在 UI 上添加以下控件:

  • 主播視頻窗口

  • 離開頻道按鈕

當你使用示例項目中的 UI 設計時,你將會看到如下界面:

2. 初始化 IRtcEngine

在調用其他 Agora API 前,需要創建並初始化 IRtcEngine 對象。

你需要在該步驟中填入項目的 App ID。請參考如下步驟在控制檯創建 Agora 項目並獲取 App ID。

1. 登錄控制檯,點擊左側導航欄的項目管理圖標 

2. 點擊創建,按照屏幕提示設置項目名,選擇一種鑑權機制,然後點擊提交

3. 在項目管理頁面,你可以獲取該項目的 App ID

調用 createAgoraRtcEngine 和 initialize 方法,傳入獲取到的 App ID,即可初始化 IRtcEngine

你也可以根據需求,在初始化時實現其他功能。如註冊用戶加入頻道和離開頻道的回調。

// 創建實例。
m_lpRtcEngine = createAgoraRtcEngine();
RtcEngineContext ctx;


// 添加註冊回調和事件。
ctx.eventHandler = &m_engineEventHandler;


// 輸入你的 App ID。
ctx.appId = "YourAppID";


// 初始化 IRtcEngine。
m_lpRtcEngine->initialize(ctx);
// 繼承 IRtcEngineEventHandler 類中的回調與事件。
class CAGEngineEventHandler :
    public IRtcEngineEventHandler
{
public:
    CAGEngineEventHandler();
    ~CAGEngineEventHandler();
    void setMainWnd(HWND wnd);
    HWND GetMsgReceiver() {return m_hMainWnd;};


    // 在主播調用 joinChannel 方法後,此回調會報告加入頻道的主播信息。
    virtual void onJoinChannelSuccess(const char* channel, uid_t uid, int elapsed);


    // 在主播調用 leaveChannel 方法後,此回調會報告離開頻道的主播信息。
    virtual void onLeaveChannel(const RtcStats& stat);




    // 在引擎收到第一幀遠端視頻流並解碼成功時,會觸發此回調。
    virtual void onFirstRemoteVideoDecoded(uid_t uid, int width, int height, int elapsed);




    // 在主播調用 leaveChannel 方法後,此回調會報告該主播離開頻道及離線原因。
    virtual void onUserOffline(uid_t uid, USER_OFFLINE_REASON_TYPE reason);
private:
    HWND m_hMainWnd;
};

3. 設置頻道模式

初始化結束後,調用 setChannelProfile 方法,將頻道模式設爲直播。

一個 IRtcEngine 只能使用一種頻道模式。如果想切換爲其他模式,需要先調用 release 方法釋放當前的 IRtcEngine 實例,然後調用 createAgoraRtcEngine 和 initialize 方法創建一個新實例,再調用 setChannelProfile 設置新的頻道模式。

// 設置頻道模式爲直播。
m_lpRtcEngine->setChannelProfile(CHANNEL_PROFILE_LIVE_BROADCASTING);

4. 設置用戶角色

直播頻道有兩種用戶角色:主播和觀衆,其中默認的角色爲觀衆。設置頻道模式爲直播後,你可以在 App 中參考如下步驟設置用戶角色:

  • 讓用戶選擇自己的角色是主播還是觀衆

  • 調用 setClientRole 方法,然後使用用戶選擇的角色進行傳參

注意,直播頻道內的用戶,只能看到主播的畫面、聽到主播的聲音。加入頻道後,如果你想切換用戶角色,也可以調用 setClientRole 方法。

BOOL CAgoraObject::SetClientRole(CLIENT_ROLE_TYPE role, LPCSTR lpPermissionKey)
{
    // 設置用戶角色。
    int nRet = m_lpAgoraEngine->setClientRole(role);
    m_nRoleType = role;
    return nRet == 0 ? TRUE : FALSE;
}
// 創建選擇用戶角色的對話框。
void CEnterChannelDlg::OnCbnSelchangeCmbRole()
{
    int nSel = m_ctrRole.GetCurSel();
    if (nSel == 0)
        CAgoraObject::GetAgoraObject()->SetClientRole(CLIENT_ROLE_BROADCASTER);
    else
        CAgoraObject::GetAgoraObject()->SetClientRole(CLIENT_ROLE_AUDIENCE);
}

5. 設置本地視圖

如果你想實現一個語音直播,可以直接查看加入頻道。

成功初始化 IRtcEngine 對象後,需要在加入頻道前設置本地視圖,以便主播在直播中看到本地圖像。參考以下步驟設置本地視圖:

  • 調用 enableVideo 方法啓用視頻模塊。

  • 調用 setupLocalVideo 方法設置本地視圖。

// 啓用視頻模塊。
m_lpRtcEngine->enableVideo();


// 設置本地視圖。
VideoCanvas vc;
vc.uid = 0;
vc.view = hVideoWnd;
vc.renderMode = RENDER_MODE_TYPE::RENDER_MODE_HIDDEN;
m_lpRtcEngine->setupLocalVideo(vc);

6. 加入頻道

完成設置角色和本地視圖後(視頻直播場景),你就可以調用 joinChannel 方法加入頻道。你需要在該方法中傳入如下參數:

  • channelName: 傳入能標識頻道的頻道 ID。輸入頻道 ID 相同的用戶會進入同一個頻道。

  • token:傳入能標識用戶角色和權限的 Token。可設爲如下一個值:

    若項目已啓用 App 證書,請使用 Token。

    • NULL

    • 臨時 Token。臨時 Token 服務有效期爲 24 小時。你可以在控制檯裏生成一個臨時 Token,詳見獲取臨時 Token。

    • 在你的服務器端生成的 Token。在安全要求高的場景下,我們推薦你使用此種方式生成的 Token,詳見生成 Token。

  • uid: 本地用戶的 ID。數據類型爲整型,且頻道內每個用戶的 uid 必須是唯一的。若將 uid 設爲 0,則 SDK 會自動分配一個 uid,並在 onJoinChannelSuccess 回調中報告。

更多的參數設置注意事項請在聲網文檔中心查找並參考 joinChannel 接口中的參數描述。

// 在頻道中開啓 Web SDK 與 Native SDK 互通。
m_lpRtcEngine->enableWebSdkInteroperability(true);




// 加入頻道。
BOOL CAgoraObject::JoinChannel(LPCTSTR lpChannelName, UINT nUID, LPCSTR lpDynamicKey)
{
    int nRet = 0;
    LPCSTR lpStreamInfo = "{\"owner\":true,\"width\":640,\"height\":480,\"bitrate\":500}";
#ifdef UNICODE
    CHAR szChannelName[128];
    ::WideCharToMultiByte(CP_ACP, 0, lpChannelName, -1, szChannelName, 128, NULL, NULL);
    nRet = m_lpAgoraEngine->joinChannel(lpDynamicKey, szChannelName, lpStreamInfo, nUID);
#else
    nRet = m_lpAgoraEngine->joinChannel(lpDynamicKey, lpChannelName, lpStreamInfo, nUID);
#endif
    if (nRet == 0)
        m_strChannelName = lpChannelName;
    return nRet == 0 ? TRUE : FALSE;
}

7. 設置遠端視圖

視頻直播中,不論你是主播還是觀衆,都應該看到頻道中的所有主播。在加入頻道後,可通過調用 setupRemoteVideo 方法設置遠端主播的視圖。

遠端主播成功加入頻道後,SDK 會觸發 onFirstRemoteVideoDecoded 回調,該回調中會包含這個主播的 uid 信息。在該回調中調用 setupRemoteVideo 方法,傳入獲取到的 uid,設置該主播的視圖。

// 在引擎收到第一幀遠端視頻流並解碼成功時,會觸發此回調。
void CAGEngineEventHandler::onFirstRemoteVideoDecoded(uid_t uid, int width, int height, int elapsed)
{
    LPAGE_FIRST_REMOTE_VIDEO_DECODED lpData = new AGE_FIRST_REMOTE_VIDEO_DECODED;
    lpData->uid = uid;
    lpData->width = width;
    lpData->height = height;
    lpData->elapsed = elapsed;
    if(m_hMainWnd != NULL)
        ::PostMessage(m_hMainWnd, WM_MSGID(EID_FIRST_REMOTE_VIDEO_DECODED), (WPARAM)lpData, 0);
}
VideoCanvas canvas;
canvas.renderMode = RENDER_MODE_FIT;
POSITION pos = m_listWndInfo.GetHeadPosition();
......
AGVIDEO_WNDINFO &agvWndInfo = m_listWndInfo.GetNext(pos);
canvas.uid = agvWndInfo.nUID;
canvas.view = m_wndVideo[nIndex].GetSafeHwnd();
agvWndInfo.nIndex = nIndex;


// 設置遠端視圖。
CAgoraObject::GetEngine()->setupRemoteVideo(canvas);

8. 離開頻道

根據場景需要,如結束通話、關閉 App 或 App 切換至後臺時,調用 leaveChannel 離開當前通話頻道。

BOOL CAgoraObject::LeaveCahnnel()
{
    m_lpAgoraEngine->stopPreview();


    // 離開頻道。
    int nRet = m_lpAgoraEngine->leaveChannel();
    m_nSelfUID = 0;
    return nRet == 0 ? TRUE : FALSE;
}




void CAgoraObject::CloseAgoraObject()
{
    if(m_lpAgoraEngine != NULL)
        // 釋放 IRtcEngine 對象。
        m_lpAgoraEngine->release();
    if(m_lpAgoraObject != NULL)
        delete m_lpAgoraObject;
    m_lpAgoraEngine = NULL;
    m_lpAgoraObject = NULL;
}

示例代碼

你可以在 OpenLive-Windows 示例代碼中查看完整的源碼和代碼邏輯。

github:https://github.com/AgoraIO/Basic-Video-Broadcasting/tree/master/OpenLive-Windows

運行項目

在 Windows 設備中運行該項目。當成功開始視頻直播時,主播可以看到自己的畫面;觀衆可以看到主播的畫面。

更多產品信息、開發教程以及相關技術活動,請點擊「閱讀原文」獲取。

如開發中遇到問題,可訪問 RTC 開發者社區發帖提問

發佈了100 篇原創文章 · 獲贊 76 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章