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;
|
min-width: 40em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pos {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
#currentTime {
|
#currentTime {
|
||||||
background-color: #001;
|
background-color: #001;
|
||||||
float: right;
|
float: right;
|
||||||
|
|
162
playlist.js
162
playlist.js
|
@ -1,19 +1,22 @@
|
||||||
|
// jshint asi:true
|
||||||
|
|
||||||
// HTML5 Playlist by Neale Pickett
|
// HTML5 Playlist by Neale Pickett
|
||||||
// https://github.com/nealey/playlst
|
// https://github.com/nealey/playlst
|
||||||
|
|
||||||
var base = ".";
|
|
||||||
|
var base = "."
|
||||||
|
|
||||||
function loadTrack(e) {
|
function loadTrack(e) {
|
||||||
let li = e.srcElement;
|
let li = e.target
|
||||||
let audio = document.querySelector("#audio");
|
let audio = document.querySelector("#audio")
|
||||||
audio.src = base + "/" + li.textContent;
|
audio.src = base + "/" + li.textContent
|
||||||
audio.load();
|
audio.load()
|
||||||
|
|
||||||
// Update "current"
|
// Update "current"
|
||||||
for (let cur of document.querySelectorAll(".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) {
|
function clickOn(element) {
|
||||||
|
@ -21,125 +24,149 @@ function clickOn(element) {
|
||||||
view: window,
|
view: window,
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
cancelable: true
|
cancelable: true
|
||||||
});
|
})
|
||||||
element.dispatchEvent(e);
|
element.dispatchEvent(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
function prev() {
|
function prev() {
|
||||||
let cur = document.querySelector(".current");
|
let cur = document.querySelector(".current")
|
||||||
let prev = cur.previousElementSibling;
|
let prev = cur.previousElementSibling
|
||||||
if (prev) {
|
if (prev) {
|
||||||
cur = prev;
|
cur = prev
|
||||||
}
|
}
|
||||||
clickOn(cur);
|
clickOn(cur)
|
||||||
}
|
}
|
||||||
|
|
||||||
function next() {
|
function next() {
|
||||||
let cur = document.querySelector(".current");
|
let cur = document.querySelector(".current")
|
||||||
let next = cur.nextElementSibling;
|
let next = cur.nextElementSibling
|
||||||
if (next) {
|
if (next) {
|
||||||
cur = next;
|
cur = next
|
||||||
}
|
}
|
||||||
clickOn(cur);
|
clickOn(cur)
|
||||||
}
|
}
|
||||||
|
|
||||||
function ended() {
|
function ended() {
|
||||||
next();
|
next()
|
||||||
}
|
}
|
||||||
|
|
||||||
function mmss(s) {
|
function mmss(s) {
|
||||||
let mm = Math.floor(s / 60);
|
let mm = Math.floor(s / 60)
|
||||||
let ss = Math.floor(s % 60);
|
let ss = Math.floor(s % 60)
|
||||||
|
|
||||||
if (ss < 10) {
|
if (ss < 10) {
|
||||||
ss = "0" + ss;
|
ss = "0" + ss
|
||||||
}
|
}
|
||||||
return mm + ":" + ss;
|
return mm + ":" + ss
|
||||||
}
|
}
|
||||||
|
|
||||||
function durationchange(e) {
|
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) {
|
function timeupdate(e) {
|
||||||
let currentTime = e.srcElement.currentTime;
|
let currentTime = e.target.currentTime
|
||||||
let tgt = document.querySelector("#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) {
|
if (duration - currentTime < 20) {
|
||||||
tgt.classList.add("fin");
|
tgt.classList.add("fin")
|
||||||
} else {
|
} 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) {
|
function keydown(e) {
|
||||||
let audio = document.querySelector("#audio");
|
let audio = document.querySelector("#audio")
|
||||||
|
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
case " ": // space bar
|
case " ": // space bar
|
||||||
if (audio.paused) {
|
if (audio.paused) {
|
||||||
audio.play();
|
audio.play()
|
||||||
} else {
|
} else {
|
||||||
audio.pause();
|
audio.pause()
|
||||||
}
|
}
|
||||||
break;
|
break
|
||||||
|
|
||||||
case "ArrowDown": // Next track
|
case "ArrowDown": // Next track
|
||||||
next();
|
next()
|
||||||
break;
|
break
|
||||||
|
|
||||||
case "ArrowUp": // Previous track
|
case "ArrowUp": // Previous track
|
||||||
prev();
|
prev()
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function midiMessage(e) {
|
function midiMessage(e) {
|
||||||
let audio = document.querySelector("#audio");
|
let audio = document.querySelector("#audio")
|
||||||
let data = e.data;
|
let data = e.data
|
||||||
let ctrl = data[1];
|
let ctrl = data[1]
|
||||||
let val = data[2];
|
let val = data[2]
|
||||||
if ((data[0] == 0xb0) || (data[0] == 0xbf)) {
|
if ((data[0] == 0xb0) || (data[0] == 0xbf)) {
|
||||||
switch (ctrl) {
|
switch (ctrl) {
|
||||||
case 0: // master volume slider
|
case 0: // master volume slider
|
||||||
audio.volume = val / 127;
|
audio.volume = val / 127
|
||||||
break;
|
document.querySelector("#vol").value = audio.volume
|
||||||
|
break
|
||||||
case 41: // play button
|
case 41: // play button
|
||||||
if (val == 127) {
|
if (val == 127) {
|
||||||
audio.play();
|
audio.play()
|
||||||
}
|
}
|
||||||
break;
|
break
|
||||||
case 42: // stop button
|
case 42: // stop button
|
||||||
if (val == 127) {
|
if (val == 127) {
|
||||||
audio.pause();
|
audio.pause()
|
||||||
}
|
}
|
||||||
break;
|
break
|
||||||
case 58: // prev button
|
case 58: // prev button
|
||||||
if (val == 127) {
|
if (val == 127) {
|
||||||
prev();
|
prev()
|
||||||
}
|
}
|
||||||
break;
|
break
|
||||||
case 59: // next button
|
case 59: // next button
|
||||||
if (val == 127) {
|
if (val == 127) {
|
||||||
next();
|
next()
|
||||||
}
|
}
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMidiAccess(access) {
|
function handleMidiAccess(access) {
|
||||||
for (let input of access.inputs.values()) {
|
for (let input of access.inputs.values()) {
|
||||||
input.addEventListener("midimessage", midiMessage);
|
input.addEventListener("midimessage", midiMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let output of access.outputs.values()) {
|
for (let output of access.outputs.values()) {
|
||||||
if (output.name == "nanoKONTROL2 MIDI 1") {
|
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([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, 0x2a, 0x7f]); // Stop
|
||||||
output.send([0xbf, 0x29, 0x7f]); // Play
|
output.send([0xbf, 0x29, 0x7f]); // Play
|
||||||
|
@ -148,31 +175,36 @@ function handleMidiAccess(access) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
let audio = document.querySelector("#audio");
|
let audio = document.querySelector("#audio")
|
||||||
|
|
||||||
// Set up events:
|
// Set up events:
|
||||||
// - Prev/Next buttons
|
// - Prev/Next buttons
|
||||||
// - ended / timeupdate events on audio
|
// - ended / timeupdate events on audio
|
||||||
// - Track items
|
// - Track items
|
||||||
document.querySelector("#prev").addEventListener("click", prev);
|
document.querySelector("#prev").addEventListener("click", prev)
|
||||||
document.querySelector("#next").addEventListener("click", next);
|
document.querySelector("#next").addEventListener("click", next)
|
||||||
audio.addEventListener("ended", ended);
|
document.querySelector("#pos").addEventListener("input", setPos)
|
||||||
audio.addEventListener("timeupdate", timeupdate);
|
document.querySelector("#vol").addEventListener("input", setGain)
|
||||||
audio.addEventListener("durationchange", durationchange);
|
audio.addEventListener("ended", ended)
|
||||||
|
audio.addEventListener("timeupdate", timeupdate)
|
||||||
|
audio.addEventListener("durationchange", durationchange)
|
||||||
|
audio.addEventListener("volumechange", volumechange)
|
||||||
for (let li of document.querySelectorAll("#playlist li")) {
|
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
|
// Bind keypress events
|
||||||
// - space: play/pause
|
// - space: play/pause
|
||||||
//
|
//
|
||||||
document.addEventListener("keydown", keydown);
|
document.addEventListener("keydown", keydown)
|
||||||
|
|
||||||
// Load up first track
|
// Load up first track
|
||||||
document.querySelector("#playlist li").classList.add("current");
|
document.querySelector("#playlist li").classList.add("current")
|
||||||
prev();
|
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