-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplaylist.js
More file actions
144 lines (122 loc) · 4.66 KB
/
playlist.js
File metadata and controls
144 lines (122 loc) · 4.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
SimplePlaylist: Audio player from a list
Copyright (c) 2024 Petko Yotov
MIT License
https://www.pmwiki.org/Cookbook/SimplePlaylist
*/
var SimplePlaylistOptions = document.currentScript.dataset.options;
document.addEventListener('DOMContentLoaded', function() {
var echo = console.log;
var extRX = /\.(flac|wav|mp3|ogg|oga|opus|aac|m4a|webm)(?:[#]t=[\d.,]+)?$/i;
if(SimplePlaylistOptions)
SimplePlaylistOptions = JSON.parse(SimplePlaylistOptions);
var autoplay_count = 0;
function shuffleElArray(x) {
for(var a of x) a.rndsort = Math.random();
x.sort(function(a, b) { return a.rndsort - b.rndsort });
}
function makePagelist(ol) {
if(SimplePlaylistOptions) {
for(var o of SimplePlaylistOptions) {
if(ol.classList.contains('x'+o)) continue;
ol.classList.add(o);
}
}
var items = Array.from(ol.children);
if(ol.classList.contains('shuffle')) {
shuffleElArray(items);
for(var item of items) {
ol.appendChild(item);
}
}
var tracks = [];
for(var li of items) {
var a = li.querySelector('a');
if(!a) continue;
var href = a.href;
// ignore links that are not audio files
if(a.className.match(/createlink/)) continue;
if(href.match(/action=upload/)) continue;
var m = href.match(extRX);
if(! m) continue;
li.classList.add('track');
li.dataset.tracknb = tracks.length;
tracks.push(href);
li.dataset.counter = tracks.length;
}
if(!tracks.length) return;
ol.classList.add('simpleplaylist');
var notracks = ol.querySelectorAll('li:not(.track,.divider)');
for(var li of notracks) ol.appendChild(li);
var audio = document.createElement('audio');
audio.className = 'simpleplaylist';
audio.setAttribute('preload', 'metadata');
audio.setAttribute('controls', 'controls');
if(ol.classList.contains('autoplay') && ! autoplay_count++)
audio.setAttribute('autoplay', 'autoplay');
var prev = ol.previousElementSibling;
if(prev && prev.dataset.jets)
prev.insertAdjacentElement('beforebegin', audio);
else
ol.insertAdjacentElement('beforebegin', audio);
audio.src = tracks[0];
ol.querySelector('li.track').classList.add('current');
var currentTrack = 0;
audio.addEventListener('pause', function(e) {
var a = audio.src.match(/[#]t=[\d.]+,([\d.]+)$/);
if(!a) return;
var endsec = Math.round(parseFloat(a[1]), 10);
var currsec = Math.round(audio.currentTime);
if(endsec == currsec) audio.dispatchEvent(new Event('ended'));
});
audio.addEventListener('error', function(e) {
ol.querySelector('li.track.current').classList.add('error');
audio.dispatchEvent(new Event('ended'));
});
audio.addEventListener('ended', function(e) {
if(!ol.classList.contains('autonext')) return;
currentTrack++;
if(ol.classList.contains('loop')) currentTrack %= tracks.length;
playtrack();
});
audio.addEventListener('play', function(e) {
var all_audios = document.querySelectorAll('audio.simpleplaylist');
for(var el of all_audios) if(el !== audio) el.pause();
});
function playtrack() {
var prev = ol.previousElementSibling;
if(prev && prev.dataset.jets && prev.value !== '') {
prev.value = '';
prev.dispatchEvent(new Event('input'));
}
if(currentTrack>=tracks.length) return;
if(audio.src == tracks[currentTrack]) {
var a = tracks[currentTrack].match(/[#]t=([\d.]+)/);
start = a? parseFloat(a[1]) : 0;
audio.currentTime = start;
}
else {
ol.querySelector('li.track.current').classList.remove('current');
var currentitem = ol.querySelector('li.track[data-tracknb="'+currentTrack+'"]')
currentitem.classList.add('current');
audio.src = tracks[currentTrack];
audio.load();
}
audio.play()
.then(function(){currentitem.classList.remove('error');})
.catch(function(error) { /*on error play next*/ });
if(ol.clientHeight < ol.scrollHeight) // only if taller than container
currentitem.scrollIntoView({ behavior: "smooth", block: "center", inline: "nearest" });
}
ol.addEventListener('click', function(e){
var track = e.target.closest('li.track');
if(!track) return;
e.preventDefault();
e.stopPropagation();
currentTrack = parseInt(track.dataset.tracknb);
playtrack();
});
}
var playlists = document.querySelectorAll('ol.playlist,ol.simpleplaylist,ol.SimplePlaylist');
for(var ol of playlists) makePagelist(ol);
});