Both 2023 playlists

This commit is contained in:
Neale Pickett 2023-03-12 09:40:47 -07:00
parent 4047779e6e
commit 8a5083cc94
3 changed files with 123 additions and 40 deletions

View File

@ -52,17 +52,6 @@
<li>2-05 Wellerman Sea Shanty.m4a</li> <li>2-05 Wellerman Sea Shanty.m4a</li>
<li>01 Boogie Woogie Bugle Boy.m4a</li> <li>01 Boogie Woogie Bugle Boy.m4a</li>
<li>Amsterdam Blues Extra A Original.mp3</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> </ol>
</body> </body>
</html> </html>

64
2023-b.html Normal file
View File

@ -0,0 +1,64 @@
<!DOCTYPE html>
<!-- HTML5 Playlist by Neale Pickett -->
<!-- https://github.com/nealey/playlist -->
<html>
<head>
<title>ROF 2023-B</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>21 Planxty Davis 108.m4a</li>
<li>04 The Jura Wedding Reels.m4a</li>
<li>--- Maria ---</li>
<li>--- St Patrick's Day---</li>
<li>09 Taylor Bar, 4am _ Ceol Na Mara.m4a</li>
<li>15 The Sweets of May (Ceili).mp3</li>
<li>Ni Liom Fein - 121.mp3</li>
<li value=0>----- Intermission -----</li>
<li>07 The Red Shoes.mp3</li>
<li>--- Maria ---</li>
<li>07 Geantraí.mp3</li>
<li>03 Scotch Cap _ Road to Lisdoonvarna (single Jigs).m4a</li>
<li>09 Slow Treble Jig.m4a</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>
</ol>
</body>
</html>

View File

@ -8,20 +8,27 @@ class Track {
constructor() { constructor() {
this.startedAt = 0 this.startedAt = 0
this.pausedAt = 0 this.pausedAt = 0
console.log(this)
window.track = this window.track = this
} }
async load(url) { async Load(url) {
this.filename = url.split("/").pop() this.filename = url.split("/").pop()
let resp = await fetch(url) let resp = await fetch(url)
let buf = await resp.arrayBuffer() if (resp.ok) {
this.abuf = await ctx.decodeAudioData(buf) let buf = await resp.arrayBuffer()
this.abuf = await ctx.decodeAudioData(buf)
} else {
let options = {
length: 1,
sampleRate: 3000,
}
this.abuf = new AudioBuffer(options)
}
} }
Duration() { Duration() {
if (this.abuf) { if (this.abuf) {
return this.abuf.duration * Second return this.abuf.duration
} }
return 0 return 0
} }
@ -36,45 +43,69 @@ class Playlist {
this.pausedAt = 0 this.pausedAt = 0
} }
async add(filename) { /**
* Preload a track
*
* @param {String} filename
* @returns {Track}
*/
async Add(filename) {
let track = new Track() let track = new Track()
this.list[filename] = track this.list[filename] = track
await track.load(`${this.base}/${filename}`) await track.Load(`${this.base}/${filename}`)
return track return track
} }
async load(filename) { /**
this.stop() * Load a track by filename
*
* @param {String} filename
*/
async Load(filename) {
this.Stop()
this.current = this.list[filename] this.current = this.list[filename]
if (!this.current) { if (!this.current) {
this.current = await this.add(filename) this.current = await this.add(filename)
} }
} }
play(pos=null) { /**
let offset = this.pausedAt / Second * Returns current position as a percentage (0.0-1.0)
*/
Position() {
let duration = this.Duration()
let pos = 0
if (!duration) {
return 0
}
if (this.startedAt) {
pos = ctx.currentTime - this.startedAt
pos = Math.min(pos, duration)
}
return pos / duration
}
Play(pos=null) {
let offset = this.pausedAt
if (pos) { if (pos) {
offset = this.current.abuf.duration * pos offset = this.current.abuf.duration * pos
} }
if (this.startedAt) { this.Stop()
this.stop()
}
console.log(offset)
this.source = new AudioBufferSourceNode(ctx) this.source = new AudioBufferSourceNode(ctx)
this.source.buffer = this.current.abuf this.source.buffer = this.current.abuf
this.source.connect(ctx.destination) this.source.connect(ctx.destination)
this.source.start(0, offset) this.source.start(0, offset)
this.startedAt = (ctx.currentTime - offset) * Second this.startedAt = ctx.currentTime - offset
this.pausedAt = 0 this.pausedAt = 0
} }
pause() { Pause() {
let pos = this.CurrentTime() let pos = this.CurrentTime()
this.stop() this.Stop()
this.pausedAt = pos this.pausedAt = pos
} }
stop() { Stop() {
if (this.source) { if (this.source) {
this.source.disconnect() this.source.disconnect()
this.source.stop() this.source.stop()
@ -84,11 +115,10 @@ class Playlist {
} }
PlayPause() { PlayPause() {
console.log("Play/Pause")
if (this.startedAt) { if (this.startedAt) {
this.pause() this.Pause()
} else { } else {
this.play() this.Play()
} }
} }
@ -102,7 +132,7 @@ class Playlist {
CurrentTime() { CurrentTime() {
if (this.startedAt) { if (this.startedAt) {
return ctx.currentTime*Second - this.startedAt return ctx.currentTime - this.startedAt
} }
if (this.pausedAt) { if (this.pausedAt) {
return this.pausedAt return this.pausedAt
@ -121,7 +151,7 @@ window.playlist = playlist
async function loadTrack(e) { async function loadTrack(e) {
let li = e.target let li = e.target
playlist.load(li.textContent) playlist.Load(li.textContent)
// Update "current" // Update "current"
for (let cur of document.querySelectorAll(".current")) { for (let cur of document.querySelectorAll(".current")) {
@ -177,8 +207,8 @@ function volumechange(e) {
function timeupdate() { function timeupdate() {
let currentTime = playlist.CurrentTime() let currentTime = playlist.CurrentTime() * Second
let duration = playlist.Duration() let duration = playlist.Duration() * Second
let tgt = document.querySelector("#currentTime") let tgt = document.querySelector("#currentTime")
let pos = document.querySelector("#pos") let pos = document.querySelector("#pos")
@ -238,12 +268,12 @@ function midiMessage(e) {
// The first time, the browser will reject this, // The first time, the browser will reject this,
// because it doesn't consider MIDI input user interaction, // because it doesn't consider MIDI input user interaction,
// so it looks like an autoplaying video. // so it looks like an autoplaying video.
audio.play() playlist.Play()
} }
break break
case 42: // stop button case 42: // stop button
if (val == 127) { if (val == 127) {
audio.pause() playlist.Pause()
} }
break break
case 58: // prev button case 58: // prev button
@ -289,7 +319,7 @@ function run() {
audio.addEventListener("ended", ended) audio.addEventListener("ended", ended)
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) playlist.Add(li.textContent)
li.addEventListener("click", loadTrack) li.addEventListener("click", loadTrack)
} }