Changeset 5e72413 in Klonkt for src/assets/js/audio-player.js


Ignore:
Timestamp:
08/22/2026 11:23:57 AM (2 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
1e194e4, fbacddc
Parents:
c0e463b
Message:

Seek over de hele band (shaer-tmyn, stap 4 en laatste)

De balk TOONDE al de hele band -- de teller rekent sinds c0e463b met de
trackduren -- maar aanklikken seekte binnen het lopende nummer. En de keten
houdt het lopende nummer plus een vooruit, dus op een band van twaalf nummers
reikte die balk in werkelijkheid tot nummer twee. Een balk die belooft wat hij
niet doet is erger dan geen balk.

bandPositie(ratio) rekent de verhouding om naar nummer + positie daarin, met
dezelfde duren als de teller. Ligt het doel in het lopende nummer, dan wordt de
positie gewoon verzet: geen herlaadsprong voor een paar seconden. Ligt het
verderop, dan zet hij pendingSeek en laadt dat nummer -- exact de weg die het
sessieherstel al gebruikt -- met de speelstand mee, zodat springen niet stiekem
start of stopt.

Er valt een hoorbaar gat bij zo'n sprong. Dat hoort bij spoelen naar een plek
die niet in de buffer zit, en het is eerlijker dan een balk die daar nooit komt.

DEZELFDE OMREKENING IS OOK DE ENIGE DIE OP iOS KAN: de blob-motor heeft geen
doorlopende tijdlijn, dus daar bestaat "seek over de keten" niet eens. Nu delen
beide motoren een model in plaats van twee.

Nagemeten op dev, klikken op vijf plekken van de balk (band van 373 s,
nummers van 103, 144 en 126 s):

10% -> 39 s, nummer 1 50% -> 189 s, nummer 2
25% -> 95 s, nummer 1 85% -> 319 s, nummer 3
95% -> 356 s, nummer 3

Steeds twee seconden voor op de verwachting, en dat is het doorspelen tijdens
het meten zelf.

audio-player v39.

Co-Authored-By: Claude Opus 5 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/assets/js/audio-player.js

    rc0e463b r5e72413  
    885885  }
    886886
     887  /**
     888   * Waar op de BAND ligt deze verhouding? Geeft het nummer en de positie erin.
     889   *
     890   * Dit is de hele truc van hele-band-seek. De balk toont al de hele band (de
     891   * teller rekent met de trackduren), maar aanklikken werkte binnen het lopende
     892   * nummer -- en de keten houdt maar een nummer vooruit, dus een balk die de
     893   * hele band belooft reikte in werkelijkheid tot nummer twee. Dat is erger dan
     894   * geen balk, want het ziet eruit alsof het werkt.
     895   *
     896   * Omrekenen kan alleen met de echte duren, en die hebben we sinds de teller
     897   * uit bandDuur()/bandOffset() komt. Dezelfde omrekening werkt op BEIDE
     898   * motoren: de blob-motor heeft helemaal geen doorlopende tijdlijn, dus daar
     899   * is dit niet alleen de beste maar de enige manier.
     900   */
     901  function bandPositie(ratio) {
     902    const totaal = bandDuur();
     903    if (!totaal) return null;
     904    const doel = Math.max(0, Math.min(ratio, 1)) * totaal;
     905    for (let i = 0; i < queue.length; i++) {
     906      const start = bandOffset(i);
     907      const eind = start + (Number(queue[i].duration) || 0);
     908      if (doel < eind || i === queue.length - 1) {
     909        return { index: i, binnen: Math.max(0, Math.min(doel - start, (Number(queue[i].duration) || 0) - 0.25)) };
     910      }
     911    }
     912    return null;
     913  }
     914
    887915  function attachSeek(seekEl) {
    888916    seekEl.addEventListener('click', (e) => {
    889917      const rect = seekEl.getBoundingClientRect();
    890918      const ratio = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
     919
     920      // BANDMODUS: de balk is de hele band, dus de klik ook.
     921      const plek = tapeMode ? bandPositie(ratio) : null;
     922      if (plek) {
     923        if (plek.index === currentIndex) {
     924          // Binnen het lopende nummer: gewoon verzetten, geen herlaadsprong.
     925          if (useMse() && chain.length) {
     926            const seg = currentSegment();
     927            if (seg) { try { audio.currentTime = seg.start + plek.binnen; } catch (er) {} }
     928          } else {
     929            try { audio.currentTime = plek.binnen; } catch (er) {}
     930          }
     931          updatePositionState();
     932          return;
     933        }
     934        // Een ander nummer: laden en er meteen in springen. pendingSeek is de
     935        // bestaande weg daarvoor -- het sessieherstel doet precies dit -- en
     936        // wordt toegepast zodra de metadata er is. Er valt een hoorbaar gat bij
     937        // de sprong; dat hoort bij spoelen naar een plek die nog niet in de
     938        // buffer zit, en is eerlijker dan een balk die daar niet komt.
     939        pendingSeek = plek.binnen;
     940        loadTrack(plek.index, !audio.paused);
     941        return;
     942      }
     943
    891944      if (useMse() && chain.length) {
    892945        // Seek within the CURRENT track's segment of the chain timeline.
Note: See TracChangeset for help on using the changeset viewer.