Skip to content

feat: seasons, episodes and audio tracks (0.5.0) - #8

Merged
kvachikk merged 4 commits into
mainfrom
feat/v0.5.0-playlist-audio
Aug 9, 2026
Merged

kvachikk merged 4 commits into
mainfrom
feat/v0.5.0-playlist-audio

Conversation

@kvachikk

@kvachikk kvachikk commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Two things a phone viewer cannot do on a film site, and now can.

Seasons and episodes

A series on a Playerjs site keeps a path — the season, the dub, the episode —
and the player draws one control per step of it. Nocturne reads those and puts
them in the top-left corner of the player, laid out across, where a thumb
reaches with the phone held sideways: the season, then the episode, each
opening a list with the one being watched marked. Picking an episode plays it
without leaving the player.

Playerjs answers api('next') and api('prev') but refuses an entry asked for
by index or by name — api('playlist') is undefined, api('play', n) throws,
api('find') returns false. So a choice is made the way its own menu makes it:
by pressing the row the player drew. The rows are read again at the moment of
the press, because choosing a season has the player rebuild every step under it
and rows held from before that are detached elements no press can reach.

A step with one entry in it is not a choice and is not drawn; a page that is a
film has no bar at all.

Audio tracks

Film sites often carry two or three dubs, and switching them from a phone was
close to impossible. The sheet grows a row for it, reading hls.js
audioTracks, dash.js getTracksFor('audio'), Shaka's audio languages,
Playerjs's own list and the audioTracks a browser exposes on the video
element. Like quality, it stays hidden when there is nothing to choose between.

Also

Quality hunted for hls.js, dash.js, Shaka and Playerjs on its own, and audio
was about to hunt for the same four. That search moves into engines.js so
both ask once, and one pass over the page's globals now answers for every
engine rather than one pass each.

Privacy

Reads and presses on elements and objects the page already published. No code
injected, nothing evaluated from a string, no network, no new permissions. The
privacy check passes on 31 files.

Checked

  • 60 unit tests, eslint, prettier, web-ext lint (0 errors, 0 warnings)
  • On the emulator (AOSP 16, Firefox 153), on a real series page:
    • both dropdowns draw in the top-left, the dub step correctly not drawn
    • the episode list opens with the episode being watched marked
    • picking an episode switches it in place, player never closes
    • picking a season switches the season, and its episode list replaces the old
      one; picking from it plays that episode

Quality hunted for hls.js, dash.js, Shaka and Playerjs on its own, and audio
tracks were about to hunt for the same four. The search moves into engines.js
so both ask once, and findGlobalMatch becomes findGlobalMatches: one pass over
the page's globals answers for every engine rather than one pass each.
Film sites often carry two or three dubs, and switching them from a phone was
close to impossible. The row reads hls.js audioTracks, dash.js getTracksFor,
Shaka's audio languages, Playerjs's own list and the audioTracks a browser
exposes on the video element itself.

The sheet grows a way to hide a row that has nothing to offer, so quality and
audio both stay out of the way on a page with one of each.
A series on a Playerjs site keeps a path — the season, the dub, the episode —
and the player draws one control per step of it. Those are read and put in the
top-left corner of the player, laid out across, where a thumb reaches with the
phone held sideways: the season, then the episode, each opening a list with the
one being watched marked.

Playerjs answers next and prev but refuses an entry by index or by name:
api('playlist') is undefined, api('play', n) throws and api('find') returns
false. So a choice is made the way its own menu makes it — by pressing the row
the player drew. The rows are read again at the moment of the press, because
choosing a season has the player rebuild every step under it and rows held from
before that are detached.

A step with one entry in it is not a choice and is not drawn; a page that is a
film has no bar at all.
@kvachikk
kvachikk merged commit 2c384f8 into main Aug 9, 2026
2 checks passed
@kvachikk
kvachikk deleted the feat/v0.5.0-playlist-audio branch August 9, 2026 18:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant