|
|
@@ -1,10 +1,15 @@
|
|
|
<template>
|
|
|
- <div ref="easyPlayerRef" style="width: 200px; height: 300px; background-color: #000000"></div>
|
|
|
+ <div
|
|
|
+ ref="easyPlayerRef"
|
|
|
+ style="width: 100%; height: 100%; background-color: #000000; margin: 0 auto"
|
|
|
+ ></div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import { ref, reactive, onMounted, onBeforeUnmount, nextTick, watch } from 'vue'
|
|
|
import { ptzdirection, ptzscale } from '@/api/pms/video/sipdevice'
|
|
|
+import { useRoute } from 'vue-router'
|
|
|
+const route = useRoute()
|
|
|
|
|
|
// 响应式数据
|
|
|
const easyPlayerRef = ref(null)
|
|
|
@@ -12,6 +17,10 @@ const playInfo = ref({})
|
|
|
const playInfo2 = ref({})
|
|
|
const playtype = ref('play')
|
|
|
const props = defineProps({
|
|
|
+ videourl: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
playerInfo: {
|
|
|
type: Object,
|
|
|
default: null
|
|
|
@@ -25,10 +34,15 @@ const props = defineProps({
|
|
|
default: '630px'
|
|
|
}
|
|
|
})
|
|
|
+const playing = ref(false)
|
|
|
|
|
|
-const videoUrl = ref('')
|
|
|
+let videoUrl = ref('')
|
|
|
const isPlay = ref(false)
|
|
|
|
|
|
+let easyplayer = {}
|
|
|
+
|
|
|
+const emit = defineEmits(['screenshot', 'destroy'])
|
|
|
+
|
|
|
const config = reactive({
|
|
|
hasAudio: true,
|
|
|
isLive: true,
|
|
|
@@ -36,39 +50,125 @@ const config = reactive({
|
|
|
WCS: false
|
|
|
})
|
|
|
|
|
|
-// 方法定义
|
|
|
-const play = async (url) => {
|
|
|
- console.log('EasyPlayer 播放视频 url: ', url)
|
|
|
- videoUrl.value = url
|
|
|
- await onDestroy()
|
|
|
- playCreate()
|
|
|
- onPlayer()
|
|
|
+const playCreate = () => {
|
|
|
+ const container = easyPlayerRef.value
|
|
|
+ if (!container) return
|
|
|
+
|
|
|
+ const uid = route.params._uid || Date.now() // 使用时间戳作为唯一标识
|
|
|
+
|
|
|
+ easyplayer[uid] = new EasyPlayerPro(container, {
|
|
|
+ isLive: config.isLive,
|
|
|
+ bufferTime: 0.2,
|
|
|
+ stretch: false,
|
|
|
+ MSE: config.MSE,
|
|
|
+ WCS: config.WCS,
|
|
|
+ hasAudio: config.hasAudio,
|
|
|
+ watermark: { text: { content: '' }, right: 10, top: 10 },
|
|
|
+ isBand: true,
|
|
|
+ btns: {
|
|
|
+ play: true,
|
|
|
+ audio: true,
|
|
|
+ record: true,
|
|
|
+ zoom: true,
|
|
|
+ ptz: true,
|
|
|
+ quality: true,
|
|
|
+ stretch: false,
|
|
|
+ screenshot: true,
|
|
|
+ fullscreen: true
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ let easyplay = easyplayer[uid]
|
|
|
+
|
|
|
+ easyplay.on('fullscreen', function (flag) {
|
|
|
+ console.log('is fullscreen', flag)
|
|
|
+ })
|
|
|
+
|
|
|
+ easyplay.on('ptz', (direction) => {
|
|
|
+ handlePtz(direction)
|
|
|
+ })
|
|
|
+
|
|
|
+ easyplay.on('playbackRate', (rate) => {
|
|
|
+ easyplay.setRate(rate)
|
|
|
+ })
|
|
|
+
|
|
|
+ easyplay.on('playbackSeek', (data) => {
|
|
|
+ console.log('playbackSeek', data)
|
|
|
+ })
|
|
|
+
|
|
|
+ playInfo.value = easyplayer
|
|
|
+ if (playInfo2.value && playInfo2.value.id && playInfo2.value.deviceId) {
|
|
|
+ playInfo.value.channelId = playInfo2.value.id
|
|
|
+ playInfo.value.deviceId = playInfo2.value.deviceId
|
|
|
+ }
|
|
|
+
|
|
|
+ playInfo.value.playtype = playtype.value
|
|
|
}
|
|
|
|
|
|
-const pause = () => {
|
|
|
- onPause()
|
|
|
+// 播放视频
|
|
|
+function play(url) {
|
|
|
+ const uid = route.params._uid || Date.now()
|
|
|
+
|
|
|
+ // 确保容器已准备就绪
|
|
|
+ if (!easyPlayerRef.value) {
|
|
|
+ console.error('Cannot play: container is not ready')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (easyplayer[uid]) {
|
|
|
+ destroy().then(() => {
|
|
|
+ if (easyplayer[uid]) {
|
|
|
+ easyplayer[uid].play(url)
|
|
|
+ } else {
|
|
|
+ easyplayer[uid].on('load', () => {
|
|
|
+ console.log('load 播放')
|
|
|
+ easyplayer[uid].play(url)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ playCreate()
|
|
|
+
|
|
|
+ if (easyplayer[uid]) {
|
|
|
+ easyplayer[uid].play(url)
|
|
|
+ } else {
|
|
|
+ easyplayer[uid].on('load', () => {
|
|
|
+ console.log('load 播放')
|
|
|
+ easyplayer[uid].play(url)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-const destroy = () => {
|
|
|
- onDestroy()
|
|
|
+const pause = () => {
|
|
|
+ const uid = route.params._uid || Date.now()
|
|
|
+
|
|
|
+ if (easyplayer[uid]) {
|
|
|
+ easyplayer[uid].pause()
|
|
|
+ }
|
|
|
+ playing.value = false
|
|
|
}
|
|
|
|
|
|
-const registercallback = (events, func) => {}
|
|
|
+// 截图
|
|
|
+const screenshot = () => {
|
|
|
+ const uid = route.params._uid || Date.now()
|
|
|
|
|
|
-const onUse = (type) => {
|
|
|
- if (type === 'hasAudio') {
|
|
|
- config.hasAudio = !config.hasAudio
|
|
|
- } else {
|
|
|
- config.MSE = false
|
|
|
- config.WCS = false
|
|
|
- if (type === 'MSE') config.MSE = true
|
|
|
- if (type === 'WCS') config.WCS = true
|
|
|
+ if (easyplayer[uid]) {
|
|
|
+ easyplayer[uid].screenshot()
|
|
|
+ emit('screenshot', easyplayer[uid].screenshot())
|
|
|
}
|
|
|
- if (isPlay.value) {
|
|
|
- onDestroy().then(() => {
|
|
|
+}
|
|
|
+
|
|
|
+const destroy = async () => {
|
|
|
+ const uid = route.params._uid || Date.now()
|
|
|
+
|
|
|
+ if (easyplayer[uid]) {
|
|
|
+ await easyplayer[uid].destroy().then(() => {
|
|
|
+ easyplayer[uid] = null
|
|
|
+ playing.value = false
|
|
|
playCreate()
|
|
|
- onPlayer()
|
|
|
})
|
|
|
+ emit('destroy', uid)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -78,47 +178,16 @@ const setFullscreen = () => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-const onPause = () => {
|
|
|
- if (playInfo.value) {
|
|
|
- playInfo.value.pause()
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
const onMute = () => {
|
|
|
- if (playInfo.value) {
|
|
|
- playInfo.value.setMute(true)
|
|
|
- }
|
|
|
-}
|
|
|
+ // if (playInfo.value) {
|
|
|
+ // playInfo.value.setMute(true)
|
|
|
+ // }
|
|
|
|
|
|
-const onPlayer = () => {
|
|
|
- isPlay.value = true
|
|
|
- nextTick(() => {
|
|
|
- if (playInfo.value) {
|
|
|
- playInfo.value
|
|
|
- .play(videoUrl.value)
|
|
|
- .then(() => {})
|
|
|
- .catch((e) => {
|
|
|
- console.error(e)
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
+ const uid = route.params._uid || Date.now()
|
|
|
|
|
|
-const onPlayerPlayback = () => {
|
|
|
- onDestroy().then(() => {
|
|
|
- playCreate()
|
|
|
- config.isLive = false
|
|
|
- nextTick(() => {
|
|
|
- if (playInfo.value) {
|
|
|
- playInfo.value
|
|
|
- .play(videoUrl.value)
|
|
|
- .then(() => {})
|
|
|
- .catch((e) => {
|
|
|
- console.error(e)
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
- })
|
|
|
+ if (easyplayer[uid]) {
|
|
|
+ easyplayer[uid].setMute(true)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
const onStop = async () => {
|
|
|
@@ -127,24 +196,6 @@ const onStop = async () => {
|
|
|
playCreate()
|
|
|
}
|
|
|
|
|
|
-const onDestroy = () => {
|
|
|
- return new Promise((resolve) => {
|
|
|
- if (playInfo.value) {
|
|
|
- playInfo.value.destroy()
|
|
|
- playInfo.value = null
|
|
|
- }
|
|
|
- setTimeout(() => {
|
|
|
- resolve()
|
|
|
- }, 100)
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-const onReplay = async () => {
|
|
|
- await onDestroy()
|
|
|
- playCreate()
|
|
|
- onPlayer()
|
|
|
-}
|
|
|
-
|
|
|
// 处理PTZ控制
|
|
|
const handlePtz = (arrow) => {
|
|
|
let leftRight = 0
|
|
|
@@ -172,93 +223,82 @@ const handlePtz = (arrow) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-const playCreate = () => {
|
|
|
- const container = easyPlayerRef.value
|
|
|
- if (!container) return
|
|
|
-
|
|
|
- const easyplayer = new EasyPlayerPro(container, {
|
|
|
- isLive: config.isLive,
|
|
|
- bufferTime: 0.2,
|
|
|
- stretch: false,
|
|
|
- MSE: config.MSE,
|
|
|
- WCS: config.WCS,
|
|
|
- hasAudio: config.hasAudio,
|
|
|
- watermark: { text: { content: '' }, right: 10, top: 10 },
|
|
|
- isBand: true,
|
|
|
- btns: {
|
|
|
- play: true,
|
|
|
- audio: true,
|
|
|
- record: true,
|
|
|
- zoom: true,
|
|
|
- ptz: true,
|
|
|
- quality: true,
|
|
|
- stretch: false,
|
|
|
- screenshot: true,
|
|
|
- fullscreen: true
|
|
|
+watch(
|
|
|
+ () => props.videourl,
|
|
|
+ (newData, oldData) => {
|
|
|
+ if (easyPlayerRef.value) {
|
|
|
+ play(newData)
|
|
|
}
|
|
|
- })
|
|
|
-
|
|
|
- easyplayer.on('fullscreen', function (flag) {
|
|
|
- console.log('is fullscreen', flag)
|
|
|
- })
|
|
|
-
|
|
|
- easyplayer.on('ptz', (direction) => {
|
|
|
- handlePtz(direction)
|
|
|
- })
|
|
|
+ },
|
|
|
+ { immediate: true }
|
|
|
+)
|
|
|
|
|
|
- easyplayer.on('playbackRate', (rate) => {
|
|
|
- easyplayer.setRate(rate)
|
|
|
- })
|
|
|
+// 更新播放器DOM尺寸
|
|
|
+const updatePlayerDomSize = () => {
|
|
|
+ if (!easyPlayerRef.value) return
|
|
|
|
|
|
- easyplayer.on('playbackSeek', (data) => {
|
|
|
- console.log('playbackSeek', data)
|
|
|
- })
|
|
|
+ let dom = easyPlayerRef.value
|
|
|
+ let width = dom.parentNode.clientWidth
|
|
|
+ let height = (9 / 16) * width
|
|
|
+ const clientHeight = Math.min(document.body.clientHeight, document.documentElement.clientHeight)
|
|
|
|
|
|
- playInfo.value = easyplayer
|
|
|
- if (playInfo2.value && playInfo2.value.channelId && playInfo2.value.deviceId) {
|
|
|
- playInfo.value.channelId = playInfo2.value.channelId
|
|
|
- playInfo.value.deviceId = playInfo2.value.deviceId
|
|
|
+ if (height > clientHeight) {
|
|
|
+ height = clientHeight
|
|
|
+ width = (16 / 9) * height
|
|
|
}
|
|
|
|
|
|
- playInfo.value.playtype = playtype.value
|
|
|
+ dom.style.width = width + 'px'
|
|
|
+ dom.style.height = height + 'px'
|
|
|
}
|
|
|
-watch(
|
|
|
- () => props.playerInfo,
|
|
|
- (newVal, oldVal) => {
|
|
|
- playInfo.value = newVal
|
|
|
- playInfo2.value = newVal
|
|
|
- if (newVal && newVal.playtype !== '') {
|
|
|
- playtype.value = newVal.playtype
|
|
|
- }
|
|
|
- }
|
|
|
-)
|
|
|
// 生命周期钩子
|
|
|
onMounted(() => {
|
|
|
+ console.log('####################', props.playerInfo)
|
|
|
+ window.onerror = (msg) => {
|
|
|
+ // console.error(msg)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保DOM已经渲染完毕后再初始化播放器
|
|
|
+ nextTick(() => {
|
|
|
+ updatePlayerDomSize()
|
|
|
+ window.onresize = () => {
|
|
|
+ updatePlayerDomSize()
|
|
|
+ }
|
|
|
+
|
|
|
+ let paramUrl = decodeURIComponent(route.params.url)
|
|
|
+ let url = props.videourl !== undefined ? props.videourl : paramUrl
|
|
|
+ console.log('初始化时的地址为: ' + url)
|
|
|
+
|
|
|
+ // 确保容器已准备就绪
|
|
|
+ if (easyPlayerRef.value) {
|
|
|
+ play(url)
|
|
|
+ } else {
|
|
|
+ console.error('Container element is not available')
|
|
|
+ }
|
|
|
+ })
|
|
|
playInfo.value = props.playerInfo
|
|
|
playInfo2.value = props.playerInfo
|
|
|
+ videoUrl.value = props.videourl
|
|
|
+
|
|
|
if (playInfo.value && playInfo.value.playtype !== '') {
|
|
|
playtype.value = playInfo.value.playtype
|
|
|
}
|
|
|
- playCreate()
|
|
|
})
|
|
|
|
|
|
-onBeforeUnmount(() => {
|
|
|
- onDestroy()
|
|
|
+onUnmounted(() => {
|
|
|
+ if (easyplayer[route.params._uid]) {
|
|
|
+ easyplayer[route.params._uid].destroy()
|
|
|
+ }
|
|
|
+ playing.value = false
|
|
|
})
|
|
|
|
|
|
defineExpose({
|
|
|
play,
|
|
|
pause,
|
|
|
destroy,
|
|
|
- registercallback,
|
|
|
- onUse,
|
|
|
setFullscreen,
|
|
|
- onPause,
|
|
|
onMute,
|
|
|
- onPlayer,
|
|
|
- onPlayerPlayback,
|
|
|
onStop,
|
|
|
- onReplay
|
|
|
+ updatePlayerDomSize
|
|
|
})
|
|
|
</script>
|
|
|
|