new-map
parent
4b77a4e0ee
commit
47e700d274
|
|
@ -51,6 +51,7 @@
|
|||
"crypto-js": "^4.1.1",
|
||||
"dayjs": "^1.11.1",
|
||||
"echarts": "^5.3.2",
|
||||
"flv.js": "^1.6.2",
|
||||
"intro.js": "^5.1.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"mockjs": "^1.1.0",
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1667813004156" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2571" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M240.8 196l178.4 178.4-45.6 45.6-177.6-179.2-68 68V128h180.8l-68 68z m133.6 408.8L196 783.2 128 715.2V896h180.8l-68-68 178.4-178.4-44.8-44.8zM715.2 128l68 68-178.4 178.4 45.6 45.6 178.4-178.4 68 68V128H715.2z m-65.6 476.8l-45.6 45.6 178.4 178.4-68 68H896V715.2l-68 68-178.4-178.4z" p-id="2572"></path></svg>
|
||||
|
After Width: | Height: | Size: 638 B |
|
|
@ -32,9 +32,18 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="flex-1 px-11px flex flex-col">
|
||||
<div class="flex-1 border border-solid"></div>
|
||||
<div class="flex-1">
|
||||
<VideoFlv v-if="currentVido" :url="currentVido.url" :name="currentVido.base_name" />
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-x-6px my-10px">
|
||||
<div class="border border-solid h-66px" v-for="item in list" :key="item.id"> </div>
|
||||
<div class="h-66px" v-for="item in list" :key="item.id">
|
||||
<VideoFlv
|
||||
:url="item.url"
|
||||
:name="item.base_name"
|
||||
:screen="false"
|
||||
@click.prevent.stop="onChangeVideo(item)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -47,6 +56,7 @@
|
|||
import { Dropdown, Menu } from 'ant-design-vue'
|
||||
import { getAgriculturalDeviceBasic, getDevices } from '/@/api/sys/other'
|
||||
import Box from './Box.vue'
|
||||
import VideoFlv from './VideoFlv.vue'
|
||||
export default defineComponent({
|
||||
components: {
|
||||
Box,
|
||||
|
|
@ -54,6 +64,7 @@
|
|||
DownOutlined,
|
||||
Menu,
|
||||
MenuItem: Menu.Item,
|
||||
VideoFlv,
|
||||
},
|
||||
setup() {
|
||||
const Data = reactive({
|
||||
|
|
@ -64,6 +75,8 @@
|
|||
|
||||
const chartRef = ref<HTMLDivElement | null>(null)
|
||||
|
||||
const currentVido = ref<any>(null)
|
||||
|
||||
const currentTabValue = computed(
|
||||
() => Data.tabList.find((e) => e.id == Data.currentTab)?.name ?? '',
|
||||
)
|
||||
|
|
@ -71,6 +84,7 @@
|
|||
function onMenuClick({ key }) {
|
||||
if (Data.currentTab == key) return
|
||||
Data.currentTab = key
|
||||
getData()
|
||||
}
|
||||
|
||||
async function getTabs() {
|
||||
|
|
@ -79,6 +93,8 @@
|
|||
})
|
||||
Data.tabList = resData
|
||||
if (resData.length) Data.currentTab = resData[0].id
|
||||
|
||||
getData()
|
||||
}
|
||||
|
||||
async function getData() {
|
||||
|
|
@ -87,15 +103,30 @@
|
|||
type: 1,
|
||||
status: 1,
|
||||
})
|
||||
Data.list = resData
|
||||
Data.list = resData.map((e) => {
|
||||
// const { username, passage, ip, port, rtsp_url } = e.extends
|
||||
// const url = `rtsp://${username}:${passage}@${ip}:${port}${rtsp_url}`
|
||||
const url =
|
||||
'rtsp://admin:admin12345@183.222.79.115:9007/cam/realmonitor?channel=1&subtype=0'
|
||||
return {
|
||||
...e,
|
||||
url: `ws://127.0.0.1:8100/rtsp?url=${window.btoa(url)}`,
|
||||
}
|
||||
})
|
||||
if (Data.list.length > 0) currentVido.value = Data.list[0]
|
||||
}
|
||||
|
||||
function onChangeVideo(e) {
|
||||
currentVido.value = e
|
||||
}
|
||||
|
||||
onBeforeMount(() => {
|
||||
getTabs()
|
||||
getData()
|
||||
})
|
||||
|
||||
return {
|
||||
onChangeVideo,
|
||||
currentVido,
|
||||
...toRefs(Data),
|
||||
chartRef,
|
||||
currentTabValue,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,157 @@
|
|||
<template>
|
||||
<div class="w-full h-full relative">
|
||||
<SvgIcon
|
||||
v-if="isScreen && false"
|
||||
name="full-screen"
|
||||
class="text-white absolute left-15px top-15px z-20 cursor-pointer"
|
||||
size="20"
|
||||
@click="visibleModal = true"
|
||||
/>
|
||||
|
||||
<video
|
||||
@click.prevent.stop="onScreen"
|
||||
class="w-full h-full"
|
||||
autoplay
|
||||
controls
|
||||
ref="videoRef"
|
||||
muted
|
||||
></video>
|
||||
|
||||
<LinkModal v-model:visible="visibleModal" :footer="null" :title1="pName">
|
||||
<template #content>
|
||||
<div class="w-full">
|
||||
<VideoFlv :url="pUrl" :screen="false" :name="pName" />
|
||||
</div>
|
||||
</template>
|
||||
</LinkModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import flvjs from 'flv.js'
|
||||
import { defineComponent, ref, unref, onMounted, watch, onBeforeUnmount, computed } from 'vue'
|
||||
import { SvgIcon } from '/@/components/Icon'
|
||||
import LinkModal from '../LinkModal.vue'
|
||||
export default defineComponent({
|
||||
name: 'VideoFlv',
|
||||
components: {
|
||||
SvgIcon,
|
||||
LinkModal,
|
||||
},
|
||||
props: {
|
||||
url: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
screen: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
console.log(props)
|
||||
|
||||
const videoRef = ref<HTMLDivElement | null>(null)
|
||||
let player: any | null = null
|
||||
const pUrl = ref(props.url)
|
||||
|
||||
const visibleModal = ref(false)
|
||||
|
||||
const pName = computed(() => props.name)
|
||||
|
||||
const isScreen = computed(() => props.screen)
|
||||
|
||||
function videoPlayer() {
|
||||
if (!props.url) return
|
||||
if (flvjs.isSupported()) {
|
||||
let videoElement: any = unref(videoRef)
|
||||
var flvPlayer = flvjs.createPlayer({
|
||||
type: 'flv', // 媒体类型,默认是 flv,
|
||||
isLive: true, // 是否是直播流
|
||||
url: props.url, //你的url地址
|
||||
})
|
||||
flvPlayer.attachMediaElement(videoElement)
|
||||
flvPlayer.load()
|
||||
flvPlayer.play()
|
||||
player = flvPlayer
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
videoPlayer()
|
||||
})
|
||||
|
||||
function onScreen() {
|
||||
if (isScreen.value) {
|
||||
visibleModal.value = true
|
||||
}
|
||||
}
|
||||
|
||||
function destroyVideos() {
|
||||
if (!player) return
|
||||
player?.pause()
|
||||
player?.unload()
|
||||
player?.detachMediaElement()
|
||||
player?.destroy()
|
||||
player = null
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
destroyVideos()
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.url,
|
||||
(e) => {
|
||||
if (e) {
|
||||
destroyVideos()
|
||||
videoPlayer()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
return {
|
||||
pName,
|
||||
onScreen,
|
||||
isScreen,
|
||||
pUrl,
|
||||
visibleModal,
|
||||
videoRef,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
video::-webkit-media-controls-enclosure {
|
||||
display: none;
|
||||
}
|
||||
/* 进度条 */
|
||||
video::-webkit-media-controls-timeline {
|
||||
display: none;
|
||||
}
|
||||
|
||||
video::-webkit-media-controls-current-time-display {
|
||||
display: none;
|
||||
}
|
||||
/* 音量按钮 */
|
||||
video::-webkit-media-controls-mute-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
video::-webkit-media-controls-toggle-closed-captions-button {
|
||||
display: none;
|
||||
}
|
||||
/* 音量的控制条 */
|
||||
video::-webkit-media-controls-volume-slider {
|
||||
display: none;
|
||||
}
|
||||
/* 播放按钮 */
|
||||
video::-webkit-media-controls-play-button {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue