From a9bcb882120da7565cbf342d9ff2d0b75027e15c Mon Sep 17 00:00:00 2001 From: Mitchell-Johnson Date: Sun, 11 Oct 2026 16:40:42 -0700 Subject: [PATCH] Files: play video and audio in the viewer, as the file is; reads answer Range requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The viewer hands a video or audio file to the browser untouched — container, codec and all — and the browser plays what it can; when it can't, the viewer says so and offers the download. What the server adds is the part a player needs: /api/files/read now goes through http.ServeContent for a real file of known size, so Range requests (seeking) and HEAD work, and a download can resume. The root backend's helper takes an offset for that, and a Seeker opens the backend once, at the range asked for, instead of streaming from the top. Audio files are a preview kind too: their cover art is the thumbnail. Co-Authored-By: Claude Fable 5.1 --- internal/api/files_test.go | 62 ++++++++++++++++++++ internal/api/server.go | 33 +++++++---- internal/files/files.go | 32 ++++++++++- internal/files/seek.go | 89 ++++++++++++++++++++++++++++ internal/files/seek_test.go | 112 ++++++++++++++++++++++++++++++++++++ internal/thumbs/thumbs.go | 6 +- web/src/Files.tsx | 18 +++++- web/src/api.ts | 2 +- web/src/styles.css | 8 ++- 9 files changed, 343 insertions(+), 19 deletions(-) create mode 100644 internal/api/files_test.go create mode 100644 internal/files/seek.go create mode 100644 internal/files/seek_test.go diff --git a/internal/api/files_test.go b/internal/api/files_test.go new file mode 100644 index 0000000..06fcaea --- /dev/null +++ b/internal/api/files_test.go @@ -0,0 +1,62 @@ +package api + +import ( + "net/http/httptest" + "net/url" + "os" + "path/filepath" + "testing" + + "hamlab/internal/files" +) + +// A file read answers Range requests — what a