mirror of https://github.com/VERT-sh/VERT.git
feat: audio metadata
This commit is contained in:
parent
a7e2ecda57
commit
1328cdcb05
|
@ -17,6 +17,7 @@
|
||||||
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
||||||
"@types/eslint": "^9.6.0",
|
"@types/eslint": "^9.6.0",
|
||||||
"@types/js-cookie": "^3.0.6",
|
"@types/js-cookie": "^3.0.6",
|
||||||
|
"@types/jsmediatags": "^3.9.6",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"eslint": "^9.7.0",
|
"eslint": "^9.7.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
@ -42,8 +43,12 @@
|
||||||
"client-zip": "^2.4.5",
|
"client-zip": "^2.4.5",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
|
"jsmediatags": "^3.9.7",
|
||||||
"lucide-svelte": "^0.456.0",
|
"lucide-svelte": "^0.456.0",
|
||||||
"svelte-adapter-bun": "^0.5.2",
|
"svelte-adapter-bun": "^0.5.2",
|
||||||
"wasm-vips": "^0.0.11"
|
"wasm-vips": "^0.0.11"
|
||||||
|
},
|
||||||
|
"patchedDependencies": {
|
||||||
|
"jsmediatags@3.9.7": "patches/jsmediatags@3.9.7.patch"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
diff --git a/package.json b/package.json
|
||||||
|
index 1265c61a16be5dc94dea97e1a7bcd117b0b5c0fe..602a37452738d778bf705b7a2931a661e363e33c 100644
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -18,8 +18,8 @@
|
||||||
|
"email": "jesse.ditson@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
- "main": "build2/jsmediatags.js",
|
||||||
|
- "browser": "dist/jsmediatags.js",
|
||||||
|
+ "main": "dist/jsmediatags.min.js",
|
||||||
|
+ "browser": "dist/jsmediatags.min.js",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/aadsm/jsmediatags.git"
|
|
@ -6,6 +6,8 @@
|
||||||
import { files } from "$lib/store/index.svelte";
|
import { files } from "$lib/store/index.svelte";
|
||||||
import { VertFile } from "$lib/types/file.svelte";
|
import { VertFile } from "$lib/types/file.svelte";
|
||||||
import { Check } from "lucide-svelte";
|
import { Check } from "lucide-svelte";
|
||||||
|
import jsmediatags from "jsmediatags";
|
||||||
|
import type { TagType } from "jsmediatags/types/index.js";
|
||||||
|
|
||||||
const { data } = $props();
|
const { data } = $props();
|
||||||
|
|
||||||
|
@ -59,7 +61,53 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
img.onerror = async () => {
|
img.onerror = async () => {
|
||||||
resolve(new VertFile(f, to, converter));
|
// resolve(new VertFile(f, to, converter));
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = async (e) => {
|
||||||
|
try {
|
||||||
|
const tags = await new Promise<TagType>(
|
||||||
|
(resolve, reject) => {
|
||||||
|
jsmediatags.read(
|
||||||
|
new Blob([
|
||||||
|
new Uint8Array(
|
||||||
|
e.target
|
||||||
|
?.result as ArrayBuffer,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
{
|
||||||
|
onSuccess: (tag) =>
|
||||||
|
resolve(tag),
|
||||||
|
onError: (error) =>
|
||||||
|
reject(error),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
console.log(tags);
|
||||||
|
const picture = tags.tags.picture;
|
||||||
|
if (!picture) {
|
||||||
|
resolve(new VertFile(f, to, converter));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const blob = new Blob(
|
||||||
|
[new Uint8Array(picture.data)],
|
||||||
|
{
|
||||||
|
type: picture.format,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
resolve(
|
||||||
|
new VertFile(
|
||||||
|
f,
|
||||||
|
to,
|
||||||
|
converter,
|
||||||
|
URL.createObjectURL(blob),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
resolve(new VertFile(f, to, converter));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.readAsArrayBuffer(f);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
import { files } from "$lib/store/index.svelte";
|
import { files } from "$lib/store/index.svelte";
|
||||||
import type { VertFile } from "$lib/types";
|
import type { VertFile } from "$lib/types";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { ArrowRight, XIcon } from "lucide-svelte";
|
import { ArrowRight, Disc2Icon, FileAudioIcon, XIcon } from "lucide-svelte";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import { quintOut } from "svelte/easing";
|
import { quintOut } from "svelte/easing";
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class={clsx(
|
class={clsx(
|
||||||
"flex relative flex-shrink-0 items-center w-full rounded-xl h-32",
|
"flex relative flex-shrink-0 items-center w-full rounded-xl h-72",
|
||||||
{
|
{
|
||||||
"initial-fade": !finisheds[i],
|
"initial-fade": !finisheds[i],
|
||||||
},
|
},
|
||||||
|
@ -270,17 +270,19 @@
|
||||||
<div class="w-full flex-shrink-0">
|
<div class="w-full flex-shrink-0">
|
||||||
<div
|
<div
|
||||||
class={clsx(
|
class={clsx(
|
||||||
"py-3 px-4 w-full flex transition-colors duration-300 flex-shrink text-left border-b-2 border-solid border-foreground-muted-alt rounded-tl-[9.5px] rounded-tr-[10px] overflow-hidden",
|
"py-3 dynadark:[--transparency:50%] [--transparency:25%] px-4 w-full flex transition-colors duration-300 flex-shrink text-left border-b-2 border-solid border-foreground-muted-alt rounded-tl-[9.5px] rounded-tr-[10px] overflow-hidden",
|
||||||
{
|
{
|
||||||
"bg-accent-background text-accent-foreground":
|
"text-accent-foreground":
|
||||||
file.result,
|
file.result,
|
||||||
"bg-background text-foreground":
|
"text-foreground": !file.result,
|
||||||
!file.result,
|
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
|
style="background-color: color-mix(in srgb, var(--{file.result
|
||||||
|
? 'accent-bg'
|
||||||
|
: 'bg'}), transparent var(--transparency)); backdrop-filter: blur(18px);"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="w-full grid grid-cols-1 grid-rows-"
|
class="w-full grid grid-cols-1 grid-rows-1"
|
||||||
>
|
>
|
||||||
{#if processings[files.files.length - i - 1]}
|
{#if processings[files.files.length - i - 1]}
|
||||||
<div
|
<div
|
||||||
|
@ -340,47 +342,53 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="flex items-center gap-3 justify-normal flex-grow w-full h-full"
|
class="flex gap-3 justify-normal flex-grow w-full h-full"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex flex-col items-center gap-3 w-full"
|
class="flex flex-col items-end gap-3 w-full"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex items-center gap-3 w-full h-full px-5"
|
class="flex items-end gap-3 w-full h-full px-5"
|
||||||
>
|
>
|
||||||
{#if converter && converter.supportedFormats.includes(file.from)}
|
<div
|
||||||
<span>from</span>
|
class="flex items-center justify-center gap-3 w-full pb-4"
|
||||||
<span
|
>
|
||||||
class="py-2 px-3 font-display bg-foreground text-background rounded-xl"
|
{#if converter && converter.supportedFormats.includes(file.from)}
|
||||||
>{file.from}</span
|
<span>from</span>
|
||||||
>
|
<span
|
||||||
<span>to</span>
|
class="py-2 px-3 font-display bg-foreground text-background rounded-xl"
|
||||||
<div class="inline-flex">
|
>{file.from}</span
|
||||||
<Dropdown
|
>
|
||||||
options={converter.supportedFormats}
|
<span>to</span>
|
||||||
bind:selected={files
|
<div class="inline-flex">
|
||||||
.files[
|
<Dropdown
|
||||||
files.files.length -
|
options={converter.supportedFormats}
|
||||||
i -
|
bind:selected={files
|
||||||
1
|
.files[
|
||||||
].to}
|
files.files
|
||||||
onselect={() => {
|
.length -
|
||||||
file.result = null;
|
i -
|
||||||
}}
|
1
|
||||||
/>
|
].to}
|
||||||
</div>
|
onselect={() => {
|
||||||
{:else}
|
file.result =
|
||||||
<span
|
null;
|
||||||
class="py-2 px-3 font-display bg-foreground-failure text-white rounded-xl"
|
}}
|
||||||
>{file.from}</span
|
/>
|
||||||
>
|
</div>
|
||||||
|
{:else}
|
||||||
|
<span
|
||||||
|
class="py-2 px-3 font-display bg-foreground-failure text-white rounded-xl"
|
||||||
|
>{file.from}</span
|
||||||
|
>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
class="text-foreground-failure"
|
class="text-foreground-failure"
|
||||||
>
|
>
|
||||||
is not supported!
|
is not supported!
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div
|
<!-- <div
|
||||||
class="hidden lg:flex gap-4 w-full"
|
class="hidden lg:flex gap-4 w-full"
|
||||||
|
@ -405,22 +413,35 @@
|
||||||
{#if converter && converter.supportedFormats.includes(file.from)}
|
{#if converter && converter.supportedFormats.includes(file.from)}
|
||||||
<!-- god knows why, but setting opacity > 0.98 causes a z-ordering issue in firefox ??? -->
|
<!-- god knows why, but setting opacity > 0.98 causes a z-ordering issue in firefox ??? -->
|
||||||
<div
|
<div
|
||||||
class="absolute top-0 -z-50 left-0 w-full h-full opacity-[0.98] rounded-[9px] overflow-hidden"
|
class="absolute top-[0px] -z-50 left-0 w-full h-full opacity-[0.98] rounded-xl overflow-hidden"
|
||||||
>
|
>
|
||||||
<div
|
{#if file.blobUrl}
|
||||||
class="bg-cover bg-center w-full h-full"
|
<div
|
||||||
style="background-image: url({file.blobUrl});"
|
class="bg-cover bg-center w-full h-full"
|
||||||
></div>
|
style="background-image: url({file.blobUrl});"
|
||||||
<div
|
></div>
|
||||||
class="absolute left-0 bottom-0 h-5/6 w-full"
|
<div
|
||||||
>
|
class="absolute left-0 top-0 pt-[50px] h-full w-full"
|
||||||
<ProgressiveBlur
|
>
|
||||||
direction="left"
|
<ProgressiveBlur
|
||||||
endIntensity={64}
|
direction="bottom"
|
||||||
iterations={6}
|
endIntensity={64}
|
||||||
fadeTo="var(--bg-transparent)"
|
iterations={8}
|
||||||
/>
|
fadeTo="var(--bg-transparent)"
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div
|
||||||
|
class="w-full h-full flex items-center justify-center"
|
||||||
|
>
|
||||||
|
<FileAudioIcon
|
||||||
|
size="96"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
color="var(--fg)"
|
||||||
|
opacity="0.9"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue