matrix_components 2.0.318 → 2.0.319
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/ComponentDemo/VideoDemo copy 2.vue +268 -0
- package/dist/ComponentDemo/VideoDemo copy 3.vue +356 -0
- package/dist/ComponentDemo/VideoDemo copy.vue +289 -0
- package/dist/ComponentDemo/VideoDemo.vue +187 -131
- package/dist/matrix_components.css +1 -1
- package/dist/matrix_components.js +159 -152
- package/dist/matrix_components.umd.cjs +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { onMounted, reactive, ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
const nsVideoRef = ref()
|
|
5
|
+
|
|
6
|
+
// 视频信息
|
|
7
|
+
const videoData = reactive({
|
|
8
|
+
// videoModel: 'hk',
|
|
9
|
+
// hkPath: '/martrix/cdn/h5player',
|
|
10
|
+
// 显示视频关闭按钮
|
|
11
|
+
showClose: false,
|
|
12
|
+
// 显示树
|
|
13
|
+
showTree: true,
|
|
14
|
+
// 树数据
|
|
15
|
+
treeData: [
|
|
16
|
+
{
|
|
17
|
+
id: '1',
|
|
18
|
+
label: '分组1',
|
|
19
|
+
children: [
|
|
20
|
+
{
|
|
21
|
+
id: '11',
|
|
22
|
+
label: '分组1-1',
|
|
23
|
+
children: [
|
|
24
|
+
{
|
|
25
|
+
videoModel: 'easyplayer',
|
|
26
|
+
id: '111',
|
|
27
|
+
label: '视频A--1视频A--1视频A--1',
|
|
28
|
+
url: 'http://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000001/hls.m3u8',
|
|
29
|
+
deviceId: 'a1',
|
|
30
|
+
channelId: 'a11',
|
|
31
|
+
icontype: 'on',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: 'D',
|
|
35
|
+
label: '视频A--2',
|
|
36
|
+
url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000013.live.flv',
|
|
37
|
+
deviceId: 'b1',
|
|
38
|
+
channelId: 'b11',
|
|
39
|
+
icontype: 'off',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: 'b',
|
|
45
|
+
label: '分组b',
|
|
46
|
+
children: [
|
|
47
|
+
{
|
|
48
|
+
id: 'b1',
|
|
49
|
+
label: '视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1视频A--1',
|
|
50
|
+
url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000003.live.flv',
|
|
51
|
+
deviceId: 'a1',
|
|
52
|
+
channelId: 'a11',
|
|
53
|
+
icontype: 'on',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'b2',
|
|
57
|
+
label: '视频A--2',
|
|
58
|
+
url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000015.live.flv',
|
|
59
|
+
deviceId: 'b1',
|
|
60
|
+
channelId: 'b11',
|
|
61
|
+
icontype: 'off',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: 'b3',
|
|
65
|
+
label: '视频A--3',
|
|
66
|
+
url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000009.live.flv',
|
|
67
|
+
deviceId: 'c1',
|
|
68
|
+
channelId: 'c11',
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 'xxx2',
|
|
77
|
+
label: '视频Zxxxx2',
|
|
78
|
+
url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000009.live.flv',
|
|
79
|
+
deviceId: '34020000001110000001',
|
|
80
|
+
channelId: '34020000001320000003',
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
// 树节点对应的key(!!!用于改变选中后的颜色)
|
|
84
|
+
treeNodeKey: 'id',
|
|
85
|
+
// 树节点展开的key
|
|
86
|
+
treeExpandedKeys: ['11'],
|
|
87
|
+
// 树节点属性 (videoUrlKey值要和treeData中的播放地址key一致, 默认为url)
|
|
88
|
+
treeOptions: {
|
|
89
|
+
icontype: 'icontype',
|
|
90
|
+
background: 'background',
|
|
91
|
+
videoUrlKey: 'url',
|
|
92
|
+
children: 'children',
|
|
93
|
+
label: 'label',
|
|
94
|
+
},
|
|
95
|
+
// 获取、设置打开的播放视频信息
|
|
96
|
+
videoInfos: [
|
|
97
|
+
{
|
|
98
|
+
index: 0,
|
|
99
|
+
url: 'https://sf3-ttcdn-tos.pstatp.com/obj/developer/bytdance.flv',
|
|
100
|
+
info: {
|
|
101
|
+
videoModel: 'easyplayer',
|
|
102
|
+
id: 'xxx2',
|
|
103
|
+
url: 'https://sf3-ttcdn-tos.pstatp.com/obj/developer/bytdance.flv',
|
|
104
|
+
deviceId: 'c1',
|
|
105
|
+
channelId: 'c11',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
// {
|
|
109
|
+
// index: 1,
|
|
110
|
+
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000015.live.flv',
|
|
111
|
+
// info: {
|
|
112
|
+
// videoModel: 'easyplayer',
|
|
113
|
+
// id: '222',
|
|
114
|
+
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000015.live.flv',
|
|
115
|
+
// deviceId: 'c2',
|
|
116
|
+
// channelId: 'c11',
|
|
117
|
+
// },
|
|
118
|
+
// },
|
|
119
|
+
// {
|
|
120
|
+
// index: 2,
|
|
121
|
+
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000009.live.flv',
|
|
122
|
+
// info: {
|
|
123
|
+
// videoModel: 'easyplayer',
|
|
124
|
+
// id: 'xxx2',
|
|
125
|
+
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000009.live.flv',
|
|
126
|
+
// deviceId: 'c3',
|
|
127
|
+
// channelId: 'c11',
|
|
128
|
+
// },
|
|
129
|
+
// },
|
|
130
|
+
// {
|
|
131
|
+
// index: 3,
|
|
132
|
+
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000008.live.flv',
|
|
133
|
+
// info: {
|
|
134
|
+
// videoModel: 'easyplayer',
|
|
135
|
+
// id: 'b3',
|
|
136
|
+
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000008.live.flv',
|
|
137
|
+
// deviceId: 'c4',
|
|
138
|
+
// channelId: 'c11',
|
|
139
|
+
// },
|
|
140
|
+
// },
|
|
141
|
+
],
|
|
142
|
+
// !!! 单点播放
|
|
143
|
+
videoSingleUrl: false,
|
|
144
|
+
// !!! 已经在播放的是否关闭后再点击打开(需要单点播 videoSingleUrl:true)
|
|
145
|
+
videoSingleClose: false,
|
|
146
|
+
// 回调函数后是否继续执行默认播放操作
|
|
147
|
+
callbackContinueExecute: true,
|
|
148
|
+
// 播放模式: 1: 单击,2: 双击
|
|
149
|
+
videoPlayModel: 1,
|
|
150
|
+
// 分屏模式: 1: 单屏, 2: 四屏, 3: 九屏
|
|
151
|
+
videoSplitType: 1,
|
|
152
|
+
// 显示分屏按钮
|
|
153
|
+
showVideoSplit: true,
|
|
154
|
+
// 分屏使用图标
|
|
155
|
+
// videoSplitUseIcon: true,
|
|
156
|
+
// 显示方向控制按钮
|
|
157
|
+
showVideoCtrls: false,
|
|
158
|
+
// 禁止控制按钮默认请求行为(默认false,true则不使用组件的发送请求仅调用自定义回调函数)
|
|
159
|
+
stopVideoCtrlMethods: true,
|
|
160
|
+
// 单个视频错误最大次数
|
|
161
|
+
videoErrorMaxCount: 3,
|
|
162
|
+
// easyplayer配置 (默认一般不需要配置, 加载不出来的时候修改)
|
|
163
|
+
videoConfig: {
|
|
164
|
+
MSE: true,
|
|
165
|
+
WCS: true,
|
|
166
|
+
WASM:true,
|
|
167
|
+
WASMSIMD: true,
|
|
168
|
+
isLive: true,
|
|
169
|
+
hasAudio: false,
|
|
170
|
+
stretch: false
|
|
171
|
+
},
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
const drawW = ref('0')
|
|
175
|
+
const drawH = ref('0')
|
|
176
|
+
const videoPlayerCoverRef = ref()
|
|
177
|
+
const videoDrawRef = ref()
|
|
178
|
+
|
|
179
|
+
// 视频操作事件
|
|
180
|
+
const videoEvent = {
|
|
181
|
+
videoOriginalInfo: (info: any) => {
|
|
182
|
+
console.log('===============>视频原始信息:', info)
|
|
183
|
+
const coverEle = videoPlayerCoverRef.value;
|
|
184
|
+
const currentVideoInfo = info?.[0]
|
|
185
|
+
if(coverEle && currentVideoInfo?.width && currentVideoInfo?.height){
|
|
186
|
+
let _w = coverEle.clientWidth
|
|
187
|
+
let _h = coverEle.clientHeight
|
|
188
|
+
if(currentVideoInfo.width > currentVideoInfo.height){
|
|
189
|
+
_h = _w * (currentVideoInfo.height / currentVideoInfo.width)
|
|
190
|
+
}else{
|
|
191
|
+
_w = _h * (currentVideoInfo.width / currentVideoInfo.height)
|
|
192
|
+
}
|
|
193
|
+
drawW.value = _w + 'px'
|
|
194
|
+
drawH.value = _h + 'px'
|
|
195
|
+
setTimeout(() => {
|
|
196
|
+
const videoDrawEle = videoDrawRef.value;
|
|
197
|
+
// debugger
|
|
198
|
+
}, 1000)
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
onMounted(() => {
|
|
204
|
+
// setTimeout(() => {
|
|
205
|
+
// // !!!暴露方法
|
|
206
|
+
// // nsVideoRef.value.[setVideoUrl / removeVideo / fouceIndex / videoInfos / treeRef]
|
|
207
|
+
// // 设置视频
|
|
208
|
+
// videoData.videoInfos = [
|
|
209
|
+
// {
|
|
210
|
+
// index: 1,
|
|
211
|
+
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000004.live.flv',
|
|
212
|
+
// info: {
|
|
213
|
+
// videoModel: 'easyplayer',
|
|
214
|
+
// id: 'xxx',
|
|
215
|
+
// label: '视频A--3',
|
|
216
|
+
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000004.live.flv',
|
|
217
|
+
// deviceId: 'c1',
|
|
218
|
+
// channelId: 'c11',
|
|
219
|
+
// },
|
|
220
|
+
// },
|
|
221
|
+
// ]
|
|
222
|
+
// // }, 3000)
|
|
223
|
+
// setTimeout(() => {
|
|
224
|
+
// // 关闭视频方法1:
|
|
225
|
+
// nsVideoRef.value.removeVideo(7, true)
|
|
226
|
+
// // 关闭视频方法2:
|
|
227
|
+
// // nsVideoRef.value.setVideoUrl('', false, 7)
|
|
228
|
+
// }, 5000)
|
|
229
|
+
// 播放视频
|
|
230
|
+
// nextTick(()=>{
|
|
231
|
+
// nsVideoRef.value.setVideoUrl('ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000010.live.flv', false, 1, {
|
|
232
|
+
// videoModel: 'easyplayer',
|
|
233
|
+
// /* videoModel: 'hk',
|
|
234
|
+
// hkPath: '/xxxx', */
|
|
235
|
+
// })
|
|
236
|
+
// })
|
|
237
|
+
})
|
|
238
|
+
function changeSplitHandler(num: number) {
|
|
239
|
+
console.log('分屏模式:如1,2,3代表单屏,四屏,九屏', num)
|
|
240
|
+
}
|
|
241
|
+
</script>
|
|
242
|
+
<template>
|
|
243
|
+
<div class="video-demo">
|
|
244
|
+
<h1 class="title" style="color: #fff" v-sline>视频组件(国标28181 + 海康威视)</h1>
|
|
245
|
+
<NsVideo class="nsvideo" ref="nsVideoRef" v-bind="videoData" v-on="videoEvent" @changeSplit='changeSplitHandler'>
|
|
246
|
+
<template #video-player-cover>
|
|
247
|
+
<div class="video-player-cover" ref="videoPlayerCoverRef">
|
|
248
|
+
<div class="video-draw" ref="videoDrawRef">
|
|
249
|
+
<canvas width="100%" height="100%" class="video-canvas"></canvas>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
</template>
|
|
253
|
+
</NsVideo>
|
|
254
|
+
</div>
|
|
255
|
+
</template>
|
|
256
|
+
<style scoped lang="scss">
|
|
257
|
+
.video-demo {
|
|
258
|
+
display: flex;
|
|
259
|
+
flex-direction: column;
|
|
260
|
+
height: 100%;
|
|
261
|
+
background-color: #0f2a3b;
|
|
262
|
+
.title {
|
|
263
|
+
margin-bottom: 10px;
|
|
264
|
+
}
|
|
265
|
+
.video-player-cover {
|
|
266
|
+
pointer-events: none;
|
|
267
|
+
position: absolute;
|
|
268
|
+
top: 0;
|
|
269
|
+
left: 0;
|
|
270
|
+
width: 100%;
|
|
271
|
+
height: 100%;
|
|
272
|
+
// background-color: rgba(255, 0, 0, 0.3);
|
|
273
|
+
display: flex;
|
|
274
|
+
justify-content: center;
|
|
275
|
+
align-items: center;
|
|
276
|
+
.video-draw {
|
|
277
|
+
pointer-events: auto;
|
|
278
|
+
width: v-bind(drawW);
|
|
279
|
+
height: v-bind(drawH);
|
|
280
|
+
// background-color: rgba(238, 255, 0, 0.1);
|
|
281
|
+
.video-canvas {
|
|
282
|
+
width: 100%;
|
|
283
|
+
height: 100%;
|
|
284
|
+
background-color: rgba(0, 255, 234, 0.1);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
</style>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { onMounted, reactive, ref } from 'vue'
|
|
2
|
+
import { onMounted, reactive, ref, nextTick } from 'vue'
|
|
3
|
+
import { useVideoDraw } from '../hooks/videoDraw'
|
|
3
4
|
|
|
4
5
|
const nsVideoRef = ref()
|
|
5
6
|
|
|
@@ -8,7 +9,7 @@ const videoData = reactive({
|
|
|
8
9
|
// videoModel: 'hk',
|
|
9
10
|
// hkPath: '/martrix/cdn/h5player',
|
|
10
11
|
// 显示视频关闭按钮
|
|
11
|
-
showClose:
|
|
12
|
+
showClose: false,
|
|
12
13
|
// 显示树
|
|
13
14
|
showTree: true,
|
|
14
15
|
// 树数据
|
|
@@ -105,39 +106,6 @@ const videoData = reactive({
|
|
|
105
106
|
channelId: 'c11',
|
|
106
107
|
},
|
|
107
108
|
},
|
|
108
|
-
// {
|
|
109
|
-
// index: 1,
|
|
110
|
-
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000015.live.flv',
|
|
111
|
-
// info: {
|
|
112
|
-
// videoModel: 'easyplayer',
|
|
113
|
-
// id: '222',
|
|
114
|
-
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000015.live.flv',
|
|
115
|
-
// deviceId: 'c2',
|
|
116
|
-
// channelId: 'c11',
|
|
117
|
-
// },
|
|
118
|
-
// },
|
|
119
|
-
// {
|
|
120
|
-
// index: 2,
|
|
121
|
-
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000009.live.flv',
|
|
122
|
-
// info: {
|
|
123
|
-
// videoModel: 'easyplayer',
|
|
124
|
-
// id: 'xxx2',
|
|
125
|
-
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000009.live.flv',
|
|
126
|
-
// deviceId: 'c3',
|
|
127
|
-
// channelId: 'c11',
|
|
128
|
-
// },
|
|
129
|
-
// },
|
|
130
|
-
// {
|
|
131
|
-
// index: 3,
|
|
132
|
-
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000008.live.flv',
|
|
133
|
-
// info: {
|
|
134
|
-
// videoModel: 'easyplayer',
|
|
135
|
-
// id: 'b3',
|
|
136
|
-
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000008.live.flv',
|
|
137
|
-
// deviceId: 'c4',
|
|
138
|
-
// channelId: 'c11',
|
|
139
|
-
// },
|
|
140
|
-
// },
|
|
141
109
|
],
|
|
142
110
|
// !!! 单点播放
|
|
143
111
|
videoSingleUrl: false,
|
|
@@ -169,132 +137,220 @@ const videoData = reactive({
|
|
|
169
137
|
hasAudio: false,
|
|
170
138
|
stretch: false
|
|
171
139
|
},
|
|
172
|
-
// -----------事件回调-------------
|
|
173
|
-
// 点击树节点的操作
|
|
174
|
-
treeClick: () => {
|
|
175
|
-
console.log('点击树节点回调函数')
|
|
176
|
-
},
|
|
177
|
-
// 双击树节点的操作
|
|
178
|
-
treeDBClick: () => {
|
|
179
|
-
console.log('双击树节点回调函数')
|
|
180
|
-
},
|
|
181
|
-
// 右键树展示菜单
|
|
182
|
-
treeRightMenu: () => {
|
|
183
|
-
console.log('右键树展示菜单')
|
|
184
|
-
},
|
|
185
|
-
// 展开树节点
|
|
186
|
-
treeExpand: () => {
|
|
187
|
-
console.log('展开树节点')
|
|
188
|
-
},
|
|
189
|
-
// 视频错误回调函数
|
|
190
|
-
videoError: () => {
|
|
191
|
-
console.log('视频错误回调函数')
|
|
192
|
-
},
|
|
193
140
|
})
|
|
194
141
|
|
|
142
|
+
const drawW = ref('0')
|
|
143
|
+
const drawH = ref('0')
|
|
144
|
+
const videoPlayerCoverRef = ref()
|
|
145
|
+
const videoDrawRef = ref()
|
|
146
|
+
const canvasRef = ref()
|
|
147
|
+
|
|
148
|
+
// 使用画布绘图功能
|
|
149
|
+
const {
|
|
150
|
+
initCanvas,
|
|
151
|
+
clearCanvas,
|
|
152
|
+
drawFromCoordinates,
|
|
153
|
+
getState,
|
|
154
|
+
points,
|
|
155
|
+
areaCoordinates,
|
|
156
|
+
isDrawing,
|
|
157
|
+
isComplete
|
|
158
|
+
} = useVideoDraw()
|
|
159
|
+
|
|
195
160
|
// 视频操作事件
|
|
196
161
|
const videoEvent = {
|
|
197
162
|
videoOriginalInfo: (info: any) => {
|
|
198
163
|
console.log('===============>视频原始信息:', info)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
speak: () => {
|
|
225
|
-
console.log('视频开始说话')
|
|
226
|
-
},
|
|
227
|
-
scan: () => {
|
|
228
|
-
console.log('视频扫描')
|
|
229
|
-
},
|
|
230
|
-
cruise: () => {
|
|
231
|
-
console.log('视频巡航')
|
|
232
|
-
},
|
|
233
|
-
call: () => {
|
|
234
|
-
console.log('视频调用')
|
|
164
|
+
const coverEle = videoPlayerCoverRef.value;
|
|
165
|
+
const currentVideoInfo = info?.[0]
|
|
166
|
+
if(coverEle && currentVideoInfo?.width && currentVideoInfo?.height){
|
|
167
|
+
let _w = coverEle.clientWidth
|
|
168
|
+
let _h = coverEle.clientHeight
|
|
169
|
+
if(currentVideoInfo.width > currentVideoInfo.height){
|
|
170
|
+
_h = _w * (currentVideoInfo.height / currentVideoInfo.width)
|
|
171
|
+
}else{
|
|
172
|
+
_w = _h * (currentVideoInfo.width / currentVideoInfo.height)
|
|
173
|
+
}
|
|
174
|
+
drawW.value = _w + 'px'
|
|
175
|
+
drawH.value = _h + 'px'
|
|
176
|
+
|
|
177
|
+
// 初始化画布绘图功能
|
|
178
|
+
nextTick(() => {
|
|
179
|
+
if (canvasRef.value && videoDrawRef.value) {
|
|
180
|
+
// 确保canvas尺寸正确
|
|
181
|
+
canvasRef.value.width = videoDrawRef.value.clientWidth
|
|
182
|
+
canvasRef.value.height = videoDrawRef.value.clientHeight
|
|
183
|
+
|
|
184
|
+
initCanvas(canvasRef.value, videoDrawRef.value)
|
|
185
|
+
console.log('画布绘图功能已初始化,尺寸:', videoDrawRef.value.clientWidth, 'x', videoDrawRef.value.clientHeight)
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
}
|
|
235
189
|
},
|
|
236
190
|
}
|
|
237
191
|
|
|
192
|
+
// 显示绘图状态和坐标
|
|
193
|
+
const showDrawInfo = () => {
|
|
194
|
+
const state = getState()
|
|
195
|
+
console.log('当前绘图状态:', state)
|
|
196
|
+
|
|
197
|
+
if (state.points.length > 0) {
|
|
198
|
+
console.log('所有点坐标:', state.points)
|
|
199
|
+
console.log('区域信息:', state.areaCoordinates)
|
|
200
|
+
|
|
201
|
+
// 可以在这里处理坐标数据,比如发送到后端或保存到本地
|
|
202
|
+
localStorage.setItem('videoCanvasCoordinates', JSON.stringify(state.points))
|
|
203
|
+
|
|
204
|
+
alert(`已获取 ${state.points.length} 个点的坐标,数据已保存到控制台和localStorage`)
|
|
205
|
+
} else {
|
|
206
|
+
alert('当前没有绘制任何点')
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// 测试回显功能
|
|
211
|
+
const testDrawFromCoordinates = () => {
|
|
212
|
+
const testCoordinates = [
|
|
213
|
+
{ x: 100, y: 100 },
|
|
214
|
+
{ x: 200, y: 50 },
|
|
215
|
+
{ x: 300, y: 150 },
|
|
216
|
+
{ x: 250, y: 250 },
|
|
217
|
+
{ x: 150, y: 200 }
|
|
218
|
+
]
|
|
219
|
+
drawFromCoordinates(testCoordinates)
|
|
220
|
+
}
|
|
221
|
+
|
|
238
222
|
onMounted(() => {
|
|
239
|
-
//
|
|
240
|
-
// // !!!暴露方法
|
|
241
|
-
// // nsVideoRef.value.[setVideoUrl / removeVideo / fouceIndex / videoInfos / treeRef]
|
|
242
|
-
// // 设置视频
|
|
243
|
-
// videoData.videoInfos = [
|
|
244
|
-
// {
|
|
245
|
-
// index: 1,
|
|
246
|
-
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000004.live.flv',
|
|
247
|
-
// info: {
|
|
248
|
-
// videoModel: 'easyplayer',
|
|
249
|
-
// id: 'xxx',
|
|
250
|
-
// label: '视频A--3',
|
|
251
|
-
// url: 'ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000004.live.flv',
|
|
252
|
-
// deviceId: 'c1',
|
|
253
|
-
// channelId: 'c11',
|
|
254
|
-
// },
|
|
255
|
-
// },
|
|
256
|
-
// ]
|
|
257
|
-
// // }, 3000)
|
|
258
|
-
// setTimeout(() => {
|
|
259
|
-
// // 关闭视频方法1:
|
|
260
|
-
// nsVideoRef.value.removeVideo(7, true)
|
|
261
|
-
// // 关闭视频方法2:
|
|
262
|
-
// // nsVideoRef.value.setVideoUrl('', false, 7)
|
|
263
|
-
// }, 5000)
|
|
264
|
-
// 播放视频
|
|
265
|
-
// nextTick(()=>{
|
|
266
|
-
// nsVideoRef.value.setVideoUrl('ws://199.10.9.192:30200/rtp/34020000001110000001_34020000001320000010.live.flv', false, 1, {
|
|
267
|
-
// videoModel: 'easyplayer',
|
|
268
|
-
// /* videoModel: 'hk',
|
|
269
|
-
// hkPath: '/xxxx', */
|
|
270
|
-
// })
|
|
271
|
-
// })
|
|
223
|
+
// 示例:可以在这里添加一些初始化逻辑
|
|
272
224
|
})
|
|
225
|
+
|
|
273
226
|
function changeSplitHandler(num: number) {
|
|
274
227
|
console.log('分屏模式:如1,2,3代表单屏,四屏,九屏', num)
|
|
275
228
|
}
|
|
276
229
|
</script>
|
|
230
|
+
|
|
277
231
|
<template>
|
|
278
232
|
<div class="video-demo">
|
|
279
233
|
<h1 class="title" style="color: #fff" v-sline>视频组件(国标28181 + 海康威视)</h1>
|
|
234
|
+
|
|
235
|
+
<!-- 画布控制面板 -->
|
|
236
|
+
<div class="canvas-controls" v-if="isDrawing || isComplete">
|
|
237
|
+
<div class="canvas-status">
|
|
238
|
+
<span>绘图状态: {{ isDrawing ? '绘制中' : isComplete ? '已完成' : '未开始' }}</span>
|
|
239
|
+
<span>点数: {{ points.length }}</span>
|
|
240
|
+
<span v-if="areaCoordinates">区域: {{ areaCoordinates.width }} × {{ areaCoordinates.height }}</span>
|
|
241
|
+
</div>
|
|
242
|
+
<div class="canvas-buttons">
|
|
243
|
+
<button @click="clearCanvas" class="btn-clear">清除画布</button>
|
|
244
|
+
<button @click="testDrawFromCoordinates" class="btn-test">测试回显</button>
|
|
245
|
+
<button @click="showDrawInfo" class="btn-info">显示坐标</button>
|
|
246
|
+
</div>
|
|
247
|
+
</div>
|
|
248
|
+
|
|
280
249
|
<NsVideo class="nsvideo" ref="nsVideoRef" v-bind="videoData" v-on="videoEvent" @changeSplit='changeSplitHandler'>
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
250
|
+
<template #video-player-cover>
|
|
251
|
+
<div class="video-player-cover" ref="videoPlayerCoverRef">
|
|
252
|
+
<div class="video-draw" ref="videoDrawRef">
|
|
253
|
+
<canvas ref="canvasRef" width="100%" height="100%" class="video-canvas"></canvas>
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
</template>
|
|
287
257
|
</NsVideo>
|
|
288
258
|
</div>
|
|
289
259
|
</template>
|
|
260
|
+
|
|
290
261
|
<style scoped lang="scss">
|
|
291
262
|
.video-demo {
|
|
292
263
|
display: flex;
|
|
293
264
|
flex-direction: column;
|
|
294
265
|
height: 100%;
|
|
295
266
|
background-color: #0f2a3b;
|
|
267
|
+
|
|
296
268
|
.title {
|
|
297
269
|
margin-bottom: 10px;
|
|
298
270
|
}
|
|
271
|
+
|
|
272
|
+
// 画布控制面板样式
|
|
273
|
+
.canvas-controls {
|
|
274
|
+
background: rgba(255, 255, 255, 0.1);
|
|
275
|
+
padding: 10px;
|
|
276
|
+
border-radius: 4px;
|
|
277
|
+
margin-bottom: 10px;
|
|
278
|
+
display: flex;
|
|
279
|
+
justify-content: space-between;
|
|
280
|
+
align-items: center;
|
|
281
|
+
|
|
282
|
+
.canvas-status {
|
|
283
|
+
display: flex;
|
|
284
|
+
gap: 15px;
|
|
285
|
+
color: #fff;
|
|
286
|
+
font-size: 14px;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.canvas-buttons {
|
|
290
|
+
display: flex;
|
|
291
|
+
gap: 10px;
|
|
292
|
+
|
|
293
|
+
button {
|
|
294
|
+
padding: 6px 12px;
|
|
295
|
+
border: none;
|
|
296
|
+
border-radius: 4px;
|
|
297
|
+
cursor: pointer;
|
|
298
|
+
font-size: 12px;
|
|
299
|
+
transition: background-color 0.3s;
|
|
300
|
+
|
|
301
|
+
&.btn-clear {
|
|
302
|
+
background: #ff6b6b;
|
|
303
|
+
color: white;
|
|
304
|
+
|
|
305
|
+
&:hover {
|
|
306
|
+
background: #ff5252;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
&.btn-test {
|
|
311
|
+
background: #4ecdc4;
|
|
312
|
+
color: white;
|
|
313
|
+
|
|
314
|
+
&:hover {
|
|
315
|
+
background: #26a69a;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
&.btn-info {
|
|
320
|
+
background: #45b7d1;
|
|
321
|
+
color: white;
|
|
322
|
+
|
|
323
|
+
&:hover {
|
|
324
|
+
background: #3498db;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.video-player-cover {
|
|
332
|
+
pointer-events: none;
|
|
333
|
+
position: absolute;
|
|
334
|
+
top: 0;
|
|
335
|
+
left: 0;
|
|
336
|
+
width: 100%;
|
|
337
|
+
height: 100%;
|
|
338
|
+
display: flex;
|
|
339
|
+
justify-content: center;
|
|
340
|
+
align-items: center;
|
|
341
|
+
|
|
342
|
+
.video-draw {
|
|
343
|
+
pointer-events: auto;
|
|
344
|
+
width: v-bind(drawW);
|
|
345
|
+
height: v-bind(drawH);
|
|
346
|
+
|
|
347
|
+
.video-canvas {
|
|
348
|
+
width: 100%;
|
|
349
|
+
height: 100%;
|
|
350
|
+
background-color: rgba(0, 255, 234, 0.1);
|
|
351
|
+
cursor: crosshair;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
299
355
|
}
|
|
300
356
|
</style>
|