Stupid CORS, stupid non-indexed audio files!
This commit is contained in:
parent
b91a90e980
commit
4047779e6e
|
@ -0,0 +1 @@
|
||||||
|
music/
|
|
@ -0,0 +1,68 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- HTML5 Playlist by Neale Pickett -->
|
||||||
|
<!-- https://github.com/nealey/playlist -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>ROF 2023-A</title>
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<link href="playlist.css" rel="stylesheet">
|
||||||
|
<script src="playlist.mjs" type="module"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<audio preload id="audio">
|
||||||
|
Your browser does not support HTML5 Audio!
|
||||||
|
</audio>
|
||||||
|
<input type="range" min="0.0" max="1.0" list="audiopos" step="any" id="pos">
|
||||||
|
<datalist id="audiopos">
|
||||||
|
<option value="0.1"></option>
|
||||||
|
<option value="0.2"></option>
|
||||||
|
<option value="0.3"></option>
|
||||||
|
<option value="0.4"></option>
|
||||||
|
<option value="0.5"></option>
|
||||||
|
<option value="0.6"></option>
|
||||||
|
<option value="0.7"></option>
|
||||||
|
<option value="0.8"></option>
|
||||||
|
<option value="0.9"></option>
|
||||||
|
</datalist>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<ol id="playlist">
|
||||||
|
<li value=0>0-0 God.mp3</li>
|
||||||
|
<li>01 Drums of Belfast.m4a</li>
|
||||||
|
<li>04 The Jura Wedding Reels.m4a</li>
|
||||||
|
<li>07 Geantraí.mp3</li>
|
||||||
|
<li>15 The Sweets of May (Ceili).mp3</li>
|
||||||
|
<li>Ni Liom Fein - 121.mp3</li>
|
||||||
|
<li>--- Maria ---</li>
|
||||||
|
<li>--- St Patrick's Day---</li>
|
||||||
|
<li>2-05 Wellerman – Sea Shanty.m4a</li>
|
||||||
|
<li>01 Boogie Woogie Bugle Boy.m4a</li>
|
||||||
|
<li>Amsterdam Blues Extra A Original.mp3</li>
|
||||||
|
<li value=0>----- Intermission -----</li>
|
||||||
|
<li value=1>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>
|
||||||
|
</ol>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,16 +1,127 @@
|
||||||
// jshint asi:true
|
let ctx = new AudioContext()
|
||||||
|
|
||||||
// HTML5 Playlist by Neale Pickett
|
const Millisecond = 1
|
||||||
// https://github.com/nealey/playlst
|
const Second = 1000 * Millisecond
|
||||||
|
const Minute = 60 * Second
|
||||||
|
|
||||||
|
class Track {
|
||||||
|
constructor() {
|
||||||
|
this.startedAt = 0
|
||||||
|
this.pausedAt = 0
|
||||||
|
console.log(this)
|
||||||
|
window.track = this
|
||||||
|
}
|
||||||
|
|
||||||
var base = "."
|
async load(url) {
|
||||||
|
this.filename = url.split("/").pop()
|
||||||
|
let resp = await fetch(url)
|
||||||
|
let buf = await resp.arrayBuffer()
|
||||||
|
this.abuf = await ctx.decodeAudioData(buf)
|
||||||
|
}
|
||||||
|
|
||||||
function loadTrack(e) {
|
Duration() {
|
||||||
|
if (this.abuf) {
|
||||||
|
return this.abuf.duration * Second
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Playlist {
|
||||||
|
constructor(base="./music") {
|
||||||
|
this.base = base
|
||||||
|
this.list = {}
|
||||||
|
this.current = null
|
||||||
|
this.startedAt = 0
|
||||||
|
this.pausedAt = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(filename) {
|
||||||
|
let track = new Track()
|
||||||
|
this.list[filename] = track
|
||||||
|
await track.load(`${this.base}/${filename}`)
|
||||||
|
return track
|
||||||
|
}
|
||||||
|
|
||||||
|
async load(filename) {
|
||||||
|
this.stop()
|
||||||
|
this.current = this.list[filename]
|
||||||
|
if (!this.current) {
|
||||||
|
this.current = await this.add(filename)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
play(pos=null) {
|
||||||
|
let offset = this.pausedAt / Second
|
||||||
|
if (pos) {
|
||||||
|
offset = this.current.abuf.duration * pos
|
||||||
|
}
|
||||||
|
if (this.startedAt) {
|
||||||
|
this.stop()
|
||||||
|
}
|
||||||
|
console.log(offset)
|
||||||
|
this.source = new AudioBufferSourceNode(ctx)
|
||||||
|
this.source.buffer = this.current.abuf
|
||||||
|
this.source.connect(ctx.destination)
|
||||||
|
this.source.start(0, offset)
|
||||||
|
this.startedAt = (ctx.currentTime - offset) * Second
|
||||||
|
this.pausedAt = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pause() {
|
||||||
|
let pos = this.CurrentTime()
|
||||||
|
this.stop()
|
||||||
|
this.pausedAt = pos
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if (this.source) {
|
||||||
|
this.source.disconnect()
|
||||||
|
this.source.stop()
|
||||||
|
}
|
||||||
|
this.pausedAt = 0
|
||||||
|
this.startedAt = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayPause() {
|
||||||
|
console.log("Play/Pause")
|
||||||
|
if (this.startedAt) {
|
||||||
|
this.pause()
|
||||||
|
} else {
|
||||||
|
this.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Seek(pos) {
|
||||||
|
if (this.startedAt) {
|
||||||
|
this.play(pos)
|
||||||
|
} else {
|
||||||
|
this.pausedAt = this.Duration() * pos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentTime() {
|
||||||
|
if (this.startedAt) {
|
||||||
|
return ctx.currentTime*Second - this.startedAt
|
||||||
|
}
|
||||||
|
if (this.pausedAt) {
|
||||||
|
return this.pausedAt
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
Duration() {
|
||||||
|
return this.current.Duration()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let playlist = new Playlist()
|
||||||
|
window.playlist = playlist
|
||||||
|
|
||||||
|
async function loadTrack(e) {
|
||||||
let li = e.target
|
let li = e.target
|
||||||
let audio = document.querySelector("#audio")
|
|
||||||
audio.src = base + "/" + li.textContent
|
playlist.load(li.textContent)
|
||||||
audio.load()
|
|
||||||
|
|
||||||
// Update "current"
|
// Update "current"
|
||||||
for (let cur of document.querySelectorAll(".current")) {
|
for (let cur of document.querySelectorAll(".current")) {
|
||||||
|
@ -50,9 +161,9 @@ function ended() {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|
||||||
function mmss(s) {
|
function mmss(duration) {
|
||||||
let mm = Math.floor(s / 60)
|
let mm = Math.floor(duration / Minute)
|
||||||
let ss = Math.floor(s % 60)
|
let ss = Math.floor((duration / Second) % 60)
|
||||||
|
|
||||||
if (ss < 10) {
|
if (ss < 10) {
|
||||||
ss = "0" + ss
|
ss = "0" + ss
|
||||||
|
@ -60,28 +171,21 @@ function mmss(s) {
|
||||||
return mm + ":" + ss
|
return mm + ":" + ss
|
||||||
}
|
}
|
||||||
|
|
||||||
function durationchange(e) {
|
|
||||||
let duration = e.target.duration
|
|
||||||
|
|
||||||
document.querySelector("#duration").textContent = mmss(duration)
|
|
||||||
timeupdate(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
function volumechange(e) {
|
function volumechange(e) {
|
||||||
document.querySelector("#vol").value = e.target.volume
|
document.querySelector("#vol").value = e.target.volume
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function timeupdate(e) {
|
function timeupdate() {
|
||||||
let currentTime = e.target.currentTime
|
let currentTime = playlist.CurrentTime()
|
||||||
let duration = e.target.duration || 1
|
let duration = playlist.Duration()
|
||||||
let tgt = document.querySelector("#currentTime")
|
let tgt = document.querySelector("#currentTime")
|
||||||
let pos = document.querySelector("#pos")
|
let pos = document.querySelector("#pos")
|
||||||
|
|
||||||
pos.value = currentTime / duration
|
pos.value = currentTime / duration
|
||||||
|
|
||||||
tgt.textContent = mmss(currentTime)
|
tgt.textContent = mmss(currentTime)
|
||||||
if (duration - currentTime < 20) {
|
if (duration - currentTime < 20 * Second) {
|
||||||
tgt.classList.add("fin")
|
tgt.classList.add("fin")
|
||||||
} else {
|
} else {
|
||||||
tgt.classList.remove("fin")
|
tgt.classList.remove("fin")
|
||||||
|
@ -90,9 +194,7 @@ function timeupdate(e) {
|
||||||
|
|
||||||
function setPos(e) {
|
function setPos(e) {
|
||||||
let val = e.target.value
|
let val = e.target.value
|
||||||
let audio = document.querySelector("#audio")
|
playlist.Seek(val)
|
||||||
|
|
||||||
audio.currentTime = audio.duration * val
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setGain(e) {
|
function setGain(e) {
|
||||||
|
@ -105,13 +207,9 @@ function setGain(e) {
|
||||||
function keydown(e) {
|
function keydown(e) {
|
||||||
let audio = document.querySelector("#audio")
|
let audio = document.querySelector("#audio")
|
||||||
|
|
||||||
switch (event.key) {
|
switch (e.key) {
|
||||||
case " ": // space bar
|
case " ": // space bar
|
||||||
if (audio.paused) {
|
playlist.PlayPause()
|
||||||
audio.play()
|
|
||||||
} else {
|
|
||||||
audio.pause()
|
|
||||||
}
|
|
||||||
break
|
break
|
||||||
|
|
||||||
case "ArrowDown": // Next track
|
case "ArrowDown": // Next track
|
||||||
|
@ -189,13 +287,14 @@ function run() {
|
||||||
document.querySelector("#pos").addEventListener("input", setPos)
|
document.querySelector("#pos").addEventListener("input", setPos)
|
||||||
document.querySelector("#vol").addEventListener("input", setGain)
|
document.querySelector("#vol").addEventListener("input", setGain)
|
||||||
audio.addEventListener("ended", ended)
|
audio.addEventListener("ended", ended)
|
||||||
audio.addEventListener("timeupdate", timeupdate)
|
|
||||||
audio.addEventListener("durationchange", durationchange)
|
|
||||||
audio.addEventListener("volumechange", volumechange)
|
audio.addEventListener("volumechange", volumechange)
|
||||||
for (let li of document.querySelectorAll("#playlist li")) {
|
for (let li of document.querySelectorAll("#playlist li")) {
|
||||||
|
playlist.add(li.textContent)
|
||||||
li.addEventListener("click", loadTrack)
|
li.addEventListener("click", loadTrack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setInterval(() => timeupdate(), 250 * Millisecond)
|
||||||
|
|
||||||
document.querySelector("#vol").value = audio.volume
|
document.querySelector("#vol").value = audio.volume
|
||||||
|
|
||||||
// Bind keypress events
|
// Bind keypress events
|
Loading…
Reference in New Issue