wx-starlock/pages/p2p/p2pPlayer.vue

244 lines
6.5 KiB
Vue

<template>
<view>
<iot-p2p-player-with-mjpg
v-if="deviceInfo"
id="playerRef"
:deviceInfo="deviceInfo"
:xp2pInfo="xp2pInfo"
:rotate="90"
:muted="isMute"
mode="RTC"
:acceptPlayerEvents="true"
soundMode="speaker"
sceneType="live"
:streamQuality="range[index].value"
:minCache="0.2"
:maxCache="0.8"
:fill="true"
orientation="horizontal"
@playsuccess="handlePlaySuccess"
>
</iot-p2p-player-with-mjpg>
<view
v-if="buttonInfo"
:style="{
top: buttonInfo.bottom + 15 + 'px'
}"
class="bg-[rgba(0,0,0,0.35)] rounded-full px-2 py-1.5 fixed right-32"
>
<picker :value="index" mode="selector" :range="range" range-key="name" @change="changeEvent">
<up-icon
:label="range[index].name"
color="#ffffff"
label-color="#ffffff"
labelPos="left"
name="arrow-down-fill"
size="32rpx"
space="16rpx"
></up-icon>
</picker>
</view>
<image
v-if="!isVideoLoaded"
src="https://oss-lock.xhjcn.ltd/mp/background_monitor.png"
class="w-full h-full absolute top-0 left-0"
></image>
<iot-p2p-voice
v-if="deviceInfo"
id="voiceComponent"
:deviceInfo="deviceInfo"
:xp2pInfo="xp2pInfo"
voiceType="Pusher"
>
</iot-p2p-voice>
<view
v-if="isVideoLoaded"
class="fixed bottom-[calc(32rpx+env(safe-area-inset-bottom))] bg-[rgba(0,0,0,0.3)] rounded-xl p-4 shadow-lg mx-4 w-622"
>
<view class="flex items-center justify-around mx-10">
<image
@click="isMute = !isMute"
:src="
isMute
? 'https://oss-lock.xhjcn.ltd/mp/icon_mute.png'
: 'https://oss-lock.xhjcn.ltd/mp/icon_not_mute.png'
"
class="w-48 h-48 p-2"
></image>
<image
@click="handleScreenshot"
src="https://oss-lock.xhjcn.ltd/mp/icon_screenshot.png"
class="w-48 h-48 p-2"
></image>
</view>
<view class="flex items-center justify-around text-white mt-2">
<view class="flex flex-col items-center" @longpress="startVoice" @touchend="stopVoice">
<view class="bg-white w-80 h-80 rounded-full flex items-center justify-center">
<image
:src="
isVoice
? 'https://oss-lock.xhjcn.ltd/mp/icon_microphone.png'
: 'https://oss-lock.xhjcn.ltd/mp/icon_no_microphone.png'
"
class="w-55 h-55"
></image>
</view>
<view class="mt-2">长按说话</view>
</view>
<view class="flex flex-col items-center" @click="handleHangUp">
<view class="bg-[#eb292b] w-80 h-80 rounded-full flex items-center justify-center">
<image src="https://oss-lock.xhjcn.ltd/mp/icon_hang_up.png" class="w-60 h-60"></image>
</view>
<view class="mt-2">挂断</view>
</view>
<view class="flex flex-col items-center" @click="handleLock">
<view class="bg-[#63b8af] w-80 h-80 rounded-full flex items-center justify-center">
<image
src="https://oss-lock.xhjcn.ltd/mp/icon_lock_white.png"
class="w-60 h-60"
></image>
</view>
<view class="mt-2">开锁</view>
</view>
</view>
</view>
<view
v-if="!isVideoLoaded"
class="fixed bottom-[calc(48rpx+env(safe-area-inset-bottom))] w-full flex justify-center"
>
<up-loading-icon
size="70rpx"
:vertical="true"
textSize="28rpx"
text="连接中"
mode="circle"
></up-loading-icon>
</view>
</view>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import { onUnload } from '@dcloudio/uni-app'
import { useBluetoothStore } from '@/stores/bluetooth'
import { useBasicStore } from '@/stores/basic'
import { passthrough } from '@/api/sdk'
const $bluetooth = useBluetoothStore()
const $basic = useBasicStore()
const buttonInfo = ref(null)
const index = ref(1)
const range = ref([
{ name: '标清', value: 'standard' },
{ name: '高清', value: 'high' },
{ name: '超清', value: 'super' }
])
const deviceInfo = ref()
const xp2pInfo = ref()
const isVoice = ref(false)
const isMute = ref(false)
const isVideoLoaded = ref(false)
onMounted(async () => {
buttonInfo.value = await $basic.getButtonInfo()
const { code, data, message } = await passthrough({
request_method: 'GET',
request_uri: '/api/v1/tencentYun/getDeviceDetailData',
post_args: {
lockId: $bluetooth.currentLockInfo.lockId
}
})
if (code === 0) {
deviceInfo.value = {
deviceId: `${data.productId}/${data.deviceName}`,
productId: data.productId,
deviceName: data.deviceName
}
xp2pInfo.value = data.xp2pInfo
} else {
$basic.backAndToast(message)
}
})
onUnload(() => {
const page = getCurrentPages().pop()
const player = page.selectComponent('#playerRef')
if (player.stopAll) {
player.stopAll()
}
})
const changeEvent = e => {
index.value = e.detail.value
}
const handleScreenshot = () => {
const page = getCurrentPages().pop()
const player = page.selectComponent('#playerRef')
player.snapshot().then(res => {
uni.saveImageToPhotosAlbum({
filePath: res.tempImagePath,
success: () => {
uni.showToast({
title: '截图已保存到相册',
icon: 'none'
})
},
fail: () => {
uni.showToast({
title: '保存失败',
icon: 'none'
})
}
})
})
}
const handleHangUp = () => {
const page = getCurrentPages().pop()
const player = page.selectComponent('#playerRef')
if (player.stopAll) {
player.stopAll()
}
uni.navigateBack()
}
const handleLock = () => {
console.log('handleLock')
}
const startVoice = () => {
uni.vibrateLong()
isVoice.value = true
const page = getCurrentPages().pop()
const voice = page.selectComponent('#voiceComponent')
voice.startVoice()
}
const stopVoice = () => {
isVoice.value = false
const page = getCurrentPages().pop()
const voice = page.selectComponent('#voiceComponent')
voice.stopVoice()
}
const handlePlaySuccess = () => {
isVideoLoaded.value = true
}
</script>
<style lang="scss" scoped>
:deep(.mjpg-player--iot-player) {
height: 100vh !important;
}
</style>