优化播放弹窗

This commit is contained in:
lin 2026-06-11 11:34:27 +08:00
parent f5494c0b95
commit 5eea3a19f5
8 changed files with 246 additions and 165 deletions

View File

@ -69,6 +69,14 @@ export function resetGuard(deviceId) {
})
}
export function homePosition(params) {
return request({
method: 'get',
url: '/api/device/control/home_position',
params
})
}
export function subscribeCatalog(params) {
const { id, cycle } = params
return request({

View File

@ -3,6 +3,7 @@ import {
changeChannelAudio,
deleteDevice,
deviceRecord, getKeepaliveTimeStatistics, getRegisterTimeStatistics,
homePosition,
queryBasicParam,
queryChannelOne,
queryChannels,
@ -83,6 +84,16 @@ const actions = {
})
})
},
homePosition({ commit }, params) {
return new Promise((resolve, reject) => {
homePosition(params).then(response => {
const { data } = response
resolve(data)
}).catch(error => {
reject(error)
})
})
},
subscribeCatalog({ commit }, params) {
return new Promise((resolve, reject) => {
subscribeCatalog(params).then(response => {

View File

@ -1,6 +1,6 @@
<template>
<div id="h265Player" ref="container" style="background-color: #000000; " @dblclick="fullscreenSwich">
<div id="glplayer" ref="playerBox" style="width: 100%; height: 100%; margin: 0 auto;" >
<div id="h265Player" ref="container" style="background-color: #000000; position: relative; display: flex; align-items: center; justify-content: center;" @dblclick="fullscreenSwich">
<div id="glplayer" ref="playerBox" style="width: 100%; height: 100%; margin: 0 auto;">
<div v-if="playerLoading" class="play-loading">
<i class="el-icon-loading" />
视频加载中
@ -264,12 +264,14 @@ export default {
}
.buttons-box {
width: 100%;
height: 28px;
background-color: rgba(43, 51, 63, 0.7);
height: 56px;
background: linear-gradient(to top, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0));
position: absolute;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
align-items: flex-end;
padding-bottom: 10px;
left: 0;
bottom: 0;
user-select: none;
@ -279,7 +281,6 @@ export default {
.h265web-btn {
width: 20px;
color: rgb(255, 255, 255);
line-height: 27px;
margin: 0px 10px;
padding: 0px 2px;
cursor: pointer;
@ -290,6 +291,7 @@ export default {
.buttons-box-right {
position: absolute;
right: 0;
bottom: 10px;
}
.player-loading {
width: fit-content;

View File

@ -289,8 +289,6 @@ export default {
height: 28px;
background-color: rgba(43, 51, 63, 0.7);
position: absolute;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
left: 0;
bottom: 0;
@ -302,7 +300,7 @@ export default {
width: 20px;
color: rgb(255, 255, 255);
line-height: 27px;
margin: 0px 10px;
margin: 0px 20px;
padding: 0px 2px;
cursor: pointer;
text-align: center;

View File

@ -1,65 +1,31 @@
<template>
<div class="player-tabs-wrapper" ref="playerWrapper">
<el-tabs v-if="playerCount > 1" v-model="activePlayer" type="card" :stretch="true" @tab-click="changePlayer">
<el-tab-pane label="Jessibuca" name="jessibuca">
<div v-if="activePlayer === 'jessibuca'" class="player-video-area">
<jessibucaPlayer
ref="jessibuca"
style="width: 100%; height: 100%;"
:video-url="videoUrl"
:has-audio="hasAudio"
:show-button="showButton"
fluent autoplay live
/>
</div>
</el-tab-pane>
<el-tab-pane label="WebRTC" name="webRTC">
<div v-if="activePlayer === 'webRTC'" class="player-video-area">
<rtc-player
ref="webRTC"
style="width: 100%; height: 100%;"
:video-url="videoUrl"
:has-audio="hasAudio"
fluent autoplay live
/>
</div>
</el-tab-pane>
<el-tab-pane label="h265web" name="h265web">
<div v-if="activePlayer === 'h265web'" class="player-video-area">
<h265web
style="width: 100%; height: 100%;"
ref="h265web"
:video-url="videoUrl"
:has-audio="hasAudio"
:show-button="showButton"
fluent autoplay live
/>
</div>
</el-tab-pane>
<el-tabs v-if="showTab && playerCount > 1" v-model="activePlayer" type="card" :stretch="true" @tab-click="changePlayer">
<el-tab-pane label="Jessibuca" name="jessibuca"></el-tab-pane>
<el-tab-pane label="WebRTC" name="webRTC"></el-tab-pane>
<el-tab-pane label="h265web" name="h265web"></el-tab-pane>
</el-tabs>
<div v-if="playerCount <= 1" class="player-video-area">
<div class="player-video-area">
<jessibucaPlayer
v-if="player.jessibuca"
v-if="activePlayer === 'jessibuca'"
ref="jessibuca"
style="width: 100%; height: 100%;"
:video-url="videoUrl"
:has-audio="hasAudio"
:show-button="showButton"
fluent autoplay live
/>
<rtc-player
v-if="player.webRTC"
v-if="activePlayer === 'webRTC'"
ref="webRTC"
style="width: 100%; height: 100%;"
:video-url="videoUrl"
:has-audio="hasAudio"
:show-button="showButton"
fluent autoplay live
/>
<h265web
v-if="player.h265web"
v-if="activePlayer === 'h265web'"
ref="h265web"
style="width: 100%; height: 100%;"
:video-url="videoUrl"
:has-audio="hasAudio"
:show-button="showButton"
fluent autoplay live
@ -77,13 +43,13 @@ export default {
name: 'PlayerTabs',
components: { jessibucaPlayer, rtcPlayer, h265web },
props: {
videoUrl: { type: String, default: '' },
hasAudio: { type: Boolean, default: false },
showButton: { type: Boolean, default: true },
height: { type: String, default: '' }
showButton: { type: Boolean, default: true }
},
data() {
return {
showTab: true,
streamInfo: null,
activePlayer: 'jessibuca',
player: { jessibuca: ['ws_flv', 'wss_flv'], webRTC: ['rtc', 'rtcs'], h265web: ['ws_flv', 'wss_flv'] }
}
@ -99,10 +65,9 @@ export default {
}
},
methods: {
getUrlByStreamInfo(streamInfo) {
const info = streamInfo || this.streamInfo
if (!info) return ''
const src = info.transcodeStream || info
getUrlByStreamInfo() {
if (!this.streamInfo) return ''
const src = this.streamInfo.transcodeStream || this.streamInfo
if (location.protocol === 'https:') {
return src[this.player[this.activePlayer][1]]
}
@ -110,14 +75,23 @@ export default {
},
changePlayer(tab) {
this.activePlayer = tab.name
this.$emit('player-changed', this.activePlayer)
this.play()
},
play(url) {
setStreamInfo(streamInfo) {
this.streamInfo = streamInfo
this.play()
},
play() {
let playUrl = this.getUrlByStreamInfo()
this.$nextTick(() => {
if (this.$refs[this.activePlayer]) {
this.$refs[this.activePlayer].play(url)
this.$refs[this.activePlayer].play(playUrl)
}
})
const typeMap = { jessibuca: 0, webRTC: 1, h265web: 2 }
const type = typeMap[this.activePlayer] || 0
const playerUrl = window.location.origin + '/#/play/share?type=' + type + '&url=' + encodeURIComponent(playUrl)
this.$emit('playerChanged', { playUrl, playerUrl })
},
stop() {
if (this.$refs[this.activePlayer]) {

View File

@ -1,69 +1,81 @@
<template>
<div class="ptz-section-inner">
<div class="ptz-left">
<div class="ptz-top">
<div class="ptz-dpad">
<div class="dpad-ring"></div>
<button class="dpad-btn card card-up" @mousedown.prevent="$emit('ptz-move', { direction: 'up', speed: controSpeed })" @mouseup.prevent="$emit('ptz-stop')"></button>
<button class="dpad-btn card card-right" @mousedown.prevent="$emit('ptz-move', { direction: 'right', speed: controSpeed })" @mouseup.prevent="$emit('ptz-stop')"></button>
<button class="dpad-btn card card-down" @mousedown.prevent="$emit('ptz-move', { direction: 'down', speed: controSpeed })" @mouseup.prevent="$emit('ptz-stop')"></button>
<button class="dpad-btn card card-left" @mousedown.prevent="$emit('ptz-move', { direction: 'left', speed: controSpeed })" @mouseup.prevent="$emit('ptz-stop')"></button>
<button class="dpad-btn diag diag-upright" @mousedown.prevent="$emit('ptz-move', { direction: 'upright', speed: controSpeed })" @mouseup.prevent="$emit('ptz-stop')"><span style="display:inline-block;transform:rotate(45deg)"></span></button>
<button class="dpad-btn diag diag-downright" @mousedown.prevent="$emit('ptz-move', { direction: 'downright', speed: controSpeed })" @mouseup.prevent="$emit('ptz-stop')"><span style="display:inline-block;transform:rotate(135deg)"></span></button>
<button class="dpad-btn diag diag-downleft" @mousedown.prevent="$emit('ptz-move', { direction: 'downleft', speed: controSpeed })" @mouseup.prevent="$emit('ptz-stop')"><span style="display:inline-block;transform:rotate(225deg)"></span></button>
<button class="dpad-btn diag diag-upleft" @mousedown.prevent="$emit('ptz-move', { direction: 'upleft', speed: controSpeed })" @mouseup.prevent="$emit('ptz-stop')"><span style="display:inline-block;transform:rotate(-45deg)"></span></button>
<button class="dpad-btn card card-up" @mousedown.prevent="handlePtzMove('up')" @mouseup.prevent="handlePtzStop()"></button>
<button class="dpad-btn card card-right" @mousedown.prevent="handlePtzMove('right')" @mouseup.prevent="handlePtzStop()"></button>
<button class="dpad-btn card card-down" @mousedown.prevent="handlePtzMove('down')" @mouseup.prevent="handlePtzStop()"></button>
<button class="dpad-btn card card-left" @mousedown.prevent="handlePtzMove('left')" @mouseup.prevent="handlePtzStop()"></button>
<button class="dpad-btn diag diag-upright" @mousedown.prevent="handlePtzMove('upright')" @mouseup.prevent="handlePtzStop()"><span style="display:inline-block;transform:rotate(45deg)"></span></button>
<button class="dpad-btn diag diag-downright" @mousedown.prevent="handlePtzMove('downright')" @mouseup.prevent="handlePtzStop()"><span style="display:inline-block;transform:rotate(135deg)"></span></button>
<button class="dpad-btn diag diag-downleft" @mousedown.prevent="handlePtzMove('downleft')" @mouseup.prevent="handlePtzStop()"><span style="display:inline-block;transform:rotate(225deg)"></span></button>
<button class="dpad-btn diag diag-upleft" @mousedown.prevent="handlePtzMove('upleft')" @mouseup.prevent="handlePtzStop()"><span style="display:inline-block;transform:rotate(-45deg)"></span></button>
<button class="dpad-btn dpad-center" title="停止" @click="$emit('ptz-stop')"></button>
</div>
<div class="ptz-speed-slider">
<span class="ptz-speed-label">速度</span>
<el-slider v-model="controSpeed" :max="8" :min="1" style="flex: 1" />
<div class="ptz-func-col">
<div class="ptz-func-group" :class="{ row: btnLayout === 'row' }">
<div class="ptz-func-row">
<div class="ptz-func-row">
<div class="ptz-func-btn" title="看守位" @click.prevent="$emit('ptz-guard')">
<i class="el-icon-s-home" /><span>看守位</span>
</div>
</div>
</div>
<div class="ptz-func-row">
<div class="ptz-func-btn" title="变倍+" @mousedown.prevent="handlePtzMove('zoomin')" @mouseup.prevent="handlePtzStop()">
<i class="el-icon-zoom-in" /><span>变倍+</span>
</div>
<div class="ptz-func-btn" title="变倍-" @mousedown.prevent="handlePtzMove('zoomout')" @mouseup.prevent="handlePtzStop()">
<i class="el-icon-zoom-out" /><span>变倍-</span>
</div>
</div>
<div class="ptz-func-row">
<div class="ptz-func-btn" title="聚焦+" @mousedown.prevent="$emit('focus-move', { command: 'near', speed: controSpeed })" @mouseup.prevent="$emit('focus-stop')">
<i class="iconfont icon-bianjiao-fangda" /><span>聚焦+</span>
</div>
<div class="ptz-func-btn" title="聚焦-" @mousedown.prevent="$emit('focus-move', { command: 'far', speed: controSpeed })" @mouseup.prevent="$emit('focus-stop')">
<i class="iconfont icon-bianjiao-suoxiao" /><span>聚焦-</span>
</div>
</div>
<div class="ptz-func-row">
<div class="ptz-func-btn" title="光圈+" @mousedown.prevent="$emit('iris-move', { command: 'in', speed: controSpeed })" @mouseup.prevent="$emit('iris-stop')">
<i class="iconfont icon-guangquan" /><span>光圈+</span>
</div>
<div class="ptz-func-btn" title="光圈-" @mousedown.prevent="$emit('iris-move', { command: 'out', speed: controSpeed })" @mouseup.prevent="$emit('iris-stop')">
<i class="iconfont icon-guangquan-" /><span>光圈-</span>
</div>
</div>
<div class="ptz-func-row">
<div class="ptz-func-btn" title="拉框放大" @mousedown.prevent="$emit('iris-move', { command: 'in', speed: controSpeed })" @mouseup.prevent="$emit('iris-stop')">
<i class="iconfont icon-guangquan" /><span>拉框放大</span>
</div>
</div>
</div>
</div>
</div>
<div class="ptz-right">
<div class="ptz-func-group">
<div class="ptz-func-row">
<div class="ptz-func-btn" title="变倍+" @mousedown.prevent="$emit('ptz-move', { direction: 'zoomin', speed: controSpeed })" @mouseup.prevent="$emit('ptz-stop')">
<i class="el-icon-zoom-in" /><span>变倍+</span>
</div>
<div class="ptz-func-btn" title="变倍-" @mousedown.prevent="$emit('ptz-move', { direction: 'zoomout', speed: controSpeed })" @mouseup.prevent="$emit('ptz-stop')">
<i class="el-icon-zoom-out" /><span>变倍-</span>
</div>
</div>
<div class="ptz-func-row">
<div class="ptz-func-btn" title="聚焦+" @mousedown.prevent="$emit('focus-move', { command: 'near', speed: controSpeed })" @mouseup.prevent="$emit('focus-stop')">
<i class="iconfont icon-bianjiao-fangda" /><span>聚焦+</span>
</div>
<div class="ptz-func-btn" title="聚焦-" @mousedown.prevent="$emit('focus-move', { command: 'far', speed: controSpeed })" @mouseup.prevent="$emit('focus-stop')">
<i class="iconfont icon-bianjiao-suoxiao" /><span>聚焦-</span>
</div>
</div>
<div class="ptz-func-row">
<div class="ptz-func-btn" title="光圈+" @mousedown.prevent="$emit('iris-move', { command: 'in', speed: controSpeed })" @mouseup.prevent="$emit('iris-stop')">
<i class="iconfont icon-guangquan" /><span>光圈+</span>
</div>
<div class="ptz-func-btn" title="光圈-" @mousedown.prevent="$emit('iris-move', { command: 'out', speed: controSpeed })" @mouseup.prevent="$emit('iris-stop')">
<i class="iconfont icon-guangquan-" /><span>光圈-</span>
</div>
</div>
<div class="ptz-bottom">
<div class="slider-with-controls">
<span class="slider-label">速度</span>
<el-button type="text" icon="el-icon-minus" class="slider-btn" @click="adjustSpeed(-1)" />
<el-slider v-model="controSpeed" :max="100" :min="1" />
<el-button type="text" icon="el-icon-plus" class="slider-btn" @click="adjustSpeed(1)" />
<span class="slider-value">{{ controSpeed }}</span>
</div>
<ptzPrecise v-if="showPrecise" :device-id="deviceId" :channel-device-id="channelId" @position="$emit('precise-position', $event)" style="margin-top: 6px" />
</div>
</div>
</template>
<script>
import ptzPrecise from './ptzPrecise.vue'
export default {
name: 'PtzControls',
components: { ptzPrecise },
props: {
deviceId: { type: String, default: null },
channelId: { type: String, default: null },
showPrecise: { type: Boolean, default: true }
btnLayout: { type: String, default: 'column' }
},
data() {
return {
controSpeed: 5
controSpeed: 50,
currentCommand: null
}
},
mounted() {
@ -73,8 +85,24 @@ export default {
window.removeEventListener('mouseup', this.onWindowMouseUp)
},
methods: {
adjustSpeed(delta) {
const newVal = this.controSpeed + delta
if (newVal >= 1 && newVal <= 100) {
this.controSpeed = newVal
}
},
handlePtzMove(direction) {
this.currentCommand = direction
this.$emit('ptz-move', { direction, speed: this.controSpeed })
},
handlePtzStop() {
this.$emit('ptz-stop', { direction: this.currentCommand })
this.currentCommand = null
},
onWindowMouseUp() {
this.$emit('ptz-stop')
if (this.currentCommand) {
this.handlePtzStop()
}
}
}
}
@ -83,14 +111,15 @@ export default {
<style scoped>
.ptz-section-inner {
display: flex;
flex-direction: column;
padding: 8px 4px;
overflow-y: auto;
}
.ptz-left {
.ptz-top {
display: flex;
flex-direction: column;
align-items: center;
margin-right: 12px;
gap: 12px;
flex: 1;
min-height: 0;
}
.ptz-dpad {
position: relative;
@ -185,19 +214,14 @@ export default {
background: #337ecc;
transform: translate(-50%, -50%) scale(0.92);
}
.ptz-speed-slider {
.ptz-func-col {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
width: 120px;
margin-top: 8px;
justify-content: center;
min-width: 0;
}
.ptz-speed-label {
font-size: 12px;
color: #606266;
margin-right: 6px;
white-space: nowrap;
}
.ptz-right { flex: 1; }
.ptz-func-group {
display: flex;
flex-wrap: wrap;
@ -220,7 +244,7 @@ export default {
cursor: pointer;
background: #fff;
user-select: none;
font-size: 11px;
font-size: 12px;
}
.ptz-func-btn:hover {
background: #409EFF;
@ -230,4 +254,39 @@ export default {
background: #337ecc;
}
.ptz-func-btn i { font-size: 14px; margin-bottom: 2px; }
.ptz-func-group.row .ptz-func-btn {
flex-direction: row;
gap: 4px;
}
.ptz-func-group.row .ptz-func-btn i {
margin-bottom: 0;
margin-right: 4px;
}
.ptz-bottom {
margin-top: 12px;
padding: 0 4px;
}
.slider-label {
font-size: 13px;
color: #606266;
white-space: nowrap;
}
.slider-btn {
font-weight: bold;
color: #1a1a1a;
}
.slider-with-controls {
display: flex;
align-items: center;
gap: 8px;
}
.slider-with-controls .el-slider {
flex: 1;
}
.slider-value {
min-width: 28px;
text-align: center;
font-size: 13px;
color: #606266;
}
</style>

View File

@ -12,6 +12,7 @@
:show-precise="false"
@ptz-move="onPtzMove"
@ptz-stop="onPtzStop"
@ptz-guard="onPtzGuard"
@focus-move="onFocusMove"
@focus-stop="onFocusStop"
@iris-move="onIrisMove"
@ -48,14 +49,35 @@ export default {
},
methods: {
ptzSpeed(speed) {
return parseInt(speed * 255 / 8)
return parseInt(speed * 255 / 100)
},
onPtzMove(e) {
const speedVal = this.ptzSpeed(e.speed)
this.$store.dispatch('frontEnd/ptz', [this.deviceId, this.channelDeviceId, e.direction, speedVal, speedVal, speedVal])
this.$store.dispatch('frontEnd/ptz', {
deviceId: this.deviceId,
channelId: this.channelDeviceId,
command: e.direction,
horizonSpeed: speedVal,
verticalSpeed: speedVal,
zoomSpeed: speedVal
})
},
onPtzStop() {
this.$store.dispatch('frontEnd/ptz', [this.deviceId, this.channelDeviceId, 'stop', 0, 0, 0])
this.$store.dispatch('frontEnd/ptz', {
deviceId: this.deviceId,
channelId: this.channelDeviceId,
command: 'stop',
horizonSpeed: 0,
verticalSpeed: 0,
zoomSpeed: 0
})
},
onPtzGuard() {
this.$store.dispatch('device/homePosition', {
deviceId: this.deviceId,
channelId: this.channelDeviceId,
enabled: true
})
},
onFocusMove(e) {
const speedVal = this.ptzSpeed(e.speed)

View File

@ -15,17 +15,17 @@
<div class="player-side">
<div class="player-container" :style="{ height: playerHeight }">
<playerTabs ref="playerTabs" :video-url="videoUrl" :has-audio="hasAudio" :show-button="true" />
<playerTabs ref="playerTabs" :has-audio="hasAudio" :show-button="true" @playerChanged="playerChanged"/>
</div>
</div>
<div class="control-side">
<div v-if="showPtz" class="ptz-section">
<div class="ptz-section">
<ptzControls
:device-id="deviceId"
:channel-id="channelId"
btn-layout="row"
@ptz-move="onPtzMove"
@ptz-stop="onPtzStop"
@ptz-guard="onPtzGuard"
@focus-move="onFocusMove"
@focus-stop="onFocusStop"
@iris-move="onIrisMove"
@ -39,31 +39,31 @@
v-if="tabActiveName === 'preset'"
:device-id="deviceId"
:channel-device-id="channelId"
style="margin-top: 8px"
style="margin-top: 8px;"
/>
</el-tab-pane>
<el-tab-pane label="实时视频" name="media">
<div v-if="tabActiveName === 'media'" class="media-info-content">
<div class="media-row">
<span class="media-label">播放地址</span>
<el-input v-model="getPlayerShared.sharedUrl" :disabled="true">
<el-input v-model="playerUrlInfo.playerUrl" :disabled="true">
<template slot="append">
<i class="cpoy-btn el-icon-document-copy" title="点击拷贝" style="cursor: pointer" @click="copyUrl(getPlayerShared.sharedUrl)" />
<i class="cpoy-btn el-icon-document-copy" title="点击拷贝" style="cursor: pointer" @click="copyUrl(playerUrlInfo.playerUrl)" />
</template>
</el-input>
</div>
<div class="media-row">
<span class="media-label">iframe</span>
<el-input v-model="getPlayerShared.sharedIframe" :disabled="true">
<el-input v-model="sharedIframe" :disabled="true">
<template slot="append">
<i class="cpoy-btn el-icon-document-copy" title="点击拷贝" style="cursor: pointer" @click="copyUrl(getPlayerShared.sharedIframe)" />
<i class="cpoy-btn el-icon-document-copy" title="点击拷贝" style="cursor: pointer" @click="copyUrl(sharedIframe)" />
</template>
</el-input>
</div>
<div class="media-row">
<span class="media-label">资源地址</span>
<el-input v-model="getPlayerShared.sharedRtmp" :disabled="true">
<el-button slot="append" icon="el-icon-document-copy" title="点击拷贝" style="cursor: pointer" @click="copyUrl(getPlayerShared.sharedIframe)" />
<el-input v-model="playerUrlInfo.playUrl" :disabled="true">
<el-button slot="append" icon="el-icon-document-copy" title="点击拷贝" style="cursor: pointer" @click="copyUrl(playerUrlInfo.playUrl)" />
<el-dropdown v-if="streamInfo" slot="prepend" trigger="click" @command="copyUrl">
<el-button>更多地址<i class="el-icon-arrow-down el-icon--right" /></el-button>
<el-dropdown-menu slot="dropdown">
@ -148,25 +148,21 @@ export default {
hasAudio: false,
isLoging: false,
showVideoDialog: false,
showPtz: true,
showBroadcast: true,
streamInfo: null,
broadcastMode: true,
broadcastRtc: null,
broadcastStatus: -1,
playerHeight: '36vh'
playerHeight: '48vh',
playerUrlInfo: {
playerUrl: null,
playUrl: null,
}
}
},
computed: {
getPlayerShared: function() {
const typeMap = { jessibuca: 0, webRTC: 1, h265web: 2 }
const type = typeMap['jessibuca'] || 0
const baseUrl = window.location.origin + '/#/play/share?type=' + type + '&url=' + encodeURIComponent(this.videoUrl)
return {
sharedUrl: baseUrl,
sharedIframe: '<iframe src="' + baseUrl + '"></iframe>',
sharedRtmp: this.videoUrl
}
sharedIframe: function(){
return `<iframe src="${this.playerUrlInfo.playerUrl}"></iframe>`
}
},
created() {
@ -174,14 +170,35 @@ export default {
},
methods: {
ptzSpeed(speed) {
return parseInt(speed * 255 / 8)
return parseInt(speed * 255 / 100)
},
onPtzMove(e) {
const speedVal = this.ptzSpeed(e.speed)
this.$store.dispatch('frontEnd/ptz', [this.deviceId, this.channelId, e.direction, speedVal, speedVal, speedVal])
this.$store.dispatch('frontEnd/ptz', {
deviceId: this.deviceId,
channelId: this.channelId,
command: e.direction,
horizonSpeed: speedVal,
verticalSpeed: speedVal,
zoomSpeed: parseInt(e.speed * 15 / 100)
})
},
onPtzStop() {
this.$store.dispatch('frontEnd/ptz', [this.deviceId, this.channelId, 'stop', 0, 0, 0])
this.$store.dispatch('frontEnd/ptz', {
deviceId: this.deviceId,
channelId: this.channelId,
command: 'stop',
horizonSpeed: 0,
verticalSpeed: 0,
zoomSpeed: 0
})
},
onPtzGuard() {
this.$store.dispatch('device/homePosition', {
deviceId: this.deviceId,
channelId: this.channelId,
enabled: true
})
},
onFocusMove(e) {
const speedVal = this.ptzSpeed(e.speed)
@ -221,25 +238,18 @@ export default {
this.streamInfo = streamInfo
this.hasAudio = hasAudio
this.isLoging = false
this.videoUrl = this.getUrlByStreamInfo(streamInfo)
this.streamId = streamInfo.stream
this.app = streamInfo.app
this.mediaServerId = streamInfo.mediaServerId
this.showVideoDialog = true
this.$nextTick(() => {
if (this.$refs.playerTabs) {
this.$refs.playerTabs.play(this.videoUrl)
this.$refs.playerTabs.setStreamInfo(streamInfo)
}
})
},
getUrlByStreamInfo(streamInfo) {
const info = streamInfo || this.streamInfo
if (!info) return ''
const src = info.transcodeStream || info
if (location.protocol === 'https:') {
return src['wss_flv']
}
return src['ws_flv']
playerChanged: function(playerUrlInfo) {
this.playerUrlInfo = playerUrlInfo
},
close: function() {
if (this.$refs.playerTabs) {
@ -249,9 +259,6 @@ export default {
this.showVideoDialog = false
this.stopBroadcast()
},
videoError: function(e) {
console.log('播放器错误:' + JSON.stringify(e))
},
copyUrl: function(dropdownItem) {
this.$copyText(dropdownItem).then(() => {
this.$message.success({ showClose: true, message: '成功拷贝到粘贴板' })
@ -318,7 +325,7 @@ export default {
.player-container { width: 100%; }
.control-side { flex: 2; min-width: 340px; display: flex; flex-direction: column; }
.ptz-section { flex-shrink: 0; margin-bottom: 8px; }
.control-tabs { flex: 1; display: flex; flex-direction: column; }
.control-tabs { flex: 1; display: flex; flex-direction: column; min-height: 180px}
.control-tabs .el-tabs__content { flex: 1; overflow: auto; }
.media-info-content { overflow: auto; }
.media-row { display: flex; margin-bottom: 0.5rem; height: 2.5rem; }