feat: audio metadata

This commit is contained in:
not-nullptr 2024-11-14 19:23:54 +00:00
parent a7e2ecda57
commit 1328cdcb05
4 changed files with 147 additions and 58 deletions

View File

@ -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"
} }
} }

View File

@ -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"

View File

@ -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);
}; };
}, },
); );

View File

@ -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>