Used in 2018 ROF
This commit is contained in:
parent
88c2022927
commit
f155d52b6d
|
@ -0,0 +1,26 @@
|
||||||
|
This is a pure HTML5 playlist,
|
||||||
|
specifically designed for theater work.
|
||||||
|
|
||||||
|
You give it a play list, and it cues them up,
|
||||||
|
one at a time.
|
||||||
|
Press "play" to play the cued-up track,
|
||||||
|
use the arrow keys to select a different track.
|
||||||
|
|
||||||
|
The normal browser media controls are available too.
|
||||||
|
|
||||||
|
You can also plug a Korg NanoKontrol 2 in,
|
||||||
|
and use its play/stop/prev/next buttons,
|
||||||
|
as well as the first fader.
|
||||||
|
|
||||||
|
This features a massive time display,
|
||||||
|
so everybody else in the control booth can see how far into the track you are,
|
||||||
|
for things like light cues, etc.
|
||||||
|
|
||||||
|
Just drop these three files in the directory with all your tracks,
|
||||||
|
and edit the HTML to have the right list of tracks.
|
||||||
|
You can have the same track more than once, if you want.
|
||||||
|
|
||||||
|
Author
|
||||||
|
------
|
||||||
|
|
||||||
|
Neale Pickett
|
|
@ -0,0 +1,50 @@
|
||||||
|
body {
|
||||||
|
background-color: #000;
|
||||||
|
color: #fa4;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio {
|
||||||
|
min-width: 40em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#currentTime {
|
||||||
|
background-color: #001;
|
||||||
|
float: right;
|
||||||
|
font-size: 1500%;
|
||||||
|
font-family: "Roboto", "Droid Sans Mono", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
#controls {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
#controls a {
|
||||||
|
font-size: 200%;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#playlist {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current {
|
||||||
|
background-color: #224;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
background-color: #430;
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-color: #430;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.fin {
|
||||||
|
animation: pulse 1s infinite;
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>2018 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" controls="controls">
|
||||||
|
Your browser does not support HTML5 Audio!
|
||||||
|
</audio>
|
||||||
|
|
||||||
|
<div id="currentTime">00:00</div>
|
||||||
|
|
||||||
|
<div id="controls">
|
||||||
|
<a id="prev">⏮</a>
|
||||||
|
<a id="next">⏭</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul id="playlist">
|
||||||
|
<li>0-0 God.mp3</li>
|
||||||
|
<li>1-2 Amsterdam Blues.mp3</li>
|
||||||
|
<li>1-3 Minute 5.m4a</li>
|
||||||
|
<li>1-4 Axial Symmetry (Tommy's Tarbukas).mp3</li>
|
||||||
|
<li>1-5 I'm Here Because I'm Here (Song).mp3</li>
|
||||||
|
<li>1-6 The Cuil Aodha Jig - The Lark on the Strand.m4a</li>
|
||||||
|
<li>1-7 Shetland Reels long.mp3</li>
|
||||||
|
<li>1-8 Ellery Klein & Ryan Lacey - King of the Faeries 124.mp3</li>
|
||||||
|
<li>1-9 Ni Liom Fein - 121.mp3</li>
|
||||||
|
<li>2-1 2018 ROF Disco_r1_session_2018-01-27_12.33.mp3</li>
|
||||||
|
<li>2-2 Gillie (Short).mp3</li>
|
||||||
|
<li>2-3 Scottiche 113.mp3</li>
|
||||||
|
<li>2-4 The Hunt 70 Kevin Joyce (ab).wav</li>
|
||||||
|
<li>2-5 Slow Jig ROF 2018.1.mp3</li>
|
||||||
|
<li>2-6 Matt & Nat's Faster 120.mp3</li>
|
||||||
|
<li>2-7 Neale Pickett - 2018 ROF Curtain (original).mp3</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,159 @@
|
||||||
|
var base = ".";
|
||||||
|
|
||||||
|
function loadTrack(e) {
|
||||||
|
let li = e.srcElement;
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
li.classList.add("current");
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickOn(element) {
|
||||||
|
let e = new MouseEvent("click", {
|
||||||
|
view: window,
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true
|
||||||
|
});
|
||||||
|
element.dispatchEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
function prev() {
|
||||||
|
let cur = document.querySelector(".current");
|
||||||
|
let prev = cur.previousElementSibling;
|
||||||
|
if (prev) {
|
||||||
|
cur = prev;
|
||||||
|
}
|
||||||
|
clickOn(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
let cur = document.querySelector(".current");
|
||||||
|
let next = cur.nextElementSibling;
|
||||||
|
if (next) {
|
||||||
|
cur = next;
|
||||||
|
}
|
||||||
|
clickOn(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ended() {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mmss(s) {
|
||||||
|
let mm = Math.floor(s / 60);
|
||||||
|
let ss = Math.floor(s % 60);
|
||||||
|
|
||||||
|
if (ss < 10) {
|
||||||
|
ss = "0" + ss;
|
||||||
|
}
|
||||||
|
return mm + ":" + ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
function timeupdate(e) {
|
||||||
|
let currentTime = e.srcElement.currentTime;
|
||||||
|
let duration = e.srcElement.duration;
|
||||||
|
let tgt = document.querySelector("#currentTime");
|
||||||
|
|
||||||
|
document.querySelector("#currentTime").textContent = mmss(currentTime);
|
||||||
|
if (duration - currentTime < 20) {
|
||||||
|
tgt.classList.add("fin");
|
||||||
|
} else {
|
||||||
|
tgt.classList.remove("fin");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function keydown(e) {
|
||||||
|
let audio = document.querySelector("#audio");
|
||||||
|
|
||||||
|
switch (event.key) {
|
||||||
|
case " ": // space bar
|
||||||
|
if (audio.paused) {
|
||||||
|
audio.play();
|
||||||
|
} else {
|
||||||
|
audio.pause();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "ArrowDown": // Next track
|
||||||
|
next();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "ArrowUp": // Previous track
|
||||||
|
prev();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function midiMessage(e) {
|
||||||
|
let audio = document.querySelector("#audio");
|
||||||
|
let data = e.data;
|
||||||
|
let ctrl = data[1];
|
||||||
|
let val = data[2];
|
||||||
|
if (data[0] == 176) {
|
||||||
|
switch (ctrl) {
|
||||||
|
case 0: // master volume slider
|
||||||
|
audio.volume = val / 127;
|
||||||
|
break;
|
||||||
|
case 41: // play button
|
||||||
|
if (val == 127) {
|
||||||
|
audio.play();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 42: // stop button
|
||||||
|
if (val == 127) {
|
||||||
|
audio.pause();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 58: // prev button
|
||||||
|
if (val == 127) {
|
||||||
|
prev();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 59: // next button
|
||||||
|
if (val == 127) {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMidiAccess(access) {
|
||||||
|
for (let input of access.inputs.values()) {
|
||||||
|
input.addEventListener("midimessage", midiMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
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);
|
||||||
|
for (let li of document.querySelectorAll("#playlist li")) {
|
||||||
|
li.addEventListener("click", loadTrack);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind keypress events
|
||||||
|
// - space: play/pause
|
||||||
|
//
|
||||||
|
document.addEventListener("keydown", keydown);
|
||||||
|
|
||||||
|
// Load up first track
|
||||||
|
document.querySelector("#playlist li").classList.add("current");
|
||||||
|
prev();
|
||||||
|
|
||||||
|
navigator.requestMIDIAccess().then(handleMidiAccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", run);
|
Loading…
Reference in New Issue