eplayer 1.6.7 → 1.6.8
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/docs/eplayer.js +202 -42
- package/docs/index.html +6 -1
- package/package.json +1 -1
package/docs/eplayer.js
CHANGED
|
@@ -4,10 +4,18 @@ class Eplayer extends HTMLElement {
|
|
|
4
4
|
this.doms = {}
|
|
5
5
|
this.src = this.getAttribute('src')
|
|
6
6
|
this.type = this.getAttribute('type')
|
|
7
|
+
this.cover = this.getAttribute('cover')
|
|
7
8
|
this.live = JSON.parse(this.getAttribute('live'))
|
|
8
9
|
this.danmaku = null
|
|
9
10
|
this.subs = []
|
|
10
11
|
|
|
12
|
+
// 添加长按右箭头3倍速相关状态
|
|
13
|
+
this.rightKeyHoldTimer = null
|
|
14
|
+
this.rightKeyPressTime = null
|
|
15
|
+
this.originalPlaybackRate = 1
|
|
16
|
+
this.isRightKeyPressed = false
|
|
17
|
+
this.isSpeedModeActive = false
|
|
18
|
+
|
|
11
19
|
this.init()
|
|
12
20
|
this.stream()
|
|
13
21
|
}
|
|
@@ -37,11 +45,14 @@ class Eplayer extends HTMLElement {
|
|
|
37
45
|
this.$('.time').style.display = 'inline-block'
|
|
38
46
|
}
|
|
39
47
|
}
|
|
40
|
-
if (name === '
|
|
48
|
+
if (name === 'danmu') {
|
|
41
49
|
this.danmaku.add({
|
|
42
50
|
msg: newVal
|
|
43
51
|
})
|
|
44
52
|
}
|
|
53
|
+
if (name === 'cover') {
|
|
54
|
+
this.cover = newVal
|
|
55
|
+
}
|
|
45
56
|
}
|
|
46
57
|
|
|
47
58
|
$(key) {
|
|
@@ -115,64 +126,143 @@ class Eplayer extends HTMLElement {
|
|
|
115
126
|
}
|
|
116
127
|
|
|
117
128
|
progress(e) {
|
|
118
|
-
|
|
119
|
-
|
|
129
|
+
const progressBarRect = this.$('.progress').getBoundingClientRect()
|
|
130
|
+
let clickX = e.clientX - progressBarRect.left
|
|
131
|
+
clickX = Math.max(0, Math.min(clickX, progressBarRect.width))
|
|
132
|
+
const offsetRatio = clickX / progressBarRect.width
|
|
133
|
+
|
|
134
|
+
this.video.currentTime = this.video.duration * offsetRatio
|
|
135
|
+
this.$('.now').innerHTML = getTimeStr(this.video.currentTime)
|
|
136
|
+
this.$('.current').style.width = offsetRatio * 100 + '%'
|
|
120
137
|
}
|
|
121
138
|
|
|
122
139
|
down(e) {
|
|
123
|
-
|
|
140
|
+
e.preventDefault()
|
|
124
141
|
this.moving = true
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
142
|
+
const progressBarRect = this.$('.progress').getBoundingClientRect()
|
|
143
|
+
this.progressBarWidth = progressBarRect.width
|
|
144
|
+
this.initialClientX = e.clientX
|
|
145
|
+
const initialOffsetRatio = this.video.currentTime / this.video.duration
|
|
146
|
+
this.initialOffsetPixels = initialOffsetRatio * this.progressBarWidth
|
|
147
|
+
|
|
148
|
+
document.addEventListener('pointermove', this.handleMove)
|
|
149
|
+
document.addEventListener('pointerup', this.handleUp, { once: true })
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
handleMove = (e) => {
|
|
153
|
+
if (!this.moving) return
|
|
154
|
+
|
|
155
|
+
const deltaX = e.clientX - this.initialClientX
|
|
156
|
+
let newOffsetPixels = this.initialOffsetPixels + deltaX
|
|
157
|
+
newOffsetPixels = Math.max(0, Math.min(newOffsetPixels, this.progressBarWidth))
|
|
158
|
+
|
|
159
|
+
this.$('.current').style.width = (newOffsetPixels / this.progressBarWidth) * 100 + '%'
|
|
160
|
+
|
|
161
|
+
const newTime = (newOffsetPixels / this.progressBarWidth) * this.video.duration
|
|
162
|
+
this.video.currentTime = Math.max(0, Math.min(newTime, this.video.duration))
|
|
163
|
+
|
|
164
|
+
this.$('.now').innerHTML = getTimeStr(this.video.currentTime)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
handleUp = (e) => {
|
|
168
|
+
this.moving = false
|
|
169
|
+
document.removeEventListener('pointermove', this.handleMove)
|
|
170
|
+
delete this.progressBarWidth
|
|
171
|
+
delete this.initialClientX
|
|
172
|
+
delete this.initialOffsetPixels
|
|
131
173
|
}
|
|
132
174
|
|
|
133
175
|
move(e) {
|
|
134
176
|
let offset = e.clientX - this.disX + 12
|
|
135
177
|
if (offset < 0) offset = 0
|
|
136
178
|
if (offset > this.$('.progress').clientWidth) {
|
|
137
|
-
|
|
179
|
+
offset = this.$('.progress').clientWidth
|
|
138
180
|
}
|
|
139
181
|
this.$('.current').style.width = offset + 'px'
|
|
140
182
|
this.video.currentTime = (offset / this.$('.progress').clientWidth) * this.video.duration
|
|
141
|
-
|
|
142
|
-
setTimeout((document.onpointermove = (e) => e && this.move(e)), 30)
|
|
183
|
+
this.$('.now').innerHTML = getTimeStr(this.video.currentTime)
|
|
143
184
|
}
|
|
144
185
|
|
|
145
186
|
alow() {
|
|
146
187
|
clearTimeout(this.timer)
|
|
147
188
|
this.$('.mark').style.cursor = 'default'
|
|
148
189
|
this.$('.eplayer').classList.add('hover')
|
|
149
|
-
this.
|
|
150
|
-
this
|
|
151
|
-
|
|
152
|
-
|
|
190
|
+
if (!this.cover) {
|
|
191
|
+
this.timer = setTimeout(() => {
|
|
192
|
+
this.$('.eplayer').classList.remove('hover')
|
|
193
|
+
}, 5000)
|
|
194
|
+
}
|
|
153
195
|
}
|
|
154
196
|
|
|
155
197
|
keydown(e) {
|
|
198
|
+
e.preventDefault()
|
|
156
199
|
switch (e.keyCode) {
|
|
157
|
-
case 37:
|
|
158
|
-
this.video.currentTime
|
|
200
|
+
case 37: // 左箭头 - 后退10秒
|
|
201
|
+
this.video.currentTime = Math.max(0, this.video.currentTime - 10)
|
|
159
202
|
break
|
|
160
|
-
case 39:
|
|
161
|
-
this.
|
|
203
|
+
case 39: // 右箭头 - 前进10秒 (支持长按3倍速)
|
|
204
|
+
if (!this.isRightKeyPressed) {
|
|
205
|
+
this.isRightKeyPressed = true
|
|
206
|
+
this.rightKeyPressTime = Date.now()
|
|
207
|
+
this.originalPlaybackRate = this.video.playbackRate
|
|
208
|
+
|
|
209
|
+
// 设置定时器,如果持续按住超过500ms则开启3倍速
|
|
210
|
+
this.rightKeyHoldTimer = setTimeout(() => {
|
|
211
|
+
this.isSpeedModeActive = true
|
|
212
|
+
this.video.playbackRate = 3
|
|
213
|
+
this.$('.speed').innerText = '3x'
|
|
214
|
+
this.$('.speed-indicator').style.display = 'block'
|
|
215
|
+
}, 500)
|
|
216
|
+
}
|
|
162
217
|
break
|
|
163
|
-
case 38:
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
} catch (e) { }
|
|
218
|
+
case 38: // 上箭头 - 增加音量5%
|
|
219
|
+
e.preventDefault()
|
|
220
|
+
this.video.volume = Math.min(1, this.video.volume + 0.05)
|
|
167
221
|
break
|
|
168
|
-
case 40:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
} catch (e) { }
|
|
222
|
+
case 40: // 下箭头 - 减少音量5%
|
|
223
|
+
e.preventDefault()
|
|
224
|
+
this.video.volume = Math.max(0, this.video.volume - 0.05)
|
|
172
225
|
break
|
|
173
|
-
case 32:
|
|
226
|
+
case 32: // 空格键 - 播放/暂停
|
|
227
|
+
e.preventDefault()
|
|
174
228
|
this.play()
|
|
175
229
|
break
|
|
230
|
+
case 77: // M键 - 静音/取消静音
|
|
231
|
+
this.volume()
|
|
232
|
+
break
|
|
233
|
+
default:
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
keyup(e) {
|
|
238
|
+
switch (e.keyCode) {
|
|
239
|
+
case 39: // 右箭头松开
|
|
240
|
+
if (this.isRightKeyPressed) {
|
|
241
|
+
const pressDuration = Date.now() - this.rightKeyPressTime
|
|
242
|
+
this.isRightKeyPressed = false
|
|
243
|
+
|
|
244
|
+
// 清除定时器
|
|
245
|
+
if (this.rightKeyHoldTimer) {
|
|
246
|
+
clearTimeout(this.rightKeyHoldTimer)
|
|
247
|
+
this.rightKeyHoldTimer = null
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// 判断是短按还是长按
|
|
251
|
+
if (pressDuration < 500 && !this.isSpeedModeActive) {
|
|
252
|
+
// 短按:只快进10秒
|
|
253
|
+
this.video.currentTime = Math.min(this.video.duration, this.video.currentTime + 10)
|
|
254
|
+
} else if (this.isSpeedModeActive) {
|
|
255
|
+
// 长按结束:恢复原播放速度并隐藏提示
|
|
256
|
+
this.video.playbackRate = this.originalPlaybackRate
|
|
257
|
+
this.$('.speed').innerText = this.originalPlaybackRate + 'x'
|
|
258
|
+
this.$('.speed-indicator').style.display = 'none'
|
|
259
|
+
this.isSpeedModeActive = false
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// 重置状态
|
|
263
|
+
this.rightKeyPressTime = null
|
|
264
|
+
}
|
|
265
|
+
break
|
|
176
266
|
default:
|
|
177
267
|
}
|
|
178
268
|
}
|
|
@@ -245,12 +335,32 @@ class Eplayer extends HTMLElement {
|
|
|
245
335
|
list-style:none;
|
|
246
336
|
}
|
|
247
337
|
.eplayer,video{
|
|
248
|
-
|
|
338
|
+
font-family:'黑体';
|
|
249
339
|
height:100%;
|
|
250
340
|
width:100%;
|
|
251
341
|
color:var(--icons,rgba(255,255,255,0.6));
|
|
252
342
|
font-size:12px;
|
|
253
|
-
background
|
|
343
|
+
background:var(--bg,#000);
|
|
344
|
+
}
|
|
345
|
+
.eplayer .cover{
|
|
346
|
+
position: absolute;
|
|
347
|
+
z-index: 1;
|
|
348
|
+
top: 0;
|
|
349
|
+
left: 0;
|
|
350
|
+
right: 0;
|
|
351
|
+
bottom: 0;
|
|
352
|
+
background:url(${this.cover || ''}) center/cover no-repeat #fff;
|
|
353
|
+
filter:blur(8px);
|
|
354
|
+
}
|
|
355
|
+
.eplayer .cover-img{
|
|
356
|
+
position: absolute;
|
|
357
|
+
z-index: 1;
|
|
358
|
+
width:250px;
|
|
359
|
+
height:250px;
|
|
360
|
+
border-radius:125px;
|
|
361
|
+
left:50%;
|
|
362
|
+
top:50%;
|
|
363
|
+
transform:translate(-50%,-50%);
|
|
254
364
|
}
|
|
255
365
|
.eplayer{
|
|
256
366
|
user-select:none;
|
|
@@ -261,14 +371,17 @@ class Eplayer extends HTMLElement {
|
|
|
261
371
|
position:absolute;
|
|
262
372
|
left:0;
|
|
263
373
|
right:0;
|
|
264
|
-
bottom:0;
|
|
265
|
-
background:linear-gradient(transparent,rgba(0,0,0,.5));
|
|
266
|
-
transition: .3s ease-out;
|
|
267
374
|
bottom:-34px;
|
|
268
|
-
|
|
375
|
+
background:linear-gradient(transparent,rgba(0,0,0,.5));
|
|
376
|
+
transition: bottom .3s ease-out, opacity .3s ease-out;
|
|
377
|
+
opacity: 0;
|
|
378
|
+
pointer-events: none;
|
|
379
|
+
z-index:1000;
|
|
269
380
|
}
|
|
270
|
-
.hover
|
|
381
|
+
.hover .controls{
|
|
271
382
|
bottom:0;
|
|
383
|
+
opacity: 1;
|
|
384
|
+
pointer-events: auto;
|
|
272
385
|
}
|
|
273
386
|
.progress{
|
|
274
387
|
display:${this.live ? 'none' : 'block'};
|
|
@@ -395,11 +508,28 @@ class Eplayer extends HTMLElement {
|
|
|
395
508
|
bottom: 0;
|
|
396
509
|
pointer-events: none;
|
|
397
510
|
overflow: hidden;
|
|
398
|
-
z-index:
|
|
511
|
+
z-index: 0;
|
|
399
512
|
height:100%;
|
|
400
513
|
width:100%;
|
|
401
514
|
}
|
|
402
515
|
|
|
516
|
+
.speed-indicator {
|
|
517
|
+
position: absolute;
|
|
518
|
+
top: 20px;
|
|
519
|
+
left: 50%;
|
|
520
|
+
transform: translateX(-50%);
|
|
521
|
+
background: rgba(148, 108, 230, 0.9);
|
|
522
|
+
color: white;
|
|
523
|
+
padding: 8px 16px;
|
|
524
|
+
border-radius: 20px;
|
|
525
|
+
font-size: 14px;
|
|
526
|
+
font-weight: bold;
|
|
527
|
+
z-index: 999;
|
|
528
|
+
display: none;
|
|
529
|
+
pointer-events: none;
|
|
530
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
|
531
|
+
}
|
|
532
|
+
|
|
403
533
|
iconpark-icon{
|
|
404
534
|
margin-right:5px;
|
|
405
535
|
cursor:pointer;
|
|
@@ -419,7 +549,10 @@ class Eplayer extends HTMLElement {
|
|
|
419
549
|
<div class="eplayer hover">
|
|
420
550
|
<div class="danmaku"></div>
|
|
421
551
|
<video id="video" class="video" src="${this.src || ''}"></video>
|
|
552
|
+
<div class="cover"></div>
|
|
553
|
+
<img src="${this.cover || ''}" class="cover-img"/>
|
|
422
554
|
<div class="mark loading"></div>
|
|
555
|
+
<div class="speed-indicator">倍速中</div>
|
|
423
556
|
<div class="controls">
|
|
424
557
|
<div class="progress">
|
|
425
558
|
<b class="bg"></b>
|
|
@@ -436,7 +569,7 @@ class Eplayer extends HTMLElement {
|
|
|
436
569
|
</span>
|
|
437
570
|
</div>
|
|
438
571
|
<div class="right">
|
|
439
|
-
<em class="speed"
|
|
572
|
+
<em class="speed">1x</em>
|
|
440
573
|
<em class="pip">画中画</em>
|
|
441
574
|
<iconpark-icon icon-id="volume-ok" size="2rem" class="is-volume"></iconpark-icon>
|
|
442
575
|
<iconpark-icon icon-id="web-fullscreen" size="2rem"></iconpark-icon>
|
|
@@ -475,7 +608,8 @@ class Eplayer extends HTMLElement {
|
|
|
475
608
|
'.panel',
|
|
476
609
|
'.speed',
|
|
477
610
|
'.pip',
|
|
478
|
-
'.danmaku'
|
|
611
|
+
'.danmaku',
|
|
612
|
+
'.speed-indicator'
|
|
479
613
|
]
|
|
480
614
|
|
|
481
615
|
for (const key of doms) {
|
|
@@ -503,6 +637,7 @@ class Eplayer extends HTMLElement {
|
|
|
503
637
|
'.speed': this.speed,
|
|
504
638
|
'.bg': this.progress,
|
|
505
639
|
'.buffer': this.progress,
|
|
640
|
+
'.current': this.progress,
|
|
506
641
|
'.pip': this.pip,
|
|
507
642
|
})
|
|
508
643
|
this.delegate('pointerdown', {
|
|
@@ -515,10 +650,35 @@ class Eplayer extends HTMLElement {
|
|
|
515
650
|
this.full()
|
|
516
651
|
},
|
|
517
652
|
})
|
|
518
|
-
|
|
653
|
+
|
|
654
|
+
// 使用全局键盘监听以确保按键事件能在任何地方被捕获
|
|
655
|
+
this.keydownHandler = this.keydown.bind(this)
|
|
656
|
+
this.keyupHandler = this.keyup.bind(this)
|
|
657
|
+
document.addEventListener('keydown', this.keydownHandler)
|
|
658
|
+
document.addEventListener('keyup', this.keyupHandler)
|
|
659
|
+
|
|
519
660
|
this.delegate('mousemove', this.alow)
|
|
520
661
|
}
|
|
521
662
|
|
|
663
|
+
disconnectedCallback() {
|
|
664
|
+
// 清理全局键盘事件监听器
|
|
665
|
+
if (this.keydownHandler) {
|
|
666
|
+
document.removeEventListener('keydown', this.keydownHandler)
|
|
667
|
+
}
|
|
668
|
+
if (this.keyupHandler) {
|
|
669
|
+
document.removeEventListener('keyup', this.keyupHandler)
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// 清理长按定时器和状态
|
|
673
|
+
if (this.rightKeyHoldTimer) {
|
|
674
|
+
clearTimeout(this.rightKeyHoldTimer)
|
|
675
|
+
this.rightKeyHoldTimer = null
|
|
676
|
+
}
|
|
677
|
+
this.isRightKeyPressed = false
|
|
678
|
+
this.isSpeedModeActive = false
|
|
679
|
+
this.rightKeyPressTime = null
|
|
680
|
+
}
|
|
681
|
+
|
|
522
682
|
delegate(type, map) {
|
|
523
683
|
const that = this
|
|
524
684
|
if (typeof map === 'function') {
|
|
@@ -538,7 +698,7 @@ class Eplayer extends HTMLElement {
|
|
|
538
698
|
}
|
|
539
699
|
}
|
|
540
700
|
|
|
541
|
-
emit
|
|
701
|
+
emit(name) {
|
|
542
702
|
const fn = Eplayer.subs[name]
|
|
543
703
|
fn && fn.call(this, this.shadowRoot)
|
|
544
704
|
}
|
package/docs/index.html
CHANGED
|
@@ -57,11 +57,16 @@
|
|
|
57
57
|
.wrapper a:nth-child(3) {
|
|
58
58
|
background: #1ea6e9;
|
|
59
59
|
}
|
|
60
|
+
|
|
61
|
+
e-player {
|
|
62
|
+
--bg:#fff
|
|
63
|
+
}
|
|
60
64
|
</style>
|
|
61
65
|
|
|
62
66
|
<div class="wrapper">
|
|
63
67
|
<e-player id="ep"
|
|
64
|
-
src="https://
|
|
68
|
+
src="https://aod.cos.tx.xmcdn.com/storages/9976-audiofreehighqps/C9/1C/GAqhF9kMsE7kACAAAAQZZzo_.wav"
|
|
69
|
+
cover="https://dd-static.jd.com/ddimgp/jfs/t20261103/331442/3/18576/2295463/68da8cdcF3f9f05fd/790caba1cab6753d.png">
|
|
65
70
|
</e-player>
|
|
66
71
|
</div>
|
|
67
72
|
<script src="https://unpkg.com/@webcomponents/webcomponentsjs"></script>
|