@vanwei-wcs/video-player-v3 0.1.0
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 +261 -0
- package/dist/README.md +261 -0
- package/dist/package.json +20 -0
- package/dist/style.css +1 -0
- package/dist/types/index.d.ts +151 -0
- package/dist/video-player-v3.js +1103 -0
- package/dist/video-player-v3.js.map +1 -0
- package/dist/video-player-v3.umd.cjs +3 -0
- package/dist/video-player-v3.umd.cjs.map +1 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# WwVideoPlayer 视频播放器组件
|
|
2
|
+
|
|
3
|
+
一个基于 Vue 3 的视频播放器组件,支持 H.264/H.265 视频播放、云台控制和实时流播放。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install ww-video-player
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 基础用法
|
|
12
|
+
|
|
13
|
+
```vue
|
|
14
|
+
<template>
|
|
15
|
+
<WwVideoPlayer
|
|
16
|
+
ref="videoPlayerRef"
|
|
17
|
+
:options="options"
|
|
18
|
+
:is-live="true"
|
|
19
|
+
:debug="false"
|
|
20
|
+
:show-p-t-z="true"
|
|
21
|
+
:show-controller="true"
|
|
22
|
+
@stop-video="onStopVideo"
|
|
23
|
+
@quality-change="onQualityChange"
|
|
24
|
+
/>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<script setup lang="ts">
|
|
28
|
+
import { ref } from 'vue'
|
|
29
|
+
import { WwVideoPlayer } from 'ww-video-player'
|
|
30
|
+
import type { VideoQuality } from 'ww-video-player'
|
|
31
|
+
|
|
32
|
+
const videoPlayerRef = ref<InstanceType<typeof WwVideoPlayer> | null>(null)
|
|
33
|
+
|
|
34
|
+
const options = {
|
|
35
|
+
debug: false,
|
|
36
|
+
mode: 'video',
|
|
37
|
+
baseLibPath: '/js/h265/',
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 播放视频
|
|
41
|
+
const play = async () => {
|
|
42
|
+
await videoPlayerRef.value?.openVideo({
|
|
43
|
+
url: 'ws://example.com/video',
|
|
44
|
+
token: 'optional-token'
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 关闭视频
|
|
49
|
+
const close = async () => {
|
|
50
|
+
await videoPlayerRef.value?.closeVideo()
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Props 属性
|
|
58
|
+
|
|
59
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
60
|
+
|--------|------|--------|------|
|
|
61
|
+
| `debug` | `boolean` | `false` | 是否开启调试模式 |
|
|
62
|
+
| `isLive` | `boolean` | `true` | 是否为直播模式 |
|
|
63
|
+
| `options` | `PlayerOptions` | 见下方 | 播放器配置选项 |
|
|
64
|
+
| `showPTZ` | `boolean` | `false` | 是否显示云台控制 |
|
|
65
|
+
| `showController` | `boolean` | `false` | 是否显示播放控制器 |
|
|
66
|
+
|
|
67
|
+
### PlayerOptions 配置
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
interface PlayerOptions {
|
|
71
|
+
debug: boolean // 是否调试模式
|
|
72
|
+
mode: 'video' | 'audio' // 播放模式
|
|
73
|
+
baseLibPath: string // 解码器库文件路径
|
|
74
|
+
decoderLogLevel?: number // 解码器日志级别
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
默认值:
|
|
79
|
+
```ts
|
|
80
|
+
{
|
|
81
|
+
debug: false,
|
|
82
|
+
mode: 'video',
|
|
83
|
+
baseLibPath: '/lib/',
|
|
84
|
+
decoderLogLevel: 0
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Events 事件
|
|
91
|
+
|
|
92
|
+
| 事件名 | 参数 | 说明 |
|
|
93
|
+
|--------|------|------|
|
|
94
|
+
| `stop-video` | - | 视频停止时触发 |
|
|
95
|
+
| `quality-change` | `quality: VideoQuality` | 清晰度变化时触发 |
|
|
96
|
+
| `change-play-speed` | `speed: number` | 播放速度变化时触发 |
|
|
97
|
+
| `control-talk` | `status: boolean` | 对讲状态变化时触发 |
|
|
98
|
+
| `lock-ptz` | `status: boolean` | 云台锁定状态变化时触发 |
|
|
99
|
+
| `do-zoom` | `command: PTZZoomCommand` | 云台变倍指令触发 |
|
|
100
|
+
| `move-to-direction` | `direction: PTZDirection` | 云台方向移动指令触发 |
|
|
101
|
+
| `error` | `error: Error, detail?, info?` | 发生错误时触发 |
|
|
102
|
+
| `video-status-change` | `status: number` | 视频状态变化时触发 |
|
|
103
|
+
| `sei-info` | `objects: unknown[]` | SEI 信息触发 |
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Expose 方法
|
|
108
|
+
|
|
109
|
+
通过 `ref` 调用组件暴露的方法:
|
|
110
|
+
|
|
111
|
+
| 方法名 | 参数 | 返回值 | 说明 |
|
|
112
|
+
|--------|------|--------|------|
|
|
113
|
+
| `openVideo` | `video: { url: string; token?: string }` | `Promise<void>` | 打开并播放视频 |
|
|
114
|
+
| `closeVideo` | - | `Promise<void>` | 关闭视频 |
|
|
115
|
+
| `captureVideo` | - | `void` | 截图当前画面 |
|
|
116
|
+
| `changeQuality` | `quality: VideoQuality` | `void` | 切换清晰度 |
|
|
117
|
+
|
|
118
|
+
### 方法示例
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
// 打开视频
|
|
122
|
+
await videoPlayerRef.value?.openVideo({
|
|
123
|
+
url: 'ws://example.com/stream',
|
|
124
|
+
token: 'your-token' // 可选
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
// 关闭视频
|
|
128
|
+
await videoPlayerRef.value?.closeVideo()
|
|
129
|
+
|
|
130
|
+
// 截图
|
|
131
|
+
videoPlayerRef.value?.captureVideo()
|
|
132
|
+
|
|
133
|
+
// 切换清晰度 (0: 高清, 1: 标清, 2: 流畅)
|
|
134
|
+
videoPlayerRef.value?.changeQuality(1)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Types 类型定义
|
|
140
|
+
|
|
141
|
+
### VideoQuality 视频清晰度
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
type VideoQuality = 0 | 1 | 2
|
|
145
|
+
// 0: 高清
|
|
146
|
+
// 1: 标清
|
|
147
|
+
// 2: 流畅
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### PTZDirection 云台方向
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
type PTZDirection =
|
|
154
|
+
| 'tilt_up' // 上
|
|
155
|
+
| 'up_right' // 右上
|
|
156
|
+
| 'pan_right' // 右
|
|
157
|
+
| 'down_right' // 右下
|
|
158
|
+
| 'tilt_down' // 下
|
|
159
|
+
| 'down_left' // 左下
|
|
160
|
+
| 'pan_left' // 左
|
|
161
|
+
| 'up_left' // 左上
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### PTZZoomCommand 云台变倍指令
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
type PTZZoomCommand =
|
|
168
|
+
| 'zoom_in' // 放大
|
|
169
|
+
| 'zoom_out' // 缩小
|
|
170
|
+
| 'focus_in' // 聚焦近
|
|
171
|
+
| 'focus_out' // 聚焦远
|
|
172
|
+
| 'iris_up' // 光圈增大
|
|
173
|
+
| 'iris_down' // 光圈减小
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### VideoStatus 视频状态
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
const VideoStatus = {
|
|
180
|
+
vConnect: 0, // 开始连接
|
|
181
|
+
vStart: 1, // 开始播放
|
|
182
|
+
vPlay: 2, // 正在播放
|
|
183
|
+
vPause: 3, // 暂停
|
|
184
|
+
vStop: 4 // 停止
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 完整示例
|
|
191
|
+
|
|
192
|
+
```vue
|
|
193
|
+
<template>
|
|
194
|
+
<div class="app-container">
|
|
195
|
+
<button @click="openVideo">播放</button>
|
|
196
|
+
<button @click="changeQuality(0)">高清</button>
|
|
197
|
+
<button @click="changeQuality(1)">标清</button>
|
|
198
|
+
<button @click="changeQuality(2)">流畅</button>
|
|
199
|
+
|
|
200
|
+
<div class="player-wrapper">
|
|
201
|
+
<WwVideoPlayer
|
|
202
|
+
ref="videoPlayerRef"
|
|
203
|
+
:options="options"
|
|
204
|
+
:is-live="true"
|
|
205
|
+
:show-p-t-z="true"
|
|
206
|
+
:show-controller="true"
|
|
207
|
+
@stop-video="onStopVideo"
|
|
208
|
+
@quality-change="onQualityChange"
|
|
209
|
+
@move-to-direction="onMoveToDirection"
|
|
210
|
+
@do-zoom="onDoZoom"
|
|
211
|
+
/>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
</template>
|
|
215
|
+
|
|
216
|
+
<script setup lang="ts">
|
|
217
|
+
import { ref } from 'vue'
|
|
218
|
+
import { WwVideoPlayer } from 'ww-video-player'
|
|
219
|
+
import type { VideoQuality, PTZDirection, PTZZoomCommand } from 'ww-video-player'
|
|
220
|
+
|
|
221
|
+
interface VideoPlayerExpose {
|
|
222
|
+
openVideo: (video: { url: string; token?: string }) => Promise<void>
|
|
223
|
+
closeVideo: () => Promise<void>
|
|
224
|
+
captureVideo: () => void
|
|
225
|
+
changeQuality: (quality: VideoQuality) => void
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const videoPlayerRef = ref<VideoPlayerExpose | null>(null)
|
|
229
|
+
|
|
230
|
+
const options = {
|
|
231
|
+
debug: false,
|
|
232
|
+
mode: 'video' as const,
|
|
233
|
+
baseLibPath: '/js/h265/',
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// 播放视频
|
|
237
|
+
const openVideo = async () => {
|
|
238
|
+
await videoPlayerRef.value?.openVideo({
|
|
239
|
+
url: 'ws://example.com/stream'
|
|
240
|
+
})
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// 切换清晰度
|
|
244
|
+
const changeQuality = (quality: VideoQuality) => {
|
|
245
|
+
videoPlayerRef.value?.changeQuality(quality)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// 事件处理
|
|
249
|
+
const onStopVideo = () => console.log('视频已停止')
|
|
250
|
+
const onQualityChange = (q: VideoQuality) => console.log('清晰度:', q)
|
|
251
|
+
const onMoveToDirection = (d: PTZDirection) => console.log('云台方向:', d)
|
|
252
|
+
const onDoZoom = (c: PTZZoomCommand) => console.log('变倍:', c)
|
|
253
|
+
</script>
|
|
254
|
+
|
|
255
|
+
<style>
|
|
256
|
+
.player-wrapper {
|
|
257
|
+
width: 600px;
|
|
258
|
+
height: 400px;
|
|
259
|
+
}
|
|
260
|
+
</style>
|
|
261
|
+
```
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
# WwVideoPlayer 视频播放器组件
|
|
2
|
+
|
|
3
|
+
一个基于 Vue 3 的视频播放器组件,支持 H.264/H.265 视频播放、云台控制和实时流播放。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install ww-video-player
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 基础用法
|
|
12
|
+
|
|
13
|
+
```vue
|
|
14
|
+
<template>
|
|
15
|
+
<WwVideoPlayer
|
|
16
|
+
ref="videoPlayerRef"
|
|
17
|
+
:options="options"
|
|
18
|
+
:is-live="true"
|
|
19
|
+
:debug="false"
|
|
20
|
+
:show-p-t-z="true"
|
|
21
|
+
:show-controller="true"
|
|
22
|
+
@stop-video="onStopVideo"
|
|
23
|
+
@quality-change="onQualityChange"
|
|
24
|
+
/>
|
|
25
|
+
</template>
|
|
26
|
+
|
|
27
|
+
<script setup lang="ts">
|
|
28
|
+
import { ref } from 'vue'
|
|
29
|
+
import { WwVideoPlayer } from 'ww-video-player'
|
|
30
|
+
import type { VideoQuality } from 'ww-video-player'
|
|
31
|
+
|
|
32
|
+
const videoPlayerRef = ref<InstanceType<typeof WwVideoPlayer> | null>(null)
|
|
33
|
+
|
|
34
|
+
const options = {
|
|
35
|
+
debug: false,
|
|
36
|
+
mode: 'video',
|
|
37
|
+
baseLibPath: '/js/h265/',
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 播放视频
|
|
41
|
+
const play = async () => {
|
|
42
|
+
await videoPlayerRef.value?.openVideo({
|
|
43
|
+
url: 'ws://example.com/video',
|
|
44
|
+
token: 'optional-token'
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 关闭视频
|
|
49
|
+
const close = async () => {
|
|
50
|
+
await videoPlayerRef.value?.closeVideo()
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Props 属性
|
|
58
|
+
|
|
59
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
60
|
+
|--------|------|--------|------|
|
|
61
|
+
| `debug` | `boolean` | `false` | 是否开启调试模式 |
|
|
62
|
+
| `isLive` | `boolean` | `true` | 是否为直播模式 |
|
|
63
|
+
| `options` | `PlayerOptions` | 见下方 | 播放器配置选项 |
|
|
64
|
+
| `showPTZ` | `boolean` | `false` | 是否显示云台控制 |
|
|
65
|
+
| `showController` | `boolean` | `false` | 是否显示播放控制器 |
|
|
66
|
+
|
|
67
|
+
### PlayerOptions 配置
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
interface PlayerOptions {
|
|
71
|
+
debug: boolean // 是否调试模式
|
|
72
|
+
mode: 'video' | 'audio' // 播放模式
|
|
73
|
+
baseLibPath: string // 解码器库文件路径
|
|
74
|
+
decoderLogLevel?: number // 解码器日志级别
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
默认值:
|
|
79
|
+
```ts
|
|
80
|
+
{
|
|
81
|
+
debug: false,
|
|
82
|
+
mode: 'video',
|
|
83
|
+
baseLibPath: '/lib/',
|
|
84
|
+
decoderLogLevel: 0
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Events 事件
|
|
91
|
+
|
|
92
|
+
| 事件名 | 参数 | 说明 |
|
|
93
|
+
|--------|------|------|
|
|
94
|
+
| `stop-video` | - | 视频停止时触发 |
|
|
95
|
+
| `quality-change` | `quality: VideoQuality` | 清晰度变化时触发 |
|
|
96
|
+
| `change-play-speed` | `speed: number` | 播放速度变化时触发 |
|
|
97
|
+
| `control-talk` | `status: boolean` | 对讲状态变化时触发 |
|
|
98
|
+
| `lock-ptz` | `status: boolean` | 云台锁定状态变化时触发 |
|
|
99
|
+
| `do-zoom` | `command: PTZZoomCommand` | 云台变倍指令触发 |
|
|
100
|
+
| `move-to-direction` | `direction: PTZDirection` | 云台方向移动指令触发 |
|
|
101
|
+
| `error` | `error: Error, detail?, info?` | 发生错误时触发 |
|
|
102
|
+
| `video-status-change` | `status: number` | 视频状态变化时触发 |
|
|
103
|
+
| `sei-info` | `objects: unknown[]` | SEI 信息触发 |
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Expose 方法
|
|
108
|
+
|
|
109
|
+
通过 `ref` 调用组件暴露的方法:
|
|
110
|
+
|
|
111
|
+
| 方法名 | 参数 | 返回值 | 说明 |
|
|
112
|
+
|--------|------|--------|------|
|
|
113
|
+
| `openVideo` | `video: { url: string; token?: string }` | `Promise<void>` | 打开并播放视频 |
|
|
114
|
+
| `closeVideo` | - | `Promise<void>` | 关闭视频 |
|
|
115
|
+
| `captureVideo` | - | `void` | 截图当前画面 |
|
|
116
|
+
| `changeQuality` | `quality: VideoQuality` | `void` | 切换清晰度 |
|
|
117
|
+
|
|
118
|
+
### 方法示例
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
// 打开视频
|
|
122
|
+
await videoPlayerRef.value?.openVideo({
|
|
123
|
+
url: 'ws://example.com/stream',
|
|
124
|
+
token: 'your-token' // 可选
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
// 关闭视频
|
|
128
|
+
await videoPlayerRef.value?.closeVideo()
|
|
129
|
+
|
|
130
|
+
// 截图
|
|
131
|
+
videoPlayerRef.value?.captureVideo()
|
|
132
|
+
|
|
133
|
+
// 切换清晰度 (0: 高清, 1: 标清, 2: 流畅)
|
|
134
|
+
videoPlayerRef.value?.changeQuality(1)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Types 类型定义
|
|
140
|
+
|
|
141
|
+
### VideoQuality 视频清晰度
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
type VideoQuality = 0 | 1 | 2
|
|
145
|
+
// 0: 高清
|
|
146
|
+
// 1: 标清
|
|
147
|
+
// 2: 流畅
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### PTZDirection 云台方向
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
type PTZDirection =
|
|
154
|
+
| 'tilt_up' // 上
|
|
155
|
+
| 'up_right' // 右上
|
|
156
|
+
| 'pan_right' // 右
|
|
157
|
+
| 'down_right' // 右下
|
|
158
|
+
| 'tilt_down' // 下
|
|
159
|
+
| 'down_left' // 左下
|
|
160
|
+
| 'pan_left' // 左
|
|
161
|
+
| 'up_left' // 左上
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### PTZZoomCommand 云台变倍指令
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
type PTZZoomCommand =
|
|
168
|
+
| 'zoom_in' // 放大
|
|
169
|
+
| 'zoom_out' // 缩小
|
|
170
|
+
| 'focus_in' // 聚焦近
|
|
171
|
+
| 'focus_out' // 聚焦远
|
|
172
|
+
| 'iris_up' // 光圈增大
|
|
173
|
+
| 'iris_down' // 光圈减小
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### VideoStatus 视频状态
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
const VideoStatus = {
|
|
180
|
+
vConnect: 0, // 开始连接
|
|
181
|
+
vStart: 1, // 开始播放
|
|
182
|
+
vPlay: 2, // 正在播放
|
|
183
|
+
vPause: 3, // 暂停
|
|
184
|
+
vStop: 4 // 停止
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 完整示例
|
|
191
|
+
|
|
192
|
+
```vue
|
|
193
|
+
<template>
|
|
194
|
+
<div class="app-container">
|
|
195
|
+
<button @click="openVideo">播放</button>
|
|
196
|
+
<button @click="changeQuality(0)">高清</button>
|
|
197
|
+
<button @click="changeQuality(1)">标清</button>
|
|
198
|
+
<button @click="changeQuality(2)">流畅</button>
|
|
199
|
+
|
|
200
|
+
<div class="player-wrapper">
|
|
201
|
+
<WwVideoPlayer
|
|
202
|
+
ref="videoPlayerRef"
|
|
203
|
+
:options="options"
|
|
204
|
+
:is-live="true"
|
|
205
|
+
:show-p-t-z="true"
|
|
206
|
+
:show-controller="true"
|
|
207
|
+
@stop-video="onStopVideo"
|
|
208
|
+
@quality-change="onQualityChange"
|
|
209
|
+
@move-to-direction="onMoveToDirection"
|
|
210
|
+
@do-zoom="onDoZoom"
|
|
211
|
+
/>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
</template>
|
|
215
|
+
|
|
216
|
+
<script setup lang="ts">
|
|
217
|
+
import { ref } from 'vue'
|
|
218
|
+
import { WwVideoPlayer } from 'ww-video-player'
|
|
219
|
+
import type { VideoQuality, PTZDirection, PTZZoomCommand } from 'ww-video-player'
|
|
220
|
+
|
|
221
|
+
interface VideoPlayerExpose {
|
|
222
|
+
openVideo: (video: { url: string; token?: string }) => Promise<void>
|
|
223
|
+
closeVideo: () => Promise<void>
|
|
224
|
+
captureVideo: () => void
|
|
225
|
+
changeQuality: (quality: VideoQuality) => void
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const videoPlayerRef = ref<VideoPlayerExpose | null>(null)
|
|
229
|
+
|
|
230
|
+
const options = {
|
|
231
|
+
debug: false,
|
|
232
|
+
mode: 'video' as const,
|
|
233
|
+
baseLibPath: '/js/h265/',
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// 播放视频
|
|
237
|
+
const openVideo = async () => {
|
|
238
|
+
await videoPlayerRef.value?.openVideo({
|
|
239
|
+
url: 'ws://example.com/stream'
|
|
240
|
+
})
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// 切换清晰度
|
|
244
|
+
const changeQuality = (quality: VideoQuality) => {
|
|
245
|
+
videoPlayerRef.value?.changeQuality(quality)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// 事件处理
|
|
249
|
+
const onStopVideo = () => console.log('视频已停止')
|
|
250
|
+
const onQualityChange = (q: VideoQuality) => console.log('清晰度:', q)
|
|
251
|
+
const onMoveToDirection = (d: PTZDirection) => console.log('云台方向:', d)
|
|
252
|
+
const onDoZoom = (c: PTZZoomCommand) => console.log('变倍:', c)
|
|
253
|
+
</script>
|
|
254
|
+
|
|
255
|
+
<style>
|
|
256
|
+
.player-wrapper {
|
|
257
|
+
width: 600px;
|
|
258
|
+
height: 400px;
|
|
259
|
+
}
|
|
260
|
+
</style>
|
|
261
|
+
```
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vanwei-wcs/video-player-v3",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "video-player-v3.umd.cjs",
|
|
6
|
+
"module": "video-player-v3.js",
|
|
7
|
+
"types": "types/index.d.ts",
|
|
8
|
+
"style": "style.css",
|
|
9
|
+
"sideEffects": [
|
|
10
|
+
"**/*.css"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./video-player-v3.js",
|
|
15
|
+
"require": "./video-player-v3.umd.cjs",
|
|
16
|
+
"types": "./types/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./style.css": "./style.css"
|
|
19
|
+
}
|
|
20
|
+
}
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.styled-checkbox[data-v-d478ce3d]{vertical-align:top;cursor:pointer;height:100%}.wwav-player__ptz-message[data-v-97aecee1]{z-index:100;border-radius:4px;padding:8px 16px;font-size:14px;position:absolute;top:10px;left:50%;transform:translate(-50%)}.wwav-player__ptz-message.success[data-v-97aecee1]{color:#fff;background:#67c23a}.wwav-player__ptz-message.error[data-v-97aecee1]{color:#fff;background:#f56c6c}.wwav-player__ptz-message.info[data-v-97aecee1]{color:#fff;background:#909399}.fade-enter-active[data-v-97aecee1],.fade-leave-active[data-v-97aecee1]{transition:opacity .3s}.fade-enter-from[data-v-97aecee1],.fade-leave-to[data-v-97aecee1]{opacity:0}.wwav-player__ptz__direction{opacity:.55;box-sizing:border-box;z-index:1;background:radial-gradient(circle,#0000 0 0,#000 100%);border:2px solid #fff;border-radius:50%;width:144px;height:144px;position:absolute;bottom:3.5em;left:1em;overflow:hidden}.wwav-player__ptz__direction-content{background:0 0;width:95px;height:95px}.wwav-player__ptz__direction-circle-border{border:1px solid #ffffff1a;border-radius:50%;width:80px;height:80px}.wwav-player__ptz__direction-circle{background:#fff6;border:1px solid #ffffff4d;border-radius:50%;width:48px;height:48px}.wwav-player__ptz__direction-triangle{transform-origin:50%;cursor:pointer;opacity:.7;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAAwElEQVQ4T5XSTUqCURSA4edOgowoTaIlCBUEDgIHQSC6DxfXAkKl6G8RbaFxKyiufHEUNX/ud0dncN/nTE6CnPMThtVc8H4wwSjlnJv4LojWv0xSbP7EVU3gdx538IGLOsBfHNsv8Y7zUmARB3AdQLsEWIkDuMEbWvuAf3EAXbzidBewMQ7gFs842QZsjQPooTqg403AzjiAO0xxtA7sjQO4xxiNZaAoDqCPRxzOgeI4gAEecIaXWnEAB9UVppS+Zn2ZQFj4MpGPAAAAAElFTkSuQmCC);width:15px;height:15px;position:absolute}.wwav-player__ptz__direction-triangle.active,.wwav-player__ptz__direction-triangle:hover{opacity:1}.wwav-player__ptz__direction-triangle:first-child{top:-10px;left:50%;transform:translate(-50%)rotate(-45deg)}.wwav-player__ptz__direction-triangle:nth-child(3){top:50%;right:-10px;transform:translateY(-50%)rotate(45deg)}.wwav-player__ptz__direction-triangle:nth-child(5){bottom:-10px;left:50%;transform:translate(-50%)rotate(135deg)}.wwav-player__ptz__direction-triangle:nth-child(7){top:50%;left:-10px;transform:translateY(-50%)rotate(225deg)}.wwav-player__ptz__direction-triangle:nth-child(2){top:6px;right:6px}.wwav-player__ptz__direction-triangle:nth-child(4){bottom:6px;right:6px;transform:rotate(90deg)}.wwav-player__ptz__direction-triangle:nth-child(6){bottom:6px;left:6px;transform:rotate(180deg)}.wwav-player__ptz__direction-triangle:nth-child(8){top:6px;left:6px;transform:rotate(270deg)}.wwav-player__ptz__operation{text-align:center;-webkit-user-select:none;user-select:none;z-index:1;padding:1em;position:absolute;bottom:3em;left:50%;transform:translate(-50%)}.wwav-player__ptz__operation-button{vertical-align:top;box-sizing:border-box;cursor:pointer;background-color:#0000004d;border:1px solid #0000;border-radius:50%;width:48px;height:48px;margin:0 15px;padding:0;display:inline-block;position:relative}.wwav-player__ptz__operation-button:focus,.wwav-player__ptz__operation-button:hover{border-color:#fffc}.wwav-player__ptz__operation-button img{width:100%;height:100%}.wwav-player__ptz__operation-button .image{box-sizing:border-box;width:100%;height:100%;padding:8px}.wwav-player__ptz__operation-button-disable{color:#333;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE8AAAAlCAYAAAADW7S6AAABkElEQVRoQ+3ar0ssURjG8e8DBhE0mk1aTCLY/AuUq8liFYwigota7w/hcrnNYhWMgv4DmgXBYjBazIprklfOsrtMWFD3LQd8JuzCcJ5h+MwzZ8I5ontExBKwDSwAY73z/u8LPAPXwD9JF+Wsyk9E/AT2DPVpgV+S9hURP4CzT8c8sCewUvAugUWbfFngquC9eI77MlwJtAteDBV1COMlSmA84yUEElE3z3gJgUTUzTNeQiARdfOMlxBIRN084yUEElE3z3gJgUTUzTNeQiARdfOMlxBIRN084yUEEtHSvCdgPHGN7xrtLAB56XG4x99ZevSi93B4q73tFr+B1nDX+JapQ0mtDl45ImIZ2AHmvQg+sBDt7kafv5LOy4g+Xg39iYhZ4AYYGXA/b8CcpNsa7rU6vO4bcARsDgA6lrRRC1yteJPAPTDRgCp746YlPRrvA4GI2AX+NIYdSCp7CKs6qprzGh+vUeAOmAIegBlJr1XJ1fbBaOJExBpwCqxLOqkNrso5r9G+8lb8B7YkVbkN7h0eRanPahw2mAAAAABJRU5ErkJggg==) no-repeat;width:80px;height:40px;font-family:PingFang SC;font-size:16px;font-weight:400;line-height:31px;transition:display .5s ease-in;display:none;position:absolute;top:-40px;left:-17px}.wwav-player__ptz__operation-button.isLocked{background-color:#67c23a80;border-color:#67c23a}.wwav-player__ptz__operation-button.isLocked:focus,.wwav-player__ptz__operation-button.isLocked:hover{border-color:#67c23a}.wwav-player__ptz__operation-popper{color:#ddd;width:40px;cursor:unset;text-align:center;background-color:#000000b3;border-radius:5px;display:none;position:absolute;top:-124px;left:50%;transform:translate(-50%)}.wwav-player__ptz__operation-popper-show{display:block}.wwav-player__ptz__operation-popper-icon{box-sizing:border-box;color:#bbb;cursor:pointer;width:40px;height:40px;padding:8px;line-height:40px}.wwav-player__ptz__operation-popper-icon:focus,.wwav-player__ptz__operation-popper-icon:hover{color:#fff;background-color:#000c;border-radius:5px}.wwav-player__ptz__operation-popper-icon svg{fill:currentColor;vertical-align:middle;width:16px;height:16px}.wwav-player__ptz__operation-popper span{color:#ddd;height:40px;font-size:12px;line-height:40px;display:block}.wwav-player__ptz__message{text-align:center;color:#fff;background-color:#3339;border:1px solid;border-radius:5px;width:400px;padding:10px;line-height:18px;position:absolute;bottom:120px;left:50%;transform:translate(-50%)}.wwav-player__ptz__message.error{color:#f56c6c;border-color:#fde2e2}.wwav-player__ptz__message.success{color:#67c23a;border-color:#e1f3d8}.wwav-player-rotate{animation:1.5s linear infinite wwav-player-rotating}@keyframes wwav-player-rotating{0%{transform:rotate(0)}to{transform:rotate(-1turn)}}.wwav-player__common-icon,.wwav-player__common-span{color:#afb9bc;text-align:center;cursor:pointer;z-index:2;height:100%;margin:0 .5em;line-height:2.55em;transition:all .1s;display:inline-block}.wwav-player__common-icon:hover,.wwav-player__common-span:hover{color:#fff}.wwav-player__common-icon.hidden,.wwav-player__common-span.hidden{opacity:0;z-index:1}.wwav-player__common-icon{text-shadow:1px 1px 1px #000c;width:1.5em;margin:0 .3em}.wwav-player__common-icon.active{color:#67c23a}.wwav-player__svg-icon{fill:currentColor;width:13px;height:13px}.wwav-player__content{width:100%;height:100%}.wwav-player__header{z-index:9;-webkit-user-select:none;user-select:none;background:linear-gradient(#343b4acc 0,#16181dcc);width:100%;height:2.2em;padding-bottom:1px;transition:bottom .3s ease-out;position:absolute;top:-2.2em;left:0}.wwav-player__header--device-name{vertical-align:top;width:auto;margin:0 0 0 1em;line-height:2.3em;position:relative}.wwav-player__footer{z-index:10;-webkit-user-select:none;user-select:none;background:linear-gradient(#343b4acc 0,#16181dcc);width:100%;height:2.2em;padding-bottom:1px;transition:bottom .3s ease-out;position:absolute;bottom:-2.2em;left:0}.wwav-player__footer__pop{opacity:0;background:#2d3443;border:1px solid #404f6f;border-radius:3px;width:auto;margin:0;padding:6px 0;transition:opacity .5s;position:absolute;bottom:-99em}.wwav-player__footer__pop.show{opacity:1;bottom:2.4em}.wwav-player__footer--stop{width:2.2em;margin:0;position:relative;top:0;left:0}.wwav-player__footer--stop:after{content:"";background-color:#fff3;width:1px;height:66%;position:absolute;inset:17% 0 auto auto}.wwav-player__footer--fullscreen{width:2.2em;margin:0;position:absolute;top:0;right:0}.wwav-player__footer--fullscreen:after{content:"";background-color:#fff3;width:1px;height:66%;position:absolute;inset:17% auto auto 0}.wwav-player__footer--left{width:auto;height:100%;position:absolute;top:0;left:2.7em}.wwav-player__footer--play{vertical-align:top;margin:0}.wwav-player__footer--speed{vertical-align:top;width:2em;margin:0;line-height:2.3em;position:relative}.wwav-player__footer--speed>div{width:100%;height:100%;position:relative;top:0;left:0}.wwav-player__footer--speed-pop{width:7em;font-size:12px;left:-2em}.wwav-player__footer--speed-pop--item{white-space:nowrap;text-overflow:ellipsis;color:#8191a9;box-sizing:border-box;cursor:pointer;text-align:center;background:#2d3443;height:2em;padding:0 10px;line-height:2.2em;position:relative;overflow:hidden}.wwav-player__footer--speed-pop--item i{width:1.2em;margin:0;position:absolute}.wwav-player__footer--speed-pop--item i:first-child{left:.5em}.wwav-player__footer--speed-pop--item i:last-child{right:.5em}.wwav-player__footer--ai,.wwav-player__footer--capture,.wwav-player__footer--ptz{vertical-align:top}.wwav-player__footer--right{width:auto;height:100%;position:absolute;top:0;right:2.7em}.wwav-player__footer--net-speed{cursor:auto;vertical-align:top;width:4.5em;margin:0;line-height:2.3em;overflow:hidden}.wwav-player__footer--net-speed:hover{color:#afb9bc}.wwav-player__footer--net-speed span{font-size:.8em}.wwav-player__footer--info{vertical-align:top;position:relative}.wwav-player__footer--info-pop{width:11em;font-size:12px;left:-5.5em}.wwav-player__footer--info-pop--item{white-space:nowrap;text-overflow:ellipsis;color:#8191a9;box-sizing:border-box;cursor:pointer;text-align:left;background:#2d3443;height:2em;padding:0 10px;line-height:2em;overflow:hidden}.wwav-player__footer--quality{vertical-align:top;width:auto;margin:0;line-height:2.4em;position:relative}.wwav-player__footer--quality-select{width:4em;left:-1em}.wwav-player__footer--quality-select--item{white-space:nowrap;text-overflow:ellipsis;color:#8191a9;box-sizing:border-box;cursor:pointer;text-align:center;background:#2d3443;height:2em;padding:0 10px;line-height:2em;overflow:hidden}.wwav-player__footer--quality-select--item:hover{color:#4b99e7}.wwav-player__footer--quality-select--item.active{color:#409eff}.wwav-player__footer--setting-pop{cursor:default;width:11em;font-size:12px;left:-4em}.wwav-player__footer--setting-pop--item{white-space:nowrap;text-overflow:ellipsis;color:#8191a9;box-sizing:border-box;text-align:left;background:#2d3443;height:2em;padding:0 10px;line-height:2em;overflow:hidden}.wwav-player__name{color:#afb9bc;z-index:9;-webkit-user-select:none;user-select:none;background:linear-gradient(#343b4acc 0,#16181dcc);justify-content:space-between;align-items:center;width:100%;height:2.2em;padding:0 .5em;transition:top .3s ease-out;display:flex;position:absolute;top:-2.2em;left:0}.wwav-player__name span{z-index:10}.wwav-player__watermark{z-index:8;width:100%;height:100%;position:absolute}.wwav-player__watermark span{color:#fff;font-size:16px;font-weight:600}.wwav-player.active .wwav-player__header,.wwav-player:hover .wwav-player__header,.wwav-player:hover .wwav-player__name{transition:top 50ms ease-out;top:0}.wwav-player.active .wwav-player__footer,.wwav-player:hover .wwav-player__footer{transition:top 50ms ease-out;bottom:0}.wwav-player-center-middle{position:absolute;top:50%;left:50%;transform:translate(-50%)translateY(-50%)}.wwav-player__el-input{min-width:0;height:28px;font-size:12px;line-height:28px;display:inline-block;position:relative}.wwav-player__el-input__inner{-webkit-appearance:none;box-sizing:border-box;color:#eee;font-size:inherit;caret-color:#05d380;background-color:#aaaaaa80;background-image:none;border:none;border-radius:4px;outline:none;width:100%;height:28px;padding:0 10px;font-family:PingFang SC;font-weight:400;line-height:28px;display:inline-block}.wwav-player__el-input__inner::-webkit-input-placeholder{color:#bbb;font-size:14px}.wwav-player__ptz{z-index:9;box-sizing:border-box;background-color:#0000;border:none;width:100%;height:100%;margin:0;padding:0;font-size:16px;display:inline-block;position:absolute;top:0;left:0}.wwav-player__ptz-status-label{color:#fff;background-color:#0006;border:none;border-radius:3px;width:auto;padding:10px 19px;font-family:PingFang SC;font-size:27px;font-weight:400;position:absolute;top:1.8em;left:1em}.wcs-wwav-base-video__content{cursor:pointer;object-fit:fill;width:100%!important;height:100%!important}.wcs-wwav-base-video{width:100%;height:100%;position:relative}.wcs-wwav-base-video .wcs-wwav-base-video__content{cursor:pointer;object-fit:fill;width:100%!important;height:100%!important}.wcs-wwav-base-video canvas{cursor:pointer;object-fit:fill;width:100%;height:100%;display:none}.base-content{width:300px;height:300px;position:relative}.wcs-wwav-base-video__content[data-v-c3dbeeea]{cursor:pointer;object-fit:fill;width:100%!important;height:100%!important}.wcs-wwav-base-video[data-v-c3dbeeea]{width:100%;height:100%;position:relative}.wcs-wwav-base-video .wcs-wwav-base-video__content[data-v-c3dbeeea]{cursor:pointer;object-fit:fill;width:100%!important;height:100%!important}.wcs-wwav-base-video canvas[data-v-c3dbeeea]{cursor:pointer;object-fit:fill;width:100%;height:100%;display:none}.base-content[data-v-c3dbeeea]{width:100%;height:100%;position:relative;overflow:hidden}
|