api文檔:https://developers.weixin.qq.com/miniprogram/dev/api/media/live/wx.createLivePusherContext.html
開通標簽使用權限:live-pusher 和 live-player 是小程序內部用于支持音視頻上行能力的功能標簽
-
目前支持這兩個標簽的類目如下表格所示(只有非個人主體才有以下類目):
-
符合類目要求的小程序绊率,需要在小程序管理后臺的【開發(fā)】>【接口設置】中自助開通推拉流標簽的使用權限:
live-player:是小程序內部用于支持音視頻下行(播放)能力的功能標簽扎酷。 0硖贰2◎取!(基礎庫 1.7.0 開始支持歧焦,低版本需做兼容處理.
屬性定義
屬性 | 類型 | 默認值 | 必填 | 說明 | 最低版本 |
---|---|---|---|---|---|
src | string | 否 | 音視頻地址缺脉。目前僅支持 flv , rtmp 格式 |
1.7.0 | |
mode | string | live | 否 | 模式 | 1.7.0 |
autoplay | boolean | false | 否 | 自動播放 | 1.7.0 |
muted | boolean | false | 否 | 是否靜音 | 1.7.0 |
orientation | string | vertical | 否 | 畫面方向 | 1.7.0 |
object-fit | string | contain | 否 | 填充模式,可選值有 contain 劳秋,fillCrop
|
1.7.0 |
background-mute | boolean | false | 否 | 進入后臺時是否靜音(已廢棄,默認退后臺靜音) | 1.7.0 |
min-cache | number | 1 | 否 | 最小緩沖區(qū)俗批,單位s(RTC 模式推薦 0.2s) | 1.7.0 |
max-cache | number | 3 | 否 | 最大緩沖區(qū)俗或,單位s(RTC 模式推薦 0.8s)。緩沖區(qū)用來抵抗網(wǎng)絡波動岁忘,緩沖數(shù)據(jù)越多辛慰,網(wǎng)絡抗性越好,但時延越大干像。 | 1.7.0 |
sound-mode | string | speaker | 否 | 聲音輸出方式 | 1.9.90 |
auto-pause-if-navigate | boolean | true | 否 | 當跳轉到本小程序的其他頁面時帅腌,是否自動暫停本頁面的實時音視頻播放 | 2.5.0 |
auto-pause-if-open-native | boolean | true | 否 | 當跳轉到其它微信原生頁面時驰弄,是否自動暫停本頁面的實時音視頻播放 | 2.5.0 |
picture-in-picture-mode | string/Array | 否 | 設置小窗模式: push, pop,空字符串或通過數(shù)組形式設置多種模式(如: ["push", "pop"]) | 2.10.3 | |
referrer-policy | string | no-referrer | 否 | 格式固定為 https://servicewechat.com/{appid}/{version}/page-frame.html 速客,其中 {appid} 為小程序的 appid戚篙,{version} 為小程序的版本號,版本號為 0 表示為開發(fā)版溺职、體驗版以及審核版本岔擂,版本號為 devtools 表示為開發(fā)者工具,其余為正式版本浪耘; |
2.13.0 |
bindstatechange | eventhandle | 否 | 播放狀態(tài)變化事件乱灵,detail = {code} | 1.7.0 | |
bindfullscreenchange | eventhandle | 否 | 全屏變化事件,detail = {direction, fullScreen} | 1.7.0 | |
bindnetstatus | eventhandle | 否 | 網(wǎng)絡狀態(tài)通知七冲,detail = {info} | 1.9.0 | |
bindaudiovolumenotify | eventhandler | 否 | 播放音量大小通知痛倚,detail = {} | 2.10.0 | |
bindenterpictureinpicture | eventhandler | 否 | 播放器進入小窗 | 2.11.0 | |
bindleavepictureinpicture | eventhandler | 否 | 播放器退出小窗 | 2.11.0 |
狀態(tài)碼
代碼 | 說明 |
---|---|
2001 | 已經(jīng)連接服務器 |
2002 | 已經(jīng)連接 RTMP 服務器,開始拉流 |
2003 | 網(wǎng)絡接收到首個視頻數(shù)據(jù)包(IDR) |
2004 | 視頻播放開始 |
2005 | 視頻播放進度 |
2006 | 視頻播放結束 |
2007 | 視頻播放Loading |
2008 | 解碼器啟動 |
2009 | 視頻分辨率改變 |
-2301 | 網(wǎng)絡斷連,且經(jīng)多次重連搶救無效澜躺,更多重試請自行重啟播放 |
-2302 | 獲取加速拉流地址失敗 |
2101 | 當前視頻幀解碼失敗 |
2102 | 當前音頻幀解碼失敗 |
2103 | 網(wǎng)絡斷連, 已啟動自動重連 |
2104 | 網(wǎng)絡來包不穩(wěn):可能是下行帶寬不足蝉稳,或由于主播端出流不均勻 |
2105 | 當前視頻播放出現(xiàn)卡頓 |
2106 | 硬解啟動失敗,采用軟解 |
2107 | 當前視頻幀不連續(xù)掘鄙,可能丟幀 |
2108 | 當前流硬解第一個I幀失敗耘戚,SDK自動切軟解 |
3001 | RTMP -DNS解析失敗 |
3002 | RTMP服務器連接失敗 |
3003 | RTMP服務器握手失敗 |
3005 | RTMP 讀/寫失敗,之后會發(fā)起網(wǎng)絡重試 |
示例代碼
<!--
class 動態(tài)選擇誰的屏幕放大
src 播放地址
mode 模式 live-直播 RTC-實時通話
binderrorPusher 渲染錯誤事件通铲,detail = {errMsg, errCode}
beauty-style 設置美顏類型 smooth 光滑美顏 nature 自然美顏
auto-pause-if-open-native 當跳轉到其它微信原生頁面時毕莱,是否自動暫停本頁面的實時音視頻播放
bindstatechange 狀態(tài)變化事件,detail = {code}
object-fit 填充模式
picture-in-picture-mode 設置小窗模式: push, pop颅夺,空字符串或通過數(shù)組形式設置多種模式(如: ["push", "pop"])
-->
<live-player
id="player"
src="{{url_user}}"
mode="RTC"
autoplay
bindstatechange="statechangePlayer"
beauty-style="smooth"
auto-pause-if-open-native="{{false}}"
object-fit="fillCrop"
picture-in-picture-mode="['push', 'pop']"
class="{{is_small == 2 ?'small-window' : 'player'}}"
data-class="{{is_small == 2 ?'small-window' : 'pusher'}}"
bindtap="bindPlayerClick"/>
超低時延
的 RTC 模式支持500ms以內的超低時延鏈路朋截,可以應用在視頻通話和遠程遙控等場景中,要使用超低時延播放吧黄,需要注意如下幾點:
(1)推流端如果是微信小程序部服,請使用 的 RTC 模式。
(2)推流端如果是 iOS 或者 Android SDK拗慨,請使用 setVideoQuality 的 MAIN_PUBLISHER 模式廓八。
(3)推流端如果是 Windows,請不要使用 OBS赵抢,延時太高剧蹂,可以使用我們的 Windows SDK。
(4)min-cache 和 max-cache 請不要自行設置烦却,使用默認值宠叼。
(5)播放地址請使用超低延時播放地址,也就是帶了防盜鏈簽名的rtmp://地址,如下:
普通直播URL rtmp://3891.liveplay.myqcloud.com/live/3891_test_clock_for_rtmpacc >2s
超低延時URL rtmp://3891.liveplay.myqcloud.com/live/3891_test_clock_for_rtmpacc?bizid=bizid&txTime=5FD4431C&txSerect=20e6d865f462dff61ada209d53c71cf9 < 500ms
對象方法
LivePlayerContext
LivePlayerContext
實例冒冬,可通過 wx.createLivePlayerContext 獲取伸蚯。
LivePlayerContext 通過 id
跟一個 live-player 組件綁定,操作對應的 live-player 組件简烤。
wx.createLivePlayerContext('player', this)
LivePlayerContext.play()//播放
LivePlayerContext.stop()//停止
LivePlayerContext.mute()//靜音
LivePlayerContext.pause()//暫停
LivePlayerContext.resume()//恢復
LivePlayerContext.requestFullScreen(Object object)//進入全屏
LivePlayerContext.exitFullScreen()//退出全屏
LivePlayerContext.exitPictureInPicture()//退出小窗剂邮,該方法可在任意頁面調用
LivePlayerContext.snapshot(Object object)//截圖
LivePlayerContext.requestPictureInPicture()//進入小窗
var player = wx.createLivePlayerContext('pusher');
player.requestFullScreen({
success(){
console.log('enter full screen mode success!')
}
fail(){
console.log('enter full screen mode failed!')
}
complete(){
console.log('enter full screen mode complete!')
}
});
小窗特性說明
live-player 小窗支持以下三種觸發(fā)模式(在組件上設置 picture-in-picture-mode 屬性):
1.push 模式,即從當前頁跳轉至下一頁時出現(xiàn)小窗(頁面棧push)
2.pop 模式横侦,即離開當前頁面時觸發(fā)(頁面棧pop)
3.以上兩種路由行為均觸發(fā)小窗
此外挥萌,小窗還支持以下特性:
- 小窗容器尺寸會根據(jù)原組件尺寸自動判斷
- 點擊小窗,用戶會被導航回小窗對應的播放器頁面
- 小窗出現(xiàn)后丈咐,用戶可點擊小窗右上角的關閉按鈕或調用 context.exitPictureInPicture() 接口關閉小窗
- 當播放器進入小窗模式后瑞眼,播放器所在頁面處于 hide 狀態(tài)(觸發(fā) onHide 生命周期),該頁面不會被銷毀棵逊。當小窗被關閉時,播放器所在頁面會被 unload (觸發(fā) onUnload 生命周期)银酗。
分割線
live-pusher 實時音視頻錄制(v2.9.1 起支持同層渲染)辆影。需要用戶授權
scope.camera
、scope.record
黍特。
live-pusher支持的類目同live-player一樣
屬性定義
屬性 | 類型 | 默認值 | 必填 | 說明 | 最低版本 |
---|---|---|---|---|---|
url | string | 否 | 推流地址蛙讥。目前僅支持 rtmp 格式 |
1.7.0 | |
mode | string | RTC | 否 |
SD (標清), HD (高清), FHD (超清), RTC (實時通話) |
1.7.0 |
autopush | boolean | false | 否 | 自動推流 | 1.7.0 |
muted | boolean | false | 否 | 是否靜音。即將廢棄灭衷,可用 enable-mic 替代 |
1.7.0 |
enable-camera | boolean | true | 否 | 開啟攝像頭 | 1.7.0 |
auto-focus | boolean | true | 否 | 自動聚集 | 1.7.0 |
orientation | string | vertical | 否 | 畫面方向 | 1.7.0 |
beauty | number | 0 | 否 | 美顏次慢,取值范圍 0-9 ,0 表示關閉 | 1.7.0 |
whiteness | number | 0 | 否 | 美白翔曲,取值范圍 0-9 迫像,0 表示關閉 | 1.7.0 |
aspect | string | 9:16 | 否 | 寬高比,可選值有 3:4 , 9:16
|
1.7.0 |
min-bitrate | number | 200 | 否 | 最小碼率 | 1.7.0 |
max-bitrate | number | 1000 | 否 | 最大碼率 | 1.7.0 |
audio-quality | string | high | 否 | 高音質(48KHz)或低音質(16KHz)瞳遍,值為high , low
|
1.7.0 |
waiting-image | string | 否 | 進入后臺時推流的等待畫面 | 1.7.0 | |
waiting-image-hash | string | 否 | 等待畫面資源的MD5值 | 1.7.0 | |
zoom | boolean | false | 否 | 調整焦距 | 2.1.0 |
device-position | string | front | 否 | 前置或后置闻妓,值為front , back
|
2.3.0 |
background-mute | boolean | false | 否 | 進入后臺時是否靜音(已廢棄,默認退后臺靜音) | 1.7.0 |
mirror | boolean | false | 否 | 設置推流畫面是否鏡像掠械,產(chǎn)生的效果在 live-player 反應到 | 2.7.0 |
remote-mirror | boolean | false | 否 | 同 mirror 屬性由缆,后續(xù) mirror 將廢棄 | 2.10.0 |
local-mirror | string | auto | 否 | 控制本地預覽畫面是否鏡像 | 2.10.0 |
audio-reverb-type | number | 0 | 否 | 音頻混響類型 | 2.10.0 |
enable-mic | boolean | true | 否 | 開啟或關閉麥克風 | 2.10.0 |
enable-agc | boolean | false | 否 | 是否開啟音頻自動增益 | 2.10.0 |
enable-ans | boolean | false | 否 | 是否開啟音頻噪聲抑制 | 2.10.0 |
audio-volume-type | string | auto | 否 | 音量類型 | 2.10.0 |
video-width | number | 360 | 否 | 上推的視頻流的分辨率寬度 | 2.10.0 |
video-height | number | 640 | 否 | 上推的視頻流的分辨率高度 | 2.10.0 |
beauty-style | string | smooth | 否 | 設置美顏類型 | 2.12.0 |
filter | string | standard | 否 | 設置色彩濾鏡 | 2.12.0 |
bindstatechange | eventhandle | 否 | 狀態(tài)變化事件,detail = {code} | 1.7.0 | |
bindnetstatus | eventhandle | 否 | 網(wǎng)絡狀態(tài)通知猾蒂,detail = {info} | 1.9.0 | |
binderror | eventhandle | 否 | 渲染錯誤事件均唉,detail = {errMsg, errCode} | 1.7.4 | |
bindbgmstart | eventhandle | 否 | 背景音開始播放時觸發(fā) | 2.4.0 | |
bindbgmprogress | eventhandle | 否 | 背景音進度變化時觸發(fā),detail = {progress, duration} | 2.4.0 | |
bindbgmcomplete | eventhandle | 否 | 背景音播放完成時觸發(fā) | 2.4.0 | |
bindaudiovolumenotify | eventhandle | 否 | 返回麥克風采集的音量大小 | 2.12.0 |
狀態(tài)碼
代碼 | 說明 |
---|---|
1001 | 已經(jīng)連接推流服務器 |
1002 | 已經(jīng)與服務器握手完畢,開始推流 |
1003 | 打開攝像頭成功 |
1004 | 錄屏啟動成功 |
1005 | 推流動態(tài)調整分辨率 |
1006 | 推流動態(tài)調整碼率 |
1007 | 首幀畫面采集完成 |
1008 | 編碼器啟動 |
-1301 | 打開攝像頭失敗 |
-1302 | 打開麥克風失敗 |
-1303 | 視頻編碼失敗 |
-1304 | 音頻編碼失敗 |
-1305 | 不支持的視頻分辨率 |
-1306 | 不支持的音頻采樣率 |
-1307 | 網(wǎng)絡斷連,且經(jīng)多次重連搶救無效犁嗅,更多重試請自行重啟推流 |
-1308 | 開始錄屏失敗该默,可能是被用戶拒絕 |
-1309 | 錄屏失敗绊诲,不支持的Android系統(tǒng)版本限嫌,需要5.0以上的系統(tǒng) |
-1310 | 錄屏被其他應用打斷了 |
-1311 | Android Mic打開成功靴庆,但是錄不到音頻數(shù)據(jù) |
-1312 | 錄屏動態(tài)切橫豎屏失敗 |
1101 | 網(wǎng)絡狀況不佳:上行帶寬太小,上傳數(shù)據(jù)受阻 |
1102 | 網(wǎng)絡斷連, 已啟動自動重連 |
1103 | 硬編碼啟動失敗,采用軟編碼 |
1104 | 視頻編碼失敗 |
1105 | 新美顏軟編碼啟動失敗怒医,采用老的軟編碼 |
1106 | 新美顏軟編碼啟動失敗炉抒,采用老的軟編碼 |
3001 | RTMP -DNS解析失敗 |
3002 | RTMP服務器連接失敗 |
3003 | RTMP服務器握手失敗 |
3004 | RTMP服務器主動斷開,請檢查推流地址的合法性或防盜鏈有效期 |
3005 | RTMP 讀/寫失敗 |
示例代碼
<live-pusher
id="pusher"
url="{{url_doctor}}"
mode="RTC"
autopush
bindstatechange="statechangePusher"
beauty-style="smooth"
binderror="binderrorPusher"
class="{{is_small == 1 ?'small-window' : 'pusher'}}"
data-class="{{is_small == 1 ?'small-window' : 'pusher'}}"
bindtap="bindPusherClick" />
對象方法
LivePusherContext
LivePusherContext
實例稚叹,可通過 wx.createLivePusherContext 獲取焰薄。
LivePusherContext.start() //開始推流,同時開啟攝像頭預覽
LivePusherContext.stop() //停止推流扒袖,同時停止攝像頭預覽
LivePusherContext.pause() //暫停推流
LivePusherContext.resume() //恢復推流
LivePusherContext.switchCamera() //切換前后攝像頭
LivePusherContext.snapshot(Object object) //快照
LivePusherContext.toggleTorch() //切換手電筒
LivePusherContext.playBGM(Object object) //播放背景音
LivePusherContext.stopBGM() //停止背景音
LivePusherContext.pauseBGM() //暫停背景音
LivePusherContext.resumeBGM() //恢復背景音
LivePusherContext.setBGMVolume(Object object) //設置背景音音量
LivePusherContext.setMICVolume(Object object) //設置麥克風音量
LivePusherContext.startPreview() //開啟攝像頭預覽
LivePusherContext.stopPreview() //關閉攝像頭預覽
LivePusherContext.sendMessage(Object object) //發(fā)送SEI消息
Bug & Tip
-
tip
:開發(fā)者工具上暫不支持塞茅。 -
tip
:live-pusher 默認寬度為100%、無默認高度季率,請通過wxss設置寬高野瘦。 -
tip
:waiting-image
屬性在 2.3.0 起完整支持網(wǎng)絡路徑、臨時文件和包內路徑飒泻。 -
tip
:請注意原生組件使用限制鞭光。 -
tip
: 相關介紹和原理可參考此文章
附上完整示例
!E⒁拧惰许!要注意兩端推流播放 比如是a端和b端
a端 | b端 |
---|---|
pusher _a | pusher _b |
player_b | player_a |
<!-- wxml-->
<view class="chat">
<!--
binderrorPusher 渲染錯誤事件,detail = {errMsg, errCode}
bindstatechange 狀態(tài)變化事件史辙,detail = {code}
beauty-style 設置美顏類型 smooth 光滑美顏 nature 自然美顏
beauty 0 美顏汹买,取值范圍 0-9 ,0 表示關閉
device-position front 前置或后置聊倔,值為front, back
-->
<live-pusher
id="pusher"
class="{{is_small == 1 ?'small-window' : 'pusher'}}"
url="{{push_stream}}"
mode="RTC"
autopush
bindstatechange="statechangePusher"
beauty-style="smooth"
binderror="binderrorPusher"
data-class="{{is_small == 1 ?'small-window' : 'pusher'}}"
bindtap="bindPusherClick"
device-position="{{device_position}}" />
<!--
class 動態(tài)選擇誰的屏幕放大
src 播放地址
mode 模式 live-直播 RTC-實時通話
binderrorPusher 渲染錯誤事件晦毙,detail = {errMsg, errCode}
beauty-style 設置美顏類型 smooth 光滑美顏 nature 自然美顏
auto-pause-if-open-native 當跳轉到其它微信原生頁面時,是否自動暫停本頁面的實時音視頻播放
bindstatechange 狀態(tài)變化事件方库,detail = {code}
object-fit 填充模式
picture-in-picture-mode 設置小窗模式: push, pop结序,空字符串或通過數(shù)組形式設置多種模式(如: ["push", "pop"])
-->
<live-player
id="player"
src="{{pull_stream}}"
mode="RTC"
autoplay
bindstatechange="statechangePlayer"
beauty-style="smooth"
auto-pause-if-open-native="{{false}}"
object-fit="fillCrop"
picture-in-picture-mode="['push', 'pop']"
class="{{is_small == 2 ?'small-window' : 'player'}}"
data-class="{{is_small == 2 ?'small-window' : 'pusher'}}"
bindtap="bindPlayerClick"/>
<view class="fixed">
<view class="" style="height: auto;">
<image src="/images/gd.png" bindtap="hangUp"></image>
<image src="/images/qh.png" bindtap="cutCamera"></image>
</view>
</view>
</view>
//js
const app = getApp()
Page({
data: {
player: '',
pusher: '',
is_small: 2, // 1-pusher 2-player
pull_stream: 'https://domain/pull_stream',
push_stream: 'https://domain/push_stream'
},
onLoad() {
this.setData({
player: wx.createLivePlayerContext('player', this),
pusher: wx.createLivePusherContext(),
})
},
onReady() {},
onShow() {},
//狀態(tài)變化事件
statechangePusher(e) {
const code = e.detail.code
this.colse(code, 'Pusher')
},
//狀態(tài)變化事件
statechangePlayer(e) {
const code = e.detail.code
// 2004 視頻播放開始
if (code == '2004') {
// this.data.pusher.pauseBGM()
}
this.colse(code, 'Player')
},
//掛斷的操作
colse(code, type) {
console.log(type)
// 2006 視頻播放結束
// -2301網(wǎng)絡斷連,且經(jīng)多次重連搶救無效纵潦,更多重試請自行重啟播放
// -1310 錄屏被其他應用打斷了
// 3001 RTMP -DNS解析失敗
// 3002 RTMP服務器連接失敗
// 3003 RTMP服務器握手失敗
// 3005 RTMP 讀/寫失敗徐鹤,之后會發(fā)起網(wǎng)絡重試
let code_list = ['2006', '-2301', '-1310', '3001', '3002', '3003', '3005']
if (code_list.includes(code)) {
if (type == 'Pusher') {
//掛斷
this.hangUp()
} else {
//掛斷視頻、不推流邀层、關閉頁面
//請求后臺接口
this.hangUp()
}
}
},
//渲染錯誤事件
binderrorPusher(errMsg, errCode) {
// 10001 用戶禁止使用攝像頭
// 10002 用戶禁止使用錄音
if (errCode == '10001' || errCode == '10002') {
api.showToast(errMsg)
}
},
//切換大小屏
bindPusherClick(e) {
const _class = e.currentTarget.dataset.class
if (_class == 'small-window' && this.data.is_small == 1) { // 說明pusher是小屏幕
this.setData({
is_small: 2
})
}
},
//切換大小屏
bindPlayerClick(e) {
const _class = e.currentTarget.dataset.class
if (_class == 'small-window' && this.data.is_small == 2) { // 說明player是小屏幕
this.setData({
is_small: 1
})
}
},
//掛斷
hangUp() {
console.log('掛斷');
// 停止推流返敬,同時停止攝像頭預覽
this.data.pusher.stop({
success() {
//掛斷視頻、不推流寥院、關閉頁面
//dosomething
},
fail() {}
})
},
//切換攝像頭
cutCamera() {
this.data.pusher.switchCamera({
success() {
console.log('切換攝像頭 success!')
},
})
},
})
//css
.chat{
position: relative;
height: 100vh;
width: 100%;
}
.player,.pusher{
width: 100% ;height: 100%
}
.small-window{
position: absolute;
top: 0px;
right: 0px;
width: 150px;
height: 200px;
z-index: 100;
}
.fixed{
position: fixed;
bottom: 50px;
left: 50px;
right: 50px;
z-index: 101;
text-align: center;
}
.fixed image{
width: 50px;
height: 50px;
margin: 0px 40px;
}