Commit Graph
11 Commits
Author SHA1 Message Date
nvrl f0fe90f0fe feat(core,app,cli): pair subtitle files with their video and play them
A crawl now keeps .srt/.ass/.ssa/.vtt files and pairs each with a video by
name: the video's name followed by a dot or nothing, the same inside a
Subs folder, the Subs/<video>/ layout, and failing those the only video in
the folder. The words past the video's name give the language and the
picker's title. They go in a new sidecars table (schema v12), rebuilt by
every crawl.

The desktop opens them while mpv opens the video and adds them with
sub-add through the stream registry once the file has loaded. One in the
preferred language is turned on when subtitles are on and the file has
none of its own playing; the rest wait in the subtitle menu.
2026-10-13 21:11:20 +02:00
nvrl 8d795c29e6 perf(stream,player,app): start a resumed episode at its place, with that block already coming
Resuming loaded the file from the start and sought on FileLoaded. By
then mpv's demuxer had begun reading ahead from the beginning, so the
blocks the seek wanted queued behind ones fetched to be thrown away.
Player::play_from sets mpv's start option instead, and puts it back
once the file has loaded.

VideoStream::warm_resume fetches, beside the two edge blocks, the block
the resume position falls in, estimated from the running time saved
with the watch state. A video's bitrate is uneven, so it can land a
block off; then it is one block for nothing, against a round trip saved
when it lands.
2026-10-13 16:40:18 +02:00
nvrl c6b0457c4d feat(app,android,ios): end an episode without chapters as well as one with them
The up-next countdown only ran over a credits chapter, so a file with no
chapters - most that are not anime - cut straight into the next episode
with no warning and no way to stay. Such a file now shows the same card
over its last ten seconds, counted on the file's own clock so it reaches
zero at the end of file, and its second button is Cancel rather than
Watch till the end.

On the phones, an episode that ends with nothing after it - the last one,
autoplay off, or cancelled - left a black screen. It now says so, with
Play next or Watch again, and Close.

Android also:
- saves the resume position from PlaybackService rather than the player
  screen. With background audio on the service outlives the activity, and
  a position only the screen kept stopped being saved when it went. A swipe
  from Recents saves and stops instead of playing on with nothing to
  return to.
- shows "Opening <episode>..." while the stream opens, where there was a
  black screen for as long as the share session and block list took.
2026-10-12 21:50:02 +02:00
nvrl 9037e6c2d5 feat(app,player): page fade, Ctrl+S screenshots
- a page fades in over 140 ms when the page changes, rather than cutting
- Ctrl+S in the player saves the frame, without subtitles, to
  Pictures/proton-stream as "Title  S01E04  12-34.png"
2026-10-02 20:16:27 +02:00
nvrl a432a93cf9 feat(app,stream): storage and hardware-decoding settings
- the streaming cache's budget (1-16 GiB) is chosen in Settings, shows
  what it holds, and can be emptied; a lower budget evicts at once
- hardware decoding can be turned off for a driver that shows green
  frames, from the next file
- both live in desktop.json rather than the playback prefs shared with
  Android, whose bridge record would reset them on every save. A file
  that will not parse is never overwritten
2026-10-02 20:16:27 +02:00
nvrl 53a1d0afda feat(app): desktop notifications, paste a share link anywhere
- a finished batch of downloads, and a crawl long enough to walk away
  from, notify through org.freedesktop.Notifications when the window is
  not focused; once per batch, not once per file
- Ctrl+V with a share link outside a text field opens the add form
  with the link in it
2026-10-02 20:16:27 +02:00
nvrl c5808a5e50 feat(app,player): tile context menu, buffered range on the seek bar, stall spinner
- right-click a library tile to play or resume it, mark it watched or
  unwatched, download it, change its match, or take it off Continue
  watching
- mpv's demuxer-cache-time is shaded on the seek bar, so it shows
  whether a jump lands in what is already read ahead
- paused-for-cache shows a spinner over the picture and in the controls
2026-10-02 20:16:27 +02:00
nvrl 4027ab5fb3 feat(app): polish pass - toasts, shortcuts, redesigned pages, cheaper frames
- toasts replace the status line; keyboard shortcuts with a ? overlay
- library: filters, sort, row virtualisation, cached search, skeleton
  tiles until the catalog loads, gradient placeholder art
- title page: season pills, episode rows with stills and one download
  glyph, portrait poster, clamped overview, resume time in the button
- player: fading chrome, smooth scrims, subtitles lifted over the
  controls, drag-following seek knob, OSD, speed menu, auto-skip
- settings as grouped cards with toggles and palette previews
- shares: confirm before removing, inline link validation, form kept
  until the add succeeds; downloads scroll and show rate and ETA
- downloads pipeline four blocks; the next episode is warmed near the end
- a film behind another page repaints at 4 Hz, not its frame rate

Fixes B55-B60.
2026-10-02 19:27:28 +02:00
nvrl d3c5f071fb feat(player,core): remember the audio/subtitle track by name across episodes
A track picked on one episode now carries over to the next by its title as
well as its language, so e.g. "Signs & Songs" vs "Full" subtitles in the same
language stick. Catalog migration V8 adds the title columns; the Android
bridge keeps a stored title only while its language is unchanged.
2026-09-15 13:54:07 +02:00
nvrl 6db6909824 added android client 2026-08-05 13:07:56 +02:00
nvrl a1b345a029 init 2026-08-02 19:37:03 +02:00