108 lines
2.3 KiB
Vue
108 lines
2.3 KiB
Vue
<template>
|
|
<form @submit="onSubmit">
|
|
<input type="text" v-model="q" />
|
|
<button type="submit">Submit</button>
|
|
|
|
<video
|
|
v-if="videoSrc"
|
|
controls
|
|
ref="video"
|
|
:src="videoSrc"
|
|
@loadeddata="onVideoLoad"
|
|
></video>
|
|
</form>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, useTemplateRef } from "vue";
|
|
|
|
const q = ref("");
|
|
const videoSrc = ref("");
|
|
const videoEl = useTemplateRef("video");
|
|
|
|
function onSubmit(ev: SubmitEvent) {
|
|
ev.preventDefault();
|
|
if (!q.value) return;
|
|
|
|
videoSrc.value = "/" + q.value;
|
|
}
|
|
|
|
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);
|
|
|
|
ws.send(
|
|
JSON.stringify({
|
|
name: "timed_q",
|
|
q: q_value,
|
|
t,
|
|
}),
|
|
);
|
|
|
|
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;
|
|
}
|
|
};
|
|
|
|
ws.onopen = async () => {
|
|
ws.send(
|
|
JSON.stringify({
|
|
name: "download_q",
|
|
q: q_value,
|
|
duration: vid.duration,
|
|
}),
|
|
);
|
|
};
|
|
|
|
ws.onclose = () => {
|
|
};
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
form {
|
|
margin: 0.5em 0;
|
|
}
|
|
|
|
form * {
|
|
border: 1px solid gray;
|
|
}
|
|
|
|
button {
|
|
margin-left: 0.5em;
|
|
cursor: pointer;
|
|
padding: 0 0.5em;
|
|
border-radius: 5px;
|
|
}
|
|
</style>
|