從零到一,使用實時音視頻 SDK 一起開發一款 Zoom 吧

從零到一,使用實時音視頻 SDK 一起開發一款 Zoom 吧

zoom(zoom.us) 是一款受到廣泛使用的在線會議軟件。相信各位一定在辦公、會議、聊天等各種場景下體驗或者使用過,作爲一款成熟的商業軟件,zoom 提供了穩定的實時音視頻通話質量,以及白板、聊天、屏幕共享、PPT放映等常用功能。但是在當今瀏覽器成爲端上主流的時代,實時音視頻又怎甘於落後呢?相比於需要安裝包的 Zoom,直接在網頁上開發一款類似的會議軟件肯定會受到更多的關注。當需要開會的時候,直接通過一個鏈接,大家就可以接入並開始會議了。現在,使用七牛實時音視頻的 Web SDK,我們可以將您的想法輕鬆變爲現實。

首先,讓我們梳理一下一款Web的在線會議產品需要哪些關鍵點需要攻破

  • 瀏覽器兼容性要好,需要支持大部分主流桌面瀏覽器。

七牛實時音視頻基於 Google 在 Chrome 上推行的 WebRTC 協議,目前該協議已經正式寫入 Web 標準之中,所有的現代瀏覽器對其都有很好的兼容性。

  • 通話質量要好,延遲低,清晰度高

不同於傳統 WebRTC 採用用戶和用戶 P2P 的形式進行通信,我們使用了在全球範圍內部署的節點作爲低延遲的實時互動網絡來和各個端上進行 P2P 通信,在保證延遲的同時也保證了通話的質量。

  • 會議功能要豐富,ppt演示、白板、屏幕共享等等我都要

我們的 SDK 提供了豐富的功能列表,滿足絕大多數會議場景的需求,理論上使用 SDK 可以完全復刻一個 Web 版本的 zoom。

  • 說了這麼多,接入難不難?有沒有示例和文檔?

當然!目前就可以去體驗我們 Web 的 Demo(在桌面瀏覽器下打開)。https://demo-rtc.qnsdk.com。Demo 的源碼也開源在 Github 上供各位參考 https://github.com/pili-engineering/QNRTC-Web

這個 Demo 實現了絕大多數 SDK 直接提供的功能,集成白板/PPT共享/聊天等場景的 Demo 目前還在準備上線中,敬請期待哦。關於接入的具體過程我們下面將會簡單地介紹一遍,詳細的說明和參考可以移步我們的文檔站 https://developer.qiniu.com/rtn/sdk/4412/description-of-web-sdk

開發流程

一個簡單的會議產品,一般是通過如下流程:

  • 用戶註冊/登陸 (開發者自己集成,SDK 只需要用於區分用戶的 userID)
  • 創建一個會議房間/加入一個會議房間
  • 採集自己的攝像頭/麥克風數據
  • 將採集到的媒體數據發佈到房間中
  • 訂閱房間裏其他人的媒體數據並實時播放
  • 處理用戶加入/離開,發佈/取消發佈

這裏簡化到 SDK 的各個功能,其實就是 加入房間-採集本地媒體流-發佈媒體流-訂閱媒體流-事件處理,SDK 對每個步驟都做了簡單的封裝,使用幾行代碼即可搞定。

引入 SDK

推薦使用 npm 引入我們的 SDK,直接 npm i pili-rtc-web 即可,或者可以選擇直接引入打包好的 js 文件 https://github.com/pili-engineering/QNRTC-Web/blob/master/Release/pili-rtc-web.js

異步處理

實時音視頻是一個強異步的場景,各種各樣的操作因爲涉及到網絡都是異步相關的,爲了讓開發者能夠更好地控制代碼編寫過程中的異步邏輯。SDK 沒有使用繁瑣的 callback 模式,而是使用了現代 Javascript 的 async/await 或者是 Promise 特性來編寫異步代碼,儘量避免了開發過程中回調地獄的情況(以下所有 await 代碼都假定在一個 async 函數包裹之下)。

加入房間

準備完畢後,第一步,加入房間。說是加入房間,抽象後的說法其實是“什麼用戶以什麼身份加入什麼房間”。這裏有 3 個未知量:用戶標識、身份標識(權限)、房間標識。其實整個加入房間的過程需要的未知量還有很多,比如房間隸屬於哪個 APP(應用,不同應用中房間獨立),APP 隸屬於哪個七牛賬戶等等。在這裏我們將這些值統一進行編碼簽名,變成一個 roomToken 提供給前端,端上就只需要通過這個 token 即可加入房間。(token 的生成可以在七牛控制檯完成,也可以使用服務端 SDK 根據需要動態生成)

const myRTC = new QNRTC.QNRTCSession(); // 初始化
await myRTC.joinRoomWithToken(ROOM_TOKEN); // 加入房間

採集本地媒體流

一般採集都會同時採集音頻和視頻,即麥克風和攝像頭,但是根據需求 SDK 也支持純音頻採集或者純視頻採集的模式。調用方法也很簡單,更改一下 options 即可。

const DOM_ELEMENT = ... // 頁面上準備用來播放流的 dom 元素
// 採集本地流
const localStream = await QNRTC.deviceManager.getLocalStream({
    video: { enabled: true },
    audio: { enabled: true },
});
// 播放採集到的流
localStream.play(DOM_ELEMENT)

發佈媒體流

直接將剛剛拿到的流對象作爲參賽,調用 publish 方法即可

await myRTC.publish(localStream);

訂閱媒體流

當加入房間成功後,隨時可以通過訪問 users 成員來獲取當前房間內用戶狀態,如果房間內存在用戶正在發佈且不是自己,那麼我們就可以發起訂閱了

const users = myRTC.users;
users.forEach(async (user) => {
    if (user.published && user.userId !== myRTC.userId) {
        // 訂閱房間其他用戶返回的流數據
        const remoteStream = await myRTC.subscribe(user.userId);
        // 同樣,直接調用 play 就可以播放流了
        remoteStream.play(DOM_ELEMENT);
    } 
});

事件處理

SDK 暴露了豐富的事件列表來滿足絕大多數場景的需求,事件的處理也很簡單,以“有其他用戶發佈”這個事件爲例

// 監聽事件
myRTC.on('user-publish', handleUserPublish);
// 只監聽一次
myRTC.once('user-publish', handleUserPublish);
// 取消某個監聽函數
myRTC.off('user-publish', handleUserPublish);
// 取消所有監聽函數
myRTC.removeAllListeners('user-publish');

具體的事件列表可以參考 https://developer.qiniu.com/rtn/sdk/4423/the-event-list-web

特色功能

除了這些基本的功能,SDK 還提供了很多強大的高級功能,進一步滿足各行各業的使用需求。

屏幕共享

除了直接採集攝像頭,SDK 還支持進行屏幕採集(或者窗口採集)來實現共享屏幕進行會議。並且在屏幕共享和攝像頭採集之間支持無縫切換,保證用戶的使用體驗。

// 屏幕共享
await QNRTC.deviceManager.getLocalStream({
    screen: { enabled: true },
    audio: { enabled: true },
});

直播轉推

對於一個在線會議而言,參與會議討論的可能只有十個人左右,而卻有大部分的人需要實時地觀看這場會議(但不參與實時討論)。這就是實時音視頻和直播兩大塊場景的交集,將少數有實時互動需求的用戶分配到超低延遲( 200ms )的實時音視頻雲上,將大部分只有實時觀看需求的用戶分配到低延遲( 2~3s )的直播雲上,可以最大限度的減少成本滿足需求。同時,實時視頻流被轉推到直播雲上後,就可以使用七牛直播雲的 API 將這些流數據儲存到各個存儲空間中進行長期的保存。完成了一個從 實時互動 到 直播觀看 到最後 轉爲文件存儲(用於點播等等)的完整業務流程。

首先,在實時音視頻雲的控制檯頁面上關聯好相應的直播雲空間,再打開合流轉推的開關。

如果想推送到自定義的 RTMP 地址(不使用七牛直播雲),也通過實時音視頻雲的後端 API 來配置(詳細見文檔)

從零到一,使用實時音視頻 SDK 一起開發一款 Zoom 吧
從零到一,使用實時音視頻 SDK 一起開發一款 Zoom 吧

之後的工作就是 SDK 上了,使用 SDK 開啓直播轉推也非常簡單,加入房間後調用一行代碼即可。

myRTC.setDefaultMergeStream(WIDTH, HEIGHT); // 這裏的 width height 對應上文設置的合流輸出尺寸

使用這個代碼,SDK 將會默認將房間內的所有流平均佈局,最終推送到目標 RTMP 地址實現合流轉推。如果您想自定義畫面佈局,可以使用如下 API:

myRTC.setMergeStreamLayout("目標用戶ID", { w: 100, h: 100, x: 0, y: 0, muted: false, hidden: false });

另外,我們還提供了網頁實時白板的服務,就像 Zoom 一樣,用戶可以在頁面上和房間裏的其他用戶共享一個白板進行輔助演示,同時白板也支持 PPT 和 PDF 的演示。關於這一塊的演示 Demo,可以訪問我們的牛課堂體驗 https://edu-demo.qnsdk.com

以上只是列舉了一款會議軟件常用的功能場景,將這些基本功能和用戶自身的場景集成,一款簡單的會議軟件就能夠輕鬆完成。如果您已經打算開始嘗試並體驗一下,訪問我們的 Demo(見上)會是一個很好的選擇。如果您打算將自己的產品接入到我們實時音視頻中,這裏有一份更爲詳細的實時音視頻應用開發實踐https://developer.qiniu.com/rtn/sdk/5043/rtc-application-development-process,從 html/css 到 js,從每一行代碼到每一個功能都有詳細的解釋和示例,幫助您快速接入。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章