eplayer 1.5.3 → 1.5.4

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.
@@ -1,599 +0,0 @@
1
- export default class Eplayer extends HTMLElement {
2
- constructor() {
3
- super()
4
- this.doms = {}
5
- this.src = this.getAttribute('src')
6
- this.type = this.getAttribute('type')
7
-
8
- this.init()
9
- this.stream()
10
- }
11
-
12
- static get observedAttributes() {
13
- return ['src', 'type']
14
- }
15
-
16
- attributeChangedCallback(name, _, newVal) {
17
- if (name === 'src') this.src = this.$('.video').src = newVal
18
- if (name === 'type') this.type = newVal
19
- this.stream()
20
- this.video.load()
21
- }
22
-
23
- $(key) {
24
- return this.doms[key]
25
- }
26
-
27
- waiting() {
28
- this.$('.mark').removeEventListener('click', this.mark.bind(this))
29
- this.$('.mark').classList.remove('playing')
30
- this.$('.mark').classList.add('loading')
31
- }
32
-
33
- stream() {
34
- switch (this.type) {
35
- case 'hls':
36
- if (Hls.isSupported()) {
37
- let hls = new Hls()
38
- hls.loadSource(this.src)
39
- hls.attachMedia(this.video)
40
- }
41
- break
42
- }
43
- }
44
-
45
- mark() {
46
- clearTimeout(this.timer)
47
- this.timer = setTimeout(() => this.play(), 200)
48
- }
49
-
50
- canplay() {
51
- this.$('.mark').classList.remove('loading')
52
- this.$('.mark').classList.add('playing')
53
- this.$('.mark').addEventListener('click', this.mark.bind(this))
54
- this.$('.total').innerHTML = getTimeStr(this.video.duration)
55
- }
56
-
57
- play() {
58
- if (this.video.paused) {
59
- this.video.play()
60
- this.$('.ep-video').style.display = 'none'
61
- this.$('.is-play').classList.replace('ep-play', 'ep-pause')
62
- } else {
63
- this.video.pause()
64
- this.$('.ep-video').style.display = 'block'
65
- this.$('.is-play').classList.replace('ep-pause', 'ep-play')
66
- }
67
- }
68
-
69
- volume() {
70
- if (this.video.muted) {
71
- this.video.muted = false
72
- setVolume(this.video.volume * 10, this.$('.line'))
73
- this.$('.is-volume').classList.replace('ep-volume-off', 'ep-volume')
74
- } else {
75
- this.video.muted = true
76
- setVolume(0, this.$('.line'))
77
- this.$('.is-volume').classList.replace('ep-volume', 'ep-volume-off')
78
- }
79
- }
80
-
81
- update() {
82
- let cTime = getTimeStr(this.video.currentTime)
83
- if (this.video.buffered.length) {
84
- let bufferEnd = this.video.buffered.end(this.video.buffered.length - 1)
85
- this.$('.buffer').style.width = (bufferEnd / this.video.duration) * 100 + '%'
86
- }
87
- let offset = (this.video.currentTime / this.video.duration) * 100
88
- this.$('.now').innerHTML = cTime
89
- this.$('.current').style.width = offset + '%'
90
- }
91
-
92
- progress(e) {
93
- let offset = e.offsetX / this.$('.progress').offsetWidth
94
- this.video.currentTime = this.video.duration * offset
95
- }
96
-
97
- down(e) {
98
- this.disX = e.clientX - this.$('.cycle').offsetLeft
99
- document.onmousemove = (e) => this.move(e)
100
- document.onmouseup = () => {
101
- document.onmousemove = null
102
- document.onmouseup = null
103
- }
104
- }
105
-
106
- move(e) {
107
- let offset = e.clientX - this.disX + 7
108
- if (offset < 0) offset = 0
109
- if (offset > this.$('.progress').clientWidth) {
110
- offset = this.$('.progress').clientWidth
111
- }
112
- this.$('.current').style.width = offset + 'px'
113
- this.video.currentTime = (offset / this.$('.progress').clientWidth) * this.video.duration
114
- document.onmousemove = null
115
- setTimeout((document.onmousemove = (e) => e && this.move(e)), 30)
116
- }
117
-
118
- alow() {
119
- clearTimeout(this.timer)
120
- this.$('.controls').style.bottom = 0
121
- this.$('.ep-video').style.bottom = 70 + 'px'
122
- this.$('.mark').style.cursor = 'default'
123
- this.timer = setTimeout(() => {
124
- this.$('.controls').style.bottom = -70 + 'px'
125
- this.$('.ep-video').style.bottom = 25 + 'px'
126
- this.$('.mark').style.cursor = 'none'
127
- }, 5000)
128
- }
129
-
130
- keydown(e) {
131
- switch (e.keyCode) {
132
- case 37:
133
- this.video.currentTime -= 10
134
- break
135
- case 39:
136
- this.video.currentTime += 10
137
- break
138
- case 38:
139
- try {
140
- this.video.volume = parseInt(this.video.volume * 100) / 100 + 0.05
141
- } catch (e) {}
142
- setVolume(this.video.volume.toFixed(1) * 10, this.$('.line'))
143
- break
144
- case 40:
145
- try {
146
- this.video.volume = parseInt(this.video.volume * 100) / 100 - 0.05
147
- } catch (e) {}
148
- setVolume(this.video.volume.toFixed(1) * 10, this.$('.line'))
149
- break
150
- case 32:
151
- this.play()
152
- break
153
- default:
154
- }
155
- }
156
-
157
- ended() {
158
- this.$('.is-play').classList.replace('ep-pause', 'ep-play')
159
- }
160
-
161
- full() {
162
- let el = this.$('.eplayer')
163
- if (isFullScreen()) {
164
- const efs = document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen
165
- return efs()
166
- } else {
167
- let rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullscreen
168
- return rfs.call(el)
169
- }
170
- }
171
-
172
- panel(e) {
173
- e.preventDefault()
174
- const panel = this.$('.panel')
175
- const eplayer = this.$('.eplayer')
176
- if (e.button !== 2) {
177
- panel.style.display = 'none'
178
- } else {
179
- panel.style.display = 'block'
180
- panel.style.height = panel.childElementCount * 24 + 'px'
181
- if (panel.offsetHeight + e.offsetY + 40 > eplayer.offsetHeight) {
182
- panel.style.top = ''
183
- panel.style.bottom = ((eplayer.offsetHeight - e.offsetY) / eplayer.offsetHeight) * 100 + '%'
184
- } else {
185
- panel.style.bottom = ''
186
- panel.style.top = (e.offsetY / eplayer.offsetHeight) * 100 + '%'
187
- }
188
- if (panel.offsetWidth + e.offsetX + 10 > eplayer.offsetWidth) {
189
- panel.style.left = ''
190
- panel.style.right = ((eplayer.offsetWidth - e.offsetX) / eplayer.offsetWidth) * 100 + '%'
191
- } else {
192
- panel.style.right = ''
193
- panel.style.left = (e.offsetX / eplayer.offsetWidth) * 100 + '%'
194
- }
195
- }
196
- }
197
-
198
- speed(e) {
199
- this.video.playbackRate === 2 ? (this.video.playbackRate = 1) : (this.video.playbackRate = this.video.playbackRate + 0.5)
200
- this.$('.speed').innerText = this.video.playbackRate + 'x'
201
- }
202
-
203
- init() {
204
- let html = `
205
- <style>
206
- @import "https://at.alicdn.com/t/font_836948_g9fk6jqpl8l.css";
207
- *{
208
- padding:0;
209
- margin:0;
210
- }
211
- li{
212
- list-style:none;
213
- }
214
- .eplayer,video{
215
- height:100%;
216
- width:100%;
217
- color:var(--icons,rgba(255,255,255,0.6));
218
- font-size:12px;
219
- background:#000
220
- }
221
- .eplayer{
222
- user-select:none;
223
- position: relative;
224
- overflow: hidden;
225
- }
226
- .controls{
227
- position:absolute;
228
- left:0;
229
- right:0;
230
- bottom:0;
231
- padding:10px;
232
- background:linear-gradient(transparent,rgba(0,0,0,.5));
233
- transition: .3s ease-out;
234
- z-index:1;
235
- }
236
- .progress{
237
- position:relative;
238
- bottom:15px;
239
- left:0;
240
- right:0;
241
- cursor:pointer;
242
- }
243
- .options{
244
- display:flex;
245
- align-items:center;
246
- }
247
- .epicon{
248
- color:var(--icons,rgba(255,255,255,0.6));
249
- padding:0 10px;
250
- }
251
- .epicon{
252
- font-size:18px;
253
- transition: .3s;
254
- cursor:pointer;
255
- }
256
- .epicon:hover{
257
- color:#fff;
258
- }
259
- .time{
260
- position:relative;
261
- top:-2px;
262
- }
263
- .time b{
264
- font-weight:normal;
265
- }
266
- .lines{
267
- padding:0 10px;
268
- display:flex;
269
- align-items: center;
270
- }
271
- .line{
272
- padding:0 0.1rem;
273
- cursor:pointer
274
- }
275
- .line i{
276
- width:4px;
277
- display: inline-block;
278
- background: var(--icons,rgba(255,255,255,0.6));
279
- height: 12px;
280
- transform:scaleX(0.7);
281
- transition: .3s;
282
- }
283
- .line:hover i{
284
- height:14px;
285
- background:var(--theme,#946ce6);
286
- }
287
- .active i{
288
- background:var(--theme,#946ce6);
289
- }
290
- .left{
291
- flex:1;
292
- }
293
- .right{
294
- flex:1;
295
- display:flex;
296
- align-items:center;
297
- justify-content: flex-end;
298
- }
299
- .bg,.current,.buffer{
300
- left:0;
301
- height:3px;
302
- position:absolute;
303
- top:0;
304
- }
305
- .bg{
306
- right:0;
307
- background:var(--progress,rgba(255,255,255,.3));
308
- }
309
- .current{
310
- background:var(--theme,#946ce6);
311
- }
312
- .buffer{
313
- background:var(--buffer,rgba(255,255,255,.5));
314
- }
315
- .dot{
316
- position:absolute;
317
- border-radius: 50%;
318
- display: block;
319
- background:var(--theme,#946ce6);
320
- height: 9px;
321
- width:9px;
322
- right:-5px;
323
- top:-3px;
324
- cursor:pointer;
325
- z-index:1;
326
- }
327
- .cycle{
328
- position:absolute;
329
- border-radius: 50%;
330
- display: block;
331
- background:var(--theme,#946ce6);
332
- opacity:0.3;
333
- height: 15px;
334
- width:15px;
335
- right:-8px;
336
- top:-6px;
337
- cursor:pointer;
338
- z-index:1;
339
- }
340
- @keyframes loading{
341
- 0%{
342
- transform: rotate(0deg);
343
- }
344
- 100%{
345
- transform: rotate(360deg);
346
- }
347
- }
348
- .playing{
349
- position: absolute;
350
- z-index: 1;
351
- top:0;
352
- left:0;
353
- right:0;
354
- bottom:0;
355
- }
356
- .loading {
357
- position: absolute;
358
- z-index: 1;
359
- top: 50%;
360
- left: 50%;
361
- margin:-20px 0 0 -20px;
362
- width: 40px;
363
- height: 40px;
364
- z-index:1;
365
- box-shadow: 2px 0px rgba(255,255,255,.6);
366
- border-radius: 50%;
367
- animation: loading 1s linear infinite;
368
- }
369
- .ep-video {
370
- position: absolute;
371
- bottom: 25px;
372
- right: 20px;
373
- font-size:40px;
374
- color:var(--icons,rgba(255,255,255,.6));
375
- z-index:1;
376
- cursor: pointer;
377
- }
378
- .panel {
379
- position: absolute;
380
- bottom: 200px;
381
- right: 300px;
382
- background:rgba(0,0,0,.8);
383
- border-radius:4px;
384
- cursor: pointer;
385
- z-index: 1;
386
- display:none;
387
- width:150px;
388
- }
389
- .panel li{
390
- line-height:24px;
391
- text-align:center;
392
- }
393
- .panel li:hover{
394
- border-radius:4px;
395
- background:rgba(0,0,0,.8)
396
- }
397
- .speed{
398
- font-size:10px;
399
- font-style:italic;
400
- width:22px;
401
- text-align:center;
402
- border-radius:11px;
403
- color:rgba(0,0,0,.5);
404
- font-weight:900;
405
- background:var(--icons,rgba(255,255,255,.8));
406
- margin-left:-10px;
407
- display:inline-block;
408
- }
409
- </style>
410
- <div class="eplayer">
411
- <video id="video" class="video" src="${this.src || ''}"></video>
412
- <div class="mark loading"></div>
413
- <div class="controls" style="bottom:-50px">
414
- <div class="progress">
415
- <b class="bg"></b>
416
- <b class="buffer"></b>
417
- <div class="current" style="width:0">
418
- <div class="dot"></div>
419
- <div class="cycle"></div>
420
- </div>
421
- </div>
422
- <div class="options">
423
- <div class="left">
424
- <i class="epicon ep-play is-play"></i>
425
- <span class="time">
426
- <b class="now">00:00</b> / <b class="total">00:00</b>
427
- </span>
428
- </div>
429
- <div class="right">
430
- <i class="epicon ep-volume is-volume"></i>
431
- <ol class="lines">
432
- <span class="line"><i></i></span>
433
- <span class="line"><i></i></span>
434
- <span class="line"><i></i></span>
435
- <span class="line"><i></i></span>
436
- <span class="line"><i></i></span>
437
- <span class="line"><i></i></span>
438
- <span class="line"><i></i></span>
439
- <span class="line"><i></i></span>
440
- <span class="line"><i></i></span>
441
- <span class="line"><i></i></span>
442
- </ol>
443
- <i class="epicon ep-speed">
444
- <b class="speed">1x</b>
445
- </i>
446
- ${document.pictureInPictureEnabled && `<i class="epicon ep-pip"></i>`}
447
- <i class="epicon ep-full"></i>
448
- </div>
449
- </div>
450
- </div>
451
- <div class="epicon ep-video"></div>
452
- <div class="panel"></div>
453
- </div>
454
- `
455
- let template = document.createElement('template')
456
- template.innerHTML = html
457
- this.attachShadow({
458
- mode: 'open',
459
- }).appendChild(template.content.cloneNode(true))
460
-
461
- const doms = [
462
- '.video',
463
- '.mark',
464
- '.playing',
465
- '.loading',
466
- '.total',
467
- '.now',
468
- '.current',
469
- '.buffer',
470
- '.is-play',
471
- '.ep-video',
472
- '.is-volume',
473
- '.cycle',
474
- '.progress',
475
- '.controls',
476
- '.line',
477
- '.ep-pause',
478
- '.ep-play',
479
- '.ep-volume-off',
480
- '.ep-volume',
481
- '.bg',
482
- '.eplayer',
483
- '.ep-full',
484
- '.panel',
485
- '.speed',
486
- '.pip',
487
- ]
488
-
489
- for (const key of doms) {
490
- let dom = this.shadowRoot.querySelectorAll(key)
491
- this.doms[key] = dom.length > 1 ? [...dom] : dom[0]
492
- }
493
- this.mount()
494
-
495
- for (const name in Eplayer.plugins) {
496
- const cb = Eplayer.plugins[name]
497
- let node = document.createElement('li')
498
- node.innerText = name
499
- let panel = this.$('.panel')
500
- panel.appendChild(node)
501
- node.addEventListener('click', () => cb(this.shadowRoot))
502
- }
503
- }
504
-
505
- delegate(type, map) {
506
- const that = this
507
- if (typeof map === 'function') {
508
- this.shadowRoot.addEventListener(type, map.bind(that))
509
- } else {
510
- this.shadowRoot.addEventListener(type, (e) => {
511
- for (const key in map) e.target.matches(key) && map[key].call(that, e)
512
- })
513
- }
514
- }
515
-
516
- pip(e) {
517
- if (!document.pictureInPictureElement) {
518
- this.video.requestPictureInPicture()
519
- } else {
520
- document.exitPictureInPicture()
521
- }
522
- }
523
-
524
- mount() {
525
- this.video = this.$('.video')
526
- this.video.volume = 0.5
527
- setVolume(this.video.volume * 10, this.$('.line'))
528
- this.video.onwaiting = this.waiting.bind(this)
529
- this.video.oncanplay = this.canplay.bind(this)
530
- this.video.ontimeupdate = this.update.bind(this)
531
- this.video.onended = this.ended.bind(this)
532
- this.delegate('click', {
533
- '.is-volume': this.volume,
534
- '.ep-full': this.full,
535
- '.ep-video': this.play,
536
- '.is-play': this.play,
537
- '.ep-speed': this.speed,
538
- '.speed': this.speed,
539
- '.bg': this.progress,
540
- '.buffer': this.progress,
541
- '.ep-pip': this.pip,
542
- })
543
- this.delegate('mousedown', {
544
- '.cycle': this.down,
545
- '.mark': this.panel,
546
- })
547
- this.delegate('dblclick', {
548
- '.mark': (e) => {
549
- clearTimeout(this.timer)
550
- this.full()
551
- },
552
- })
553
- this.delegate('keydown', this.keydown)
554
- this.delegate('mousemove', this.alow)
555
- this.$('.line').forEach((item, index) => {
556
- item.onclick = () => {
557
- this.video.volume = (index + 1) / 10
558
- setVolume(index + 1, this.$('.line'))
559
- }
560
- })
561
- this.$('.eplayer').oncontextmenu = () => false
562
- }
563
- }
564
-
565
- Eplayer.plugins = {}
566
-
567
- Eplayer.use = function (name, cb) {
568
- this.plugins[name] = cb
569
- }
570
-
571
- function getTimeStr(time) {
572
- let h = Math.floor(time / 3600)
573
- let m = Math.floor((time % 3600) / 60)
574
- let s = Math.floor(time % 60)
575
- h = h >= 10 ? h : '0' + h
576
- m = m >= 10 ? m : '0' + m
577
- s = s >= 10 ? s : '0' + s
578
- return h === '00' ? m + ':' + s : h + ':' + m + ':' + s
579
- }
580
-
581
- function setVolume(index, node) {
582
- for (let j = index; j < node.length; j++) {
583
- node[j].classList.remove('active')
584
- }
585
- for (let i = 0; i < index; i++) {
586
- node[i].classList.add('active')
587
- }
588
- }
589
-
590
- function isFullScreen() {
591
- return document.isFullScreen || document.webkitIsFullScreen || document.mozIsFullScreen
592
- }
593
-
594
- ;(function () {
595
- let link = document.createElement('link')
596
- link.setAttribute('href', 'https://at.alicdn.com/t/font_836948_g9fk6jqpl8l.css')
597
- link.setAttribute('rel', 'stylesheet')
598
- document.head.appendChild(link)
599
- })()