diff --git a/index.html b/index.html
index 7bb8612..46d6d5a 100644
--- a/index.html
+++ b/index.html
@@ -188,7 +188,7 @@
const S = {
user: null, q: "", mode: "sub", entry: null, episodes: [], ep: null,
last: null, playToken: 0, hls: null, prefetch: null, lastSave: 0, ended: false,
- resumeAt: 0, retried: false,
+ resumeAt: 0, retried: false, canSave: false,
};
const video = $("video");
@@ -388,6 +388,7 @@
S.resumeAt = opts.resume !== undefined ? opts.resume :
(S.last && S.last.episode === ep && S.last.duration > 0 && S.last.position > 10 &&
S.last.position < S.last.duration - 30 ? S.last.position : 0);
+ S.canSave = false; // don't overwrite the saved time with 0:00 while the stream is still loading
renderEpisodes();
$("wSub").textContent = `Episode ${ep} of ${S.episodes.length} ยท ${S.mode}`;
if (S.hls) { S.hls.destroy(); S.hls = null; }
@@ -415,15 +416,23 @@
if (info.subtitle) {
video.append(el("track", { kind: "subtitles", label: "Subtitles", srclang: "en", src: info.subtitle, default: true }));
}
+ const target = S.resumeAt > 1 ? S.resumeAt : 0;
+ S.resumeAt = 0;
+ const settle = () => { // called once playback really runs at the resumed position
+ if (token !== S.playToken || S.canSave) return;
+ if (target && video.currentTime < target - 5) { try { video.currentTime = target; } catch {} }
+ S.canSave = true;
+ };
+ if (target) video.addEventListener("playing", settle, { once: true });
const onReady = () => {
if (token !== S.playToken) return;
hideOverlay();
- if (S.resumeAt > 0) { try { video.currentTime = S.resumeAt; } catch {} S.resumeAt = 0; }
+ if (target && !(S.hls)) { try { video.currentTime = target; } catch {} } // MP4 / native HLS
video.play().catch(() => showOverlay("Press play to start.", false, null));
- saveProgress(true);
+ if (!target) { S.canSave = true; saveProgress(true); } // new episode: record it as the last watched
};
if (info.kind === "hls" && window.Hls && Hls.isSupported()) {
- const hls = new Hls({ maxBufferLength: 40 });
+ const hls = new Hls({ maxBufferLength: 40, startPosition: target || -1 });
S.hls = hls;
hls.loadSource(info.src);
hls.attachMedia(video);
@@ -489,8 +498,9 @@
video.addEventListener("pause", () => { if (!video.ended) saveProgress(true); });
function saveProgress(force, keepalive) {
- if (!S.user || !S.entry || !S.ep) return;
+ if (!S.user || !S.entry || !S.ep || !S.canSave) return;
const pos = video.currentTime || 0, dur = video.duration || 0;
+ S.last = { episode: S.ep, position: Number.isFinite(pos) ? pos : 0, duration: Number.isFinite(dur) ? dur : 0 };
// while a new episode is still loading there's no position to report; record the start of it
S.lastSave = Date.now();
api("/api/progress", { method: "POST", keepalive: !!keepalive, body: {
@@ -524,4 +534,4 @@
})();