drbh commited on
Commit
099a07c
·
unverified ·
1 Parent(s): 0046e76

fix: adjust video seek

Browse files
Files changed (2) hide show
  1. backend/server.py +34 -6
  2. ui/static/app.js +4 -2
backend/server.py CHANGED
@@ -110,6 +110,12 @@ def _resolve_path(requested: str) -> Path | None:
110
 
111
 
112
  class Handler(BaseHTTPRequestHandler):
 
 
 
 
 
 
113
  def log_message(self, fmt, *args):
114
  sys.stderr.write(f"[backend] {self.address_string()} - {fmt % args}\n")
115
 
@@ -128,12 +134,34 @@ class Handler(BaseHTTPRequestHandler):
128
  return
129
  ctype, _ = mimetypes.guess_type(str(path))
130
  ctype = ctype or "application/octet-stream"
131
- data = path.read_bytes()
132
- self.send_response(status)
133
- self.send_header("Content-Type", ctype)
134
- self.send_header("Content-Length", str(len(data)))
135
- self.end_headers()
136
- self.wfile.write(data)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
  def _run_search(self, modality: str, query: str, top_k: int):
139
  fn = SEARCHERS.get(modality)
 
110
 
111
 
112
  class Handler(BaseHTTPRequestHandler):
113
+ def handle(self):
114
+ try:
115
+ super().handle()
116
+ except BrokenPipeError:
117
+ pass
118
+
119
  def log_message(self, fmt, *args):
120
  sys.stderr.write(f"[backend] {self.address_string()} - {fmt % args}\n")
121
 
 
134
  return
135
  ctype, _ = mimetypes.guess_type(str(path))
136
  ctype = ctype or "application/octet-stream"
137
+ size = path.stat().st_size
138
+ range_hdr = self.headers.get("Range")
139
+ if range_hdr and range_hdr.startswith("bytes="):
140
+ # Parse byte range (only single ranges supported).
141
+ spec = range_hdr[len("bytes="):]
142
+ start_s, _, end_s = spec.partition("-")
143
+ start = int(start_s) if start_s else 0
144
+ end = int(end_s) if end_s else size - 1
145
+ end = min(end, size - 1)
146
+ length = end - start + 1
147
+ with open(path, "rb") as f:
148
+ f.seek(start)
149
+ data = f.read(length)
150
+ self.send_response(206)
151
+ self.send_header("Content-Type", ctype)
152
+ self.send_header("Content-Range", f"bytes {start}-{end}/{size}")
153
+ self.send_header("Content-Length", str(length))
154
+ self.send_header("Accept-Ranges", "bytes")
155
+ self.end_headers()
156
+ self.wfile.write(data)
157
+ else:
158
+ data = path.read_bytes()
159
+ self.send_response(status)
160
+ self.send_header("Content-Type", ctype)
161
+ self.send_header("Content-Length", str(len(data)))
162
+ self.send_header("Accept-Ranges", "bytes")
163
+ self.end_headers()
164
+ self.wfile.write(data)
165
 
166
  def _run_search(self, modality: str, query: str, top_k: int):
167
  fn = SEARCHERS.get(modality)
ui/static/app.js CHANGED
@@ -251,12 +251,14 @@ function makeCard(hit, kind, modality, dark) {
251
  thumb.rel = "noopener";
252
  const v = document.createElement("video");
253
  v.muted = true;
254
- v.preload = "metadata";
255
- v.addEventListener("loadeddata", () => v.classList.add("loaded"));
256
  if (timestamp != null) {
257
  v.addEventListener("loadedmetadata", () => {
258
  try { v.currentTime = timestamp; } catch (_) {}
259
  });
 
 
 
260
  }
261
  v.src = fileUrl(filePath) + frag;
262
  thumb.appendChild(v);
 
251
  thumb.rel = "noopener";
252
  const v = document.createElement("video");
253
  v.muted = true;
254
+ v.preload = "auto";
 
255
  if (timestamp != null) {
256
  v.addEventListener("loadedmetadata", () => {
257
  try { v.currentTime = timestamp; } catch (_) {}
258
  });
259
+ v.addEventListener("seeked", () => v.classList.add("loaded"));
260
+ } else {
261
+ v.addEventListener("loadeddata", () => v.classList.add("loaded"));
262
  }
263
  v.src = fileUrl(filePath) + frag;
264
  thumb.appendChild(v);