eplayer 1.5.2 → 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,606 +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
- if (isFullScreen()) {
163
- if (document.exitFullscreen) {
164
- document.exitFullscreen()
165
- } else if (document.mozCancelFullScreen) {
166
- document.mozCancelFullScreen()
167
- } else if (document.webkitCancelFullScreen) {
168
- document.webkitCancelFullScreen()
169
- } else if (document.msExitFullscreen) {
170
- document.msExitFullscreen()
171
- }
172
- } else {
173
- let el = this.$('.eplayer')
174
- let rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullscreen
175
- return rfs.call(el)
176
- }
177
- }
178
-
179
- panel(e) {
180
- e.preventDefault()
181
- const panel = this.$('.panel')
182
- const eplayer = this.$('.eplayer')
183
- if (e.button !== 2) {
184
- panel.style.display = 'none'
185
- } else {
186
- panel.style.display = 'block'
187
- panel.style.height = panel.childElementCount * 24 + 'px'
188
- if (panel.offsetHeight + e.offsetY + 40 > eplayer.offsetHeight) {
189
- panel.style.top = ''
190
- panel.style.bottom = ((eplayer.offsetHeight - e.offsetY) / eplayer.offsetHeight) * 100 + '%'
191
- } else {
192
- panel.style.bottom = ''
193
- panel.style.top = (e.offsetY / eplayer.offsetHeight) * 100 + '%'
194
- }
195
- if (panel.offsetWidth + e.offsetX + 10 > eplayer.offsetWidth) {
196
- panel.style.left = ''
197
- panel.style.right = ((eplayer.offsetWidth - e.offsetX) / eplayer.offsetWidth) * 100 + '%'
198
- } else {
199
- panel.style.right = ''
200
- panel.style.left = (e.offsetX / eplayer.offsetWidth) * 100 + '%'
201
- }
202
- }
203
- }
204
-
205
- speed(e) {
206
- this.video.playbackRate === 2 ? (this.video.playbackRate = 1) : (this.video.playbackRate = this.video.playbackRate + 0.5)
207
- this.$('.speed').innerText = this.video.playbackRate + 'x'
208
- }
209
-
210
- init() {
211
- let html = `
212
- <style>
213
- @import "https://at.alicdn.com/t/font_836948_g9fk6jqpl8l.css";
214
- *{
215
- padding:0;
216
- margin:0;
217
- }
218
- li{
219
- list-style:none;
220
- }
221
- .eplayer,video{
222
- height:100%;
223
- width:100%;
224
- color:var(--icons,rgba(255,255,255,0.6));
225
- font-size:12px;
226
- background:#000
227
- }
228
- .eplayer{
229
- user-select:none;
230
- position: relative;
231
- overflow: hidden;
232
- }
233
- .controls{
234
- position:absolute;
235
- left:0;
236
- right:0;
237
- bottom:0;
238
- padding:10px;
239
- background:linear-gradient(transparent,rgba(0,0,0,.5));
240
- transition: .3s ease-out;
241
- z-index:1;
242
- }
243
- .progress{
244
- position:relative;
245
- bottom:15px;
246
- left:0;
247
- right:0;
248
- cursor:pointer;
249
- }
250
- .options{
251
- display:flex;
252
- align-items:center;
253
- }
254
- .epicon{
255
- color:var(--icons,rgba(255,255,255,0.6));
256
- padding:0 10px;
257
- }
258
- .epicon{
259
- font-size:18px;
260
- transition: .3s;
261
- cursor:pointer;
262
- }
263
- .epicon:hover{
264
- color:#fff;
265
- }
266
- .time{
267
- position:relative;
268
- top:-2px;
269
- }
270
- .time b{
271
- font-weight:normal;
272
- }
273
- .lines{
274
- padding:0 10px;
275
- }
276
- .line{
277
- padding:0;
278
- margin-bottom: -2px;
279
- cursor:pointer
280
- }
281
- .line i{
282
- width:4px;
283
- border-radius:4px;
284
- display: inline-block;
285
- background: var(--icons,rgba(255,255,255,0.6));
286
- height: 12px;
287
- transform:scaleX(0.7);
288
- transition: .3s;
289
- }
290
- .line:hover i{
291
- height:14px;
292
- background:var(--theme,#946ce6);
293
- }
294
- .active i{
295
- background:var(--theme,#946ce6);
296
- }
297
- .left{
298
- flex:1;
299
- }
300
- .right{
301
- flex:1;
302
- display:flex;
303
- align-items:center;
304
- justify-content: flex-end;
305
- }
306
- .bg,.current,.buffer{
307
- left:0;
308
- height:3px;
309
- position:absolute;
310
- top:0;
311
- }
312
- .bg{
313
- right:0;
314
- background:var(--progress,rgba(255,255,255,.3));
315
- }
316
- .current{
317
- background:var(--theme,#946ce6);
318
- }
319
- .buffer{
320
- background:var(--buffer,rgba(255,255,255,.5));
321
- }
322
- .dot{
323
- position:absolute;
324
- border-radius: 50%;
325
- display: block;
326
- background:var(--theme,#946ce6);
327
- height: 9px;
328
- width:9px;
329
- right:-5px;
330
- top:-3px;
331
- cursor:pointer;
332
- z-index:1;
333
- }
334
- .cycle{
335
- position:absolute;
336
- border-radius: 50%;
337
- display: block;
338
- background:var(--theme,#946ce6);
339
- opacity:0.3;
340
- height: 15px;
341
- width:15px;
342
- right:-8px;
343
- top:-6px;
344
- cursor:pointer;
345
- z-index:1;
346
- }
347
- @keyframes loading{
348
- 0%{
349
- transform: rotate(0deg);
350
- }
351
- 100%{
352
- transform: rotate(360deg);
353
- }
354
- }
355
- .playing{
356
- position: absolute;
357
- z-index: 1;
358
- top:0;
359
- left:0;
360
- right:0;
361
- bottom:0;
362
- }
363
- .loading {
364
- position: absolute;
365
- z-index: 1;
366
- top: 50%;
367
- left: 50%;
368
- margin:-20px 0 0 -20px;
369
- width: 40px;
370
- height: 40px;
371
- z-index:1;
372
- box-shadow: 2px 0px rgba(255,255,255,.6);
373
- border-radius: 50%;
374
- animation: loading 1s linear infinite;
375
- }
376
- .ep-video {
377
- position: absolute;
378
- bottom: 25px;
379
- right: 20px;
380
- font-size:40px;
381
- color:var(--icons,rgba(255,255,255,.6));
382
- z-index:1;
383
- cursor: pointer;
384
- }
385
- .panel {
386
- position: absolute;
387
- bottom: 200px;
388
- right: 300px;
389
- background:rgba(0,0,0,.8);
390
- border-radius:4px;
391
- cursor: pointer;
392
- z-index: 1;
393
- display:none;
394
- width:150px;
395
- }
396
- .panel li{
397
- line-height:24px;
398
- text-align:center;
399
- }
400
- .panel li:hover{
401
- border-radius:4px;
402
- background:rgba(0,0,0,.8)
403
- }
404
- .speed{
405
- font-size:10px;
406
- font-style:italic;
407
- width:22px;
408
- text-align:center;
409
- border-radius:11px;
410
- color:rgba(0,0,0,.5);
411
- font-weight:900;
412
- background:var(--icons,rgba(255,255,255,.8));
413
- margin-left:-10px;
414
- display:inline-block;
415
- }
416
- </style>
417
- <div class="eplayer">
418
- <video id="video" class="video" src="${this.src || ''}"></video>
419
- <div class="mark loading"></div>
420
- <div class="controls" style="bottom:-50px">
421
- <div class="progress">
422
- <b class="bg"></b>
423
- <b class="buffer"></b>
424
- <div class="current" style="width:0">
425
- <div class="dot"></div>
426
- <div class="cycle"></div>
427
- </div>
428
- </div>
429
- <div class="options">
430
- <div class="left">
431
- <i class="epicon ep-play is-play"></i>
432
- <span class="time">
433
- <b class="now">00:00</b> / <b class="total">00:00</b>
434
- </span>
435
- </div>
436
- <div class="right">
437
- <i class="epicon ep-volume is-volume"></i>
438
- <ol class="lines">
439
- <span class="line"><i></i></span>
440
- <span class="line"><i></i></span>
441
- <span class="line"><i></i></span>
442
- <span class="line"><i></i></span>
443
- <span class="line"><i></i></span>
444
- <span class="line"><i></i></span>
445
- <span class="line"><i></i></span>
446
- <span class="line"><i></i></span>
447
- <span class="line"><i></i></span>
448
- <span class="line"><i></i></span>
449
- </ol>
450
- <i class="epicon ep-speed">
451
- <b class="speed">1x</b>
452
- </i>
453
- ${document.pictureInPictureEnabled && `<i class="epicon ep-pip"></i>`}
454
- <i class="epicon ep-full"></i>
455
- </div>
456
- </div>
457
- </div>
458
- <div class="epicon ep-video"></div>
459
- <div class="panel"></div>
460
- </div>
461
- `
462
- let template = document.createElement('template')
463
- template.innerHTML = html
464
- this.attachShadow({
465
- mode: 'open',
466
- }).appendChild(template.content.cloneNode(true))
467
-
468
- const doms = [
469
- '.video',
470
- '.mark',
471
- '.playing',
472
- '.loading',
473
- '.total',
474
- '.now',
475
- '.current',
476
- '.buffer',
477
- '.is-play',
478
- '.ep-video',
479
- '.is-volume',
480
- '.cycle',
481
- '.progress',
482
- '.controls',
483
- '.line',
484
- '.ep-pause',
485
- '.ep-play',
486
- '.ep-volume-off',
487
- '.ep-volume',
488
- '.bg',
489
- '.eplayer',
490
- '.ep-full',
491
- '.panel',
492
- '.speed',
493
- '.pip',
494
- ]
495
-
496
- for (const key of doms) {
497
- let dom = this.shadowRoot.querySelectorAll(key)
498
- this.doms[key] = dom.length > 1 ? [...dom] : dom[0]
499
- }
500
- this.mount()
501
-
502
- for (const name in Eplayer.plugins) {
503
- const cb = Eplayer.plugins[name]
504
- let node = document.createElement('li')
505
- node.innerText = name
506
- let panel = this.$('.panel')
507
- panel.appendChild(node)
508
- node.addEventListener('click', () => cb(this.shadowRoot))
509
- }
510
- }
511
-
512
- delegate(type, map) {
513
- const that = this
514
- if (typeof map === 'function') {
515
- this.shadowRoot.addEventListener(type, map.bind(that))
516
- } else {
517
- this.shadowRoot.addEventListener(type, (e) => {
518
- for (const key in map) e.target.matches(key) && map[key].call(that, e)
519
- })
520
- }
521
- }
522
-
523
- pip(e) {
524
- if (!document.pictureInPictureElement) {
525
- this.video.requestPictureInPicture()
526
- } else {
527
- document.exitPictureInPicture()
528
- }
529
- }
530
-
531
- mount() {
532
- this.video = this.$('.video')
533
- this.video.volume = 0.5
534
- setVolume(this.video.volume * 10, this.$('.line'))
535
- this.video.onwaiting = this.waiting.bind(this)
536
- this.video.oncanplay = this.canplay.bind(this)
537
- this.video.ontimeupdate = this.update.bind(this)
538
- this.video.onended = this.ended.bind(this)
539
- this.delegate('click', {
540
- '.is-volume': this.volume,
541
- '.ep-full': this.full,
542
- '.ep-video': this.play,
543
- '.is-play': this.play,
544
- '.ep-speed': this.speed,
545
- '.speed': this.speed,
546
- '.bg': this.progress,
547
- '.buffer': this.progress,
548
- '.ep-pip': this.pip,
549
- })
550
- this.delegate('mousedown', {
551
- '.cycle': this.down,
552
- '.mark': this.panel,
553
- })
554
- this.delegate('dblclick', {
555
- '.mark': (e) => {
556
- clearTimeout(this.timer)
557
- this.full()
558
- },
559
- })
560
- this.delegate('keydown', this.keydown)
561
- this.delegate('mousemove', this.alow)
562
- this.$('.line').forEach((item, index) => {
563
- item.onclick = () => {
564
- this.video.volume = (index + 1) / 10
565
- setVolume(index + 1, this.$('.line'))
566
- }
567
- })
568
- document.oncontextmenu = () => false
569
- }
570
- }
571
-
572
- Eplayer.plugins = {}
573
-
574
- Eplayer.use = function (name, cb) {
575
- this.plugins[name] = cb
576
- }
577
-
578
- function getTimeStr(time) {
579
- let h = Math.floor(time / 3600)
580
- let m = Math.floor((time % 3600) / 60)
581
- let s = Math.floor(time % 60)
582
- h = h >= 10 ? h : '0' + h
583
- m = m >= 10 ? m : '0' + m
584
- s = s >= 10 ? s : '0' + s
585
- return h === '00' ? m + ':' + s : h + ':' + m + ':' + s
586
- }
587
-
588
- function setVolume(index, node) {
589
- for (let j = index; j < node.length; j++) {
590
- node[j].classList.remove('active')
591
- }
592
- for (let i = 0; i < index; i++) {
593
- node[i].classList.add('active')
594
- }
595
- }
596
-
597
- function isFullScreen() {
598
- return document.isFullScreen || document.webkitIsFullScreen || document.mozIsFullScreen
599
- }
600
-
601
- ;(function () {
602
- let link = document.createElement('link')
603
- link.setAttribute('href', 'https://at.alicdn.com/t/font_836948_g9fk6jqpl8l.css')
604
- link.setAttribute('rel', 'stylesheet')
605
- document.head.appendChild(link)
606
- })()