zwplayer-vue2x 1.0.36 → 1.1.1
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 +425 -601
- package/lib/zwplayervue2.common.js +13 -2
- package/lib/zwplayervue2.umd.js +13 -2
- package/lib/zwplayervue2.umd.min.js +1 -1
- package/package.json +1 -1
- package/zwplayerlib/zwplayer/css/zwplayer.css +1 -4550
- package/zwplayerlib/zwplayer/css/zwplayer.ttf +0 -0
- package/zwplayerlib/zwplayer/zwplayer.js +932 -638
package/README.md
CHANGED
|
@@ -1,73 +1,98 @@
|
|
|
1
1
|
# zwplayer-vue2x
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Vue 2.x wrapper component for zwplayer, providing easy-to-use video playback capabilities.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**[English](#english) | [中文](#中文)**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
---
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
<a id="english"></a>
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Vue 2.x wrapper component for zwplayer, providing easy-to-use video playback capabilities.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## About zwplayer
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
`zwplayer` (Zero Web Player) is a web video player built on the "zero-effort" design philosophy, dedicated to reducing the developer's integration cost to as close to zero as possible.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
### Core Principles
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
- **Zero Cost** - Completely free, forever free, no payment required
|
|
20
|
+
- **Zero Learning Curve** - Provides a clean, unified API; the smart engine handles all streaming technical details automatically
|
|
21
|
+
- **Zero Upgrade Cost** - The API is permanently stabilized; upgrading only requires replacing a single file
|
|
22
|
+
- **Zero Risk** - Clean codebase with no ads, no analytics, no network backdoors
|
|
23
|
+
- **Zero Deployment Cost** - No dependency on third-party libraries or CDNs; works on private networks and intranets
|
|
20
24
|
|
|
21
|
-
###
|
|
25
|
+
### Key Features
|
|
22
26
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
27
|
+
- **Broad Protocol Support**: HLS, DASH, HTTP-FLV, HTTP-TS, WebSocket, WebRTC (WHEP/ARTC/BRTC/TRTC)
|
|
28
|
+
- **Unique Protocol**: RTSP web playback support (no browser plugin required)
|
|
29
|
+
- **Local File Playback**: Play video/audio files directly from the user's device
|
|
30
|
+
- **Smart Subtitles**: Dual subtitles, subtitle search, subtitle translation, chapter search, drag-and-drop loading of local subtitle/chapter files
|
|
31
|
+
- **Rich Functionality**: Danmaku (bullet comments), progress bar preview, image adjustment, screenshots, volume boost, A-B loop, recording, audio extraction, and more
|
|
32
|
+
- **Live Streaming Optimization**: Ultra-low latency streaming, live catch-up, multi-bitrate switching
|
|
33
|
+
- **Flexible Modes**: Picture-in-Picture, browser fullscreen, auto mini-window, forced lock mode
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
### What's New in v3.3.0
|
|
36
|
+
|
|
37
|
+
- **Casting**: Cast to external devices via the browser Presentation API / AirPlay
|
|
38
|
+
- **Watermarks**: Multiple watermarks, image watermarks, text watermarks, animated roaming watermarks; backward-compatible with the legacy `logo` configuration
|
|
39
|
+
- **Playlists**: XML-format playlists, multi-episode group management, auto-play next episode
|
|
40
|
+
- **Interactive Video Annotations (Hotspots)**: Visual drag-and-drop design of interactive video hotspots, supporting form, quiz, vote, and other interactive nodes
|
|
41
|
+
- **Frame-by-Frame Stepping**: Precise frame-by-frame playback control via keyboard arrow keys
|
|
42
|
+
- **Subtitle Translation**: Configurable translation API with a real-time subtitle translation panel
|
|
43
|
+
- **Volume Boost**: Volume gain beyond 100% via the Web Audio API
|
|
44
|
+
- **Time Format**: Display time in seconds or milliseconds
|
|
45
|
+
- **Magnifier**: Fully rewritten magnifier feature
|
|
46
|
+
|
|
47
|
+
### Online Tools
|
|
48
|
+
|
|
49
|
+
ZWPlayer provides **8 free online tools** — no registration required, ready to use:
|
|
50
|
+
|
|
51
|
+
| # | Tool | Description | Link |
|
|
52
|
+
|---|------|-------------|------|
|
|
53
|
+
| 1 | **Online Player** | Universal protocol player for live testing and local file preview, supporting WebRTC/RTSP/HLS/DASH/FLV and all other protocols | [videoplayer](https://www.zwplayer.com/tools/videoplayer/) |
|
|
54
|
+
| 2 | **Code Generator** | Visually configure player UI skins, autoplay policies, subtitle attachment, and video hotspots; one-click export of integration code | [generator](https://www.zwplayer.com/tools/generator/) |
|
|
55
|
+
| 3 | **Annotation Editor** | Visual drag-and-drop design of interactive video hotspots, supporting form, quiz, vote, and other interactive nodes | [annotation](https://www.zwplayer.com/tools/annotation/) |
|
|
56
|
+
| 4 | **Subtitle Editor** | Create, translate, and export subtitles in SRT, VTT, BCC, JSON, and other formats online | [subtitle](https://www.zwplayer.com/tools/subtitle/) |
|
|
57
|
+
| 5 | **Chapter Editor** | Visually create and export video chapter marker data | [chapter](https://www.zwplayer.com/tools/chapter/) |
|
|
58
|
+
| 6 | **Thumbnail Generator** | Quickly generate video sprite sheets and ZWMAP JSON configuration | [thumbnail](https://www.zwplayer.com/tools/thumbnail/) |
|
|
59
|
+
| 7 | **Playlist Editor** | Visually manage and export playlist data, with group and auto-play support | [playlist](https://www.zwplayer.com/tools/playlist/) |
|
|
60
|
+
| 8 | **Watermark Editor** | Visually configure image watermarks, text watermarks, animated roaming watermarks, and tiled watermarks | [watermark](https://www.zwplayer.com/tools/watermark/) |
|
|
61
|
+
|
|
62
|
+
For more details, please visit:
|
|
63
|
+
1. [zwplayer Official Website](https://www.zwplayer.com)
|
|
64
|
+
2. [Vue Framework Integration Guide](https://www.zwplayer.com/docs/support/guide-vue-framework.html)
|
|
65
|
+
3. Example projects:
|
|
37
66
|
- **Gitee**: https://gitee.com/chenfanyu/zwplayer-vue2x-demo
|
|
38
67
|
- **GitHub**: https://github.com/chenfanyu/zwplayer-vue2x-demo
|
|
39
|
-
|
|
40
68
|
|
|
41
|
-
##
|
|
69
|
+
## Getting Started
|
|
42
70
|
|
|
43
|
-
###
|
|
71
|
+
### Installation
|
|
44
72
|
|
|
45
73
|
```bash
|
|
46
74
|
npm install zwplayer-vue2x --save
|
|
47
75
|
```
|
|
48
76
|
|
|
49
|
-
####
|
|
77
|
+
#### Installation Notes
|
|
50
78
|
|
|
51
|
-
|
|
79
|
+
**Important**: This component depends on the `zwplayer` core library. Please note the following during installation:
|
|
52
80
|
|
|
53
|
-
1.
|
|
54
|
-
-
|
|
55
|
-
-
|
|
81
|
+
1. **Automatic Configuration**: `npm install` will automatically run the `postinstall` script, which will:
|
|
82
|
+
- Create the `public` directory (if it does not exist)
|
|
83
|
+
- Copy the `zwplayer` core library to the `public/zwplayer` directory
|
|
56
84
|
|
|
57
|
-
2.
|
|
58
|
-
- 确保该目录完整包含所有 zwplayer 相关文件
|
|
59
|
-
- 不要在部署时忽略此目录
|
|
85
|
+
2. **Core Library Must Be Deployed**: The `public/zwplayer` directory must be deployed along with your project to production
|
|
60
86
|
|
|
61
|
-
3.
|
|
62
|
-
- 支持无缝升级,无需修改业务代码
|
|
63
|
-
- 升级时只需替换 `public/zwplayer` 目录中的文件即可
|
|
87
|
+
3. **Dynamic Loading Mechanism**: zwplayer uses a dynamic loading mechanism, supporting seamless upgrades without modifying your application code
|
|
64
88
|
|
|
65
|
-
4.
|
|
66
|
-
### 组件注册
|
|
89
|
+
4. **Intranet / Offline Deployment**: zwplayer does not depend on CDNs and fully supports intranet and offline environments
|
|
67
90
|
|
|
68
|
-
|
|
91
|
+
### Component Registration
|
|
69
92
|
|
|
70
|
-
|
|
93
|
+
#### Global Registration
|
|
94
|
+
|
|
95
|
+
Add in `src/main.js`:
|
|
71
96
|
|
|
72
97
|
```javascript
|
|
73
98
|
import Vue from 'vue'
|
|
@@ -81,11 +106,11 @@ new Vue({
|
|
|
81
106
|
}).$mount('#app')
|
|
82
107
|
```
|
|
83
108
|
|
|
84
|
-
|
|
109
|
+
After global registration, you can use the `<zwplayer>` component anywhere in your project.
|
|
85
110
|
|
|
86
|
-
####
|
|
111
|
+
#### Local Registration
|
|
87
112
|
|
|
88
|
-
|
|
113
|
+
Register in a single component:
|
|
89
114
|
|
|
90
115
|
```javascript
|
|
91
116
|
import { zwplayer } from 'zwplayer-vue2x'
|
|
@@ -110,15 +135,12 @@ export default {
|
|
|
110
135
|
},
|
|
111
136
|
sendDanmu(danmu) {
|
|
112
137
|
console.log('sendDanmu:', danmu)
|
|
113
|
-
// 调用websocket等方法将弹幕实际发送出去
|
|
114
138
|
}
|
|
115
139
|
}
|
|
116
140
|
}
|
|
117
141
|
```
|
|
118
142
|
|
|
119
|
-
###
|
|
120
|
-
|
|
121
|
-
在模板中使用组件:
|
|
143
|
+
### Component Usage
|
|
122
144
|
|
|
123
145
|
```html
|
|
124
146
|
<template>
|
|
@@ -144,87 +166,158 @@ export default {
|
|
|
144
166
|
</template>
|
|
145
167
|
```
|
|
146
168
|
|
|
147
|
-
###
|
|
169
|
+
### Main Properties
|
|
170
|
+
|
|
171
|
+
| Property | Type | Description | Default |
|
|
172
|
+
|---------|------|-------------|---------|
|
|
173
|
+
| murl | String/Object/Array | Media URL parameter, supports dynamic switching | - |
|
|
174
|
+
| fluid | Boolean | Enable fluid layout (adaptive to container width) | false |
|
|
175
|
+
| autoplay | Boolean | Auto-play on load | false |
|
|
176
|
+
| disableMutedConfirm | Boolean | Disable muted playback confirmation | false |
|
|
177
|
+
| enableDanmu | Boolean | Enable danmaku (bullet comments) | false |
|
|
178
|
+
| snapshotButton | Boolean | Show screenshot button | false |
|
|
179
|
+
| optionButton | Boolean | Show settings button | false |
|
|
180
|
+
| infoButton | Boolean | Show info button | false |
|
|
181
|
+
| chapterButton | Boolean | Show chapter button | false |
|
|
182
|
+
| recordButton | Boolean | Show record button | false |
|
|
183
|
+
| segmentButton | Boolean | Show segment button | false |
|
|
184
|
+
| localPlayback | Boolean | Enable local file playback | false |
|
|
185
|
+
| sendDanmu | Function | Callback function for sending danmaku | - |
|
|
186
|
+
| thumbnails | Object | Thumbnail configuration object | - |
|
|
187
|
+
| logo | Object | Logo watermark configuration object | - |
|
|
188
|
+
| poster | String | Video poster image URL | - |
|
|
189
|
+
| timeFormat | String | Time format: `'s'` = seconds, `'ms'` = milliseconds | `'s'` |
|
|
190
|
+
| castButton | Boolean | Show cast button | false |
|
|
191
|
+
| zoomButton | Boolean | Show magnifier button | false |
|
|
192
|
+
| annotationButton | Boolean | Show annotation/hotspot button | false |
|
|
193
|
+
| annotation | Object | Annotation/hotspot configuration data | - |
|
|
194
|
+
| annotations | Object | Annotation/hotspot configuration data (alias for annotation) | - |
|
|
195
|
+
| watermark | Array | Watermark configuration array | - |
|
|
196
|
+
| watermarks | Array | Watermark configuration array (alias for watermark) | - |
|
|
197
|
+
| translateApi | String | Translation API endpoint | - |
|
|
198
|
+
| defVolume | Number | Default volume percentage (0-100) | 61.25 |
|
|
199
|
+
| hideControlbarTimeout | Number | Control bar auto-hide timeout (milliseconds) | 10000 |
|
|
200
|
+
| Others | - | See [zwplayer constructor parameters](https://www.zwplayer.com/docs/support/guide-configuration.html) | - |
|
|
201
|
+
|
|
202
|
+
**Thumbnail configuration example:**
|
|
148
203
|
|
|
149
|
-
|
|
204
|
+
```javascript
|
|
205
|
+
thumbnails: {
|
|
206
|
+
url: 'https://cdn.zwplayer.com/media/b44c43c90be3521bc352aad1e80f9cd0_thumb.jpg',
|
|
207
|
+
width: 160, // width of each thumbnail
|
|
208
|
+
height: 90, // height of each thumbnail
|
|
209
|
+
row: 9, // total rows
|
|
210
|
+
col: 9, // total columns
|
|
211
|
+
total: 74 // total number of thumbnails
|
|
212
|
+
}
|
|
213
|
+
```
|
|
150
214
|
|
|
151
|
-
|
|
215
|
+
**Logo watermark configuration example:**
|
|
152
216
|
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
:optionButton="true"
|
|
165
|
-
:infoButton="true"
|
|
166
|
-
:localPlayback="true"
|
|
167
|
-
:recordButton="true"
|
|
168
|
-
:segmentButton="true"
|
|
169
|
-
:autoplay="false"
|
|
170
|
-
:enableDanmu="true"
|
|
171
|
-
:chapterButton="true"
|
|
172
|
-
:fluid="true"
|
|
173
|
-
:disableMutedConfirm="true"
|
|
174
|
-
danmuBarId="danmu-controlbar"
|
|
175
|
-
/>
|
|
176
|
-
</div>
|
|
177
|
-
</template>
|
|
217
|
+
```javascript
|
|
218
|
+
logo: {
|
|
219
|
+
icon: 'https://cdn.zwplayer.com/logo.png', // logo image URL
|
|
220
|
+
dock: 'right', // dock position (left/right/top/bottom)
|
|
221
|
+
x: '5%', // X offset
|
|
222
|
+
y: '5%', // Y offset
|
|
223
|
+
width: '10%', // logo width
|
|
224
|
+
height: '10%', // logo height
|
|
225
|
+
opacity: 70 // opacity (0-100)
|
|
226
|
+
}
|
|
227
|
+
```
|
|
178
228
|
|
|
179
|
-
|
|
180
|
-
import { zwplayer } from 'zwplayer-vue2x'
|
|
229
|
+
### Events
|
|
181
230
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
231
|
+
| Event Name | Description | Callback Parameters |
|
|
232
|
+
|-----------|-------------|---------------------|
|
|
233
|
+
| onready | Player initialization complete event | - |
|
|
234
|
+
| onmediaevent | Media playback event (play, pause, ended, etc.) | event object, containing `type` and other properties |
|
|
235
|
+
|
|
236
|
+
```javascript
|
|
237
|
+
methods: {
|
|
238
|
+
onPlayerReady() {
|
|
239
|
+
console.log('Player is ready')
|
|
240
|
+
const player = this.$refs.zwplayerRef
|
|
192
241
|
},
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
},
|
|
197
|
-
onPlayerMediaEvent(event) {
|
|
198
|
-
console.log('媒体事件:', event.type)
|
|
199
|
-
}
|
|
242
|
+
onPlayerMediaEvent(event) {
|
|
243
|
+
console.log('Media event:', event.type)
|
|
244
|
+
// event.type: play, pause, ended, timeupdate, etc.
|
|
200
245
|
}
|
|
201
246
|
}
|
|
202
|
-
</script>
|
|
203
247
|
```
|
|
204
248
|
|
|
205
|
-
|
|
249
|
+
### Method Calls
|
|
250
|
+
|
|
251
|
+
```javascript
|
|
252
|
+
const player = this.$refs.zwplayerRef
|
|
253
|
+
|
|
254
|
+
// Basic playback control
|
|
255
|
+
player.play() // play
|
|
256
|
+
player.pause() // pause
|
|
257
|
+
player.seekTime(120) // seek to 120 seconds
|
|
258
|
+
player.stop() // stop
|
|
259
|
+
|
|
260
|
+
// Subtitles
|
|
261
|
+
player.addSubtitle('/subtitles/zh.vtt', '1') // add subtitle track
|
|
262
|
+
player.removeSubtitle('1') // remove subtitle track
|
|
263
|
+
|
|
264
|
+
// Danmaku
|
|
265
|
+
player.appendDanmu({
|
|
266
|
+
border: '1px solid #ccc',
|
|
267
|
+
text: 'Hello!',
|
|
268
|
+
color: '#ff6b6b'
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
// Chapters
|
|
272
|
+
player.setChapters([{
|
|
273
|
+
title: "Chapter 1",
|
|
274
|
+
desc: "Chapter 1 description",
|
|
275
|
+
time: 0,
|
|
276
|
+
duration: 50
|
|
277
|
+
}])
|
|
278
|
+
|
|
279
|
+
// Info
|
|
280
|
+
player.getDuration() // get total duration
|
|
281
|
+
player.getCurrentTime() // get current playback time
|
|
282
|
+
```
|
|
206
283
|
|
|
207
|
-
|
|
284
|
+
### Complete Example
|
|
208
285
|
|
|
209
286
|
```html
|
|
210
287
|
<template>
|
|
211
|
-
<div class="
|
|
288
|
+
<div class="video-player">
|
|
212
289
|
<zwplayer
|
|
213
290
|
v-if="playerOpen"
|
|
214
291
|
ref="zwplayerRef"
|
|
292
|
+
nodeid="main-player"
|
|
215
293
|
:murl="movieUrl"
|
|
216
|
-
|
|
217
|
-
|
|
294
|
+
:poster="poster"
|
|
295
|
+
:logo="logo"
|
|
296
|
+
:thumbnails="thumbnails"
|
|
218
297
|
:autoplay="false"
|
|
219
|
-
:sendDanmu="sendDanmu"
|
|
220
|
-
:enableDanmu="true"
|
|
221
298
|
:fluid="true"
|
|
299
|
+
:enableDanmu="true"
|
|
300
|
+
:snapshotButton="true"
|
|
301
|
+
:optionButton="true"
|
|
302
|
+
:infoButton="true"
|
|
303
|
+
:chapterButton="true"
|
|
304
|
+
:recordButton="true"
|
|
305
|
+
:localPlayback="true"
|
|
306
|
+
:sendDanmu="sendDanmu"
|
|
222
307
|
:disableMutedConfirm="true"
|
|
223
308
|
danmuBarId="danmu-controlbar"
|
|
309
|
+
@onready="onPlayerReady"
|
|
310
|
+
@onmediaevent="onPlayerMediaEvent"
|
|
224
311
|
/>
|
|
225
312
|
|
|
226
|
-
<!-- 弹幕控制条 -->
|
|
227
313
|
<div class="danmubar" id="danmu-controlbar"></div>
|
|
314
|
+
|
|
315
|
+
<div class="controls">
|
|
316
|
+
<button @click="play">Play</button>
|
|
317
|
+
<button @click="pause">Pause</button>
|
|
318
|
+
<button @click="snapshot">Screenshot</button>
|
|
319
|
+
<button @click="addSubtitle">Add Subtitle</button>
|
|
320
|
+
</div>
|
|
228
321
|
</div>
|
|
229
322
|
</template>
|
|
230
323
|
|
|
@@ -232,315 +325,289 @@ export default {
|
|
|
232
325
|
import { zwplayer } from 'zwplayer-vue2x'
|
|
233
326
|
|
|
234
327
|
export default {
|
|
235
|
-
name: '
|
|
328
|
+
name: 'VideoPlayer',
|
|
236
329
|
components: {
|
|
237
330
|
zwplayer
|
|
238
331
|
},
|
|
239
332
|
data() {
|
|
240
333
|
return {
|
|
241
|
-
movieUrl: 'https://cdn.zwplayer.
|
|
334
|
+
movieUrl: 'https://cdn.zwplayer.com/media/VMAP9lxJvRpgn5sP3lV6rQ9qkzQmh5psggso3185.mp4',
|
|
335
|
+
poster: 'https://www.zwplayer.com/zwplayer-preview.png',
|
|
242
336
|
playerOpen: true,
|
|
243
|
-
player: null
|
|
337
|
+
player: null,
|
|
338
|
+
logo: {
|
|
339
|
+
icon: 'https://cdn.zwplayer.com/logo.png',
|
|
340
|
+
dock: 'right',
|
|
341
|
+
x: '5%',
|
|
342
|
+
y: '5%',
|
|
343
|
+
width: '10%',
|
|
344
|
+
height: '10%',
|
|
345
|
+
opacity: 70
|
|
346
|
+
},
|
|
347
|
+
thumbnails: {
|
|
348
|
+
url: 'https://cdn.zwplayer.com/media/b44c43c90be3521bc352aad1e80f9cd0_thumb.jpg',
|
|
349
|
+
width: 160,
|
|
350
|
+
height: 90,
|
|
351
|
+
row: 9,
|
|
352
|
+
col: 9,
|
|
353
|
+
total: 74
|
|
354
|
+
}
|
|
244
355
|
}
|
|
245
356
|
},
|
|
246
357
|
methods: {
|
|
247
358
|
onPlayerReady() {
|
|
359
|
+
console.log('Player is ready')
|
|
248
360
|
this.player = this.$refs.zwplayerRef
|
|
249
|
-
|
|
250
|
-
// 添加测试弹幕
|
|
251
|
-
setTimeout(() => {
|
|
252
|
-
if (this.player && this.player.appendDanmu) {
|
|
253
|
-
const testDanmu1 = {
|
|
254
|
-
border: '1px solid #ccc',
|
|
255
|
-
text: '欢迎来到 zwplayer 弹幕演示!',
|
|
256
|
-
color: '#ff6b6b'
|
|
257
|
-
}
|
|
258
|
-
this.player.appendDanmu(testDanmu1)
|
|
259
|
-
}
|
|
260
|
-
}, 3000)
|
|
261
361
|
},
|
|
262
362
|
onPlayerMediaEvent(event) {
|
|
263
|
-
console.log('
|
|
363
|
+
console.log('Media event:', event.type)
|
|
364
|
+
},
|
|
365
|
+
play() {
|
|
366
|
+
this.player.play()
|
|
367
|
+
},
|
|
368
|
+
pause() {
|
|
369
|
+
this.player.pause()
|
|
370
|
+
},
|
|
371
|
+
snapshot() {
|
|
372
|
+
this.player.snapshot()
|
|
373
|
+
},
|
|
374
|
+
addSubtitle() {
|
|
375
|
+
this.player.addSubtitle('/subtitles/zh.vtt', '1')
|
|
264
376
|
},
|
|
265
377
|
sendDanmu(danmuText) {
|
|
266
|
-
console.log('发送弹幕:', danmuText)
|
|
267
|
-
|
|
268
378
|
if (!danmuText) return
|
|
269
|
-
|
|
270
|
-
const danmu = {
|
|
379
|
+
this.player.appendDanmu({
|
|
271
380
|
border: '1px solid #ccc',
|
|
272
381
|
text: danmuText
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// 将弹幕添加到播放器
|
|
276
|
-
if (this.player && this.player.appendDanmu) {
|
|
277
|
-
this.player.appendDanmu(danmu)
|
|
278
|
-
}
|
|
382
|
+
})
|
|
279
383
|
}
|
|
280
384
|
}
|
|
281
385
|
}
|
|
282
386
|
</script>
|
|
283
387
|
|
|
284
388
|
<style scoped>
|
|
389
|
+
.video-player {
|
|
390
|
+
max-width: 1280px;
|
|
391
|
+
margin: 0 auto;
|
|
392
|
+
}
|
|
393
|
+
|
|
285
394
|
.danmubar {
|
|
286
395
|
height: 50px;
|
|
287
396
|
background-color: #232323;
|
|
288
397
|
padding: 8px;
|
|
289
398
|
box-sizing: border-box;
|
|
290
399
|
}
|
|
400
|
+
|
|
401
|
+
.controls {
|
|
402
|
+
margin-top: 20px;
|
|
403
|
+
text-align: center;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.controls button {
|
|
407
|
+
margin: 0 10px;
|
|
408
|
+
padding: 8px 16px;
|
|
409
|
+
background-color: #409eff;
|
|
410
|
+
color: white;
|
|
411
|
+
border: none;
|
|
412
|
+
border-radius: 4px;
|
|
413
|
+
cursor: pointer;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.controls button:hover {
|
|
417
|
+
background-color: #66b1ff;
|
|
418
|
+
}
|
|
291
419
|
</style>
|
|
292
420
|
```
|
|
293
421
|
|
|
294
|
-
|
|
422
|
+
## Other Versions
|
|
295
423
|
|
|
296
|
-
|
|
424
|
+
### Vue 3.x
|
|
297
425
|
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
<zwplayer
|
|
302
|
-
v-if="playerOpen"
|
|
303
|
-
ref="zwplayerRef"
|
|
304
|
-
nodeid="main-player"
|
|
305
|
-
:murl="movieUrl"
|
|
306
|
-
@onready="onPlayerReady"
|
|
307
|
-
@onmediaevent="onPlayerMediaEvent"
|
|
308
|
-
:autoplay="false"
|
|
309
|
-
:fluid="true"
|
|
310
|
-
:disableMutedConfirm="true"
|
|
311
|
-
/>
|
|
312
|
-
</div>
|
|
313
|
-
</template>
|
|
426
|
+
```bash
|
|
427
|
+
npm install zwplayervue3 --save
|
|
428
|
+
```
|
|
314
429
|
|
|
315
|
-
|
|
316
|
-
import { zwplayer } from 'zwplayer-vue2x'
|
|
430
|
+
Documentation: [zwplayervue3](https://www.zwplayer.com/guide-vue-framework.html)
|
|
317
431
|
|
|
318
|
-
|
|
319
|
-
name: 'SubtitleDemo',
|
|
320
|
-
components: {
|
|
321
|
-
zwplayer
|
|
322
|
-
},
|
|
323
|
-
data() {
|
|
324
|
-
return {
|
|
325
|
-
movieUrl: 'https://cdn.zwplayer.cn/media/VMAP9lxJvRpgn5sP3lV6rQ9qkzQmh5psggso3185.mp4',
|
|
326
|
-
playerOpen: true
|
|
327
|
-
}
|
|
328
|
-
},
|
|
329
|
-
methods: {
|
|
330
|
-
onPlayerReady() {
|
|
331
|
-
const player = this.$refs.zwplayerRef
|
|
332
|
-
|
|
333
|
-
// 添加多个字幕轨道
|
|
334
|
-
setTimeout(() => {
|
|
335
|
-
if (player) {
|
|
336
|
-
player.addSubtitle('/subtitles/zh.vtt', '1')
|
|
337
|
-
player.addSubtitle('/subtitles/en.vtt', '2')
|
|
338
|
-
}
|
|
339
|
-
}, 1000)
|
|
340
|
-
},
|
|
341
|
-
onPlayerMediaEvent(event) {
|
|
342
|
-
console.log('媒体事件:', event.type)
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
</script>
|
|
347
|
-
```
|
|
432
|
+
## Related Resources
|
|
348
433
|
|
|
349
|
-
|
|
434
|
+
### Official Documentation
|
|
435
|
+
- [ZWPlayer Official Website](https://www.zwplayer.com)
|
|
436
|
+
- [Online Demo](https://www.zwplayer.com/videoplayer.html)
|
|
437
|
+
- [Vue Framework Integration Guide](https://www.zwplayer.com/docs/support/guide-vue-framework.html)
|
|
438
|
+
- [Configuration Parameters](https://www.zwplayer.com/docs/support/guide-configuration.html)
|
|
439
|
+
- [API Methods](https://www.zwplayer.com/docs/support/guide-api.html)
|
|
440
|
+
- [Events](https://www.zwplayer.com/docs/support/guide-events.html)
|
|
350
441
|
|
|
351
|
-
|
|
442
|
+
### Example Projects
|
|
443
|
+
- [Vue 3 Example (Gitee)](https://gitee.com/chenfanyu/zwplayervue3-demo)
|
|
444
|
+
- [Vue 3 Example (GitHub)](https://github.com/chenfanyu/zwplayervue3-demo)
|
|
445
|
+
- [Vue 2 Example (Gitee)](https://gitee.com/chenfanyu/zwplayer-vue2x-demo)
|
|
446
|
+
- [Vue 2 Example (GitHub)](https://github.com/chenfanyu/zwplayer-vue2x-demo)
|
|
352
447
|
|
|
353
|
-
|
|
354
|
-
<template>
|
|
355
|
-
<div class="demo">
|
|
356
|
-
<zwplayer
|
|
357
|
-
v-if="playerOpen"
|
|
358
|
-
ref="zwplayerRef"
|
|
359
|
-
nodeid="main-player"
|
|
360
|
-
:murl="movieUrl"
|
|
361
|
-
@onready="onPlayerReady"
|
|
362
|
-
@onmediaevent="onPlayerMediaEvent"
|
|
363
|
-
:thumbnails="thumbnails"
|
|
364
|
-
:enableDanmu="true"
|
|
365
|
-
:chapterButton="true"
|
|
366
|
-
:fluid="true"
|
|
367
|
-
:disableMutedConfirm="true"
|
|
368
|
-
:autoplay="false"
|
|
369
|
-
/>
|
|
370
|
-
</div>
|
|
371
|
-
</template>
|
|
448
|
+
## License
|
|
372
449
|
|
|
373
|
-
|
|
374
|
-
import { zwplayer } from 'zwplayer-vue2x'
|
|
450
|
+
MIT License. ZWPlayer core library is completely free to use.
|
|
375
451
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
452
|
+
## Technical Support
|
|
453
|
+
|
|
454
|
+
- Email: 893366640@qq.com
|
|
455
|
+
- QQ: 893366640
|
|
456
|
+
- WeChat: zwplayerX
|
|
457
|
+
- Official Account: zwplayer
|
|
458
|
+
|
|
459
|
+
---
|
|
460
|
+
|
|
461
|
+
<a id="中文"></a>
|
|
462
|
+
|
|
463
|
+
基于 Vue 2.x 的 zwplayer 组件封装,提供简单易用的视频播放能力。
|
|
464
|
+
|
|
465
|
+
## 关于 zwplayer
|
|
466
|
+
|
|
467
|
+
`zwplayer`(Zero Web Player)是一款秉持"智能傻瓜式"设计理念的网页播放器,致力于将开发者的使用成本降至无限接近于零。
|
|
468
|
+
|
|
469
|
+
### 核心特点
|
|
470
|
+
|
|
471
|
+
✅ **零费用成本** - 完全免费,永久免费,无需支付任何费用
|
|
472
|
+
|
|
473
|
+
✅ **零学习成本** - 提供统一简洁的 API,智能引擎自动处理所有流媒体技术细节
|
|
474
|
+
|
|
475
|
+
✅ **零升级成本** - API 永久固化,版本升级仅需替换文件
|
|
476
|
+
|
|
477
|
+
✅ **零风险成本** - 代码纯净,无广告、无统计、无联网后门
|
|
478
|
+
|
|
479
|
+
✅ **零部署成本** - 不依赖第三方库和 CDN,私网、内网均可使用
|
|
480
|
+
|
|
481
|
+
### 主要功能
|
|
482
|
+
|
|
483
|
+
- **广泛协议支持**:HLS、DASH、HTTP-FLV、HTTP-TS、WS、WebRTC(WHEP/ARTC/BRTC/TRTC)
|
|
484
|
+
- **特色协议**:支持 RTSP 网页播放(无需插件)
|
|
485
|
+
- **本地文件播放**:支持直接播放用户设备上的本地视频/音频文件
|
|
486
|
+
- **智能字幕**:支持双字幕、字幕搜索、字幕翻译、章节搜索、拖拽加载本地字幕/章节文件
|
|
487
|
+
- **丰富功能**:弹幕、进度条预览、画面调节、截图、音量增益、AB循环、录制、音频提取等
|
|
488
|
+
- **直播优化**:超低延时直播、直播追帧、多码流切换
|
|
489
|
+
- **灵活模式**:画中画、网页全屏、自动小窗口、强制锁定模式
|
|
490
|
+
|
|
491
|
+
### v3.3.0 新增功能
|
|
492
|
+
|
|
493
|
+
- **投屏**:支持通过浏览器 Presentation API / AirPlay 投射到外部设备
|
|
494
|
+
- **水印**:支持多水印、图片水印、文字水印、动态游走水印,兼容旧版 `logo` 配置
|
|
495
|
+
- **播放列表**:支持 XML 格式播放列表,多集分组管理,自动播放下一集
|
|
496
|
+
- **视频交互热区(标注)**:可视化拖拽设计视频交互热区,支持表单、测验、投票等交互节点
|
|
497
|
+
- **逐帧步进**:通过键盘方向键逐帧精确控制播放
|
|
498
|
+
- **字幕翻译**:可设置翻译 API,支持实时字幕翻译面板
|
|
499
|
+
- **音量增强**:通过 Web Audio API 实现超过 100% 的音量增益
|
|
500
|
+
- **时间格式**:支持秒和毫秒两种时间显示格式
|
|
501
|
+
- **放大镜**:全新重写的放大镜功能
|
|
502
|
+
|
|
503
|
+
### 在线工具
|
|
504
|
+
|
|
505
|
+
ZWPlayer 提供 **8 个免费在线工具**,无需注册,即开即用:
|
|
506
|
+
|
|
507
|
+
| # | 工具 | 说明 | 链接 |
|
|
508
|
+
|---|------|------|------|
|
|
509
|
+
| 1 | **在线播放器** | 全协议在线试播与本地文件预览,支持 WebRTC/RTSP/HLS/DASH/FLV 等所有协议 | [videoplayer](https://www.zwplayer.com/zh/tools/videoplayer/) |
|
|
510
|
+
| 2 | **代码生成器** | 可视化配置播放器 UI 皮肤、自动播放策略、字幕挂载与视频热区,一键导出集成代码 | [generator](https://www.zwplayer.com/zh/tools/generator/) |
|
|
511
|
+
| 3 | **交互标注编辑器** | 可视化拖拽设计视频交互热区,支持表单、测验、投票等交互节点 | [annotation](https://www.zwplayer.com/zh/tools/annotation/) |
|
|
512
|
+
| 4 | **字幕编辑器** | 在线创建、翻译和导出 SRT、VTT、BCC、JSON 等格式字幕 | [subtitle](https://www.zwplayer.com/zh/tools/subtitle/) |
|
|
513
|
+
| 5 | **章节编辑器** | 可视化创建和导出视频章节标记数据 | [chapter](https://www.zwplayer.com/zh/tools/chapter/) |
|
|
514
|
+
| 6 | **缩略图生成器** | 快速生成视频雪碧图(Sprite Sheet)和 ZWMAP JSON 配置 | [thumbnail](https://www.zwplayer.com/zh/tools/thumbnail/) |
|
|
515
|
+
| 7 | **播放列表编辑器** | 可视化管理和导出播放列表数据,支持分组和自动播放 | [playlist](https://www.zwplayer.com/zh/tools/playlist/) |
|
|
516
|
+
| 8 | **水印编辑器** | 可视化配置图片水印、文字水印、动态游走水印和铺满水印 | [watermark](https://www.zwplayer.com/zh/tools/watermark/) |
|
|
517
|
+
|
|
518
|
+
更多详情请访问:
|
|
519
|
+
1. [zwplayer 官网](https://www.zwplayer.com/zh)
|
|
520
|
+
2. [在线体验](https://www.zwplayer.com/zh/videoplayer.html)
|
|
521
|
+
3. [Vue 框架使用](https://www.zwplayer.com/zh/docs/support/guide-vue-framework.html)
|
|
522
|
+
4. 调用示例项目:
|
|
523
|
+
- **Gitee**: https://gitee.com/chenfanyu/zwplayer-vue2x-demo
|
|
524
|
+
- **GitHub**: https://github.com/chenfanyu/zwplayer-vue2x-demo
|
|
525
|
+
|
|
526
|
+
## 使用说明
|
|
527
|
+
|
|
528
|
+
### 安装
|
|
529
|
+
|
|
530
|
+
```bash
|
|
531
|
+
npm install zwplayer-vue2x --save
|
|
405
532
|
```
|
|
406
533
|
|
|
407
|
-
####
|
|
534
|
+
#### 安装注意事项
|
|
408
535
|
|
|
409
|
-
|
|
536
|
+
⚠️ **重要**:本组件依赖 `zwplayer` 核心库,安装时请注意以下事项:
|
|
410
537
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
<zwplayer
|
|
415
|
-
v-if="playerOpen"
|
|
416
|
-
ref="zwplayerRef"
|
|
417
|
-
nodeid="main-player"
|
|
418
|
-
:murl="movieUrl"
|
|
419
|
-
@onready="onPlayerReady"
|
|
420
|
-
@onmediaevent="onPlayerMediaEvent"
|
|
421
|
-
:chapterButton="true"
|
|
422
|
-
:autoplay="false"
|
|
423
|
-
:fluid="true"
|
|
424
|
-
:disableMutedConfirm="true"
|
|
425
|
-
/>
|
|
426
|
-
</div>
|
|
427
|
-
</template>
|
|
538
|
+
1. **自动配置**:`npm install` 会自动执行 `postinstall` 脚本,该脚本会:
|
|
539
|
+
- 创建 `public` 目录(如果不存在)
|
|
540
|
+
- 将 `zwplayer` 核心库复制到 `public/zwplayer` 目录
|
|
428
541
|
|
|
429
|
-
|
|
430
|
-
|
|
542
|
+
2. **核心库必须发布**:`public/zwplayer` 目录必须随项目一起发布到生产环境
|
|
543
|
+
- 确保该目录完整包含所有 zwplayer 相关文件
|
|
544
|
+
- 不要在部署时忽略此目录
|
|
431
545
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
thumb: null
|
|
455
|
-
},
|
|
456
|
-
{
|
|
457
|
-
title: "分段2",
|
|
458
|
-
desc: "分段2描述",
|
|
459
|
-
time: 50,
|
|
460
|
-
duration: 100,
|
|
461
|
-
style: {
|
|
462
|
-
background: "blue"
|
|
463
|
-
},
|
|
464
|
-
image: null
|
|
465
|
-
},
|
|
466
|
-
{
|
|
467
|
-
title: "分段3",
|
|
468
|
-
desc: "分段3描述",
|
|
469
|
-
time: 100,
|
|
470
|
-
duration: 200,
|
|
471
|
-
style: {
|
|
472
|
-
background: "green"
|
|
473
|
-
},
|
|
474
|
-
image: null
|
|
475
|
-
}
|
|
476
|
-
]
|
|
477
|
-
player.setChapters(chapters)
|
|
478
|
-
}
|
|
479
|
-
}, 1000)
|
|
480
|
-
},
|
|
481
|
-
onPlayerMediaEvent(event) {
|
|
482
|
-
console.log('媒体事件:', event.type)
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
</script>
|
|
546
|
+
3. **动态加载机制**:zwplayer 采用动态加载机制
|
|
547
|
+
- 支持无缝升级,无需修改业务代码
|
|
548
|
+
- 升级时只需替换 `public/zwplayer` 目录中的文件即可
|
|
549
|
+
|
|
550
|
+
4. **内网/私网部署**:zwplayer 不依赖 CDN,完全支持内网和离线环境部署
|
|
551
|
+
|
|
552
|
+
### 组件注册
|
|
553
|
+
|
|
554
|
+
#### 全局注册
|
|
555
|
+
|
|
556
|
+
在 `src/main.js` 中添加:
|
|
557
|
+
|
|
558
|
+
```javascript
|
|
559
|
+
import Vue from 'vue'
|
|
560
|
+
import App from './App.vue'
|
|
561
|
+
import ZwModule from 'zwplayer-vue2x'
|
|
562
|
+
|
|
563
|
+
Vue.use(ZwModule)
|
|
564
|
+
|
|
565
|
+
new Vue({
|
|
566
|
+
render: h => h(App),
|
|
567
|
+
}).$mount('#app')
|
|
487
568
|
```
|
|
488
569
|
|
|
489
|
-
|
|
570
|
+
全局注册后,可在项目任何组件中使用 `<zwplayer>` 组件。
|
|
490
571
|
|
|
491
|
-
|
|
572
|
+
#### 局部注册
|
|
492
573
|
|
|
493
|
-
|
|
494
|
-
<template>
|
|
495
|
-
<div class="demo">
|
|
496
|
-
<zwplayer
|
|
497
|
-
v-if="playerOpen"
|
|
498
|
-
ref="zwplayerRef"
|
|
499
|
-
nodeid="main-player"
|
|
500
|
-
:murl="movieUrl"
|
|
501
|
-
@onready="onPlayerReady"
|
|
502
|
-
@onmediaevent="onPlayerMediaEvent"
|
|
503
|
-
:snapshotButton="true"
|
|
504
|
-
:fluid="true"
|
|
505
|
-
:autoplay="false"
|
|
506
|
-
:disableMutedConfirm="true"
|
|
507
|
-
/>
|
|
508
|
-
</div>
|
|
509
|
-
</template>
|
|
574
|
+
在组件中单独注册:
|
|
510
575
|
|
|
511
|
-
|
|
576
|
+
```javascript
|
|
512
577
|
import { zwplayer } from 'zwplayer-vue2x'
|
|
513
578
|
|
|
514
579
|
export default {
|
|
515
|
-
name: '
|
|
580
|
+
name: 'MyComponent',
|
|
516
581
|
components: {
|
|
517
582
|
zwplayer
|
|
518
583
|
},
|
|
519
584
|
data() {
|
|
520
585
|
return {
|
|
521
|
-
movieUrl: 'https://
|
|
586
|
+
movieUrl: 'https://d2zihajmogu5jn.cloudfront.net/elephantsdream/ed_hd.mp4',
|
|
522
587
|
playerOpen: true
|
|
523
588
|
}
|
|
524
589
|
},
|
|
525
590
|
methods: {
|
|
526
591
|
onPlayerReady() {
|
|
527
|
-
console.log('
|
|
592
|
+
console.log('player ready event.')
|
|
528
593
|
},
|
|
529
594
|
onPlayerMediaEvent(event) {
|
|
530
|
-
console.log('
|
|
595
|
+
console.log('media event:', event.type)
|
|
596
|
+
},
|
|
597
|
+
sendDanmu(danmu) {
|
|
598
|
+
console.log('sendDanmu:', danmu)
|
|
531
599
|
}
|
|
532
600
|
}
|
|
533
601
|
}
|
|
534
|
-
</script>
|
|
535
602
|
```
|
|
536
603
|
|
|
537
|
-
|
|
604
|
+
### 组件使用
|
|
538
605
|
|
|
539
|
-
|
|
606
|
+
在模板中使用组件:
|
|
540
607
|
|
|
541
608
|
```html
|
|
542
609
|
<template>
|
|
543
|
-
<div class="
|
|
610
|
+
<div class="player-container">
|
|
544
611
|
<zwplayer
|
|
545
612
|
v-if="playerOpen"
|
|
546
613
|
ref="zwplayerRef"
|
|
@@ -553,96 +620,13 @@ export default {
|
|
|
553
620
|
:infoButton="true"
|
|
554
621
|
:enableDanmu="true"
|
|
555
622
|
:chapterButton="true"
|
|
623
|
+
danmuBarId="danmu-controlbar"
|
|
556
624
|
:fluid="true"
|
|
557
625
|
:autoplay="false"
|
|
558
626
|
:disableMutedConfirm="true"
|
|
559
627
|
/>
|
|
560
628
|
</div>
|
|
561
629
|
</template>
|
|
562
|
-
|
|
563
|
-
<script>
|
|
564
|
-
import { zwplayer } from 'zwplayer-vue2x'
|
|
565
|
-
|
|
566
|
-
export default {
|
|
567
|
-
name: 'FluidDemo',
|
|
568
|
-
components: {
|
|
569
|
-
zwplayer
|
|
570
|
-
},
|
|
571
|
-
data() {
|
|
572
|
-
return {
|
|
573
|
-
movieUrl: 'https://cdn.zwplayer.cn/media/VMAP9lxJvRpgn5sP3lV6rQ9qkzQmh5psggso3185.mp4',
|
|
574
|
-
playerOpen: true
|
|
575
|
-
}
|
|
576
|
-
},
|
|
577
|
-
methods: {
|
|
578
|
-
onPlayerReady() {
|
|
579
|
-
console.log('播放器已准备就绪')
|
|
580
|
-
},
|
|
581
|
-
onPlayerMediaEvent(event) {
|
|
582
|
-
console.log('媒体事件:', event.type)
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
</script>
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
#### 8. Logo水印
|
|
590
|
-
|
|
591
|
-
展示播放器Logo水印功能,支持自定义Logo位置、大小和透明度:
|
|
592
|
-
|
|
593
|
-
```html
|
|
594
|
-
<template>
|
|
595
|
-
<div class="demo">
|
|
596
|
-
<zwplayer
|
|
597
|
-
v-if="playerOpen"
|
|
598
|
-
ref="zwplayerRef"
|
|
599
|
-
nodeid="main-player"
|
|
600
|
-
:murl="movieUrl"
|
|
601
|
-
@onready="onPlayerReady"
|
|
602
|
-
@onmediaevent="onPlayerMediaEvent"
|
|
603
|
-
:autoplay="false"
|
|
604
|
-
:logo="logo"
|
|
605
|
-
:poster="poster"
|
|
606
|
-
:fluid="true"
|
|
607
|
-
:disableMutedConfirm="true"
|
|
608
|
-
/>
|
|
609
|
-
</div>
|
|
610
|
-
</template>
|
|
611
|
-
|
|
612
|
-
<script>
|
|
613
|
-
import { zwplayer } from 'zwplayer-vue2x'
|
|
614
|
-
|
|
615
|
-
export default {
|
|
616
|
-
name: 'LogoDemo',
|
|
617
|
-
components: {
|
|
618
|
-
zwplayer
|
|
619
|
-
},
|
|
620
|
-
data() {
|
|
621
|
-
return {
|
|
622
|
-
movieUrl: 'https://cdn.zwplayer.cn/media/VMAP9lxJvRpgn5sP3lV6rQ9qkzQmh5psggso3185.mp4',
|
|
623
|
-
playerOpen: true,
|
|
624
|
-
poster: 'https://www.zwplayer.cn/zwplayer-preview.png',
|
|
625
|
-
logo: {
|
|
626
|
-
icon: 'https://cdn.zwplayer.cn/logo.png',
|
|
627
|
-
dock: 'right',
|
|
628
|
-
x: '5%',
|
|
629
|
-
y: '5%',
|
|
630
|
-
width: '10%',
|
|
631
|
-
height: '10%',
|
|
632
|
-
opacity: 70
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
},
|
|
636
|
-
methods: {
|
|
637
|
-
onPlayerReady() {
|
|
638
|
-
console.log('播放器已准备就绪')
|
|
639
|
-
},
|
|
640
|
-
onPlayerMediaEvent(event) {
|
|
641
|
-
console.log('媒体事件:', event.type)
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
</script>
|
|
646
630
|
```
|
|
647
631
|
|
|
648
632
|
### 主要属性说明
|
|
@@ -665,13 +649,24 @@ export default {
|
|
|
665
649
|
| thumbnails | Object | 缩略图配置对象 | - |
|
|
666
650
|
| logo | Object | Logo水印配置对象 | - |
|
|
667
651
|
| poster | String | 视频封面图地址 | - |
|
|
668
|
-
|
|
|
652
|
+
| timeFormat | String | 时间格式:`'s'`=秒,`'ms'`=毫秒 | `'s'` |
|
|
653
|
+
| castButton | Boolean | 是否显示投屏按钮 | false |
|
|
654
|
+
| zoomButton | Boolean | 是否显示放大镜按钮 | false |
|
|
655
|
+
| annotationButton | Boolean | 是否显示标注/热区按钮 | false |
|
|
656
|
+
| annotation | Object | 标注/热区配置数据 | - |
|
|
657
|
+
| annotations | Object | 标注/热区配置数据(annotation 别名) | - |
|
|
658
|
+
| watermark | Array | 水印配置数组 | - |
|
|
659
|
+
| watermarks | Array | 水印配置数组(watermark 别名) | - |
|
|
660
|
+
| translateApi | String | 翻译 API 端点 | - |
|
|
661
|
+
| defVolume | Number | 默认音量百分比 (0-100) | 61.25 |
|
|
662
|
+
| hideControlbarTimeout | Number | 控制栏自动隐藏等待时间(毫秒) | 10000 |
|
|
663
|
+
| 其它 | - | 请参考 [zwplayer 播放器构造函数参数](https://www.zwplayer.com/zh/docs/support/guide-configuration.html) | - |
|
|
669
664
|
|
|
670
665
|
**缩略图配置对象(thumbnails)示例:**
|
|
671
666
|
|
|
672
667
|
```javascript
|
|
673
668
|
thumbnails: {
|
|
674
|
-
url: 'https://cdn.zwplayer.
|
|
669
|
+
url: 'https://cdn.zwplayer.com/media/b44c43c90be3521bc352aad1e80f9cd0_thumb.jpg',
|
|
675
670
|
width: 160, // 每个小缩略图的宽度
|
|
676
671
|
height: 90, // 每个小缩略图的高度
|
|
677
672
|
row: 9, // 缩略图总行数
|
|
@@ -684,7 +679,7 @@ thumbnails: {
|
|
|
684
679
|
|
|
685
680
|
```javascript
|
|
686
681
|
logo: {
|
|
687
|
-
icon: 'https://cdn.zwplayer.
|
|
682
|
+
icon: 'https://cdn.zwplayer.com/logo.png', // Logo图片地址
|
|
688
683
|
dock: 'right', // 停靠位置(left/right/top/bottom)
|
|
689
684
|
x: '5%', // X轴偏移
|
|
690
685
|
y: '5%', // Y轴偏移
|
|
@@ -696,7 +691,7 @@ logo: {
|
|
|
696
691
|
|
|
697
692
|
### 事件
|
|
698
693
|
|
|
699
|
-
组件提供了 `onready`、`onmediaevent` 等事件,详细说明请参考 [zwplayer 事件文档](https://www.zwplayer.
|
|
694
|
+
组件提供了 `onready`、`onmediaevent` 等事件,详细说明请参考 [zwplayer 事件文档](https://www.zwplayer.com/zh/docs/support/guide-events.html)。
|
|
700
695
|
|
|
701
696
|
**常用事件:**
|
|
702
697
|
|
|
@@ -705,31 +700,11 @@ logo: {
|
|
|
705
700
|
| onready | 播放器初始化完成事件 | - |
|
|
706
701
|
| onmediaevent | 媒体播放事件(播放、暂停、结束等) | event对象,包含type等属性 |
|
|
707
702
|
|
|
708
|
-
**使用示例:**
|
|
709
|
-
|
|
710
|
-
```javascript
|
|
711
|
-
methods: {
|
|
712
|
-
onPlayerReady() {
|
|
713
|
-
console.log('播放器已准备就绪')
|
|
714
|
-
// 可以在这里进行播放器初始化后的操作
|
|
715
|
-
const player = this.$refs.zwplayerRef
|
|
716
|
-
// 例如:添加字幕、设置章节等
|
|
717
|
-
},
|
|
718
|
-
onPlayerMediaEvent(event) {
|
|
719
|
-
console.log('媒体事件:', event.type)
|
|
720
|
-
// event.type 可能的值:play, pause, ended, timeupdate 等
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
```
|
|
724
|
-
|
|
725
703
|
### 方法调用
|
|
726
704
|
|
|
727
705
|
通过 `ref` 引用调用播放器方法:
|
|
728
706
|
|
|
729
|
-
**基础方法:**
|
|
730
|
-
|
|
731
707
|
```javascript
|
|
732
|
-
// 获取播放器实例
|
|
733
708
|
const player = this.$refs.zwplayerRef
|
|
734
709
|
|
|
735
710
|
// 播放控制
|
|
@@ -738,11 +713,6 @@ player.pause() // 暂停
|
|
|
738
713
|
player.seekTime(120) // 跳转到指定秒数
|
|
739
714
|
player.stop() // 停止
|
|
740
715
|
|
|
741
|
-
```
|
|
742
|
-
|
|
743
|
-
**高级方法:**
|
|
744
|
-
|
|
745
|
-
```javascript
|
|
746
716
|
// 字幕相关
|
|
747
717
|
player.addSubtitle('/subtitles/zh.vtt', '1') // 添加字幕轨道
|
|
748
718
|
player.removeSubtitle('1') // 移除字幕轨道
|
|
@@ -762,175 +732,29 @@ player.setChapters([{
|
|
|
762
732
|
duration: 50
|
|
763
733
|
}])
|
|
764
734
|
|
|
765
|
-
|
|
766
735
|
// 获取信息
|
|
767
736
|
player.getDuration() // 获取视频总时长
|
|
768
737
|
player.getCurrentTime() // 获取当前播放时间
|
|
769
|
-
|
|
770
738
|
```
|
|
771
739
|
|
|
772
|
-
### 完整示例
|
|
773
|
-
|
|
774
|
-
结合所有功能的完整组件示例:
|
|
775
|
-
|
|
776
|
-
```html
|
|
777
|
-
<template>
|
|
778
|
-
<div class="video-player">
|
|
779
|
-
<zwplayer
|
|
780
|
-
v-if="playerOpen"
|
|
781
|
-
ref="zwplayerRef"
|
|
782
|
-
nodeid="main-player"
|
|
783
|
-
:murl="movieUrl"
|
|
784
|
-
:poster="poster"
|
|
785
|
-
:logo="logo"
|
|
786
|
-
:thumbnails="thumbnails"
|
|
787
|
-
:autoplay="false"
|
|
788
|
-
:fluid="true"
|
|
789
|
-
:enableDanmu="true"
|
|
790
|
-
:snapshotButton="true"
|
|
791
|
-
:optionButton="true"
|
|
792
|
-
:infoButton="true"
|
|
793
|
-
:chapterButton="true"
|
|
794
|
-
:recordButton="true"
|
|
795
|
-
:localPlayback="true"
|
|
796
|
-
:sendDanmu="sendDanmu"
|
|
797
|
-
:disableMutedConfirm="true"
|
|
798
|
-
danmuBarId="danmu-controlbar"
|
|
799
|
-
@onready="onPlayerReady"
|
|
800
|
-
@onmediaevent="onPlayerMediaEvent"
|
|
801
|
-
/>
|
|
802
|
-
|
|
803
|
-
<div class="danmubar" id="danmu-controlbar"></div>
|
|
804
|
-
|
|
805
|
-
<div class="controls">
|
|
806
|
-
<button @click="play">播放</button>
|
|
807
|
-
<button @click="pause">暂停</button>
|
|
808
|
-
<button @click="snapshot">截图</button>
|
|
809
|
-
<button @click="addSubtitle">添加字幕</button>
|
|
810
|
-
</div>
|
|
811
|
-
</div>
|
|
812
|
-
</template>
|
|
813
|
-
|
|
814
|
-
<script>
|
|
815
|
-
import { zwplayer } from 'zwplayer-vue2x'
|
|
816
|
-
|
|
817
|
-
export default {
|
|
818
|
-
name: 'VideoPlayer',
|
|
819
|
-
components: {
|
|
820
|
-
zwplayer
|
|
821
|
-
},
|
|
822
|
-
data() {
|
|
823
|
-
return {
|
|
824
|
-
movieUrl: 'https://cdn.zwplayer.cn/media/VMAP9lxJvRpgn5sP3lV6rQ9qkzQmh5psggso3185.mp4',
|
|
825
|
-
poster: 'https://www.zwplayer.cn/zwplayer-preview.png',
|
|
826
|
-
playerOpen: true,
|
|
827
|
-
player: null,
|
|
828
|
-
logo: {
|
|
829
|
-
icon: 'https://cdn.zwplayer.cn/logo.png',
|
|
830
|
-
dock: 'right',
|
|
831
|
-
x: '5%',
|
|
832
|
-
y: '5%',
|
|
833
|
-
width: '10%',
|
|
834
|
-
height: '10%',
|
|
835
|
-
opacity: 70
|
|
836
|
-
},
|
|
837
|
-
thumbnails: {
|
|
838
|
-
url: 'https://cdn.zwplayer.cn/media/b44c43c90be3521bc352aad1e80f9cd0_thumb.jpg',
|
|
839
|
-
width: 160,
|
|
840
|
-
height: 90,
|
|
841
|
-
row: 9,
|
|
842
|
-
col: 9,
|
|
843
|
-
total: 74
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
},
|
|
847
|
-
methods: {
|
|
848
|
-
onPlayerReady() {
|
|
849
|
-
console.log('播放器已准备就绪')
|
|
850
|
-
this.player = this.$refs.zwplayerRef
|
|
851
|
-
},
|
|
852
|
-
onPlayerMediaEvent(event) {
|
|
853
|
-
console.log('媒体事件:', event.type)
|
|
854
|
-
},
|
|
855
|
-
play() {
|
|
856
|
-
this.player.play()
|
|
857
|
-
},
|
|
858
|
-
pause() {
|
|
859
|
-
this.player.pause()
|
|
860
|
-
},
|
|
861
|
-
snapshot() {
|
|
862
|
-
this.player.snapshot()
|
|
863
|
-
},
|
|
864
|
-
addSubtitle() {
|
|
865
|
-
this.player.addSubtitle('/subtitles/zh.vtt', '1')
|
|
866
|
-
},
|
|
867
|
-
sendDanmu(danmuText) {
|
|
868
|
-
if (!danmuText) return
|
|
869
|
-
this.player.appendDanmu({
|
|
870
|
-
border: '1px solid #ccc',
|
|
871
|
-
text: danmuText
|
|
872
|
-
})
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
</script>
|
|
877
|
-
|
|
878
|
-
<style scoped>
|
|
879
|
-
.video-player {
|
|
880
|
-
max-width: 1280px;
|
|
881
|
-
margin: 0 auto;
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
.danmubar {
|
|
885
|
-
height: 50px;
|
|
886
|
-
background-color: #232323;
|
|
887
|
-
padding: 8px;
|
|
888
|
-
box-sizing: border-box;
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
.controls {
|
|
892
|
-
margin-top: 20px;
|
|
893
|
-
text-align: center;
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
.controls button {
|
|
897
|
-
margin: 0 10px;
|
|
898
|
-
padding: 8px 16px;
|
|
899
|
-
background-color: #409eff;
|
|
900
|
-
color: white;
|
|
901
|
-
border: none;
|
|
902
|
-
border-radius: 4px;
|
|
903
|
-
cursor: pointer;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
.controls button:hover {
|
|
907
|
-
background-color: #66b1ff;
|
|
908
|
-
}
|
|
909
|
-
</style>
|
|
910
|
-
```
|
|
911
|
-
|
|
912
|
-
|
|
913
740
|
## 其他版本
|
|
914
741
|
|
|
915
742
|
### Vue 3.x
|
|
916
743
|
|
|
917
|
-
如果你使用 Vue 3.x,请安装 `zwplayervue3`:
|
|
918
|
-
|
|
919
744
|
```bash
|
|
920
745
|
npm install zwplayervue3 --save
|
|
921
746
|
```
|
|
922
747
|
|
|
923
|
-
详细文档:[zwplayervue3](https://www.zwplayer.
|
|
748
|
+
详细文档:[zwplayervue3](https://www.zwplayer.com/zh/guide-vue-framework.html)
|
|
924
749
|
|
|
925
750
|
## 相关资源
|
|
926
751
|
|
|
927
752
|
### 官方文档
|
|
928
|
-
- [ZWPlayer 官网](https://www.zwplayer.
|
|
929
|
-
- [
|
|
930
|
-
- [
|
|
931
|
-
- [
|
|
932
|
-
- [
|
|
933
|
-
- [事件文档](https://www.zwplayer.cn/docs/support/guide-events.html)
|
|
753
|
+
- [ZWPlayer 官网](https://www.zwplayer.com/zh)
|
|
754
|
+
- [Vue 框架集成指南](https://www.zwplayer.com/zh/docs/support/guide-vue-framework.html)
|
|
755
|
+
- [配置参数文档](https://www.zwplayer.com/zh/docs/support/guide-configuration.html)
|
|
756
|
+
- [API 方法文档](https://www.zwplayer.com/zh/docs/support/guide-api.html)
|
|
757
|
+
- [事件文档](https://www.zwplayer.com/zh/docs/support/guide-events.html)
|
|
934
758
|
|
|
935
759
|
### 示例项目
|
|
936
760
|
- [Vue 3 示例 (Gitee)](https://gitee.com/chenfanyu/zwplayervue3-demo)
|