Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
37cfb375b8
|
|||
|
ea3d92974b
|
|||
|
0cb2a7739a
|
|||
|
5d82e92461
|
|||
|
151c719901
|
13
bun.lock
13
bun.lock
@@ -4,6 +4,9 @@
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "space-stream",
|
||||
"dependencies": {
|
||||
"jassub": "^2.4.2",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^7.0.0",
|
||||
"@sveltejs/adapter-cloudflare": "^7.2.8",
|
||||
@@ -272,6 +275,8 @@
|
||||
|
||||
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
|
||||
|
||||
"abslink": ["abslink@1.1.6", "", {}, "sha512-8fQgnUoVSgc1IhOrYzdDY+wTDPktbuYjds2LKf9kWYWKwDnHgXU168gdV3sPei7vevFf5m2fPZ6IQSKZkSjHVg=="],
|
||||
|
||||
"acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="],
|
||||
|
||||
"aria-query": ["aria-query@5.3.1", "", {}, "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g=="],
|
||||
@@ -314,10 +319,14 @@
|
||||
|
||||
"is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="],
|
||||
|
||||
"jassub": ["jassub@2.4.2", "", { "dependencies": { "abslink": "^1.1.6", "lfa-ponyfill": "^1.1.0", "rvfc-polyfill": "^1.0.8", "throughput": "^1.0.2" } }, "sha512-qWECKZWADUYAlXrzTEKPw+zY06XNy4tuZhTTWyk/ML+axRSMuOcbI0tAxL6tdXg+wdROd+EZU83SQFh/frugCg=="],
|
||||
|
||||
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
|
||||
|
||||
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
|
||||
|
||||
"lfa-ponyfill": ["lfa-ponyfill@1.1.0", "", {}, "sha512-YS3/DmyDdywWwoEu1ZacAudqkJ4q7WtKE9+bWlaSuEoVrXva7ChIJHMJYs19zyVc1H198pzqAreQU0r/+YNeew=="],
|
||||
|
||||
"lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
|
||||
|
||||
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
|
||||
@@ -382,6 +391,8 @@
|
||||
|
||||
"rollup": ["rollup@4.60.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.1", "@rollup/rollup-android-arm64": "4.60.1", "@rollup/rollup-darwin-arm64": "4.60.1", "@rollup/rollup-darwin-x64": "4.60.1", "@rollup/rollup-freebsd-arm64": "4.60.1", "@rollup/rollup-freebsd-x64": "4.60.1", "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", "@rollup/rollup-linux-arm-musleabihf": "4.60.1", "@rollup/rollup-linux-arm64-gnu": "4.60.1", "@rollup/rollup-linux-arm64-musl": "4.60.1", "@rollup/rollup-linux-loong64-gnu": "4.60.1", "@rollup/rollup-linux-loong64-musl": "4.60.1", "@rollup/rollup-linux-ppc64-gnu": "4.60.1", "@rollup/rollup-linux-ppc64-musl": "4.60.1", "@rollup/rollup-linux-riscv64-gnu": "4.60.1", "@rollup/rollup-linux-riscv64-musl": "4.60.1", "@rollup/rollup-linux-s390x-gnu": "4.60.1", "@rollup/rollup-linux-x64-gnu": "4.60.1", "@rollup/rollup-linux-x64-musl": "4.60.1", "@rollup/rollup-openbsd-x64": "4.60.1", "@rollup/rollup-openharmony-arm64": "4.60.1", "@rollup/rollup-win32-arm64-msvc": "4.60.1", "@rollup/rollup-win32-ia32-msvc": "4.60.1", "@rollup/rollup-win32-x64-gnu": "4.60.1", "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w=="],
|
||||
|
||||
"rvfc-polyfill": ["rvfc-polyfill@1.0.8", "", {}, "sha512-uA+0wwTkZ4OT8v45pfDfH+7Yq8mY6MvNngiF5Sq6VBgjJsvsfgt7Q18cyZqZjfAhW9rhkgXPX0cW0R9uw7yElA=="],
|
||||
|
||||
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
|
||||
|
||||
"safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="],
|
||||
@@ -410,6 +421,8 @@
|
||||
|
||||
"tapable": ["tapable@2.3.2", "", {}, "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA=="],
|
||||
|
||||
"throughput": ["throughput@1.0.2", "", {}, "sha512-jvK1ZXuhsggjb3qYQjMiU/AVYYiTeqT5thWvYR2yuy2LGM84P5MSSyAinwHahGsdBYKR9m9HncVR/3f3nFKkxg=="],
|
||||
|
||||
"tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="],
|
||||
|
||||
"totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="],
|
||||
|
||||
@@ -36,5 +36,8 @@
|
||||
"vite": "^7.3.1",
|
||||
"vite-plugin-devtools-json": "^1.0.0",
|
||||
"wrangler": "^4.81.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"jassub": "^2.4.2"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
src/lib/assets/fonts/AdobeArabic-Bold.otf
Normal file
BIN
src/lib/assets/fonts/AdobeArabic-Bold.otf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/AdobeArabic-BoldItalic.otf
Normal file
BIN
src/lib/assets/fonts/AdobeArabic-BoldItalic.otf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/Tahoma_0.ttf
Normal file
BIN
src/lib/assets/fonts/Tahoma_0.ttf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/arialbd_3.ttf
Normal file
BIN
src/lib/assets/fonts/arialbd_3.ttf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/arialbi_2.ttf
Normal file
BIN
src/lib/assets/fonts/arialbi_2.ttf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/ariblk_1.TTF
Normal file
BIN
src/lib/assets/fonts/ariblk_1.TTF
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/georgia_0.ttf
Normal file
BIN
src/lib/assets/fonts/georgia_0.ttf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/georgiab_0.ttf
Normal file
BIN
src/lib/assets/fonts/georgiab_0.ttf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/timesbd_3.ttf
Normal file
BIN
src/lib/assets/fonts/timesbd_3.ttf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/trebuc_0.ttf
Normal file
BIN
src/lib/assets/fonts/trebuc_0.ttf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/trebucbd_0.ttf
Normal file
BIN
src/lib/assets/fonts/trebucbd_0.ttf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/trebucbi_0.ttf
Normal file
BIN
src/lib/assets/fonts/trebucbi_0.ttf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/trebucit_0.ttf
Normal file
BIN
src/lib/assets/fonts/trebucit_0.ttf
Normal file
Binary file not shown.
BIN
src/lib/assets/fonts/verdanab_0.ttf
Normal file
BIN
src/lib/assets/fonts/verdanab_0.ttf
Normal file
Binary file not shown.
@@ -1,6 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { useSpacetimeDB, useTable, useReducer } from "spacetimedb/svelte";
|
||||
import { tables, reducers } from "$lib/st-bindings";
|
||||
import JASSUB from "jassub";
|
||||
import font1 from "$lib/assets/fonts/trebuc_0.ttf";
|
||||
|
||||
const conn = useSpacetimeDB();
|
||||
|
||||
@@ -14,11 +16,30 @@
|
||||
const seekReducer = useReducer(reducers.seek);
|
||||
|
||||
let videoElement: HTMLVideoElement | undefined = $state();
|
||||
let containerElement: HTMLDivElement | undefined = $state();
|
||||
let newUrl = $state("");
|
||||
let newSubtitleUrl = $state("");
|
||||
|
||||
let isSyncing = false;
|
||||
let syncTimeout: ReturnType<typeof setTimeout> | undefined;
|
||||
let jassubInstance: any | undefined;
|
||||
let currentSubtitleUrl = $derived(videoState?.subtitleUrl);
|
||||
|
||||
$effect(() => {
|
||||
console.log("effect-1");
|
||||
if (videoElement && currentSubtitleUrl && currentSubtitleUrl.endsWith(".ass")) {
|
||||
jassubInstance = new JASSUB({
|
||||
video: videoElement,
|
||||
subUrl: currentSubtitleUrl,
|
||||
fonts: [font1],
|
||||
});
|
||||
|
||||
return () => {
|
||||
jassubInstance?.destroy();
|
||||
jassubInstance = undefined;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
function syncAction(fn: () => void) {
|
||||
isSyncing = true;
|
||||
@@ -30,6 +51,7 @@
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
console.log("effect-2");
|
||||
if (!videoElement || !videoState) return;
|
||||
const el = videoElement;
|
||||
const state = videoState;
|
||||
@@ -120,6 +142,14 @@
|
||||
setSubtitleUrlReducer({ url: newSubtitleUrl });
|
||||
newSubtitleUrl = "";
|
||||
}
|
||||
|
||||
function toggleFullscreen() {
|
||||
if (!document.fullscreenElement) {
|
||||
containerElement?.requestFullscreen().catch(console.error);
|
||||
} else {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="p-4">
|
||||
@@ -146,7 +176,7 @@
|
||||
<form onsubmit={handleSetSubtitle} class="mb-2">
|
||||
<input
|
||||
type="url"
|
||||
placeholder="Enter subtitle track URL (.vtt)"
|
||||
placeholder="Enter subtitle track URL (.vtt/.ass)"
|
||||
bind:value={newSubtitleUrl}
|
||||
class="mr-2 w-96 p-2"
|
||||
/>
|
||||
@@ -154,22 +184,60 @@
|
||||
</form>
|
||||
|
||||
<div>
|
||||
<!-- svelte-ignore a11y_media_has_caption -->
|
||||
<video
|
||||
bind:this={videoElement}
|
||||
muted
|
||||
controls
|
||||
crossorigin="anonymous"
|
||||
onplay={handlePlay}
|
||||
onpause={handlePause}
|
||||
onseeked={handleSeeked}
|
||||
ontimeupdate={handleTimeUpdate}
|
||||
class="w-full max-w-2xl bg-black"
|
||||
<div
|
||||
bind:this={containerElement}
|
||||
class="fullscreen-container relative w-full max-w-2xl bg-black"
|
||||
>
|
||||
{#if videoState?.subtitleUrl}
|
||||
<track src={videoState.subtitleUrl} kind="subtitles" srclang="en" label="English" default />
|
||||
{/if}
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
<!-- svelte-ignore a11y_media_has_caption -->
|
||||
<video
|
||||
bind:this={videoElement}
|
||||
muted
|
||||
controls
|
||||
controlslist="nofullscreen"
|
||||
crossorigin="anonymous"
|
||||
onplay={handlePlay}
|
||||
onpause={handlePause}
|
||||
onseeked={handleSeeked}
|
||||
ontimeupdate={handleTimeUpdate}
|
||||
ondblclick={toggleFullscreen}
|
||||
class="h-full w-full"
|
||||
>
|
||||
{#if videoState?.subtitleUrl && !videoState.subtitleUrl.endsWith(".ass")}
|
||||
<track
|
||||
src={videoState.subtitleUrl}
|
||||
kind="subtitles"
|
||||
srclang="en"
|
||||
label="English"
|
||||
default
|
||||
/>
|
||||
{/if}
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
<button
|
||||
onclick={toggleFullscreen}
|
||||
class="absolute top-2 right-2 z-50 rounded bg-black/70 px-2 py-1 text-xs text-white opacity-50 transition-opacity hover:opacity-100"
|
||||
>
|
||||
Fullscreen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(.JASSUB) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
:global(.fullscreen-container:fullscreen) {
|
||||
max-width: none !important;
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
:global(.fullscreen-container:fullscreen video) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,4 +3,12 @@ import tailwindcss from "@tailwindcss/vite";
|
||||
import { sveltekit } from "@sveltejs/kit/vite";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig({ plugins: [tailwindcss(), sveltekit(), devtoolsJson()] });
|
||||
export default defineConfig({
|
||||
plugins: [tailwindcss(), sveltekit(), devtoolsJson()],
|
||||
optimizeDeps: {
|
||||
// for some reason this specific combination of
|
||||
// includes/excludes is required for jassub to work
|
||||
exclude: ["jassub"],
|
||||
include: ["throughput"],
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user