Web音視頻通話解決方案 —— Agora Web SDK NG 版接入教程

引言

隨著社會(huì)的發(fā)展呕童,人們對(duì)實(shí)時(shí)音視頻的需求越來(lái)越多崔赌。在線會(huì)議意蛀,電商直播,在線教育等相關(guān)產(chǎn)品不斷涌現(xiàn)健芭。但是對(duì)于個(gè)人開(kāi)發(fā)者或者小團(tuán)隊(duì)來(lái)說(shuō)县钥,自己實(shí)現(xiàn)一個(gè)實(shí)時(shí)音視頻服務(wù)并且要保障服務(wù)穩(wěn)定,滿足低延時(shí)等要求慈迈,難度非常大魁蒜。為此我們需要尋找一個(gè)合適的解決方案。功能強(qiáng)大且可靠的聲網(wǎng)Agora就成為了極佳的選擇吩翻。

今年聲網(wǎng)推出了下一代 Agora Web SDK (Agora Web SDK NG)兜看,基于 TypeScript 開(kāi)發(fā),使用 Promise 來(lái)管理異步操作狭瞎,靈活易用细移。今天我就來(lái)分享一下如何快速接入該SDK并實(shí)現(xiàn)一些簡(jiǎn)單的實(shí)時(shí)音視頻通話。

前期準(zhǔn)備

首先我們需要注冊(cè)一個(gè)聲網(wǎng)賬號(hào)(注冊(cè)地址)熊锭,注冊(cè)成功后會(huì)進(jìn)入控制臺(tái)弧轧,完成實(shí)名認(rèn)證雪侥,在左側(cè)進(jìn)入項(xiàng)目管理頁(yè)面,開(kāi)始創(chuàng)建項(xiàng)目:

創(chuàng)建項(xiàng)目

輸入項(xiàng)目名稱精绎,選擇鑒權(quán)機(jī)制速缨。為了項(xiàng)目安全性考慮,這里推薦使用安全模式代乃。提交后進(jìn)入項(xiàng)目信息頁(yè)面旬牲,記錄一下AppID和證書我們之后在代碼中會(huì)用到。由于我們選擇了安全模式搁吓,在使用SDK時(shí)我們需要生成token原茅,在本地開(kāi)發(fā)調(diào)試時(shí)可以在項(xiàng)目信息頁(yè)面下方點(diǎn)擊生成臨時(shí)token,然后拷貝到代碼中使用堕仔。

生成臨時(shí)token入口
生成臨時(shí)token

在項(xiàng)目發(fā)布時(shí)擂橘,可以參考文檔官方倉(cāng)庫(kù)編寫對(duì)應(yīng)的token生成代碼,部署到自己的服務(wù)器上通過(guò)調(diào)用接口的形式來(lái)獲取token摩骨。

新建項(xiàng)目并集成SDK

前期準(zhǔn)備工作已經(jīng)完成通贞,大家根據(jù)自己的實(shí)際情況來(lái)新建一個(gè)web項(xiàng)目,完成后恼五,我們開(kāi)始通過(guò)npm安裝SDK昌罩。

npm install agora-rtc-sdk-ng --save

你也可以通過(guò)script標(biāo)簽的形式引入SDK。

<script src="https://download.agora.io/sdk/web/AgoraRTC_N-4.1.0.js"></script>
<!-- or -->
<script src="./AgoraRTC_N-4.1.0.js"></script>

之后我們只需要在項(xiàng)目代碼中引入agora-rtc-sdk-ng就可以直接使用了唤冈。

import AgoraRTC from "agora-rtc-sdk-ng";

實(shí)現(xiàn)基礎(chǔ)的1對(duì)1視頻通話

現(xiàn)在我們開(kāi)始來(lái)按步驟實(shí)現(xiàn)基礎(chǔ)的1對(duì)1視頻通話。

1. 創(chuàng)建本地客戶端對(duì)象

首先我們需要?jiǎng)?chuàng)建一個(gè)本地客戶端對(duì)象银伟,由于我們不是直播你虹,mode我們選擇rtc,編碼有H.264和VP8兩種彤避,我這里沒(méi)有兼容性要求傅物,所以選用推薦的VP8,參考官方文檔琉预。

const rtcClient = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });

2. 加入頻道

加入頻道這里需要傳入4個(gè)參數(shù):聲網(wǎng)的項(xiàng)目appid董饰,頻道名稱,如果鑒權(quán)開(kāi)啟了安全模式需要傳入token圆米,最后傳入uid卒暂,uid為null時(shí)SDK會(huì)自動(dòng)生成一個(gè)uid返回給你。

如果你是用app證書通過(guò)自己的代碼生成token娄帖,需要保證頻道名稱和uid與生成token時(shí)保持一致也祠,否則加入頻道會(huì)失敗。

const uid = await rtcClient.join(<appid>, <channel name>, <token>, <uid>);

3. 創(chuàng)建本地音視頻軌道

加入完頻道我們開(kāi)始創(chuàng)建本地音視頻軌道近速,調(diào)用createMicrophoneAudioTrack()通過(guò)本地麥克風(fēng)采集的音頻創(chuàng)建音頻軌道對(duì)象诈嘿,調(diào)用
createCameraVideoTrack()通過(guò)本地?cái)z像頭采集的視頻創(chuàng)建視頻軌道對(duì)象堪旧。你也可以在調(diào)用時(shí)傳入?yún)?shù)來(lái)調(diào)整編碼、前置\后置攝像頭等配置奖亚。同時(shí)這里還需要注意瀏覽器提示或相關(guān)的設(shè)置淳梦,允許瀏覽器訪問(wèn)攝像頭、麥克風(fēng)等設(shè)備昔字,必要時(shí)對(duì)用戶進(jìn)行引導(dǎo)和提示爆袍。

const localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
const localVideoTrack = await AgoraRTC.createCameraVideoTrack();

4. 播放本地音視頻軌道

創(chuàng)建完本地音視頻軌道對(duì)象后,我們可以調(diào)用play()進(jìn)行播放李滴,預(yù)覽一下音頻和視頻螃宙。播放音頻軌道時(shí)不需要傳入任何參數(shù),播放視頻軌道時(shí)需要指定一個(gè)DOM元素所坯,你可以傳入一個(gè)元素對(duì)象谆扎,也可以傳入元素的id值。之后SDK會(huì)自動(dòng)在該元素內(nèi)部生成一個(gè)video元素播放視頻軌道芹助。

<div id="video-container"></div>
// 播放視頻軌道
localVideoTrack.play(document.getElementById('video-container'));
// or
localVideoTrack.play('video-container');

// 播放音頻軌道
localAudioTrack.play();

效果如圖:

本地預(yù)覽

5. 發(fā)布本地音視頻軌道

現(xiàn)在我們需要調(diào)用publish()將我們本地的音視頻軌道發(fā)布到頻道中堂湖,一個(gè)本地客戶端對(duì)象可以發(fā)布多個(gè)音頻軌道,比如:背景音樂(lè)状土、麥克風(fēng)聲音等无蜂,SDK會(huì)自動(dòng)將其合并為一個(gè)音頻軌道發(fā)布到頻道中去,但是一個(gè)本地客戶端對(duì)象只能發(fā)布一個(gè)視頻軌道蒙谓,如果有發(fā)布多個(gè)視頻軌道的需求斥季,你可以創(chuàng)建多個(gè)本地客戶端對(duì)象加入同一個(gè)頻道,然后發(fā)布不同的視頻軌道累驮,但是需要注意區(qū)分2個(gè)client使用的uid酣倾,并在本地訂閱時(shí)過(guò)濾掉,防止重復(fù)訂閱谤专,參考文檔躁锡。

await rtcClient.publish([
    localAudioTrack,
    localVideoTrack
]);

6. 訂閱遠(yuǎn)端用戶并播放遠(yuǎn)端音視頻

現(xiàn)在我們需要監(jiān)聽(tīng)user-published事件,當(dāng)同一頻道的其他用戶調(diào)用publish()發(fā)布音視頻軌道時(shí)置侍,SDK會(huì)觸發(fā)該事件映之,我們需要監(jiān)聽(tīng)這個(gè)事件并在回調(diào)中訂閱其他用戶發(fā)布的音視頻軌道,并調(diào)用play()進(jìn)行播放

<div id="remote-user"></div>
rtcClient.on("user-published", async (user, mediaType) => {
    await rtcClient.subscribe(user, mediaType);
    if (mediaType === "video") {
        console.log("subscribe video success", user);
        user.videoTrack.play(document.getElementById('remote-user'));
    }
    if (mediaType === "audio") {
        console.log("subscribe audio success");
        user.audioTrack.play();
    }
});

效果如下圖蜡坊,上方是我們本地的攝像頭畫面杠输,下方為遠(yuǎn)端的攝像頭畫面,到這里為止一個(gè)基礎(chǔ)的1對(duì)1視頻通話已經(jīng)完成了秕衙!

視頻通話效果圖

通話質(zhì)量監(jiān)測(cè)

對(duì)于實(shí)時(shí)音視頻來(lái)說(shuō)抬伺,保障通話質(zhì)量是很重要的一環(huán),在SDK中提供了相關(guān)的api供我們查詢當(dāng)前的通話質(zhì)量灾梦,文檔峡钓,通過(guò)使用這些api妓笙,客戶端可以及時(shí)采取措施,給予用戶及時(shí)的提示和反饋能岩。避免影響用戶的使用體驗(yàn)创南。

聲網(wǎng)控制臺(tái)還有水晶球面板递沪,里面提供了豐富的通話質(zhì)量數(shù)據(jù)查詢功能,開(kāi)發(fā)者可以使用這個(gè)工具更全面的掌握通話質(zhì)量狀況。

水晶球截圖

小拓展

多個(gè)音頻軌道

上文中有提到忆谓,一個(gè)客戶端對(duì)象可以發(fā)布多個(gè)音頻軌道舰始,沒(méi)有先后順序闸衫,可以多次通過(guò)調(diào)用publish()進(jìn)行發(fā)布屹蚊,SDK會(huì)自動(dòng)合并為一個(gè)音頻軌道發(fā)布到頻道中。下面我們就通過(guò)自定義音頻采集以及MediaStreamTrack API往通話中播放一個(gè)本地音頻文件作為背景音樂(lè)坝辫。

1. 創(chuàng)建HTMLAudioElement

我們?cè)谇懊婊A(chǔ)音視頻通話代碼的基礎(chǔ)上進(jìn)行修改篷就,首先創(chuàng)建一個(gè)button確保用戶,讓用戶點(diǎn)擊后再播放音頻文件近忙,確保用戶與頁(yè)面有一個(gè)交互行為竭业。并監(jiān)聽(tīng)對(duì)應(yīng)的點(diǎn)擊事件。

<button id="addMusic">添加音樂(lè)</button>
document.getElementById("addMusic").addEventListener("click", () => {
    const audio = new Audio("./music.ogg");
    audio.play();
});

2. 獲取音頻軌道并發(fā)布

調(diào)用captureStream()獲取MediaStream對(duì)象及舍,監(jiān)聽(tīng)addtrack事件未辆,觸發(fā)時(shí)調(diào)用getAudioTracks()獲取MediaStreamTrack對(duì)象的集合,由于我的音頻文件只有一個(gè)音軌锯玛,所以這里直接取第1個(gè)元素咐柜。使用createCustomAudioTrack()將獲取到的MediaStreamTrack轉(zhuǎn)換為一個(gè)可以用于SDK的音頻軌道,最后使用客戶端對(duì)象的publish()發(fā)布攘残。結(jié)合之前的音視頻通話拙友,此時(shí)在遠(yuǎn)端已經(jīng)能正常收聽(tīng)到2個(gè)音軌的聲音了(麥克風(fēng)和音樂(lè)文件)。

document.getElementById("addMusic").addEventListener("click", () => {
    const audio = new Audio("./music.ogg");
    audio.play();
    const musicStream = audio.captureStream();
    const musicStream.onaddtrack = async () => {
        const musicMediaStreamTrack = musicStream.getAudioTracks()[0];
        const musicCustomAudioTrack = AgoraRTC.createCustomAudioTrack({
            mediaStreamTrack: musicMediaStreamTrack
        });
        await rtClient.publish([musicCustomAudioTrack])        
    };
});

自定義視頻采集

和音頻一樣肯腕,SDK也支持你使用自定義的視頻軌道來(lái)實(shí)現(xiàn)如屏幕錄制献宫,播放本地視頻文件等功能钥平。屏幕錄制在官方文檔中有介紹实撒,這里我分享一下如何獲取并發(fā)布一個(gè)本地視頻文件的視頻軌道。

一個(gè)客戶端對(duì)象只支持發(fā)布一個(gè)視頻軌道涉瘾,同時(shí)發(fā)布多個(gè)(比如錄屏+攝像頭畫面)需要?jiǎng)?chuàng)建2個(gè)客戶端對(duì)象分別進(jìn)行發(fā)布知态。

1. 創(chuàng)建video元素

首先我們創(chuàng)建一個(gè)video元素用于播放視頻文件,并獲取到HTMLVideoElement對(duì)象立叛。

<video id="videoFile" src="./video.mp4" control>
const video = document.getElementById('video');

2. 獲取并發(fā)布視頻文件的媒體流

這一步和獲取音頻文件媒體流類似负敏,我們分別發(fā)布了視頻和音頻軌道后的效果如圖。畫面上方的A端播放的視頻文件秘蛇,畫面下方是B端的攝像頭畫面

視頻文件包含視頻軌道和音頻軌道其做,我們需要分別獲取對(duì)應(yīng)的軌道進(jìn)行發(fā)布顶考,如果只發(fā)布了視頻軌道會(huì)導(dǎo)致遠(yuǎn)端沒(méi)有視頻聲音

const stream = video.captureStream();
stream.onaddtrack = async () => {
    const videoMediaStreamTrack = stream.getVideoTracks()[0];
    const audioMediaStreamTrack = stream.getAudioTracks()[0];
    const videoTrack = AgoraRTC.createCustomVideoTrack({
        mediaStreamTrack: videoMediaStreamTrack
    });
    const audioTrack = AgoraRTC.createCustomAudioTrack({
        mediaStreamTrack: audioMediaStreamTrack
    });
    await this.rtc.client!.publish([videoTrack,audioTrack]);
};
自定義視頻效果圖

結(jié)尾

聲網(wǎng)的Agora Web SDK NG 版接入是十分便捷的,簡(jiǎn)單易上手妖泄,功能強(qiáng)大驹沿,文檔清晰。SDK也在github上開(kāi)源蹈胡。每個(gè)月還有10000分鐘的免費(fèi)額度渊季,他們也會(huì)不定期舉辦一些套餐包優(yōu)惠活動(dòng)。通話質(zhì)量也有可靠的保障罚渐。對(duì)于個(gè)人或小團(tuán)隊(duì)來(lái)說(shuō)實(shí)現(xiàn)音視頻通話不再是很困難的一件事了却汉。總結(jié)一下就是:真香荷并。如果你和你的團(tuán)隊(duì)有這方面的需求合砂,不妨也來(lái)試試使用聲網(wǎng)。

「本文為個(gè)人原創(chuàng)璧坟,首發(fā)于聲網(wǎng)開(kāi)發(fā)者社區(qū)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載既穆,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。
  • 序言:七十年代末雀鹃,一起剝皮案震驚了整個(gè)濱河市幻工,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黎茎,老刑警劉巖囊颅,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異傅瞻,居然都是意外死亡踢代,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門嗅骄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)胳挎,“玉大人,你說(shuō)我怎么就攤上這事溺森∧脚溃” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵屏积,是天一觀的道長(zhǎng)医窿。 經(jīng)常有香客問(wèn)我,道長(zhǎng)炊林,這世上最難降的妖魔是什么姥卢? 我笑而不...
    開(kāi)封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上独榴,老公的妹妹穿的比我還像新娘僧叉。我一直安慰自己,他們只是感情好棺榔,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布彪标。 她就那樣靜靜地躺著,像睡著了一般掷豺。 火紅的嫁衣襯著肌膚如雪捞烟。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天当船,我揣著相機(jī)與錄音题画,去河邊找鬼。 笑死德频,一個(gè)胖子當(dāng)著我的面吹牛苍息,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播壹置,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼竞思,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了钞护?” 一聲冷哼從身側(cè)響起盖喷,我...
    開(kāi)封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎难咕,沒(méi)想到半個(gè)月后课梳,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡余佃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年暮刃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片爆土。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡椭懊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出步势,到底是詐尸還是另有隱情氧猬,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布立润,位于F島的核電站狂窑,受9級(jí)特大地震影響媳板,放射性物質(zhì)發(fā)生泄漏桑腮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一蛉幸、第九天 我趴在偏房一處隱蔽的房頂上張望破讨。 院中可真熱鬧丛晦,春花似錦、人聲如沸提陶。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)隙笆。三九已至锌蓄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間撑柔,已是汗流浹背瘸爽。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铅忿,地道東北人剪决。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像檀训,于是被迫代替她去往敵國(guó)和親柑潦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1:點(diǎn)對(duì)點(diǎn)視頻:支持美顏峻凫;音頻對(duì)話渗鬼,視頻對(duì)話,預(yù)先呼叫荧琼,監(jiān)看模式乍钻。 2:多人視頻(視頻會(huì)議):傳統(tǒng)多人模式:主持人...
    DerekStrong閱讀 2,042評(píng)論 2 50
  • 目錄如下: 音視頻基礎(chǔ)技術(shù)棧 ? 抖音/快手等短視頻APP的風(fēng)靡,讓音視頻成為當(dāng)下最火熱的技術(shù)铭腕,越來(lái)越多的人想...
    LukiYLS閱讀 811評(píng)論 1 0
  • 5月以來(lái)析孽,哪怕對(duì)市場(chǎng)風(fēng)向再不敏感的人,也感覺(jué)到陣陣涼意只怎。二級(jí)市場(chǎng)連續(xù)下挫袜瞬,一級(jí)市場(chǎng)融資環(huán)境惡化,不論企業(yè)融資數(shù)量還...
    錢皓頻道閱讀 6,030評(píng)論 1 6
  • 推薦指數(shù): 6.0 書籍主旨關(guān)鍵詞:特權(quán)身堡、焦點(diǎn)邓尤、注意力、語(yǔ)言聯(lián)想、情景聯(lián)想 觀點(diǎn): 1.統(tǒng)計(jì)學(xué)現(xiàn)在叫數(shù)據(jù)分析汞扎,社會(huì)...
    Jenaral閱讀 5,705評(píng)論 0 5
  • 昨天季稳,在回家的路上,坐在車?yán)镉圃沼圃盏乜粗摹度龉衬墓适隆烦浩牵冶焕锩娴膬?nèi)容深深吸引住了景鼠,盡管上學(xué)時(shí)...
    夜闌曉語(yǔ)閱讀 3,782評(píng)論 2 9