最新欧美精品一区二区三区,在线天堂中文最新版,亚洲一,二,三区在线观看,制服丝袜另类专区制服,亚洲熟妇少妇任你躁在线观看无码

WebRTC實(shí)現(xiàn)簡單音視頻通話能力

1 WebRTC音視頻通話功能簡介

本文介紹如何基于WebRTC快速實(shí)現(xiàn)一個(gè)簡單的實(shí)時(shí)音視頻通話。

在開始之前,您可以先了解一些實(shí)時(shí)音視頻推拉流相關(guān)的基礎(chǔ)概念:

  • 流:一組按指定編碼格式封裝的音視頻數(shù)據(jù)內(nèi)容。一個(gè)流可以包含幾個(gè)軌道,比如視頻和音頻軌道。
  • 推流:把采集階段封包好的音視頻數(shù)據(jù)流推送到 ZEGO 實(shí)時(shí)音視頻云的過程。
  • 拉流:從 ZEGO 實(shí)時(shí)音視頻云將已有音視頻數(shù)據(jù)流拉取播放的過程。
  • 房間:是 ZEGO 提供的音視頻空間服務(wù),用于組織用戶群,同一房間內(nèi)的用戶可以互相收發(fā)實(shí)時(shí)音視頻及消息。
  1. 用戶需要先登錄某個(gè)房間,才能進(jìn)行音視頻推流、拉流操作。
  2. 用戶只能收到自己所在房間內(nèi)的相關(guān)消息(用戶進(jìn)出、音視頻流變化等)。

更多相關(guān)概念可參考即構(gòu)官網(wǎng)關(guān)于音視頻SDK的介紹 術(shù)語說明。 https://doc-zh.zego.im/article/5390?source=partnershare

2 實(shí)現(xiàn)WebRTC視頻通話的前提條件

在實(shí)現(xiàn)基本的WebRTC實(shí)時(shí)音視頻功能之前,請(qǐng)確保:

  • 已在項(xiàng)目中集成 ZEGO Express SDK,詳情請(qǐng)參考 快速開始 - 集成。 https://doc-zh.zego.im/article/199?source=partnershare
  • 已在 ZEGO 控制臺(tái) 創(chuàng)建項(xiàng)目,申請(qǐng)有效的 AppID 和 ServerSecret,詳情請(qǐng)參考 控制臺(tái) - 項(xiàng)目管理 中的“項(xiàng)目信息”。 https://doc-zh.zego.im/article/12107?source=partnershare

3 WebRTC音視頻通話示例代碼

我們提供了一個(gè)實(shí)現(xiàn)了WebRTC音視頻通話基本流程的完整示例 HTML 文件,可作為WebRTC開發(fā)過程中的參考。

<!DOCTYPE html>

<html>


<head>

   <meta charset="UTF-8">

   <title>Zego Express Video Call</title>

   <!-- 此處需要改成正確的 SDK 版本號(hào) -->

   <script src="ZegoExpressWebRTC-x.x.x.js"></script>


   <style type="text/css">

       h1,

       h4 {

           text-align: center;

       }


       .video-wrapper {

           width: 610px;

           margin: 0 auto;

       }


       .video-wrapper h4 {

           width: 300px;

           display: inline-block;

           position: relative;

       }

       #remote-video, #local-video {

           width: 300px;

           height: 270px;

           display: inline-block;

           position: relative;

       }


       .video-wrapper video {

           height: auto;

       }

   </style>

</head>


<body>

   <h1>

       Zego RTC Video Call

   </h1>

   <div class="video-wrapper">

       <h4>Local video</h4>

       <h4>Remote video</h4>

       <div id="local-video"></div>

       <div id="remote-video"></div>

   </div>

   <script>

       // 文檔中的 js 示例代碼可粘貼至此處

       // 項(xiàng)目唯一標(biāo)識(shí) AppID,Number 類型,請(qǐng)從 ZEGO 控制臺(tái)獲取

       let appID = 0

       // 接入服務(wù)器地址 Server,String 類型,請(qǐng)從 ZEGO 控制臺(tái)獲?。ǐ@取方式請(qǐng)參考上文“前提條件”)

       let server = ""


       // 初始化實(shí)例

       const zg = new ZegoExpressEngine(appID, server);

       zg.setDebugVerbose(false)

       // 房間狀態(tài)更新回調(diào)

       // 此處在登錄房間成功后,立即進(jìn)行推流。在實(shí)現(xiàn)具體業(yè)務(wù)時(shí),您可選擇其他時(shí)機(jī)進(jìn)行推流,只要保證當(dāng)前房間連接狀態(tài)是連接成功的即可。

       // 房間狀態(tài)更新回調(diào)

       zg.on('roomStateChanged', async (roomID, reason, errorCode, extendedData) => {

           if (reason == 'LOGINED') {

               console.log("與房間連接成功,只有當(dāng)房間狀態(tài)是連接成功時(shí),才能進(jìn)行推流、拉流等操作。")

           }

       })


       zg.on('roomUserUpdate', (roomID, updateType, userList) => {

           // 其他用戶進(jìn)出房間的通知

       });


       zg.on('roomStreamUpdate', async (roomID, updateType, streamList, extendedData) => {

           // 房間內(nèi)其他用戶音視頻流變化的通知

           if (updateType == 'ADD') {

               // 流新增,開始拉流

               // 此處演示拉取流新增的列表中第一條流的音視頻

               const streamID = streamList[0].streamID;

               // streamList 中有對(duì)應(yīng)流的 streamID

               const remoteStream = await zg.startPlayingStream(streamID);

               // 創(chuàng)建媒體流播放組件

               const remoteView = zg.createRemoteStreamView(remoteStream);

               remoteView.play("remote-video", {enableAutoplayDialog:true});


           } else if (updateType == 'DELETE') {

               // 流刪除,通過流刪除列表 streamList 中每個(gè)流的 streamID 進(jìn)行停止拉流。

               const streamID = streamList[0].streamID;

               zg.stopPlayingStream(streamID)

           }

       });


       // 登錄房間,成功則返回 true

       // userUpdate 設(shè)置為 true 才能收到 roomUserUpdate 回調(diào)。

       let userID = "user1"; // userID 用戶自己設(shè)置,必須保證全局唯一

       let userName = "user1";// userName 用戶自己設(shè)置,沒有唯一性要求

       let roomID = "123"; // roomID 用戶自己設(shè)置,必須保證全局唯一

       // token 由用戶自己的服務(wù)端生成,為了更快跑通流程,可以通過即構(gòu)控制臺(tái) https://console.zego.im/ 獲取臨時(shí)的音視頻 token,token 為字符串

       let token = ``;


       zg.loginRoom(roomID, token, { userID, userName: userID }, { userUpdate: true }).then(async result => {

           if (result == true) {

               console.log("login success");

               // 與房間連接成功,只有當(dāng)房間狀態(tài)是連接成功時(shí),才能進(jìn)行推流、拉流等操作。

               // 創(chuàng)建流、預(yù)覽

               // 調(diào)用 createStream 接口后,需要等待 ZEGO 服務(wù)器返回流媒體對(duì)象才能執(zhí)行后續(xù)操作

               const localStream = await zg.createStream();

               // 創(chuàng)建媒體流播放組件

               const localView = zg.createLocalStreamView(localStream);

               localView.play("local-video", {enableAutoplayDialog:true});

               // 開始推流,將自己的音視頻流推送到 ZEGO 音視頻云,此處 streamID 由用戶定義,需全局唯一

               let streamID = new Date().getTime().toString();

               zg.startPublishingStream(streamID, localStream)

           }

       });

       // // 登錄房間的第二種寫法

       // (async function main(){

       //     await zg.loginRoom(roomID, token, { userID, userName: userID }, { userUpdate: true })

       // })()

   </script>

</body>


</html>

4 WebRTC音視頻通話實(shí)現(xiàn)流程

以用戶 A 拉取用戶 B 的流為例,一次簡單的WebRTC實(shí)時(shí)音視頻通話主要流程如下:

  • 用戶 A 創(chuàng)建實(shí)例,登錄房間。(登錄成功后,可預(yù)覽自己的畫面并推流。)
  • 用戶 B 創(chuàng)建實(shí)例,登錄同一個(gè)房間。登錄成功后,用戶 B 開始推流,此時(shí) SDK 會(huì)觸發(fā) roomStreamUpdate 回調(diào),表示房間內(nèi)有流的變化。
  • 用戶 A 可通過監(jiān)聽 roomStreamUpdate 回調(diào),當(dāng)回調(diào)通知有流新增時(shí),獲取用戶 B 的流 ID,來拉取播放用戶 B 剛剛推送的流。

ZEGO 實(shí)時(shí)音視頻文章圖片

4.1 創(chuàng)建WebRTC實(shí)時(shí)音視頻通話界面

為方便實(shí)現(xiàn)基本的WebRTC實(shí)時(shí)音視頻功能,您可參考WebRTC實(shí)時(shí)音視頻的示例代碼和下圖實(shí)現(xiàn)一個(gè)簡單實(shí)時(shí)音視頻功能的頁面。

ZEGO 實(shí)時(shí)音視頻文章圖片

打開或新建 “index.html” 頁面文件,并拷貝以下代碼到文件中。

<html>


<head>

   <meta charset="UTF-8">

   <title>Zego Express Video Call</title>

   <style type="text/css">

       * {

           font-family: sans-serif;

       }


       h1,

       h4 {

           text-align: center;

       }


       #local-video, #remote-video {

           width: 400px;

           height: 300px;

           border: 1px solid #dfdfdf;

       }


       #local-video {

           position: relative;

           margin: 0 auto;

           display: block;

       }


       #remote-video {

           display: flex;

           margin: auto;

           position: relative !important;

       }

   </style>

</head>


<body>

   <h1>

       Zego RTC Video Call

   </h1>

   <h4>Local video</h4>

   <div id="local-video"></div>

   <h4>Remote video</h4>

   <div id="remote-video"></div>

   <script>

   // 文檔中的 js 示例代碼可粘貼至此處

   // const zg = new ZegoExpressEngine(appID, server);

   </script>

</body>

</html>

4.2 創(chuàng)建引擎并監(jiān)聽回調(diào)

  • 創(chuàng)建并初始化一個(gè) ZegoExpressEngine 的實(shí)例,將您項(xiàng)目的 AppID 傳入?yún)?shù) “appID”,Server 傳入?yún)?shù) “server”。
  • 即構(gòu)實(shí)時(shí)音視頻SDK 提供如房間連接狀態(tài)、音視頻流變化、用戶進(jìn)出等通知回調(diào)。為避免錯(cuò)過任何通知,您需要在創(chuàng)建 ZegoExpressEngine 后立即監(jiān)聽回調(diào)。

// 項(xiàng)目唯一標(biāo)識(shí) AppID,Number 類型,請(qǐng)從 ZEGO 控制臺(tái)獲取

let appID = ;

// 接入服務(wù)器地址 Server,String 類型,請(qǐng)從 ZEGO 控制臺(tái)獲?。ǐ@取方式請(qǐng)參考上文“前提條件”)

let server = "";


// 初始化實(shí)例

const zg = new ZegoExpressEngine(appID, server);


// 房間狀態(tài)更新回調(diào)

zg.on('roomStateChanged', (roomID, reason, errorCode, extendData) => {

       if (reason == 'LOGINING') {

           // 登錄中

       } else if (reason == 'LOGINED') {

           // 登錄成功

           //只有當(dāng)房間狀態(tài)是登錄成功或重連成功時(shí),推流(startPublishingStream)、拉流(startPlayingStream)才能正常收發(fā)音視頻

           //將自己的音視頻流推送到 ZEGO 音視頻云

       } else if (reason == 'LOGIN_FAILED') {

           // 登錄失敗

       } else if (reason == 'RECONNECTING') {

           // 重連中

       } else if (reason == 'RECONNECTED') {

           // 重連成功

       } else if (reason == 'RECONNECT_FAILED') {

           // 重連失敗

       } else if (reason == 'KICKOUT') {

           // 被踢出房間

       } else if (reason == 'LOGOUT') {

           // 登出成功

       } else if (reason == 'LOGOUT_FAILED') {

           // 登出失敗

       }

});


//房間內(nèi)其他用戶進(jìn)出房間的通知

//只有調(diào)用 loginRoom 登錄房間時(shí)傳入 ZegoRoomConfig,且 ZegoRoomConfig 的 userUpdate 參數(shù)為 “true” 時(shí),用戶才能收到 roomUserUpdate回調(diào)。

zg.on('roomUserUpdate', (roomID, updateType, userList) => {

   if (updateType == 'ADD') {

       for (var i = 0; i < userList.length; i++) {

           console.log(userList[i]['userID'], '加入了房間:', roomID)

       }

   } else if (updateType == 'DELETE') {

       for (var i = 0; i < userList.length; i++) {

           console.log(userList[i]['userID'], '退出了房間:', roomID)

       }

   }

});


zg.on('roomStreamUpdate', async (roomID, updateType, streamList, extendedData) => {

   // 房間內(nèi)其他用戶音視頻流變化的通知

});

4.3 檢測瀏覽器WebRTC兼容性

考慮到不同的瀏覽器對(duì) WebRTC 的兼容性不同,在實(shí)現(xiàn)實(shí)時(shí)音視頻推拉流功能之前,您需要檢測瀏覽器能否正常運(yùn)行 WebRTC。

您可以調(diào)用 checkSystemRequirements 接口檢測瀏覽器的兼容性,檢測結(jié)果的含義,請(qǐng)參考 ZegoCapabilityDetection 接口下的參數(shù)描述。

const result = await zg.checkSystemRequirements();

// 返回的 result 為兼容性檢測結(jié)果。 webRTC 為 true 時(shí)表示支持 webRTC,其他屬性含義可以參考接口 API 文檔。

console.log(result);

// {

//   webRTC: true,

//   customCapture: true,

//   camera: true,

//   microphone: true,

//   videoCodec: { H264: true, H265: false, VP8: true, VP9: true },

//   screenSharing: true,

//   errInfo: {}

// }

您還可以通過 ZEGO 提供的實(shí)時(shí)音視頻推拉流在線檢測工具 在線檢測工具,在需要檢測的瀏覽器中打開,直接檢測瀏覽器的兼容性。請(qǐng)參考 瀏覽器兼容性說明 獲取 音視頻SDK 支持的瀏覽器兼容版本。

4.4 登錄房間

1. 生成 Token

登錄房間需要用于驗(yàn)證身份的 Token,開發(fā)者可直接在 ZEGO 控制臺(tái)獲取臨時(shí) Token(有效期為 24 小時(shí))來使用,詳情請(qǐng)參考 控制臺(tái) - 項(xiàng)目管理 中的 “項(xiàng)目信息”。

臨時(shí) Token 僅供調(diào)試,正式上線前,請(qǐng)從開發(fā)者的業(yè)務(wù)服務(wù)器生成 Token,詳情可參考 使用 Token 鑒權(quán)。

2. 登錄房間

調(diào)用 loginRoom 接口,傳入房間 ID 參數(shù) “roomID”、“token” 和用戶參數(shù) “user”,根據(jù)實(shí)際情況傳入?yún)?shù) “config”,登錄房間。

  • “roomID”、“userID” 和 “userName” 參數(shù)的取值都為自定義。
  • “roomID” 和 “userID” 都必須唯一,建議開發(fā)者將 “userID” 設(shè)置為一個(gè)有意義的值,可將其與自己的業(yè)務(wù)賬號(hào)系統(tǒng)進(jìn)行關(guān)聯(lián)。
  • 只有調(diào)用 loginRoom 接口登錄房間時(shí)傳入 ZegoRoomConfig 配置,且 “userUpdate” 參數(shù)取值為 “true” 時(shí),用戶才能收到 roomUserUpdate 回調(diào)。

// 登錄房間,成功則返回 true

// userUpdate 設(shè)置為 true 才能收到 roomUserUpdate 回調(diào)。


let userID = Util.getBrow() + '_' + new Date().getTime();

let userName = "user0001";

let roomID = "0001";

let token = ;

// 為避免錯(cuò)過任何通知,您需要在登錄房間前先監(jiān)聽用戶加入/退出房間、房間連接狀態(tài)變更、推流狀態(tài)變更等回調(diào)。

zg.on('roomStateChanged', async (roomID, reason, errorCode, extendedData) => {


})

zg.loginRoom(roomID, token, { userID, userName: userID }, { userUpdate: true }).then(result => {

    if (result == true) {

       console.log("login success")

    }

});

您可以監(jiān)聽 roomStateChanged 回調(diào)實(shí)時(shí)監(jiān)控自己與房間的連接狀態(tài)。只有當(dāng)房間狀態(tài)是連接成功時(shí),才能進(jìn)行推流、拉流等操作。

4.5 預(yù)覽自己的畫面,并推送到 ZEGO 音視頻云

創(chuàng)建流并預(yù)覽自己的畫面

開始推流前需要?jiǎng)?chuàng)建本端的音視頻流,調(diào)用 createStream 接口獲取媒體流對(duì)象,默認(rèn)會(huì)采集攝像頭畫面和麥克風(fēng)聲音。媒體流對(duì)象可以使用 createLocalStreamView 創(chuàng)建本地媒體流播放組件進(jìn)行播放,也可以通過 video 元素 srcObject 屬性賦值進(jìn)行播放。

需等待 createStream 接口返回流媒體對(duì)象后,再將自己的音視頻流推送到 ZEGO 音視頻云。

調(diào)用 startPublishingStream 接口,傳入 “streamID” 和創(chuàng)建流得到的流對(duì)象 “l(fā)ocalStream”,向遠(yuǎn)端用戶發(fā)送本端的音視頻流。

“streamID” 由您本地生成,但是需要保證同一個(gè) AppID 下,“streamID” 全局唯一。如果同一個(gè) AppID 下,不同用戶各推了一條 “streamID” 相同的流,會(huì)導(dǎo)致后推流的用戶推流失敗。

// 此處在登錄房間成功后,立即進(jìn)行推流。在實(shí)現(xiàn)具體業(yè)務(wù)時(shí),您可選擇其他時(shí)機(jī)進(jìn)行推流,只要保證當(dāng)前房間連接狀態(tài)是連接成功的即可。


zg.loginRoom(roomID, token, { userID, userName: userID }, { userUpdate: true }).then(async result => {

    if (result == true) {

       console.log("login success")

       // 創(chuàng)建流、預(yù)覽

          // 調(diào)用 createStream 接口后,需要等待 ZEGO 服務(wù)器返回流媒體對(duì)象才能執(zhí)行后續(xù)操作

          const localStream = await zg.createStream();

         

          // 創(chuàng)建媒體流播放組件對(duì)象,用于預(yù)覽本地流

          const localView = zg.createLocalStreamView(localStream);

          // 將播放組件掛載到頁面,"local-video" 為組件容器 DOM 元素的 id 。

          localView.play("local-video");


          // 開始推流,將自己的音視頻流推送到 ZEGO 音視頻云

          let streamID = new Date().getTime().toString();

          zg.startPublishingStream(streamID, localStream)

    }

});

(可選)設(shè)置音視頻采集參數(shù)

通過屬性設(shè)置相關(guān)采集參數(shù)

可根據(jù)需要通過 createStream 接口中的如下屬性設(shè)置音視頻相關(guān)采集參數(shù),詳情可參考 自定義視頻采集:

  • camera:攝像頭麥克風(fēng)采集流相關(guān)配置
  • screen:屏幕捕捉采集流相關(guān)配置
  • custom:第三方流采集相關(guān)配置

4.6 拉取其他用戶的音視頻

進(jìn)行視頻通話時(shí),我們需要拉取到其他用戶的音視頻。

房間內(nèi)有其他用戶加入時(shí),SDK 會(huì)觸發(fā) roomStreamUpdate 回調(diào),通知房間內(nèi)有流新增,基于此可獲取其他用戶的 “streamID”。此時(shí),調(diào)用 startPlayingStream 接口根據(jù)傳入的其他用戶的 “streamID”,拉取遠(yuǎn)端已推送到 ZEGO 服務(wù)器的音視頻畫面。若需要從 CDN 拉流,可參考 使用 CDN 直播。

// 流狀態(tài)更新回調(diào)

zg.on('roomStreamUpdate', async (roomID, updateType, streamList, extendedData) => {

   // 當(dāng) updateType 為 ADD 時(shí),代表有音視頻流新增,此時(shí)可以調(diào)用 startPlayingStream 接口拉取播放該音視頻流

   if (updateType == 'ADD') {

       // 流新增,開始拉流

       // 這里為了使示例代碼更加簡潔,我們只拉取新增的音視頻流列表中第的第一條流,在實(shí)際的業(yè)務(wù)中,建議開發(fā)者循環(huán)遍歷 streamList ,拉取每一條音視頻流

       const streamID = streamList[0].streamID;

       // streamList 中有對(duì)應(yīng)流的 streamID

       const remoteStream = await zg.startPlayingStream(streamID);


       // 創(chuàng)建媒體流播放組件對(duì)象,用于播放遠(yuǎn)端媒體流 。

       const remoteView = zg.createRemoteStreamView(remoteStream);

       // 將播放組件掛載到頁面,"remote-video" 為組件容器 DOM 元素的 id 。

       remoteView.play("remote-video");


   } else if (updateType == 'DELETE') {

       // 流刪除,停止拉流

   }

});

部分瀏覽器因自動(dòng)播放限制策略問題,使用 ZegoStreamView 媒體流播放組件進(jìn)行播放媒體流可能受阻,SDK 默認(rèn)會(huì)在界面上彈窗提示恢復(fù)播放。

您可以將 ZegoStreamView.play() 方法的第二個(gè)參數(shù) options.enableAutoplayDialog 設(shè)置為 false 關(guān)閉自動(dòng)彈窗,通過在 autoplayFailed 事件回調(diào)中,在頁面上顯示一個(gè)按鈕,引導(dǎo)用戶點(diǎn)擊恢復(fù)播放。

至此,您已經(jīng)成功實(shí)現(xiàn)了簡單的實(shí)時(shí)音視頻通話,可在瀏覽器中打開 “index.html”,體驗(yàn)實(shí)時(shí)音視頻功能。

5 實(shí)時(shí)音視頻SDK常用功能

5.1 常用通知回調(diào)

// 房間連接狀態(tài)更新回調(diào)

// 本地調(diào)用 loginRoom 加入房間時(shí),您可通過監(jiān)聽 roomStateChanged 回調(diào)實(shí)時(shí)監(jiān)控自己在本房間內(nèi)的連接狀態(tài)。

zg.on('roomStateChanged', (roomID, reason, errorCode, extendData) => {

   if (reason == 'LOGINING') {

       // 登錄中

   } else if (reason == 'LOGINED') {

       // 登錄成功

       //只有當(dāng)房間狀態(tài)是登錄成功或重連成功時(shí),推流(startPublishingStream)、拉流(startPlayingStream)才能正常收發(fā)音視頻

       //將自己的音視頻流推送到 ZEGO 音視頻云

   } else if (reason == 'LOGIN_FAILED') {

       // 登錄失敗

   } else if (reason == 'RECONNECTING') {

       // 重連中

   } else if (reason == 'RECONNECTED') {

       // 重連成功

   } else if (reason == 'RECONNECT_FAILED') {

       // 重連失敗

   } else if (reason == 'KICKOUT') {

       // 被踢出房間

   } else if (reason == 'LOGOUT') {

       // 登出成功

   } else if (reason == 'LOGOUT_FAILED') {

       // 登出失敗

   }

});


//房間內(nèi)其他用戶推送的音視頻流新增/減少的通知

//自己推送的流不能在這里接收到通知

zg.on('roomStreamUpdate', async (roomID, updateType, streamList, extendedData) => {

   if (updateType == 'ADD') {

       // 流新增

       for (var i = 0; i < streamList.length; i++) {

           console.log('房間',roomID,'內(nèi)新增了流:', streamList[i]['streamID'])

       }

       const message = "其他用戶的視頻流streamID: " + streamID.toString();

   } else if (updateType == 'DELETE') {

       // 流刪除

       for (var i = 0; i < streamList.length; i++) {

           console.log('房間',roomID,'內(nèi)減少了流:', streamList[i]['streamID'])

       }

   }

});


//房間內(nèi)其他用戶進(jìn)出房間的通知

//只有調(diào)用 loginRoom 登錄房間時(shí)傳入 ZegoRoomConfig,且 ZegoRoomConfig 的 userUpdate 參數(shù)為 “true” 時(shí),用戶才能收到 roomUserUpdate回調(diào)。

zg.on('roomUserUpdate', (roomID, updateType, userList) => {

   if (updateType == 'ADD') {

       for (var i = 0; i < userList.length; i++) {

           console.log(userList[i]['userID'], '加入了房間:', roomID)

       }

   } else if (updateType == 'DELETE') {

       for (var i = 0; i < userList.length; i++) {

           console.log(userList[i]['userID'], '退出了房間:', roomID)

       }

   }

});


//用戶推送音視頻流的狀態(tài)通知

//用戶推送音視頻流的狀態(tài)發(fā)生變更時(shí),會(huì)收到該回調(diào)。如果網(wǎng)絡(luò)中斷導(dǎo)致推流異常,SDK 在重試推流的同時(shí)也會(huì)通知狀態(tài)變化。

zg.on('publisherStateUpdate', result => {

   // 推流狀態(tài)更新回調(diào)

   var state = result['state']

   var streamID = result['streamID']

   var errorCode = result['errorCode']

   var extendedData = result['extendedData']

   if (state == 'PUBLISHING') {

       console.log('成功推送音視頻流:', streamID);

   } else if (state == 'NO_PUBLISH') {

       console.log('未推送音視頻流');

   } else if (state == 'PUBLISH_REQUESTING') {

       console.log('請(qǐng)求推送音視頻流:', streamID);

   }

   console.log('錯(cuò)誤碼:', errorCode,' 額外信息:', extendedData)

})


//推流質(zhì)量回調(diào)。

//成功推流后,您會(huì)定時(shí)收到回調(diào)音視頻流質(zhì)量數(shù)據(jù)(如分辨率、幀率、碼率等)。

zg.on('publishQualityUpdate', (streamID, stats) => {

   // 推流質(zhì)量回調(diào)

   console.log('流質(zhì)量回調(diào)')

})


//用戶拉取音視頻流的狀態(tài)通知

//用戶拉取音視頻流的狀態(tài)發(fā)生變更時(shí),會(huì)收到該回調(diào)。如果網(wǎng)絡(luò)中斷導(dǎo)致拉流異常,SDK 會(huì)自動(dòng)進(jìn)行重試。

zg.on('playerStateUpdate', result => {

   // 拉流狀態(tài)更新回調(diào)

   var state = result['state']

   var streamID = result['streamID']

   var errorCode = result['errorCode']

   var extendedData = result['extendedData']

   if (state == 'PLAYING') {

       console.log('成功拉取音視頻流:', streamID);

   } else if (state == 'NO_PLAY') {

       console.log('未拉取音視頻流');

   } else if (state == 'PLAY_REQUESTING') {

       console.log('請(qǐng)求拉取音視頻流:', streamID);

   }

   console.log('錯(cuò)誤碼:', errorCode,' 額外信息:', extendedData)

})


//拉取音視頻流時(shí)的質(zhì)量回調(diào)。

//成功拉流后,您會(huì)定時(shí)收到拉取音視頻流時(shí)的質(zhì)量數(shù)據(jù)通知(如分辨率、幀率、碼率等)。

zg.on('playQualityUpdate', (streamID,stats) => {

   // 拉流質(zhì)量回調(diào)

})


//收到廣播消息的通知

zg.on('IMRecvBroadcastMessage', (roomID, chatData) => {

   console.log('廣播消息IMRecvBroadcastMessage', roomID, chatData[0].message);

   alert(chatData[0].message)

});


//收到彈幕消息的通知

zg.on('IMRecvBarrageMessage', (roomID, chatData) => {

   console.log('彈幕消息IMRecvBroadcastMessage', roomID, chatData[0].message);

   alert(chatData[0].message)

});


//收到自定義信令消息的通知

zg.on('IMRecvCustomCommand', (roomID, fromUser, command) => {

   console.log('自定義消息IMRecvCustomCommand', roomID, fromUser, command);

   alert(command)

});

5.2 停止音視頻通話

1. 停止推流、銷毀流

調(diào)用 stopPublishingStream 接口停止向遠(yuǎn)端用戶發(fā)送本端的音視頻流。調(diào)用 destroyStream 接口銷毀創(chuàng)建的流數(shù)據(jù),銷毀流后開發(fā)需自行銷毀 video(停止采集)。

// 根據(jù)本端 streamID 停止推流

zg.stopPublishingStream(streamID)

// localStream 是調(diào)用 createStream 接口獲取的 MediaStream 對(duì)象

zg.destroyStream(localStream)

2. 停止拉流

調(diào)用 stopPlayingStream 接口停止拉取遠(yuǎn)端推送的音視頻流。

// 流狀態(tài)更新回調(diào)

zg.on('roomStreamUpdate', async (roomID, updateType, streamList, extendedData) => {

   if (updateType == 'ADD') {

       // 流新增,開始拉流

   } else if (updateType == 'DELETE') {

       // 流刪除,通過流刪除列表 streamList 中每個(gè)流的 streamID 進(jìn)行停止拉流。

       const streamID = streamList[0].streamID;

       zg.stopPlayingStream(streamID)

   }

});

3. 退出房間

調(diào)用 logoutRoom 接口退出房間。

zg.logoutRoom(roomID)

ZEGO 實(shí)時(shí)音視頻文章圖片

6 調(diào)試視頻通話功能

在真機(jī)中運(yùn)行項(xiàng)目,運(yùn)行成功后,可以看到本端視頻畫面。

為方便體驗(yàn),ZEGO 提供了一個(gè) Web 端調(diào)試示例 ,在該頁面下,輸入相同的 AppID、RoomID,輸入一個(gè)不同的 UserID,即可加入同一房間與真機(jī)設(shè)備互通。當(dāng)成功開始音視頻通話時(shí),可以聽到遠(yuǎn)端的音頻,看到遠(yuǎn)端的視頻畫面。

7 獲取音視頻SDK更多支持

獲取本文的Demo、開發(fā)文檔、技術(shù)支持,訪問即構(gòu)文檔中心 https://doc-zh.zego.im/article/7638?source=partnershare

近期有開發(fā)規(guī)劃的開發(fā)者可上即構(gòu)官網(wǎng)查看,恰逢即構(gòu)七周年全線音視頻產(chǎn)品1折的優(yōu)惠,聯(lián)系商務(wù)獲取RTC產(chǎn)品優(yōu)惠;

ZEGO 實(shí)時(shí)音視頻文章圖片

更多資訊
暫無其它資訊
查看全部