【實作紀錄】Agora × Angular 視訊通話

Ray
10 min readOct 16, 2021

--

透過Agora的服務可以實現即時的通訊。本文使用Agora的服務搭配Angular來實現視訊通話。

分成幾個部分來說明

  1. Agora控制台 項目設定
  2. Angular程式部分
  • 前置設定(架構、SDK安裝)
  • 核心程式碼(主要流程)

3. 補充

Agora控制台

1.註冊成功後,點擊創建項目,新增一個新的項目

2.接著項目名稱、使用場景自訂

這邊需要注意的是,調試模式跟安全模式的差別在:「調適模式只需要APP ID就可以加入房間,而安全模式則額外需要Token才能進入」,這邊我選安全模式

3.複製APP ID

點擊眼睛圖示複製

4.建立頻道Token

如果剛剛選的是安全模式,則需要取得頻道Token。點擊鑰匙

輸入頻道名後取得該頻道的Token(之後要進入此房間就需要這個Token)

此時我們手上已經有三個東西,APP ID 、 Channel Name 以及 Token。

Angular 前置設定

1.新增專案以及Component、Service

架構說明

  • 建立一Component負責提供視訊相關邏輯(初始化RTC、負責顯示視訊畫面之HTML)
ng g c agora-io
  • 建立一Service提供Component呼叫,將Agora相關方法抽離至此
ng g s metting
  • app.component不處理任何事,只將agora-io.component引入至HTML

2.安裝SDK

npm install agora-rtc-sdk-ng --save // 這邊安裝的SDK版本是4.x

3.引入agora-rtc-sdk-ng至meeting.service

import AgoraRTC, 
{
IAgoraRTC,
IAgoraRTCClient,
ICameraVideoTrack,
ILocalAudioTrack,
ILocalVideoTrack,
IMicrophoneAudioTrack,
UID
}
from “agora-rtc-sdk-ng”

TypeScript的關係,我們需要引入agora所提供的Interface來規範我們的程式碼

Angular 核心程式碼

基本流程(文檔)

  1. 根據項目的 App ID 創建一個本地客戶端 AgoraRTCClient 對象。
  2. 通過 AgoraRTCClient.join 加入到一個指定的頻道中。
  3. 通過麥克風採集的音頻創建一個 MicrophoneAudioTrack 對象(本地音頻軌道對象)。
  4. 通過 AgoraRTCClient.publish 將創建的本地音頻軌道對象發布到頻道中。

接著我們照著上面的步驟一步一步來,首先...

1.根據項目的 App ID 創建一個本地客戶端 AgoraRTCClient 對象。

Meeting.servcie

先建立一個rtc本地端的起始參數及其對應到的interface

private rtc: { 
client: IAgoraRTCClient | null,
localAudioTrack: IMicrophoneAudioTrack | null,
localVideoTrack: ICameraVideoTrack | null,
localScreenVideoTrack: ILocalVideoTrack | null, localScreenAudioTrack: ILocalAudioTrack | null,
uid: UID | null
} = {
client: null,localAudioTrack: null,localVideoTrack: null,localScreenVideoTrack: null,localScreenAudioTrack: null,uid: null};

實現剛剛建立的變數

initRTCClient(): IAgoraRTCClient {   if (!this.rtc.client) {    this.rtc.client = AgoraRTC.createClient({ 
mode: “rtc”,
codec: “vp8”
});
} return this.rtc.client;}
  • mode 用於設置頻道場景,直播使用"live",通話使用"rtc"
  • codec 用於設置瀏覽器使用的編解碼格式。

2.通過 AgoraRTCClient.join 加入到一個指定的頻道中。

Meeting.service

async joinRTCChannel(channel: string, uid?: string): Promise<UID | null | undefined> {  this.rtc.uid = await this.rtc.client.join(options.appId, options.channel, options.token, null)  return this.rtc.uid;}

這邊.join後依序填入從Agora控制台取得的AppID、頻道名稱、頻道Token

  • uid代表進房的使用者編號,必須是唯一的,可以給null讓系統自動分配
  • 如果選的是調試模式,Token可以給null。否則則為必填

3.通過麥克風採集的音頻創建一個 MicrophoneAudioTrack 對象(本地音頻軌道對象)。

Meeting.service

建立麥克風對象

async createAudioTrack(): Promise<ILocalAudioTrack | null | undefined> {  this.rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();  return this.rtc.localAudioTrack;}

建立鏡頭對象

async createVideoTrack(): Promise<ILocalVideoTrack | null | undefined> {  this.rtc.localVideoTrack = await AgoraRTC.createCameraVideoTrack();  return this.rtc.localVideoTrack;}

4.通過 AgoraRTCClient.publish 將創建的本地音頻軌道對象發布到頻道中。

async publish() {  if (this.rtc.localAudioTrack && this.rtc.localVideoTrack) {    await this.rtc.client.publish([this.rtc.localAudioTrack, this.rtc.localVideoTrack]);    console.log(‘publish成功’)  }}

以上步驟,就已經完成將自己的影音資訊透過Agora的軌道送至頻道中了,接著就是獲取他人的軌道資訊,訂閱的部分。

5.訂閱他人

agora-io.component

主要的訂閱事件為user-published,因為根據上面的流程,我們會在初始話的時候將本地端的影音流推送至頻道,而這會觸發其他人的user-published,可以透過user-published這個事件提供的res參數(user,mediaType)來執行我們想要的結果。

下面這段程式碼"subscribeRTCEvent()"的意思為:

如果加入的是video(視訊)則將該使用者的視訊資料綁訂到我們agora-io.HTML預先設定好的Div中進行撥放

<div id=”play-div” class=”player”></div>

如果加入的是audio(音訊)則將該加入的使用者所送出的資料直接在頻道內進行撥放,就可以聽到該使用者的音樂。

subscribeRTCEvent(): void {this.meetingService.getRTCClient()!.on(“user-published”, async (user, mediaType) => {    await this.meetingService.getRTCClient()!.subscribe(user, mediaType);    console.log(“subscribe success”, “type:” + mediaType);    if (mediaType === “video”) {        const playerContainer = document.getElementById(`play-div`);        playerContainer && user.videoTrack?.play(playerContainer);    }    if (mediaType === “audio”) {        const remoteAudioTrack = user.audioTrack;        remoteAudioTrack?.play();    }}); }

這樣就完成視訊的功能了

6.agora.component

補充agora.component控制Service的程式碼

在ngOnInit()呼叫initRTC(),step的部分請與上面(或文檔)對著看

async initRTC() {  // step 1 創建本地端  const client = this.meetingService.initRTCClient();  // step 2 加入頻道  await this.meetingService.joinRTCChannel(“Test”);  // step 3 建立視訊對象及音訊對象  Promise.all([this.meetingService.createAudioTrack(), this.meetingService.createVideoTrack()]).then(() => {  // step 4    this.meetingService.publish(); // 發布本地影音流至頻道
this.subscribeRTCEvent(); // 訂閱事件
}).catch((err)=>{ console.log(‘Init失敗’,err) })}

補充

1.檢查是否work

程式碼寫好後若要測試功能是否正常,可以開啟一個Chrome正常網頁以及Chrome無痕網頁,同時開啟ng serve後的網址查看是否正常。

注意:使用ng serve --host,就算同網域(如192.168.xx.xx)也是無法連進來的,因為安全考慮,agora只提供localhost或者HTTPS進行溝通,並不提供http://192.168.xx.xx這種類型的網址進行連接。

因此,建議的方法是佈署上Heroku。

2.Console正常,有訂閱到他人的視訊及音訊,但畫面沒有東西

請確認agora.component.html是否有設定提供影片撥放使用的Div,以及該DIV的CSS大小是否正確。(這邊提供範例)

<div 
id="play-div"
style=
"
width: 50vw;
height: 50vh;
background-color: bisque;
"
>
</div>

--

--

No responses yet