Changeset 4fbe2c1 in Klonkt
- Timestamp:
- 08/22/2026 10:35:33 AM (2 weeks ago)
- Branches:
- main
- Children:
- c0e463b
- Parents:
- 8bb3b09
- Files:
-
- 4 edited
-
src/assets/js/audio-player.js (modified) (5 diffs)
-
src/assets/js/mod/tape.js (modified) (2 diffs)
-
src/views/shell.ejs (modified) (2 diffs)
-
test/mixtape-ui.test.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/assets/js/audio-player.js
r8bb3b09 r4fbe2c1 279 279 function preloadNext() { 280 280 if (queue.length < 2) return; 281 if (tapeMode && currentIndex >= queue.length - 1) return; // einde band 281 282 const ni = (currentIndex + 1) % queue.length; 282 283 const t = queue[ni]; … … 361 362 const start = chain.length ? chain[chain.length - 1].end : (buffered.length ? buffered.start(0) : 0); 362 363 chain.push({ qIndex, start, end: chainEnd }); 363 if (queue.length === 1 && ms && ms.readyState === 'open') { 364 // DE STREAM MOET DICHT ALS ER NIETS MEER KOMT, anders vuurt `ended` nooit. 365 // Bij een wachtrij van een was dat al zo. Een BANDJE heeft nu hetzelfde 366 // nodig: sinds hij niet meer rondloopt haakt de keten na het laatste nummer 367 // niets meer aan, en dan bleef de band aan het eind hangen -- de teller 368 // stilstaand op de laatste seconde, isPlaying() waar, en de spoelen 369 // draaiend. Gemeten op dev (22-8): 125,6 van 125,7 en daar bleef hij. 370 const laatsteVanDeBand = tapeMode && qIndex >= queue.length - 1; 371 if ((queue.length === 1 || laatsteVanDeBand) && ms && ms.readyState === 'open') { 364 372 // Single-track queue: close the stream so `ended` fires (which replays 365 // it, matching the old engine's behaviour). 373 // it, matching the old engine's behaviour). Bij een bandje stopt `ended` 374 // hem juist, want next() pauzeert daar aan het eind. 366 375 try { ms.endOfStream(); } catch (e) {} 367 376 } … … 374 383 const seg = currentSegment(); 375 384 if (!seg || chain.length - 1 - chain.indexOf(seg) >= 1) return; // already one ahead 376 const nextIdx = (chain[chain.length - 1].qIndex + 1) % queue.length; 385 // EEN BANDJE LOOPT NIET ROND (Robins eis, 22-8). Deze modulo is precies wat 386 // een cassette eindeloos maakte: na het laatste nummer hing hij nummer een 387 // er weer achter, en omdat het een doorlopende keten is merk je dat niet 388 // eens als een trackwissel -- de band gaat gewoon door. 389 const volgendeInRij = chain[chain.length - 1].qIndex + 1; 390 if (tapeMode && volgendeInRij > queue.length - 1) return; // einde band 391 const nextIdx = volgendeInRij % queue.length; 377 392 const t = queue[nextIdx]; 378 393 if (!t || !t.url) return; … … 642 657 function next() { 643 658 if (!queue.length) return; 659 // Aan het eind van een bandje: stoppen. `ended` roept deze functie aan, dus 660 // zonder deze tak begint de band na het laatste nummer weer vooraan. 661 if (tapeMode && currentIndex >= queue.length - 1) { pause(); return; } 644 662 loadTrack((currentIndex + 1) % queue.length, true); 645 663 } 646 664 function prev() { 647 665 if (!queue.length) return; 666 // En aan het begin ook niet omlopen. Terugspoelen voorbij het begin levert 667 // de kop van de band op, niet het laatste nummer. 668 if (tapeMode && currentIndex === 0) { 669 try { audio.currentTime = 0; } catch (e) { /* nog niets geladen */ } 670 return; 671 } 648 672 loadTrack(currentIndex === 0 ? queue.length - 1 : currentIndex - 1, true); 649 673 } … … 1157 1181 const duur = audio.duration || 0; 1158 1182 const nu = audio.currentTime || 0; 1159 if (duur && nu + d >= duur) { next(); return; } 1160 if (nu + d < 0) { prev(); return; } 1183 if (duur && nu + d >= duur) { 1184 // Vooruit voorbij het eind. In bandmodus stopt next() aan het eind van de 1185 // band; daarbuiten loopt hij door naar het volgende nummer. 1186 next(); 1187 return; 1188 } 1189 if (nu + d < 0) { 1190 // TERUGSPOELEN VOORBIJ HET BEGIN moet in het vorige nummer landen aan het 1191 // EIND, niet aan het begin -- dat is wat terugspoelen doet. Zonder dit 1192 // sprong je bij elke druk naar de kop van het vorige nummer en kwam je 1193 // nooit ergens in het midden uit. 1194 if (!(tapeMode && currentIndex === 0)) pendingSeek = Number.MAX_SAFE_INTEGER; 1195 prev(); 1196 return; 1197 } 1161 1198 try { audio.currentTime = Math.max(0, nu + d); } catch (e) {} 1162 1199 } -
src/assets/js/mod/tape.js
r8bb3b09 r4fbe2c1 109 109 stopWinden(tape); 110 110 let snelheid = START_SNELHEID; 111 let vorigePositie = null; 112 let stil = 0; 111 113 tape.classList.add('is-winding'); 112 114 if (richting < 0) tape.classList.add('is-winding-back'); … … 115 117 p.seekBy(richting * snelheid * (STAP_MS / 1000)); 116 118 tekenBand(tape); 119 // AAN HET EIND VAN DE BAND STOPPEN MET SPOELEN. De speler klemt de positie 120 // af, dus daar gebeurt niets meer -- maar de spoelen bleven wel doordraaien 121 // en de knop bleef oplichten, alsof er nog band was. Beweegt de teller twee 122 // rondes niet, dan zijn we bij de kop of de staart. 123 const nu = p.tapeTijden ? p.tapeTijden().cur : null; 124 if (nu !== null && vorigePositie !== null && Math.abs(nu - vorigePositie) < 0.05) { 125 if (++stil >= 2) { stopWinden(tape); return; } 126 } else stil = 0; 127 vorigePositie = nu; 117 128 }, STAP_MS); 118 129 winder = { timer, tape }; -
src/views/shell.ejs
r8bb3b09 r4fbe2c1 406 406 ?v=N — cache-buster: bump bij elke audio-player.js wijziging zodat 407 407 Cloudflare (max-age=1y) niet de oude versie blijft serveren. --> 408 <script src="/assets/js/audio-player.js?v=3 5"></script>408 <script src="/assets/js/audio-player.js?v=37"></script> 409 409 <!-- Eigen custom media-embeds (YouTube/SoundCloud/Spotify) via de echte 410 410 player-API's + gedeelde mutual-exclusion registry met de site-speler. --> … … 505 505 // Eén nummer voor de hele map. Te vaak bumpen kost één download; te weinig 506 506 // bumpen kost een bugfix die nooit aankomt. 507 var MOD_V = 5 3;507 var MOD_V = 54; 508 508 509 509 // name -> 1 (aan het laden) of de module-namespace (geladen). Een module -
test/mixtape-ui.test.js
r8bb3b09 r4fbe2c1 166 166 assert.doesNotMatch(mod, /p\.next\(\); else p\.prev\(\)/, 'de oude sprong per nummer'); 167 167 }); 168 169 test('een bandje loopt niet rond, aan geen van beide kanten', () => { 170 const speler = fs.readFileSync('src/assets/js/audio-player.js', 'utf8'); 171 172 // De keten mag na het laatste nummer niet nummer een er weer achter hangen. 173 // Dat was de stilste van de drie: omdat het EEN doorlopende tijdlijn is merk 174 // je die omloop niet eens als een trackwissel, de band gaat gewoon door. 175 assert.match(speler, /if \(tapeMode && volgendeInRij > queue\.length - 1\) return;/, 176 'de keten hoort te stoppen aan het eind van de band'); 177 178 // ended roept next() aan, dus zonder deze tak begint de band opnieuw. 179 assert.match(speler, /if \(tapeMode && currentIndex >= queue\.length - 1\) \{ pause\(\); return; \}/, 180 'aan het eind stoppen in plaats van omlopen'); 181 182 // En terugspoelen voorbij het begin levert de kop van de band op, niet het 183 // laatste nummer. 184 assert.match(speler, /if \(tapeMode && currentIndex === 0\) \{/, 185 'aan het begin niet naar achteren omlopen'); 186 187 // Alle drie de modulo's zijn nog aanwezig voor de NIET-bandmodus: een gewone 188 // playlist hoort wel te blijven rondlopen. 189 assert.equal((speler.match(/% queue\.length/g) || []).length, 3, 190 'de omloop van een gewone wachtrij mag niet gesneuveld zijn'); 191 }); 192 193 test('terugspoelen komt in het vorige nummer uit aan het EIND', () => { 194 const speler = fs.readFileSync('src/assets/js/audio-player.js', 'utf8'); 195 // Zonder dit sprong terugspoelen naar de kop van het vorige nummer, en kwam 196 // je nooit ergens in het midden uit -- dat is geen terugspoelen maar 197 // terugspringen. Geldt voor de blob-motor; op MSE is de band een tijdlijn en 198 // gaat het vanzelf goed. 199 assert.match(speler, /pendingSeek = Number\.MAX_SAFE_INTEGER;/); 200 }); 201 202 test('aan het eind van de band gaat de stream dicht', () => { 203 const speler = fs.readFileSync('src/assets/js/audio-player.js', 'utf8'); 204 // ZONDER DIT HANGT DE BAND. Bij een MediaSource vuurt `ended` pas als de 205 // stream gesloten is. Sinds een bandje niet meer rondloopt haakt de keten na 206 // het laatste nummer niets meer aan, en dan bleef hij op de laatste seconde 207 // staan: teller stil, isPlaying() waar, spoelen draaiend. Gemeten op dev 208 // (22-8): 125,6 van 125,7 en daar bleef hij staan. 209 assert.match(speler, /const laatsteVanDeBand = tapeMode && qIndex >= queue\.length - 1;/); 210 assert.match(speler, /if \(\(queue\.length === 1 \|\| laatsteVanDeBand\) && ms && ms\.readyState === 'open'\)/); 211 });
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)