244 lines
6.5 KiB
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>
|