live-player 实现全屏切换、播放暂停、静音外放的骚操作
前段时间项目中有一个对接监控视频流的功能?
啧啧啧!!!
在小程序上去对接监控视频流我还是第一次,之前都是web端去对接直播流。
相信小伙伴有和我一样需要去处理这种功能。下面我将介绍一下这种功能的实现方式及步骤。
首先,请小伙伴们确定一下自己所使用的框架是否是 uniapp / 微信原生,如果不是这两种的话请各位迅速移步赶紧跑去外面寻找新的方案。
好,废话不多说,开始下面的骚操作!!!
live-player 组件
这玩意是什么呢?它又要如何使用呢?我呢就直接放官网的截图了。
总结一下:这玩意就是用来作为一个直播流播放器用的,然后呢如果你的小程序需要发布,那就要申请指定的类目才行,不然用不了。
它有哪些属性值和方法呢?
下面我就直接粘官网的表了:
属性名 | 类型 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|
id | String | live-player 属性的唯一标志符 | ||
src | String | 音视频地址。百度小程序支持 m3u8 格式;微信小程序支持 flv, rtmp 格式 | ||
mode | String | live | live(直播),RTC(实时通话,该模式时延更低) | 微信小程序 |
autoplay | Boolean | false | 自动播放 | |
muted | Boolean | false | 是否静音 | |
orientation | String | vertical | 画面方向,可选值有 vertical,horizontal | |
object-fit | String | contain | 填充模式,可选值:contain、fillCrop | |
background-mute | Boolean | false | 进入后台时是否静音 | |
sound-mode | string | speaker | 声音输出方式;可选值speaker、ear | 微信小程序、QQ小程序1.5.0(仅支持speaker) |
min-cache | Number | 1 | 最小缓冲区,单位s | |
max-cache | Number | 3 | 最大缓冲区,单位s | |
picture-in-picture-mode | string/Array | 3 | 设置小窗模式: push, pop,空字符串或通过数组形式设置多种模式(如: [“push”, “pop”]) | 微信小程序(2.10.3) |
@statechange | EventHandle | 播放状态变化事件,detail = {code} | ||
@netstatus | EventHandle | 网络状态通知,detail = {info} | ||
@fullscreenchange | EventHandle | 全屏变化事件,detail = {direction, fullScreen}。 | ||
@audiovolumenotify | EventHandle | 播放音量大小通知,detail = {} | 微信小程序(2.10.0) | |
@enterpictureinpicture | EventHandle | 播放器进入小窗 | 微信小程序(2.11.0) | |
@leavepictureinpicture | EventHandle | 播放器退出小窗 | 2.11.0 |
看到这么多属性值是不是很懵,兄弟们不要慌哈,这里面的东西呀,我们不会全部用到。
需求
OK,上面的这些属性看一眼就完事了,知道这个组件能够做些什么就行,下面来看看我们的 UI 图
先来看一下这个图上需要的功能点:
- 直播流的暂停/播放
- 直播流的静音/恢复
- 直播流的全屏/小屏
代码实现
上面功能点已经明确,下面我们开始写我们的代码
HTML 部分
下面的代码有点长,我在代码之前呢讲一下页面逻辑。
由于 live-player 是没有操作栏的,所以我们需要自己去做一下操作栏,操作栏分为两个:正常状态、全屏状态
操作栏中有三种 icon,每个 icon 有两种状态,根据状态的不同去切换对应状态的 icon
页面逻辑就是这样,很简单吧。下面请看代码演示
<live-player
id="livePlayer"
catchtouchmove
autoplay
background-mute
sound-mode="speaker"
:src="currentUrl"
mode="live"
@click="handleControlbar">
<!-- 正常状态 -->
<view v-if="!fullScreenFlag && showControlbar" class="operate_box" @tap.stop>
<view class="left">
<image v-if="play" @tap.stop="bindPause" :src="$ossAssetUrl('/uni_image/flv_bf.png')"/>
<image v-else @tap.stop="bindResume" :src="$ossAssetUrl('/uni_image/flv_zt.png')"/>
</view>
<view class="right">
<image v-if="isMute" @tap.stop="bindMute" class="flv_sy" :src="$ossAssetUrl('/uni_image/flv_sy.png')"/>
<image v-else @tap.stop="bindMuteResume" class="flv_sy" :src="$ossAssetUrl('/uni_image/flv_jy.png')"/>
<image @tap.stopfullScreenFlag="full" :src="$ossAssetUrl('/uni_image/flv_qp.png')"/>
</view>
</view>
<!-- 全屏状态 -->
<view v-if="fullScreenFlag && showControlbar" class="operate_box operate_y_box" @tap.stop style="height: 36rpx">
<view class="left">
<image v-if="play" @tap.stop="bindPause" :src="$ossAssetUrl('/uni_image/flv_bf.png')"/>
<image v-else @tap.stop="bindResume" :src="$ossAssetUrl('/uni_image/flv_zt.png')"/>
</view>
<view class="right">
<image v-if="isMute" @tap.stop="bindMute" class="flv_sy" :src="$ossAssetUrl('/uni_image/flv_sy.png')"/>
<image v-else @tap.stop="bindMuteResume" class="flv_sy" :src="$ossAssetUrl('/uni_image/flv_jy.png')"/>
<image @tap.stop="exitfull" :src="$ossAssetUrl('/uni_image/flv_tcqp.png')"/>
</view>
</view>
</live-player>
Script 部分
页面搞定后我们来搞定功能吧。
data 部分
data() {
return {
playerCtx: null, // live-player操作
currentUrl: '', // 播放路径
showControlbar: true, // 是否显示状态栏
fullScreenFlag: false, // 是否是全屏
play: true, // 直播: 恢复与开始
isMute: true, // 直播: 播放与静音
timer: '' // 关闭定时器的标识
}
}
onLoad 部分
onLoad() {
this.getDeviceLive(); // 获取直播流路径
this.playerCtx = uni.createLivePlayerContext('livePlayer'); // live-play操作上下文对象
setTimeout(() => {
this.showControlbar = false // 10 秒后关闭直播状态栏
}, 10000)
},
watch 部分
watch: {
showControlbar(val, oldVal) { // 监听是否显示操作栏的值从而在变化 5s 后关闭操作栏的显示
if (val) {
this.timer = setTimeout(() => {
this.showControlbar = false
}, 5000)
} else {
clearTimeout(this.timer);
}
}
}
method 部分
method: {
// 获取直播流路径
async getDeviceLive() {
const res = await getLiveApi() // 获取直播流的接口
this.currentUrl = res.currentUrl
},
// 是否显示播放状态栏
handleControlbar() {
this.showControlbar = !this.showControlbar
},
// 暂停播放
bindPause() {
this.playerCtx.stop({
success: res => {
this.play = false
},
fail: res => {
this.$toast('暂停播放失败')
}
})
},
// 恢复播放
bindResume() {
this.playerCtx.play({
success: res => {
this.play = true
},
fail: res => {
this.$toast('暂停播放失败')
}
})
},
// 静音
bindMute() {
this.playerCtx.mute({
success: res => {
this.isMute = false
},
fail: res => {
this.$toast('静音失败')
}
})
},
// 恢复声音
bindMuteResume() {
this.playerCtx.mute({
success: res => {
this.isMute = true
},
fail: res => {
this.$toast('恢复静音失败')
}
})
},
// 全屏
full() {
this.playerCtx.requestFullScreen({
direction: 90,
success: res => {
this.fullScreenFlag = true
},
fail: res => {
this.$toast('进入全屏失败')
}
})
},
// 退出全屏
exitfull() {
this.playerCtx.exitFullScreen({
direction: 90,
success: res => {
this.fullScreenFlag = false
},
fail: res => {
this.$toast('退出全屏失败')
}
})
},
}
Css 部分
.live_box {
width: 100%;
height: 420rpx;
// 播放器操作栏
.operate_box {
width: 100%;
height: 72rpx;
position: absolute;
left: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 32rpx;
background-color: rgba(43,51,63,.7);
image {
width: 40rpx;
height: 40rpx;
}
view {
display: inline-block;
}
.flv_sy {
margin-right: 16rpx;
}
}
.operate_y_box {
image {
width: 20rpx;
height: 20rpx;
}
}
#livePlayer {
width: 100%;
height: 420rpx;
}
}
结语
当你看到这里的时候,需要恭喜你,你又掌握了一个前端组件。如果你感觉这篇文章对你有作用的话请点赞、收藏加关注。
感谢您的阅读,这里是开发小白,期待与您的下次相遇(●’◡’●)