保姆級教程!基於聲網 Web SDK實現音視訊通話及螢幕共享
前言
大家好,我是 @小曾同學,小夥伴們也可以叫我小曾~
如果你想實現一對一音視訊通話和螢幕共享功能,不妨來看看這篇文章,保姆級教程,不需要從零實現,直接整合聲網 SDK 即可輕鬆上手。
本文也分享了我在實踐過程中遇到的一些問題,幫助小夥伴們避坑。如果文章知識點有錯誤的地方,還請大家指正,讓我們一起學習,一起進步~
01 背景介紹
聲網提供了各端豐富的音視訊 SDK,本文將要使用的是 Web 端 SDK。
本篇文章主要給小夥伴們分享如何使用聲網 SDK 實現 Web 端音視訊通話及螢幕共享功能,其中也會涵蓋在實踐過程中遇到的一些問題,以此記錄防止小夥伴們踩坑,同時也希望通過從 0 到 1 實戰的分享,能夠幫助更多的小夥伴。
02 前期準備
在實戰之前,需要有以下準備條件:
- Npm & Node.js
- 前端開發基礎,如 html & CSS & JavaScript
- 註冊聲網賬號,申請聲網APPID、臨時Token ,詳見開始使用聲網平臺。
如果你還沒有聲網賬號,可以通過這裡免費註冊,每個賬戶每月都有10000分鐘免費額度。如果是個人學習/除錯,時長完全夠用。
我個人的開發環境,具體資訊如下:
- MacBook Pro
- Visual Studio Code:v1.75.1
- Npm:v8.19.3
- Node.js:v16.19.0
- 聲網 SDK:v4.2.1 ,sdk的下載可檢視這裡。
- Google Chrome :v110.0.5481.177
03 實戰環節
通過[前期準備],我們已經完成了相關配置,已經擁有了 App ID、Channel、臨時 Token、聲網 SDK,在本次實戰中,主要詳細講解兩個 demo,分別是音視訊通話及螢幕共享連麥。
3.1 實現音視訊通話
在開始實戰之前,先宣告下 Demo 組成架構,
建立一個資料夾名為 Agora_VideoCall,資料夾中包含五個檔案,分別是:
- index.html:用於設計 Web 應用的使用者介面
- index.css:用於設計網頁樣式
- basicVideoCall.js:實現音視訊通話邏輯程式碼,主要通過 AgoraRTCClient 實現
- AgoraRTC_N-4.2.1.js:聲網音視訊SDK
- assets:第三方庫,主要用於設計使用者介面
在 index.html 檔案中匯入聲網SDK,具體內容可檢視詳細程式碼,接下來主要詳細講解音視訊通話及螢幕共享實現邏輯。
<script src="./AgoraRTC-N-4.2.1.js"></script>
3.1.1 實現音視訊通話邏輯
以下程式碼均在 basicVideoCall.js 文字中寫入
1)首先呼叫 AgoraRTC.createClient 方法建立一個 client 物件,也就是建立客戶端物件
var client = AgoraRTC.createClient({ mode: "rtc", codec: "vp8" });
2)定義變數 App ID,Token、Channel、User ID,並使用箭頭函式實現當頁面被呼叫時用於加入音視訊通話通道。
var options = {
appid: null,
channel: null,
uid: null,
token: null
};
$(() => {
var urlParams = new URL(location.href).searchParams;
options.appid = urlParams.get("appid");
options.channel = urlParams.get("channel");
options.token = urlParams.get("token");
options.uid = urlParams.get("uid");
if (options.appid && options.channel) {
$("#uid").val(options.uid);
$("#appid").val(options.appid);
$("#token").val(options.token);
$("#channel").val(options.channel);
$("#join-form").submit();
}
})
3)加入頻道
定義 join 函式主要是將本地音視訊 track 加入一個 RTC 頻道,此時需要在函式中傳入 App ID,Token、Channel、User ID。加入房間後,需要釋出音視訊track,所以還需要建立音視訊 track,並呼叫 publish 方法將這些本地音視訊track物件當作引數釋出到頻道中。
注意注意,在建立音視訊 track 時需要先呼叫 createMicrophoneAudioTrack :通過麥克風採集的音訊建立本地音訊軌道物件;再呼叫 createCameraVideoTrack :通過攝像頭採集的視訊建立本地視訊軌道物件。(如果先呼叫createCameraVideoTrack ,那麼頁面中將不會顯示本地視訊預覽畫面)
建立之後即可呼叫 play 方法展示本地預覽,並呼叫 publish 方法釋出到 RTC 頻道中。注意 play 和 publish 方法的使用沒有先後順序,誰在前在後沒有什麼影響。
async function join() {
[ options.uid, localTracks.audioTrack, localTracks.videoTrack ] = await Promise.all([
// 加入頻道
client.join(options.appid, options.channel, options.token || null, options.uid || null),
// 建立本地音視訊track
//AgoraRTC.createCameraVideoTrack(),
AgoraRTC.createMicrophoneAudioTrack(),
AgoraRTC.createCameraVideoTrack()
]);
localTracks.videoTrack.play("local-player");
$("#local-player-name").text(`localVideo(${options.uid})`);
await client.publish(Object.values(localTracks));
console.log("publish success");
}
4)在頻道中新增或移除遠端使用者邏輯
實現將同頻道的遠端使用者新增到本地介面,當遠端使用者取消釋出時,則從本地將使用者移除。
function handleUserPublished(user, mediaType) {
const id = user.uid;
remoteUsers[id] = user;
subscribe(user, mediaType);
}
function handleUserUnpublished(user, mediaType) {
if (mediaType === 'video') {
const id = user.uid;
delete remoteUsers[id];
$(`#player-wrapper-${id}`).remove();
}
}
5)訂閱遠端音視訊邏輯
當遠端使用者釋出音視訊時,本地使用者需要對其訂閱,從而實現音視訊通話,在 subscribe 函式中需要傳入兩個引數,分別是同頻道遠端使用者 user id 和遠端 mediaType,並呼叫 play 方法,播放遠端使用者音視訊,從而實現一對一連麥。
async function subscribe(user, mediaType) {
const uid = user.uid;
// 訂閱遠端使用者
await client.subscribe(user, mediaType);
console.log("subscribe success");
if (mediaType === 'video') {
const player = $(`
<div id="player-wrapper-${uid}">
<p class="player-name">remoteUser(${uid})</p>
<div id="player-${uid}" class="player"></div>
</div>
`);
$("#remote-playerlist").append(player);
user.videoTrack.play(`player-${uid}`);
}
if (mediaType === 'audio') {
user.audioTrack.play();
}
}
6)監聽事件
當遠端使用者釋出或者取消釋出音視訊 track 時,本地還需要對其監聽,在 join 函式中,監聽 client.on("user-published", handleUserPublished) 事件和 client.on("user-unpublished", handleUserUnpublished) 事件,具體如下
client.on("user-published", handleUserPublished);
client.on("user-unpublished", handleUserUnpublished);
7)離開頻道
當用戶點選 leave 按鈕時,則將 stop 本地和遠端音視訊 track。
async function leave() {
for (trackName in localTracks) {
var track = localTracks[trackName];
if(track) {
track.stop();
track.close();
localTracks[trackName] = undefined;
}
}
3.1.2 Demo展示
接下來可以執行我們的 Demo 啦,輸入 APPID、Token、Channel、Userid,點選 join,即可看到自己本地的畫面,如果想和別人連麥,可以再複製一下網址,輸入相同的 APPID、Token、Channel,即可實現連麥,趕快試試吧。
3.2 螢幕共享連麥
螢幕共享就是將本地使用者的螢幕內容,以視訊畫面的方式分享給其他遠端使用者觀看。其工作原理實際上是通過 createScreenVideoTrack 建立一個螢幕共享的視訊軌道物件來實現。採集螢幕的過程中瀏覽器會詢問需要共享哪些螢幕,根據終端使用者的選擇去獲取螢幕資訊。
在上述音視訊 demo 的基礎上實現螢幕共享功能。
3.2.1 新增螢幕共享UI
在 index.html 頁面中新增螢幕共享(ScreenShare)button
3.2.2 螢幕共享實現邏輯
以下程式碼均在 basicVideoCall.js 文字中寫入
1)實現 share 函式
和上述 join 函式功能類似,主要用於開啟螢幕共享,使用 createScreenVideoTrack 建立螢幕共享的視訊軌道物件,同時也可以對視訊編碼進行一些簡單的配置。函式中同樣也需要新增監聽事件。
async function share() {
client.on("user-published", handleUserPublished);
client.on("user-unpublished", handleUserUnpublished);
let screenTrack;
[options.uid, localTracks.audioTrack, screenTrack] = await Promise.all([
client.join(options.appid, options.channel, options.token || null, options.uid || null),
AgoraRTC.createMicrophoneAudioTrack(),
AgoraRTC.createScreenVideoTrack({
encoderConfig: {
framerate: 15,
height: 720,
width: 1280
}
}, "auto")
]);
2)新增螢幕共享音視訊軌道,並呼叫 play 方法播放本地螢幕共享的視訊。
if(screenTrack instanceof Array){
localTracks.screenVideoTrack = screenTrack[0]
localTracks.screenAudioTrack = screenTrack[1]
}
else{
localTracks.screenVideoTrack = screenTrack
}
localTracks.screenVideoTrack.play("local-player");
$("#local-player-name").text(`localVideo(${options.uid})`);
3)釋出螢幕共享
釋出本地音訊和螢幕共享畫面至 RTC 頻道中。
if(localTracks.screenAudioTrack == null){
await client.publish([localTracks.screenVideoTrack, localTracks.audioTrack]);
}
else{
await client.publish([localTracks.screenVideoTrack, localTracks.audioTrack, localTracks.screenAudioTrack]);
}
4)在 share 函式實現邏輯中需要繫結 "track-ended" 事件,當螢幕共享停止時,會有一個警報通知終端使用者。
localTracks.screenVideoTrack.on("track-ended", () => {
alert(`Screen-share track ended, stop sharing screen ` + localTracks.screenVideoTrack.getTrackId());
localTracks.screenVideoTrack && localTracks.screenVideoTrack.close();
localTracks.screenAudioTrack && localTracks.screenAudioTrack.close();
localTracks.audioTrack && localTracks.audioTrack.close();
});
3.2.3 Demo 展示
當點選 ScreenShare 時,會提示使用者選擇哪一個 page 進行分享,同時也有一個預設音訊選項,點選分享之後,即可釋出螢幕共享。
04 小結
如果你想實現音視訊和螢幕共享的 Web 應用,完全可以借鑑本篇文章 + 聲網SDK,如果不是很熟悉的話,可以先看聲網給出的「快速開始 - 實現音視訊通話」。
在實踐過程中需要注意的是:在建立音視訊 track 時需要先呼叫 createMicrophoneAudioTrack ,再呼叫 createCameraVideoTrack ,如果先呼叫 createCameraVideoTrack 那麼頁面中將不會顯示本地視訊預覽畫面。
Generally,本篇文章給出的 demo 比較簡單,如果想要新增其他的功能比如,虛擬背景、AI降噪等,可以在此基礎上繼續新增功能。
(正文完)
參考資料
• 註冊聲網賬號
- 保姆級教程!整合聲網 SDK 實現 iOS 平臺音視訊通話和虛擬背景功能
- 在 Flutter 多人視訊中實現虛擬背景、美顏與空間音效
- 基於聲網 Flutter SDK 實現互動直播
- 保姆級教程!基於聲網 Web SDK實現音視訊通話及螢幕共享
- 基於聲網 Flutter SDK 實現多人視訊通話
- 把 ChatGPT 加入 Flutter 開發,會有怎樣的體驗?
- 如何基於開源 demo 在 Web 端實現一個多人數獨遊戲
- 《鵝鴨殺》爆火,一文帶你瞭解如何實現頂流社交遊戲
- 聲網許振明:RTC 場景 UHD 視訊應用和探索
- RTE 領域的發展,為視訊編解碼標準帶來哪些新變化?丨Dev for Dev 專欄
- 人臉關鍵點的應用場景及重難點解析丨Dev for Dev 專欄
- 糾刪碼在實時視訊流中的應用丨Dev for Dev 專欄
- 音訊技術的下一個“熱點”,會出現在哪個領域?丨一期一會 • 音訊工程師專場
- 一片紅的泛娛樂出海,藍色在哪裡?
- 聲網“失聲”的危機
- 百鍊成鋼 —— 聲網實時網路的自動運維丨Dev for Dev 專欄
- 桌面軟體開發框架大賞
- 基於物件的實時空間音訊渲染丨Dev for Dev 專欄
- 即時通訊場景下安全合規的實踐和經驗
- 基於 Web SDK 實現視訊通話場景 | 聲網 SDK 教程