update component and add video

This commit is contained in:
polv committed 2026-03-30 16:46:48 +07:00
1 parent 9f5f3a8e14
commit bdc54b676b
4 files changed
+959 -44

No files matched your search

+42 -36
View File
@@ -24,53 +24,60 @@ function onSubmit(ev: SubmitEvent) {
ev.preventDefault();
if (!q.value) return;
videoSrc.value = "/" + q.value;
const src = "/" + q.value;
const isSameSrc = videoSrc.value === src;
videoSrc.value = src;
if (isSameSrc) {
// Force load
onVideoLoad();
}
}
function onVideoLoad() {
const ws = new WebSocket("ws://localhost:8080");
const vid = videoEl.value!;
const q_value = q.value;
ws.onmessage = (ev) => {
const { name, ts } = JSON.parse(ev.data);
switch (name) {
case "seek_q_ts": (async () => {
for (const t of ts) {
const b = await new Promise<Blob | null>((resolve) => {
vid.onseeked = () => {
const v = videoEl.value!;
let c = document.createElement("canvas");
c.height = v.videoHeight || parseInt(v.style.height);
c.width = v.videoWidth || parseInt(v.style.width);
const ctx = c.getContext("2d")!;
ctx.drawImage(v, 0, 0);
case "seek_q_ts":
(async () => {
for (const t of ts) {
const b = await new Promise<Blob | null>((resolve) => {
vid.onseeked = () => {
const v = videoEl.value!;
let c = document.createElement("canvas");
c.height = v.videoHeight || parseInt(v.style.height);
c.width = v.videoWidth || parseInt(v.style.width);
const ctx = c.getContext("2d")!;
ctx.drawImage(v, 0, 0);
ws.send(
JSON.stringify({
name: "timed_q",
q: q_value,
t,
}),
);
ws.send(
JSON.stringify({
name: "timed_q",
q: q_value,
t,
}),
);
c.toBlob((b) => resolve(b));
}
c.toBlob((b) => resolve(b));
};
if (typeof t === 'string'){
const [min, sec] = t.split('_');
vid.currentTime = parseInt(min) * 60 + parseInt(sec) + 1;
} else {
vid.currentTime = t;
}
})
if (b) ws.send(b);
vid.onseeked = null;
}
ws.send(JSON.stringify({ name: 'done', q: q_value }));
})(); break;
if (typeof t === "string") {
const [min, sec] = t.split("_");
vid.currentTime = parseInt(min) * 60 + parseInt(sec) + 1;
} else {
vid.currentTime = t;
}
});
if (b) ws.send(b);
vid.onseeked = null;
}
ws.send(JSON.stringify({ name: "done", q: q_value }));
})();
break;
}
};
@@ -84,8 +91,7 @@ function onVideoLoad() {
);
};
ws.onclose = () => {
};
ws.onclose = () => {};
}
</script>
+16 -8
View File
@@ -13,10 +13,8 @@ const videoURL = computed(() => frontmatter.value?.video);
const videoEl = useTemplateRef("video");
function setImgClick() {
const v = videoEl.value;
if (!v) {
return;
}
document.removeEventListener("click", imgClickListener);
document.addEventListener("click", imgClickListener);
document.querySelectorAll("img").forEach((img) => {
const [, min, sec] = /^(\d+)\:(\d+)$/.exec(img.alt) || [];
@@ -24,13 +22,23 @@ function setImgClick() {
if (!t) return;
img.title = img.title || img.alt;
img.onclick = () => {
v.currentTime = t;
};
});
}
function imgClickListener(ev: PointerEvent) {
if (!(ev.target instanceof HTMLImageElement)) return;
const img = ev.target;
if (!videoEl.value) return;
const v = videoEl.value;
const [, min, sec] = /^(\d+)\:(\d+)$/.exec(img.alt) || [];
const t = min && sec ? parseInt(min) * 60 + parseInt(sec) : null;
if (!t) return;
v.currentTime = t;
}
watch(videoURL, () => {
setImgClick();
});