2019 updates
This commit is contained in:
parent
5134fb14d3
commit
22e82ac561
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<!-- HTML5 Playlist by Neale Pickett -->
|
||||
<!-- https://github.com/nealey/playlist -->
|
||||
<html>
|
||||
<head>
|
||||
<title>2019 ROF</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link href="playlist.css" rel="stylesheet">
|
||||
<script src="playlist.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<audio preload id="audio">
|
||||
Your browser does not support HTML5 Audio!
|
||||
</audio>
|
||||
<input type="range" min="0" max="1" step="any" id="pos">
|
||||
|
||||
<div id="currentTime"></div>
|
||||
<div id="duration"></div>
|
||||
|
||||
<div id="controls">
|
||||
<a id="prev">⏮</a>
|
||||
<a id="next">⏭</a>
|
||||
|
||||
<input type="range" min="0.0" max="1.0" list="tickmarks" step="any" id="vol">
|
||||
<datalist id="tickmarks">
|
||||
<option value="0.0" label="0%">
|
||||
<option value="0.5" label="50%">
|
||||
<option value="1.0" label="100%">
|
||||
</datalist>
|
||||
</div>
|
||||
|
||||
<ul id="playlist">
|
||||
<li>0-0 God.mp3</li>
|
||||
<li>1 - 1 - Summer Set 1.mp3</li>
|
||||
<li>1 - 1 - Summer Set 2.mp3</li>
|
||||
<li>1 - 2 - Live Set</li>
|
||||
<li>1 - 3 - Ole Irlanda.mp3</li>
|
||||
<li>1 - 4 - Slip Jig.mp3</li>
|
||||
<li>1 - 5 - El Son de la Negra.m4a</li>
|
||||
<li>1 - 6 - Gweebarra.wav</li>
|
||||
<li>----- Intermission -----</li>
|
||||
<li>2 - 1 - Adventure of a Lifetime.m4a</li>
|
||||
<li>2 - 2 - El Portorico de los Machetes.mp3</li>
|
||||
<li>2 - 3 - Orange Rouge.wav</li>
|
||||
<li>2 - 4 - Live Set</li>
|
||||
<li>2 - 5 - Live Set</li>
|
||||
<li>2 - 6 - Pink Panther.mp3</li>
|
||||
<li>2 - 7 - Alegrias.wav</li>
|
||||
<li>2 - 8 - Rock n Rince.mp3</li>
|
||||
<li>2 - 9 - Finale 1.m4a</li>
|
||||
<li>2 - 9 - Finale 2.mp3</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
|
@ -8,6 +8,10 @@ audio {
|
|||
min-width: 40em;
|
||||
}
|
||||
|
||||
#pos {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#currentTime {
|
||||
background-color: #001;
|
||||
float: right;
|
||||
|
|
162
playlist.js
162
playlist.js
|
@ -1,19 +1,22 @@
|
|||
// jshint asi:true
|
||||
|
||||
// HTML5 Playlist by Neale Pickett
|
||||
// https://github.com/nealey/playlst
|
||||
|
||||
var base = ".";
|
||||
|
||||
var base = "."
|
||||
|
||||
function loadTrack(e) {
|
||||
let li = e.srcElement;
|
||||
let audio = document.querySelector("#audio");
|
||||
audio.src = base + "/" + li.textContent;
|
||||
audio.load();
|
||||
let li = e.target
|
||||
let audio = document.querySelector("#audio")
|
||||
audio.src = base + "/" + li.textContent
|
||||
audio.load()
|
||||
|
||||
// Update "current"
|
||||
for (let cur of document.querySelectorAll(".current")) {
|
||||
cur.classList.remove("current");
|
||||
cur.classList.remove("current")
|
||||
}
|
||||
li.classList.add("current");
|
||||
li.classList.add("current")
|
||||
}
|
||||
|
||||
function clickOn(element) {
|
||||
|
@ -21,125 +24,149 @@ function clickOn(element) {
|
|||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
element.dispatchEvent(e);
|
||||
})
|
||||
element.dispatchEvent(e)
|
||||
}
|
||||
|
||||
function prev() {
|
||||
let cur = document.querySelector(".current");
|
||||
let prev = cur.previousElementSibling;
|
||||
let cur = document.querySelector(".current")
|
||||
let prev = cur.previousElementSibling
|
||||
if (prev) {
|
||||
cur = prev;
|
||||
cur = prev
|
||||
}
|
||||
clickOn(cur);
|
||||
clickOn(cur)
|
||||
}
|
||||
|
||||
function next() {
|
||||
let cur = document.querySelector(".current");
|
||||
let next = cur.nextElementSibling;
|
||||
let cur = document.querySelector(".current")
|
||||
let next = cur.nextElementSibling
|
||||
if (next) {
|
||||
cur = next;
|
||||
cur = next
|
||||
}
|
||||
clickOn(cur);
|
||||
clickOn(cur)
|
||||
}
|
||||
|
||||
function ended() {
|
||||
next();
|
||||
next()
|
||||
}
|
||||
|
||||
function mmss(s) {
|
||||
let mm = Math.floor(s / 60);
|
||||
let ss = Math.floor(s % 60);
|
||||
let mm = Math.floor(s / 60)
|
||||
let ss = Math.floor(s % 60)
|
||||
|
||||
if (ss < 10) {
|
||||
ss = "0" + ss;
|
||||
ss = "0" + ss
|
||||
}
|
||||
return mm + ":" + ss;
|
||||
return mm + ":" + ss
|
||||
}
|
||||
|
||||
function durationchange(e) {
|
||||
let duration = e.srcElement.duration;
|
||||
let duration = e.target.duration
|
||||
|
||||
document.querySelector("#duration").textContent = mmss(duration);
|
||||
document.querySelector("#duration").textContent = mmss(duration)
|
||||
timeupdate(e)
|
||||
}
|
||||
|
||||
function volumechange(e) {
|
||||
document.querySelector("#vol").value = e.target.volume
|
||||
}
|
||||
|
||||
|
||||
function timeupdate(e) {
|
||||
let currentTime = e.srcElement.currentTime;
|
||||
let tgt = document.querySelector("#currentTime");
|
||||
let currentTime = e.target.currentTime
|
||||
let duration = e.target.duration || 1
|
||||
let tgt = document.querySelector("#currentTime")
|
||||
let pos = document.querySelector("#pos")
|
||||
|
||||
tgt.textContent = mmss(currentTime);
|
||||
pos.value = currentTime / duration
|
||||
|
||||
tgt.textContent = mmss(currentTime)
|
||||
if (duration - currentTime < 20) {
|
||||
tgt.classList.add("fin");
|
||||
tgt.classList.add("fin")
|
||||
} else {
|
||||
tgt.classList.remove("fin");
|
||||
tgt.classList.remove("fin")
|
||||
}
|
||||
}
|
||||
|
||||
function setPos(e) {
|
||||
let val = e.target.value
|
||||
let audio = document.querySelector("#audio")
|
||||
|
||||
audio.currentTime = audio.duration * val
|
||||
}
|
||||
|
||||
function setGain(e) {
|
||||
let val = e.target.value
|
||||
let audio = document.querySelector("#audio")
|
||||
|
||||
audio.volume = val
|
||||
}
|
||||
|
||||
function keydown(e) {
|
||||
let audio = document.querySelector("#audio");
|
||||
let audio = document.querySelector("#audio")
|
||||
|
||||
switch (event.key) {
|
||||
case " ": // space bar
|
||||
if (audio.paused) {
|
||||
audio.play();
|
||||
audio.play()
|
||||
} else {
|
||||
audio.pause();
|
||||
audio.pause()
|
||||
}
|
||||
break;
|
||||
break
|
||||
|
||||
case "ArrowDown": // Next track
|
||||
next();
|
||||
break;
|
||||
next()
|
||||
break
|
||||
|
||||
case "ArrowUp": // Previous track
|
||||
prev();
|
||||
break;
|
||||
prev()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function midiMessage(e) {
|
||||
let audio = document.querySelector("#audio");
|
||||
let data = e.data;
|
||||
let ctrl = data[1];
|
||||
let val = data[2];
|
||||
let audio = document.querySelector("#audio")
|
||||
let data = e.data
|
||||
let ctrl = data[1]
|
||||
let val = data[2]
|
||||
if ((data[0] == 0xb0) || (data[0] == 0xbf)) {
|
||||
switch (ctrl) {
|
||||
case 0: // master volume slider
|
||||
audio.volume = val / 127;
|
||||
break;
|
||||
audio.volume = val / 127
|
||||
document.querySelector("#vol").value = audio.volume
|
||||
break
|
||||
case 41: // play button
|
||||
if (val == 127) {
|
||||
audio.play();
|
||||
audio.play()
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 42: // stop button
|
||||
if (val == 127) {
|
||||
audio.pause();
|
||||
audio.pause()
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 58: // prev button
|
||||
if (val == 127) {
|
||||
prev();
|
||||
prev()
|
||||
}
|
||||
break;
|
||||
break
|
||||
case 59: // next button
|
||||
if (val == 127) {
|
||||
next();
|
||||
next()
|
||||
}
|
||||
break;
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleMidiAccess(access) {
|
||||
for (let input of access.inputs.values()) {
|
||||
input.addEventListener("midimessage", midiMessage);
|
||||
input.addEventListener("midimessage", midiMessage)
|
||||
}
|
||||
|
||||
for (let output of access.outputs.values()) {
|
||||
if (output.name == "nanoKONTROL2 MIDI 1") {
|
||||
controller = output;
|
||||
controller = output
|
||||
output.send([0xf0, 0x42, 0x40, 0x00, 0x01, 0x13, 0x00, 0x00, 0x00, 0x01, 0xf7]); // Native Mode (lets us control LEDs, requires sysex privilege)
|
||||
output.send([0xbf, 0x2a, 0x7f]); // Stop
|
||||
output.send([0xbf, 0x29, 0x7f]); // Play
|
||||
|
@ -148,31 +175,36 @@ function handleMidiAccess(access) {
|
|||
}
|
||||
|
||||
function run() {
|
||||
let audio = document.querySelector("#audio");
|
||||
let audio = document.querySelector("#audio")
|
||||
|
||||
// Set up events:
|
||||
// - Prev/Next buttons
|
||||
// - ended / timeupdate events on audio
|
||||
// - Track items
|
||||
document.querySelector("#prev").addEventListener("click", prev);
|
||||
document.querySelector("#next").addEventListener("click", next);
|
||||
audio.addEventListener("ended", ended);
|
||||
audio.addEventListener("timeupdate", timeupdate);
|
||||
audio.addEventListener("durationchange", durationchange);
|
||||
document.querySelector("#prev").addEventListener("click", prev)
|
||||
document.querySelector("#next").addEventListener("click", next)
|
||||
document.querySelector("#pos").addEventListener("input", setPos)
|
||||
document.querySelector("#vol").addEventListener("input", setGain)
|
||||
audio.addEventListener("ended", ended)
|
||||
audio.addEventListener("timeupdate", timeupdate)
|
||||
audio.addEventListener("durationchange", durationchange)
|
||||
audio.addEventListener("volumechange", volumechange)
|
||||
for (let li of document.querySelectorAll("#playlist li")) {
|
||||
li.addEventListener("click", loadTrack);
|
||||
li.addEventListener("click", loadTrack)
|
||||
}
|
||||
|
||||
document.querySelector("#vol").value = audio.volume
|
||||
|
||||
// Bind keypress events
|
||||
// - space: play/pause
|
||||
//
|
||||
document.addEventListener("keydown", keydown);
|
||||
document.addEventListener("keydown", keydown)
|
||||
|
||||
// Load up first track
|
||||
document.querySelector("#playlist li").classList.add("current");
|
||||
prev();
|
||||
document.querySelector("#playlist li").classList.add("current")
|
||||
prev()
|
||||
|
||||
navigator.requestMIDIAccess({sysex: true}).then(handleMidiAccess);
|
||||
navigator.requestMIDIAccess({sysex: true}).then(handleMidiAccess)
|
||||
}
|
||||
|
||||
window.addEventListener("load", run);
|
||||
window.addEventListener("load", run)
|
||||
|
|
Loading…
Reference in New Issue