Player controls + recognising subtitles a video arrives with - #32
Merged
Conversation
… backend seek instead of one per click (twelve clicks used to mean twelve decode restarts and a frozen dialog), drawn transport icons and a click-anywhere seek bar replace the emoji and the stock slider, and switching both subtitle tracks off finally hides them.
…scanned and named by their second-level suffix (no suffix means English, aliases like .cn and .zh-Hans included, .part2 is not a language), so an already subtitled file is skipped instead of re-transcribed and lands in history with every language it has — not silently absent, which is what skipped files were until now.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two things reported from actually using the player.
Player controls
Skipping stalled. Every 10s click called
setPosition()straight away, and a seek is a full decode restart in the media backend — hammer the button and the seeks queue up behind each other, leaving the dialog stuck on the last one's buffering. Position changes (buttons, arrow keys, clicking or dragging the bar) now accumulate into one pending target: the UI moves immediately, the backend is seeked once the burst stops. Positions the backend reports while a seek is in flight are ignored so the bar never snaps back, with a settle-timeout backstop in case a seek never reports its target.Measured against a real 60s file: 12 clicks in 193ms produced 0 seeks during the burst, then one seek to the right place.
Icons.
⏪ 10/10 ⏩rendered differently on every platform and matched nothing else in the app.gui_qt/icons.pydraws them instead — circular arrow with the skip amount inside, plus play/pause — from theme tokens, at device pixel ratio.Seek bar. A stock QSlider page-steps when you click the groove, so you could not seek by clicking. It is now self-painted: click anywhere to jump there, drag to scrub with live subtitle/time preview, hover for the time under the cursor, and the bar thickens on hover so a 5px target is easy to hit. Self-painted rather than styled because a QSS
::sub-pageignores the groove height and floods the whole widget rect — and this way the painted geometry is the same arithmetic that maps clicks to positions.Subtitle bug. Setting both track selectors to "no subtitle" left the text on screen.
_sync_tracksreset the cache to["", ""]and then_update_subtitlessaw new text""equal to cached"", called it unchanged, and skipped thehide(). The cache now starts asNone, which is distinct from "no text". Selectors also show whenever there is at least one track — with a single track they were hidden, so there was no way to turn subtitles off at all.Subtitles a video arrives with
A video usually comes with its own
.srtfiles, named the way everyone names them.output.sibling_transcripts()scans the source's directory for same-stem transcripts and reads the language off the second-level suffix:.zh→ zh, aliases like.cn/.chs/.zh-Hans/.engmapped to their language, no suffix at all → English, a well-formed unregistered tag → itself (the mirror of how unknown codes are written), and.part2/.final→ not a language.Two consequences:
existing_transcript()now recognises a suffix-lesslecture.srt, which it could not see before, so an already subtitled video is skipped rather than transcribed again.overwritestill forces a re-run._record()call, so a video that already had subtitles produced no history row and there was no way to reach its subtitles from the app. It is recorded now, and the entry lists every language found on disk, not just the one this run touched. A failed job does not pick up sibling files, so a failure row cannot look like it produced something.End to end,
Lecture 01.mp4beside.srt/.zh.srt/.ja.srt/.part2.srt:All three reach the player as selectable tracks;
.part2.srtis correctly ignored.Tests
13 new: seek-burst coalescing, bound clamping, stale positions not snapping the bar, settle backstop, click-to-position mapping, subtitle slots hiding; suffix parsing, sibling scanning, suffix-less detection, skipped-file history, sibling merge on a transcribed file, failed job staying empty. Suite is 186 passed / 5 skipped.
Worth a look before merging
The skip behaviour changes: a bare
lecture.srtnext to a video now counts as an existing English transcript, where before it was invisible and the file got transcribed again. That is the requested rule, but it is a behaviour change for anyone relying on the old blindness — say the word if suffix-less files should inform history only and stay out of the skip decision.