|
|
@@ -1,7 +1,61 @@
|
|
|
<template>
|
|
|
<div class="root">
|
|
|
<div class="container-shell">
|
|
|
- <div id="container" ref="containerRef" :style="{width: width, height: height}"></div>
|
|
|
+ <div id="container" ref="container" :style="{ width: width, height: height }"></div>
|
|
|
+ </div>
|
|
|
+ <div id="jb-pro-ptz-btns" style="display: none">
|
|
|
+ <div class="jb-pro-ptz-btns">
|
|
|
+ <div class="jb-pro-ptz-btn">
|
|
|
+ <div class="jb-pro-ptz-expand jb-pro-ptz-icon">
|
|
|
+ <div class="jb-pro-ptz-expand-icon-fangda icon" onclick="handlePtzScale('fangda')"></div>
|
|
|
+ <span class="icon-title-tips">
|
|
|
+ <span class="icon-title">放大</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="jb-pro-ptz-narrow jb-pro-ptz-icon">
|
|
|
+ <div class="jb-pro-ptz-narrow-icon-suoxiao icon" onclick="handlePtzScale('suoxiao')"></div>
|
|
|
+ <span class="icon-title-tips">
|
|
|
+ <span class="icon-title">缩小</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="jb-pro-ptz-btn">
|
|
|
+ <div class="jb-pro-ptz-aperture-far jb-pro-ptz-icon">
|
|
|
+ <div
|
|
|
+ class="jb-pro-ptz-aperture-icon-guangquan icon"
|
|
|
+ onclick="handlePtzScale('guangquan')"
|
|
|
+ ></div>
|
|
|
+ <span class="icon-title-tips">
|
|
|
+ <span class="icon-title">光圈+</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="jb-pro-ptz-aperture-near jb-pro-ptz-icon">
|
|
|
+ <div
|
|
|
+ class="jb-pro-ptz-aperture-icon-guangquan- icon"
|
|
|
+ onclick="handlePtzScale('guangquan-')"
|
|
|
+ ></div>
|
|
|
+ <span class="icon-title-tips">
|
|
|
+ <span class="icon-title">光圈-</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="jb-pro-ptz-btn">
|
|
|
+ <div class="jb-pro-ptz-focus-far jb-pro-ptz-icon">
|
|
|
+ <div class="jb-pro-ptz-focus-icon-jujiao icon" onclick="handlePtzScale('jujiao')"></div>
|
|
|
+ <span class="icon-title-tips">
|
|
|
+ <span class="icon-title">聚焦+</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="jb-pro-ptz-focus-near jb-pro-ptz-icon">
|
|
|
+ <div class="jb-pro-ptz-focus-icon-jujiao- icon" onclick="handlePtzScale('jujiao-')"></div>
|
|
|
+ <span class="icon-title-tips">
|
|
|
+ <span class="icon-title">聚焦-</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
@@ -9,12 +63,13 @@
|
|
|
<script setup>
|
|
|
import { ref, reactive, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
|
|
|
import { ptzdirection, ptzscale } from '@/api/pms/video/sipdevice'
|
|
|
+import { func } from 'vue-types'
|
|
|
|
|
|
// 定义props
|
|
|
const props = defineProps({
|
|
|
playerinfo: {
|
|
|
type: Object,
|
|
|
- default: null,
|
|
|
+ default: null
|
|
|
},
|
|
|
width: {
|
|
|
type: String,
|
|
|
@@ -27,7 +82,7 @@ const props = defineProps({
|
|
|
})
|
|
|
|
|
|
// 定义响应式数据
|
|
|
-const containerRef = ref(null)
|
|
|
+const container = ref(null)
|
|
|
const isPlaybackPause = ref(false)
|
|
|
const useWebGPU = ref(false)
|
|
|
const isInit = ref(false)
|
|
|
@@ -38,24 +93,25 @@ const operateBtns = reactive({
|
|
|
fullscreen: true,
|
|
|
zoom: true,
|
|
|
play: true,
|
|
|
- audio: true,
|
|
|
+ audio: true
|
|
|
})
|
|
|
|
|
|
// jessibucaPlayer实例存储
|
|
|
let jessibucaPlayer = {}
|
|
|
|
|
|
// Watch playerinfo变化
|
|
|
-watch(() => props.playerinfo, (newVal, oldVal) => {
|
|
|
- console.log('playerinfo 发生变化')
|
|
|
- playinfo.value = newVal
|
|
|
- if (newVal && newVal.playtype !== '') {
|
|
|
- playtype.value = newVal.playtype
|
|
|
+watch(
|
|
|
+ () => props.playerinfo,
|
|
|
+ (newVal, oldVal) => {
|
|
|
+ playinfo.value = newVal
|
|
|
+ if (newVal && newVal.playtype !== '') {
|
|
|
+ playtype.value = newVal.playtype
|
|
|
+ }
|
|
|
}
|
|
|
-})
|
|
|
+)
|
|
|
|
|
|
// 组件挂载时执行
|
|
|
onMounted(() => {
|
|
|
- console.log("component mounted")
|
|
|
playinfo.value = props.playerinfo
|
|
|
if (playinfo.value && playinfo.value.playtype !== '') {
|
|
|
playtype.value = playinfo.value.playtype
|
|
|
@@ -90,7 +146,7 @@ const init = () => {
|
|
|
if (useVconsole && window.VConsole) {
|
|
|
new window.VConsole()
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
nextTick(() => {
|
|
|
initplayer()
|
|
|
})
|
|
|
@@ -100,11 +156,11 @@ const init = () => {
|
|
|
const initplayer = () => {
|
|
|
isPlaybackPause.value = false
|
|
|
initconf()
|
|
|
-
|
|
|
+
|
|
|
jessibucaPlayer[currentInstanceId.value] = new window.JessibucaPro({
|
|
|
- container: containerRef.value,
|
|
|
- decoder: '/js/jessibuca-pro/decoder-pro.js',
|
|
|
+ container: container.value,
|
|
|
videoBuffer: Number(0.2), // 缓存时长
|
|
|
+ decoder: '/js/jessibuca-pro/decoder-pro.js',
|
|
|
isResize: false,
|
|
|
useWCS: false,
|
|
|
useMSE: false,
|
|
|
@@ -112,22 +168,87 @@ const initplayer = () => {
|
|
|
wcsUseVideoRender: false,
|
|
|
loadingText: '加载中',
|
|
|
debug: false,
|
|
|
- debugLevel: "debug",
|
|
|
+ debugLevel: 'debug',
|
|
|
showBandwidth: true, // 显示网速
|
|
|
showPlaybackOperate: true,
|
|
|
operateBtns: { ...operateBtns },
|
|
|
forceNoOffscreen: true,
|
|
|
isNotMute: true, // 默认关闭声音
|
|
|
showPerformance: false,
|
|
|
- // playFailedAndReplay: true,
|
|
|
- // networkDelayTimeoutReplay: true,
|
|
|
playbackForwardMaxRateDecodeIFrame: 4,
|
|
|
- useWebGPU: useWebGPU.value, // 使用WebGPU
|
|
|
+ useWebGPU: useWebGPU.value // 使用WebGPU
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
let jessibuca = jessibucaPlayer[currentInstanceId.value]
|
|
|
+
|
|
|
initcallback(jessibuca)
|
|
|
+
|
|
|
isInit.value = true
|
|
|
+ initPtzBtns()
|
|
|
+}
|
|
|
+
|
|
|
+function initPtzBtns() {
|
|
|
+ const ptzBtns = document.querySelector('.jessibuca-ptz-controls')
|
|
|
+ ptzBtns.appendChild(document.querySelector('#jb-pro-ptz-btns .jb-pro-ptz-btns').cloneNode(true))
|
|
|
+ ptzBtns.querySelector('.jb-pro-ptz-expand-icon-fangda').addEventListener('click', () => {
|
|
|
+ handlePtzScale('fangda')
|
|
|
+ })
|
|
|
+ ptzBtns.querySelector('.jb-pro-ptz-narrow-icon-suoxiao').addEventListener('click', () => {
|
|
|
+ handlePtzScale('suoxiao')
|
|
|
+ })
|
|
|
+ ptzBtns.querySelector('.jb-pro-ptz-aperture-icon-guangquan').addEventListener('click', () => {
|
|
|
+ handlePtzScale('guangquan')
|
|
|
+ })
|
|
|
+ ptzBtns.querySelector('.jb-pro-ptz-aperture-icon-guangquan-').addEventListener('click', () => {
|
|
|
+ handlePtzScale('guangquan-')
|
|
|
+ })
|
|
|
+ ptzBtns.querySelector('.jb-pro-ptz-focus-icon-jujiao').addEventListener('click', () => {
|
|
|
+ handlePtzScale('jujiao')
|
|
|
+ })
|
|
|
+ ptzBtns.querySelector('.jb-pro-ptz-focus-icon-jujiao-').addEventListener('click', () => {
|
|
|
+ handlePtzScale('jujiao-')
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function handlePtzScale(arrow) {
|
|
|
+ let inOut = 0
|
|
|
+ let irisInOut = 0
|
|
|
+ let focusInOut = 0
|
|
|
+ switch (arrow) {
|
|
|
+ case 'fangda': {
|
|
|
+ inOut = 1
|
|
|
+ break
|
|
|
+ }
|
|
|
+ case 'suoxiao': {
|
|
|
+ inOut = 2
|
|
|
+ break
|
|
|
+ }
|
|
|
+ case 'guangquan': {
|
|
|
+ irisInOut = 1
|
|
|
+ break
|
|
|
+ }
|
|
|
+ case 'guangquan-': {
|
|
|
+ irisInOut = 2
|
|
|
+ break
|
|
|
+ }
|
|
|
+ case 'jujiao': {
|
|
|
+ focusInOut = 1
|
|
|
+ break
|
|
|
+ }
|
|
|
+ case 'jujiao-': {
|
|
|
+ focusInOut = 2
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var data = {
|
|
|
+ inOut: inOut,
|
|
|
+ irisInOut: irisInOut,
|
|
|
+ focusInOut: focusInOut
|
|
|
+ }
|
|
|
+ if (playinfo.value && playinfo.value.playtype !== '') {
|
|
|
+ ptzscale(playinfo.value.deviceId, playinfo.value.channelId, data).then((response) => {})
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 初始化配置
|
|
|
@@ -146,11 +267,11 @@ const initcallback = (jessibuca) => {
|
|
|
jessibuca.on('error', function (error) {
|
|
|
console.log('jessibuca error', error)
|
|
|
})
|
|
|
-
|
|
|
- jessibuca.on("playFailedAndPaused", function (reason, lastFrameInfo, msg) {
|
|
|
+
|
|
|
+ jessibuca.on('playFailedAndPaused', function (reason, lastFrameInfo, msg) {
|
|
|
console.log('playFailedAndPaused', reason, msg)
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
jessibuca.on('visibilityChange', (value) => {
|
|
|
if (value === true) {
|
|
|
// 窗口显示
|
|
|
@@ -160,27 +281,25 @@ const initcallback = (jessibuca) => {
|
|
|
console.log('visibilityChange false')
|
|
|
}
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
jessibuca.on('pause', function (pause) {
|
|
|
console.log('pause success!', pause)
|
|
|
})
|
|
|
-
|
|
|
- jessibuca.on('play', function (flag) {
|
|
|
- console.log('play!', flag)
|
|
|
- })
|
|
|
-
|
|
|
+
|
|
|
+ jessibuca.on('play', function (flag) {})
|
|
|
+
|
|
|
jessibuca.on('loading', function (load) {
|
|
|
console.log('loading success!', load)
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
jessibuca.on('stats', function (s) {
|
|
|
// console.log('stats is', s)
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
jessibuca.on('timeout', function (error) {
|
|
|
console.log('timeout:', error)
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
jessibuca.on('playbackPreRateChange', (rate) => {
|
|
|
jessibuca.forward(rate)
|
|
|
})
|
|
|
@@ -193,12 +312,12 @@ const initcallback = (jessibuca) => {
|
|
|
pre++
|
|
|
}
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
jessibuca.on(window.JessibucaPro.EVENTS.ptz, (arrow) => {
|
|
|
console.log('ptz arrow', arrow)
|
|
|
handlePtz(arrow)
|
|
|
})
|
|
|
-
|
|
|
+
|
|
|
jessibuca.on('crashLog', (data) => {
|
|
|
console.log('crashLog is', data)
|
|
|
})
|
|
|
@@ -213,12 +332,16 @@ const registercallback = (events, func) => {
|
|
|
|
|
|
// 判断是否为移动设备
|
|
|
const isMobile = () => {
|
|
|
- return /iphone|ipad|android.*mobile|windows.*phone|blackberry.*mobile/i.test(window.navigator.userAgent.toLowerCase())
|
|
|
+ return /iphone|ipad|android.*mobile|windows.*phone|blackberry.*mobile/i.test(
|
|
|
+ window.navigator.userAgent.toLowerCase()
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
// 判断是否为平板设备
|
|
|
const isPad = () => {
|
|
|
- return /ipad|android(?!.*mobile)|tablet|kindle|silk/i.test(window.navigator.userAgent.toLowerCase())
|
|
|
+ return /ipad|android(?!.*mobile)|tablet|kindle|silk/i.test(
|
|
|
+ window.navigator.userAgent.toLowerCase()
|
|
|
+ )
|
|
|
}
|
|
|
|
|
|
// 播放
|
|
|
@@ -261,13 +384,13 @@ const handlePtz = (arrow) => {
|
|
|
} else if (arrow === 'down') {
|
|
|
upDown = 2
|
|
|
}
|
|
|
-
|
|
|
- var data = {
|
|
|
+
|
|
|
+ const data = {
|
|
|
leftRight: leftRight,
|
|
|
upDown: upDown,
|
|
|
- moveSpeed: 125,
|
|
|
+ moveSpeed: 125
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (playinfo.value && playinfo.value.playtype !== '') {
|
|
|
ptzdirection(playinfo.value.deviceId, playinfo.value.channelId, data).then(async (response) => {
|
|
|
//console.log("云台方向控制:" + JSON.stringify(response))
|
|
|
@@ -287,11 +410,11 @@ const playback = (url, playTimes) => {
|
|
|
isCacheBeforeDecodeForFpsRender: false, // rfs渲染时,是否在解码前缓存数据
|
|
|
supportWheel: true, // 是否支持滚动轴切换精度。
|
|
|
rateConfig: [
|
|
|
- {label: '正常', value: 1},
|
|
|
- {label: '2倍', value: 2},
|
|
|
- {label: '4倍', value: 4},
|
|
|
- {label: '8倍', value: 8},
|
|
|
- ],
|
|
|
+ { label: '正常', value: 1 },
|
|
|
+ { label: '2倍', value: 2 },
|
|
|
+ { label: '4倍', value: 4 },
|
|
|
+ { label: '8倍', value: 8 }
|
|
|
+ ]
|
|
|
})
|
|
|
isPlaybackPause.value = false
|
|
|
}
|
|
|
@@ -377,6 +500,8 @@ defineExpose({
|
|
|
#container {
|
|
|
background: rgba(13, 14, 27, 0.7);
|
|
|
border-radius: 5px;
|
|
|
+ width: 600px;
|
|
|
+ height: 500px;
|
|
|
}
|
|
|
|
|
|
.err {
|
|
|
@@ -405,4 +530,80 @@ defineExpose({
|
|
|
height: 52.7vw;
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
+
|
|
|
+.jb-pro-ptz-btns {
|
|
|
+ .jb-pro-ptz-btn {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-around;
|
|
|
+
|
|
|
+ .jb-pro-ptz-icon {
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .icon {
|
|
|
+ width: 28px;
|
|
|
+ height: 28px;
|
|
|
+ margin-top: 3px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-expand-icon-fangda {
|
|
|
+ background-image: url('@/assets/icon/fangda.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-narrow-icon-suoxiao {
|
|
|
+ background-image: url('@/assets/icon/suoxiao.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-aperture-icon-guangquan {
|
|
|
+ background-image: url('@/assets/icon/guangquan+.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-aperture-icon-guangquan- {
|
|
|
+ background-image: url('@/assets/icon/guangquan-.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-focus-icon-jujiao {
|
|
|
+ background-image: url('@/assets/icon/jujiao+.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-focus-icon-jujiao- {
|
|
|
+ background-image: url('@/assets/icon/jujiao-.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-icon:hover {
|
|
|
+ .icon-title-tips {
|
|
|
+ visibility: visible;
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-expand-icon-fangda {
|
|
|
+ background-image: url('@/assets/icon/fangda-hov.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-narrow-icon-suoxiao {
|
|
|
+ background-image: url('@/assets/icon/suoxiao-hov.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-aperture-icon-guangquan {
|
|
|
+ background-image: url('@/assets/icon/guangquan-hov+.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-aperture-icon-guangquan- {
|
|
|
+ background-image: url('@/assets/icon/guangquan-hov-.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-focus-icon-jujiao {
|
|
|
+ background-image: url('@/assets/icon/jujiao-hov+.png');
|
|
|
+ }
|
|
|
+
|
|
|
+ .jb-pro-ptz-focus-icon-jujiao- {
|
|
|
+ background-image: url('@/assets/icon/jujiao-hov-.png');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ img {
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|