diff --git a/README.md b/README.md index e37f2a7..2b0bd41 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,9 @@ video the first time you hover, in a single quick ffmpeg pass, and keeps it in memory so nothing is written to disk. If you already have your own sprite, point the `/scrub` route at it instead. +Hover previews are on by default. If you would rather not build them at all, start +the server with `--no-thumbnails` and the rest of the player keeps working. + ### 4. Run directly in Terminal (Standalone) If you prefer to bypass the web interface, you can render the video directly inside an ANSI-supported terminal (zero-flicker, true color): ```bash diff --git a/stream_server.py b/stream_server.py index 83d7a23..0ddb5c3 100644 --- a/stream_server.py +++ b/stream_server.py @@ -310,6 +310,9 @@ async def scrub_meta(v: int | None = None): loop) the first time it's asked for, then reuses it from memory.""" from fastapi import Response import json as _json + # Thumbnails are on by default; --no-thumbnails turns the whole thing off. + if not getattr(app.state, "thumbnails", True): + return Response(content='{"available": false}', media_type="application/json") video_path = _scrub_video_path(v) if not video_path or not os.path.exists(video_path): return Response(content='{"available": false}', media_type="application/json") @@ -757,6 +760,12 @@ if __name__ == "__main__": help="Adaptive-codec colour fidelity (lossless = bit-exact; lower = " "smaller stream via lossy temporal delta). Chars always exact." ) + playback.add_argument( + "--no-thumbnails", + action="store_true", default=False, + help="Turn off the hover thumbnails on the seek bar (skips building the " + "preview sprite). The rest of the player still works." + ) # ── Server ── srv = parser.add_argument_group('\033[33mServer\033[0m') @@ -784,6 +793,7 @@ if __name__ == "__main__": app.state.loop = args.loop app.state.tolerance = {"lossless": 0, "high": 4, "balanced": 8, "low": 16}[args.quality] app.state.debug = args.debug + app.state.thumbnails = not args.no_thumbnails global_default_cols = args.cols if args.cols is not None else (450 if args.pixel else 200) app.state.cols = global_default_cols app.state.rows = args.rows diff --git a/test/test_scrub.py b/test/test_scrub.py index 345b1a3..b2851dd 100644 --- a/test/test_scrub.py +++ b/test/test_scrub.py @@ -78,6 +78,14 @@ class ScrubTests(unittest.TestCase): finally: ss.app.state.queue = [_entry(self.video)] + def test_thumbnails_can_be_disabled(self): + ss.app.state.thumbnails = False + try: + body = json.loads(asyncio.run(ss.scrub_meta(0)).body) + self.assertFalse(body["available"]) + finally: + ss.app.state.thumbnails = True + def test_sprite_404_before_it_is_built(self): from fastapi import HTTPException ss._scrub_cache.clear()