Commit ab77ae575f24c61c745c94e59bdfedfe23fde80f

Authored by ww
1 parent 46ab5b88

feat: 实现监控视频rtsp协议播放

... ... @@ -19,6 +19,7 @@
19 19 "dependencies": {
20 20 "@amap/amap-jsapi-loader": "^1.0.1",
21 21 "@amap/amap-jsapi-types": "^0.0.8",
  22 + "@fingerprintjs/fingerprintjs": "^3.4.1",
22 23 "@types/color": "^3.0.3",
23 24 "@types/crypto-js": "^4.1.1",
24 25 "@types/keymaster": "^1.6.30",
... ...
  1 +import { defHttp } from "@/utils/external/http/axios";
  2 +import { useGlobSetting } from '@/hooks/external/setting';
  3 +enum Api {
  4 + OPEN_FLV = '/rtsp/openFlv',
  5 + CLOSE_FLV = '/rtsp/closeFlv'
  6 +}
  7 +
  8 +export const getOpenFlvPlayUrl = (url: string, browserId: string) => {
  9 + const { urlPrefix, apiUrl } = useGlobSetting()
  10 + return `${apiUrl || ''}${urlPrefix || ''}${Api.OPEN_FLV}?url=${encodeURIComponent(url)}&browserId=${browserId}`;
  11 +};
  12 +
  13 +export const closeFlvPlay = (url: string, browserId: string) => {
  14 + return defHttp.get({
  15 + url: Api.CLOSE_FLV,
  16 + params: {
  17 + url: encodeURIComponent(url),
  18 + browserId
  19 + }
  20 + });
  21 +};
... ...
... ... @@ -6,11 +6,16 @@
6 6 </div>
7 7 </template>
8 8 <script setup lang="ts">
9   -import { onMounted, ref, onUnmounted, watch } from 'vue'
  9 +import { onMounted, ref, onUnmounted, watch, unref } from 'vue'
10 10 import videojs from 'video.js'
11 11 import 'videojs-flvjs-es6'
12 12 import type { VideoJsPlayerOptions } from 'video.js'
13 13 import 'video.js/dist/video-js.min.css'
  14 +import { getJwtToken, getShareJwtToken } from '@/utils/external/auth'
  15 +import { isShareMode } from '@/views/share/hook'
  16 +import { getOpenFlvPlayUrl, closeFlvPlay } from '@/api/external/flvPlay'
  17 +import { useFingerprint } from '@/utils/external/useFingerprint'
  18 +import { GetResult } from '@fingerprintjs/fingerprintjs'
14 19
15 20 const props = defineProps({
16 21 sourceSrc: {
... ... @@ -48,11 +53,10 @@ const isRtspProtocol = (url: string) => {
48 53 };
49 54
50 55 const getVideoTypeByUrl = (url = '') => {
51   -
52 56 try {
53 57 const { protocol, pathname } = new URL(url)
54 58
55   - if (isRtspProtocol(protocol)) return VideoPlayerType.flv
  59 + if (protocol.startsWith('rtsp:')) return VideoPlayerType.flv
56 60
57 61 const reg = /[^.]\w*$/
58 62 const mathValue = pathname.match(reg) || []
... ... @@ -72,6 +76,8 @@ const videoRef = ref<HTMLElement | null>(null)
72 76 // video实例对象
73 77 let videoPlayer: videojs.Player | null = null
74 78
  79 +const fingerprintResult = ref<Nullable<GetResult>>(null)
  80 +
75 81 //options配置
76 82 const options: VideoJsPlayerOptions & Recordable = {
77 83 language: 'zh-CN', // 设置语言
... ... @@ -92,16 +98,24 @@ const options: VideoJsPlayerOptions & Recordable = {
92 98 isLive: true,
93 99 cors: true,
94 100 withCredentials: false,
95   - }
  101 + },
96 102 },
97 103 }
98 104
99 105
  106 +const { getResult } = useFingerprint()
100 107 async function getSource() {
  108 + fingerprintResult.value = await getResult()
  109 + let src = props.sourceSrc || ''
  110 +
  111 + if (isRtspProtocol(props.sourceSrc!)) {
  112 + src = getOpenFlvPlayUrl(src, unref(fingerprintResult)?.visitorId || '')
  113 + }
  114 +
101 115 return [
102 116 {
103 117 type: getVideoTypeByUrl(props.sourceSrc),
104   - src: props.sourceSrc || ''
  118 + src
105 119 }
106 120 ]
107 121 }
... ... @@ -112,6 +126,17 @@ const initVideo = async () => {
112 126 // 创建 video 实例
113 127 options.sources = await getSource()
114 128 if (options.sources && options.sources.length) {
  129 +
  130 + if (isRtspProtocol(props.sourceSrc || '')) {
  131 + options.flvjs = {
  132 + ...(options.flvjs || {}),
  133 + config: {
  134 + headers: {
  135 + 'X-Authorization': `Bearer ${isShareMode() ? getShareJwtToken() : getJwtToken()}`,
  136 + }
  137 + }
  138 + }
  139 + }
115 140 videoPlayer = videojs(videoRef.value, options)
116 141 }
117 142 }
... ... @@ -135,6 +160,9 @@ onMounted(() => {
135 160 })
136 161
137 162 onUnmounted(() => {
  163 + if (props.sourceSrc) {
  164 + closeFlvPlay(props.sourceSrc, unref(fingerprintResult)!.visitorId!)
  165 + }
138 166 handleVideoDispose()
139 167 })
140 168
... ... @@ -154,6 +182,7 @@ defineExpose({
154 182 display: flex;
155 183 align-items: center;
156 184 justify-content: center;
  185 +
157 186 .my-video {
158 187 width: 100% !important;
159 188 height: 100% !important;
... ...
  1 +import { load } from '@fingerprintjs/fingerprintjs';
  2 +export const useFingerprint = () => {
  3 + const getResult = async () => {
  4 + const fp = await load();
  5 + const result = await fp.get();
  6 + return result;
  7 + };
  8 +
  9 + return { getResult };
  10 +};
... ...