1 微信小程式原生推拉流組件功能簡介
本文將介紹如何使用微信小程式原生推拉流組件 <live-pusher> 和 <live-player> 進行推拉流,快速實作一個簡單的實時音視頻通話,
由于微信小程式原生推拉流組件使用起來比較復雜,推薦開發者使用即構封裝的音視頻SDK <zego-push> 和 <zego-player> 組件實作視頻通話,可參考 實作視頻通話,
2 實作微信小程式音視頻通話的前提條件
在實作基本的實時音視頻功能之前,請確保:
- 已在專案中集成 ZEGO Express SDK 即構音視頻SDK,詳情請參考 快速開始 - 集成,
- 已在 ZEGO 控制臺 創建專案,申請有效的 AppID 和 ServerSecret,詳情請參考 控制臺 - 專案管理 中的“專案資訊”,
3 即構音視頻SDK實作流程
用戶通過 ZEGO Express SDK 即構音視頻SDK進行視頻通話的基本流程為:
用戶 A、B 加入房間,用戶 B 預覽并將音視頻流推送到 ZEGO 云服務(推流),用戶 A 收到用戶 B 推送音視頻流的通知之后,在通知中播放用戶 B 的音視頻流(拉流),

3.1 配置微信小程式后臺
在初始化 音視頻SDK 前,需要在 微信公眾平臺 中進行如下配置:
-
服務器域名配置:在“小程式后臺 > 開發管理 > 開發設定 > 服務器域名”中,按照協議分類,將即構 Server 地址、LogUrl、以及用戶業務需要用到的地址填到指定的“request合法域名”或“socket合法域名”中,

-
相關功能開啟:在“小程式后臺 > 開發管理 > 介面設定 > 介面權限”中,打開 實時播放音視頻流 和 實時錄制音視頻流 功能開關,

3.2 即構音視頻SDK初始化
1. 創建音視頻通話界面
根據音視頻場景需要,為您的專案創建音視頻通話的用戶界面,我們推薦您在專案中添加如下元素:
- 本地預覽視窗
- 遠端視頻視窗
- 結束按鈕

小程式推流組件 <live-pusher> 中的 "video-width" 和 "video-height" 存在兼容性問題,可能會出現設定不生效的情況,
參考界面代碼:
<view wx:if="{{canShow== 1}}" >
<view >
<live-pusher
wx:if="{{pusher.url}}"
url="{{pusher.url}}"
mode="{{pusher.mode}}"
autopush="{{pusher.autopush}}"
enable-camera="{{pusher.enableCamera}}"
enable-mic="{{pusher.enableMic}}"
muted="{{!pusher.enableMic}}"
enable-agc="{{pusher.enableAgc}}"
enable-ans="{{pusher.enableAns}}"
zoom="{{pusher.enableZoom}}"
min-bitrate="{{pusher.minBitrate}}"
max-bitrate="{{pusher.maxBitrate}}"
video-
video-height="{{pusher.videoHeight}}"
beauty="{{pusher.beautyLevel}}"
whiteness="{{pusher.whitenessLevel}}"
orientation="{{pusher.videoOrientation}}"
device-position="{{pusher.frontCamera}}"
remote-mirror="{{pusher.enableRemoteMirror}}"
local-mirror="{{pusher.localMirror}}"
background-mute="{{pusher.enableBackgroundMute}}"
audio-quality="{{pusher.audioQuality}}"
audio-volume-type="{{pusher.audioVolumeType}}"
audio-reverb-type="{{pusher.audioReverbType}}"
waiting-image="{{pusher.waitingImage}}"
beauty-style="{{pusher.beautyStyle}}"
filter="{{pusher.filter}}"
bindstatechange="onPushStateChange"
bindaudiovolumenotify="bindaudiovolumenotify"
bindnetstatus="onPushNetStateChange"
waiting-image="https://storage.zego.im/downloads/pause_publish.png"></live-pusher>
<live-player wx:for="{{playerList}}" wx:key="streamID" id="{{item.id}}"
src= "https://www.cnblogs.com/zegodeveloper/p/{{item.url}}"
mode= "RTC"
autoplay= "{{item.autoplay}}"
mute-audio= "{{item.muteAudio}}"
mute-video= "{{item.muteVideo}}"
orientation= "{{item.orientation}}"
object-fit= "{{item.objectFit}}"
min-cache= "{{item.minCache}}"
max-cache= "{{item.maxCache}}"
sound-mode= "{{item.soundMode}}"
enable-recv-message= "{{item.enableRecvMessage}}"
auto-pause-if-navigate= "{{item.autoPauseIfNavigate}}"
auto-pause-if-open-native= "{{item.autoPauseIfOpenNative}}" enable-metadata="https://www.cnblogs.com/zegodeveloper/p/true" bindmetadatachange="binddatachange" bindstatechange="onPlayStateChange" bindnetstatus="onPlayNetStateChange"></live-player>
</view>
<view >
<view class='input-container'>
<input value="https://www.cnblogs.com/zegodeveloper/p/{{roomID}}" bindinput="bindKeyInput" placeholder="請輸入房間 ID" placeholder-style='color: #b3b3b3; font-size: 14px;' />
<text ></text>
</view>
<view >
<button bindtap="openRoom" data-role="1" data-option="videoAndAudio" hover- >
加入房間(推流)
</button>
<button bindtap="logout" hover->退出房間</button>
</view>
</view>
</view>
<view >
<button wx:if="{{canShow==0}}" open-type="openSetting" bindopensetting="settingCallback">
授權使用攝像頭和麥克風
</button>
</view>
2. 創建音視頻SDK引擎
創建 ZegoExpressEngine 引擎實體,將申請到的 AppID 傳入引數 “appID”,將獲取到的 Server 地址傳入引數 “server”,
// 初始化實體
zg = new ZegoExpressEngine(appID, server);
如果需要注冊回呼,開發者可根據實際需要,實作 ZegoEvent 中的某些方法,創建引擎后可通過呼叫 on 介面設定回呼,
zg.on('roomStateUpdate', (roomID, state, errorCode, extendedData) => {
if (state == 'DISCONNECTED') {
// 與房間斷開了連接
// ...
}
if (state == 'CONNECTING') {
// 與房間嘗試連接中
// ...
}
if (state == 'CONNECTED') {
// 與房間連接成功
// ...
}
})
3.3 登錄音視頻房間
1. 獲取房間登錄 Token
登錄房間需要用于驗證身份的 Token,獲取方式請參考 用戶權限控制,如需快速除錯,建議使用控制臺生成的臨時 Token,生成臨時 Token 的具體操作請參考 控制臺 - 專案管理,
2. 登錄音視頻房間
您可以呼叫 SDK 的 loginRoom 介面,傳入房間 ID 引數 “roomID”、“token” 和用戶引數 “user”,登錄房間,您可通過監聽 roomStateUpdate 回呼實時監控自己在本房間內的連接狀態,具體請參考 4.1 常見通知回呼 中的“4.1.1 我在房間內的連接狀態變化通知”,
roomID 和 user 的引數由您本地生成,但是需要滿足以下條件:
- 同一個 AppID 內,需保證 “roomID” 全域唯一,
- 同一個 AppID 內,需保證 “userID” 全域唯一,建議開發者將 “userID” 與自己業務的賬號系統進行關聯,
為避免錯過任何通知,您需要在登錄房間前先設定所有的監聽回呼(如房間狀態、用戶狀態、流狀態、推拉流狀態等),具體請參考 4.1 常見通知回呼 ,
// 登錄房間,成功則回傳 true
const result = await zg.loginRoom(roomID, token, {userID, userName});
3.4 將自己的音視頻流推送到 ZEGO 即構音視頻云
3.4.1 初始化小程式組件實體
呼叫 initContext 介面初始化小程式組件,
小程式組件中用于存盤推流屬性 pusher 和拉流屬性串列 playerList 兩個欄位需要傳給 SDK,SDK 后續將通過傳入的兩個欄位對相應的推拉流作狀態及視圖更新處理,
- pusher 欄位中的屬性值請參考 ZegoWxPusherAttributes,
- playerlist 欄位中的屬性值請參考 ZegoWxPlayerAttributes,
zg.initContext({
wxContext: this,
pushAtr: "pusher", // 物件名,物件屬性與 live-pusher 中的屬性為映射關系
playAtr: "playerList" // 物件名,物件屬性與 live-player 中的屬性為映射關系
})
即構音視頻SDK 在內部會對推拉流實體進行操作以及視圖更新,開發者無需保存推拉流實體和呼叫小程式 setData 介面更新視圖,避免與 SDK 發生沖突,后續可通過 getPusherInstance 和 getPlayerInstance 介面獲取推拉流實體,
3.4.2 創建對應業務場景的 WXML
根據您的業務場景需求,撰寫 WXML 檔案,創建推拉流組件 <live-pusher> 和 <live-player>,
- <live-pusher> 組件用于小程式的實時推送音視頻流功能,
- <live-player> 組件用戶小程式的實時播放音視頻流功能,
WXML 的具體含義與用法請參考微信官網檔案中的介紹 WXML,
WXML 中的 pusher 與 playerList,必須與初始化小程式組件 initContext 中定義的這兩個欄位屬性名保持一致,后續 SDK 呼叫推拉流介面之后才能正確地進行狀態及視圖更新,
bindstatechange 表示播放狀態變化事件;bindaudiovolumenotify 表示播放音量大小通知;bindnetstatus 表示網路狀態通知,
<live-pusher
wx:if="{{pusher.url}}"
url="{{pusher.url}}"
mode="{{pusher.mode}}"
autopush="{{pusher.autopush}}"
enable-camera="{{pusher.enableCamera}}"
enable-mic="{{pusher.enableMic}}"
muted="{{!pusher.enableMic}}"
enable-agc="{{pusher.enableAgc}}"
enable-ans="{{pusher.enableAns}}"
enable-ear-monitor="{{pusher.enableEarMonitor}}"
auto-focus="{{pusher.enableAutoFocus}}"
zoom="{{pusher.enableZoom}}"
min-bitrate="{{pusher.minBitrate}}"
max-bitrate="{{pusher.maxBitrate}}"
video-
video-height="{{pusher.videoHeight}}"
beauty="{{pusher.beautyLevel}}"
whiteness="{{pusher.whitenessLevel}}"
orientation="{{pusher.videoOrientation}}"
aspect="{{pusher.videoAspect}}"
device-position="{{pusher.frontCamera}}"
remote-mirror="{{pusher.enableRemoteMirror}}"
local-mirror="{{pusher.localMirror}}"
background-mute="{{pusher.enableBackgroundMute}}"
audio-quality="{{pusher.audioQuality}}"
audio-volume-type="{{pusher.audioVolumeType}}"
audio-reverb-type="{{pusher.audioReverbType}}"
waiting-image="{{pusher.waitingImage}}"
beauty-style="{{pusher.beautyStyle}}"
filter="{{pusher.filter}}"
bindstatechange="onPushStateChange"
bindaudiovolumenotify="bindaudiovolumenotify"
bindnetstatus="onPushNetStateChange"
waiting-image="https://storage.zego.im/downloads/pause_publish.png">
</live-pusher>
<live-player wx:for="{{playerList}}" wx:key="streamID" id="{{item.id}}"
src= "https://www.cnblogs.com/zegodeveloper/p/{{item.url}}"
mode= "RTC"
autoplay= "{{item.autoplay}}"
mute-audio= "{{item.muteAudio}}"
mute-video= "{{item.muteVideo}}"
orientation= "{{item.orientation}}"
object-fit= "{{item.objectFit}}"
min-cache= "{{item.minCache}}"
max-cache= "{{item.maxCache}}"
sound-mode= "{{item.soundMode}}"
enable-recv-message= "{{item.enableRecvMessage}}"
auto-pause-if-navigate= "{{item.autoPauseIfNavigate}}"
auto-pause-if-open-native= "{{item.autoPauseIfOpenNative}}" enable-metadata="https://www.cnblogs.com/zegodeveloper/p/true" bindmetadatachange="binddatachange" bindstatechange="onPlayStateChange" bindnetstatus="onPlayNetStateChange">
</live-player>
3.4.3 推送音視頻流到 ZEGO 即構音視頻云
必須完成初始化小程式組件實體和創建業務場景的 WXML 之后,才能呼叫 SDK 介面創建推流和拉流實體,
用戶呼叫 SDK 的 createPusher 介面創建推流實體,并通過呼叫實體物件上的 start 介面,傳入流 ID 引數 “streamID”,您可通過監聽 publisherStateUpdate 回呼知曉推流是否成功,具體請參考 4.1 常見通知回呼 中的“4.1.4 用戶推送音視頻流的狀態通知”,
“streamID” 由您本地生成,但是需要保證:
- 同一個 AppID 下,“streamID” 全域唯一,如果同一個 AppID 下,不同用戶各推了一條 “streamID” 相同的流,后推流的用戶推流失敗,
- “streamID” 長度不超過 256 位元組的字串,僅支持數字,英文字符和 “~”,“!”,“@”,“$”,“%”,“^”,“&”,“*”,“(”,“)”,“_”,“+”,“=”,“-”,“`”,“;”,“’”,“,”,“.”,“<”,“>”,“/”,“\”,
// 推流方登錄房間成功后觸發推流
const pusher = zg.createPusher();
pusher.start("streamID_xxx");
3.5 拉取其他用戶的音視頻
進行視頻通話時,我們需要拉取到其他用戶的音視頻,
用戶先呼叫 getPlayerInstance介面,根據傳入的流 ID 引數 “streamID”,獲取 streamID 對應的拉流實體,然后通過呼叫拉流實體物件的 play 介面開始拉流,您可通過監聽 playerStateUpdate 回呼知曉是否成功拉取音視頻,具體請參考 4.1 常見通知回呼 中的“4.1.5 用戶拉取音視頻流的狀態通知”,
遠端用戶推送的 “streamID” 可以從 roomStreamUpdate 回呼中獲得,具體回呼設定請參考 4.1 常見通知回呼 中的“4.1.3 房間內流狀態變更的通知”,
// 在 SDK 的回呼 roomStreamUpdate 中獲取拉流 streamID
// 當用戶加入或離開房間時,該事件被觸發
zg.on("roomStreamUpdate", (roomID, updateType, streamList) => {
console.log("roomStreamUpdate", roomID, updateType, streamList);
if (updateType === "ADD") {
streamList.forEach(i => {
zg.getPlayerInstance(i.streamID).play();
})
} else {
streamList.forEach(i => {
zg.getPlayerInstance(i.streamID).stop();
})
}
});
4 小程式音視頻通話的常用功能
4.1 常見音視頻房間通知回呼
4.1.1 我在房間內的連接狀態變化通知
roomStateUpdate:本地呼叫 loginRoom 加入房間時,您可通過監聽該回呼實時監控自己在本房間內的連接狀態,
用戶可以在回呼中根據不同狀態處理業務邏輯,
zg.on('roomStateUpdate', (roomID, state, errorCode, extendedData) => {
if (state == 'DISCONNECTED') {
// 與房間斷開了連接
// ...
}
if (state == 'CONNECTING') {
// 與房間嘗試連接中
// ...
}
if (state == 'CONNECTED') {
// 與房間連接成功
// ...
}
})

4.1.2 其他用戶進出房間的通知
roomUserUpdate:同一房間內的其他用戶進出房間時,您可通過此回呼收到通知,登錄房間后,當房間內有用戶新增或洗掉時,SDK 會通過該回呼通知,
只有呼叫 loginRoom 介面登錄房間時傳入 ZegoRoomConfig 配置,且 “userUpdate” 引數取值為 “true” 時,用戶才能收到 roomUserUpdate 回呼,
// 用戶狀態更新回呼
zg.on('roomUserUpdate', (roomID, updateType, userList) => {
console.warn(
`roomUserUpdate: room ${roomID}, user ${updateType === 'ADD' ? 'added' : 'left'} `,
JSON.stringify(userList),
);
});
4.1.3 房間內流狀態變更的通知
roomStreamUpdate:流狀態更新回呼,登錄房間后,當房間內有用戶新推送或洗掉音視頻流時,SDK 會通過該回呼通知,
// 流狀態更新回呼
zg.on('roomStreamUpdate', async (roomID, updateType, streamList, extendedData) => {
if (updateType == 'ADD') {
// 流新增,開始拉流
} else if (updateType == 'DELETE') {
// 流洗掉,停止拉流
}
});
4.1.4 用戶推送音視頻流的狀態通知
- 推流狀態事件
微信小程式會在 <live-pusher> 的 bindstatechange 系結的方法中通知出推流狀態事件,開發者需要:
a. 在 bindstatechange 系結的回呼函式中,呼叫 SDK 的 updatePlayerState 介面將推流狀態事件透傳給 SDK,
b. 在 SDK 的 publisherStateUpdate 回呼中處理推流的開始、失敗狀態,
// live-pusher 系結推流事件
onPushStateChange(e) {
// 透傳推流事件給 SDK
zg.updatePlayerState(this.data.publishStreamID, e);
},
// 推流后,服務器主動推過來的,流狀態更新
// NO_PUBLISH:未推流狀態,PUBLISH_REQUESTING:正在請求推流狀態,PUBLISHING:正在推流狀態
// state: "PUBLISHING" | "NO_PUBLISH" | "PUBLISH_REQUESTING";
zg.on("publisherStateUpdate", (result) => {
console.log("publishStateUpdate", result.state);
});
- 推流網路事件
微信小程式會在 <live-pusher> 的 bindnetstatus 系結的方法中通知出推流網路事件,開發者需要在對應的小程式回呼中,呼叫 SDK 的 updatePlayerNetStatus 介面將推流網路事件透傳給 SDK,
// live-pusher 系結網路狀態事件
onPushNetStateChange(e) {
//透傳網路狀態事件給 SDK
zg.updatePlayerNetStatus(this.data.publishStreamID, e);
},
// SDK 推流網路質量回呼
zg.on("publishQualityUpdate", (streamID, publishStats) => {
console.log("publishQualityUpdate", streamID, publishStats);
});
4.1.5 用戶拉取音視頻流的狀態通知
- 拉流狀態事件
微信小程式會在 <live-player> 的 bindstatechange 系結的方法中通知出拉流狀態事件,開發者需要:
a. 在 bindstatechange 系結的回呼函式中,呼叫 SDK 的 updatePlayerState 介面將拉流狀態事件透傳給 SDK,
b. 在 SDK 提供的 playerStateUpdate 回呼中處理拉流的開始或失敗狀態,
// live-player 系結的拉流事件
onPlayStateChange(e) {
// 透傳拉流事件給 SDK
zg.updatePlayerState(e.currentTarget.id, e);
},
// 服務器主動推過來的流的播放狀態
// 視頻播放狀態通知;state: "NO_PLAY" | "PLAY_REQUESTING" | "PLAYING";
zg.on("playerStateUpdate", (result) => {
console.log("playStateUpdate", result.state);
});
- 拉流網路事件
微信小程式會在 <live-player> 的 bindnetstatus 系結的方法中通知出拉流網路事件,開發者需要在對應的小程式回呼中,呼叫 SDK 的 updatePlayerNetStatus 介面將推流網路事件透傳給 SDK,
// live-player 系結網路狀態事件
onPlayNetStateChange(e) {
// 透傳網路狀態事件給 SDK
zg.updatePlayerNetStatus(playStreamID, e);
},
// SDK 拉流網路質量回呼
zg.on("playQualityUpdate", (playStreamID, playStats) => {
console.log("playQualityUpdate", playStreamID, playStats);
});
4.2 停止fang jian音視頻通話
4.2.1 停止推送/拉取音視頻流
1. 停止推流
呼叫 SDK 的 getPusherInstance 介面獲取推流實體,并呼叫推流實體的 stop 方法停止推流,
// 停止推流
zg.getPusherInstance().stop();
2. 停止拉流
呼叫 SDK 的 getPlayerInstance 介面獲取拉流實體,并呼叫推流實體的 stop 方法停止拉流,
// 停止拉流
zg.getPlayerInstance(streamID).stop();
4.2.2 退出房間
呼叫 SDK 的 logoutRoom 介面退出房間,
zg.logoutRoom(roomID);
5 除錯視頻通話功能
在真機中運行專案,運行成功后,可以看到本端視頻畫面,
為方便體驗,ZEGO 提供了一個 Web 端除錯示例 ,在該頁面下,輸入相同的 AppID、RoomID,輸入一個不同的 UserID,即可加入同一房間與真機設備互通,當成功開始音視頻通話時,可以聽到遠端的音頻,看到遠端的視頻畫面,
6 視頻通話 API 呼叫時序
整個推拉流程序的 API 呼叫時序可參考下圖:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/509264.html
標籤:JavaScript
上一篇:前端面試八股文
