feat: add seedance media params and model visibility

This commit is contained in:
stupid-h4er
2026-05-27 13:02:36 +08:00
parent 871bedc072
commit 4bffb55695
25 changed files with 873 additions and 140 deletions
+14 -4
View File
@@ -3,7 +3,7 @@
import localforage from "localforage";
import { nanoid } from "nanoid";
export type UploadedFile = { url: string; storageKey: string; bytes: number; mimeType: string; width?: number; height?: number };
export type UploadedFile = { url: string; storageKey: string; bytes: number; mimeType: string; width?: number; height?: number; durationMs?: number };
const store = localforage.createInstance({ name: "infinite-canvas", storeName: "media_files" });
const objectUrls = new Map<string, string>();
@@ -14,7 +14,7 @@ export async function uploadMediaFile(input: string | Blob, prefix = "file"): Pr
await store.setItem(storageKey, blob);
const url = URL.createObjectURL(blob);
objectUrls.set(storageKey, url);
const meta = blob.type.startsWith("video/") ? await readVideoMeta(url) : {};
const meta = blob.type.startsWith("video/") ? await readVideoMeta(url) : blob.type.startsWith("audio/") ? await readAudioMeta(url) : {};
return { url, storageKey, bytes: blob.size, mimeType: blob.type || "application/octet-stream", ...meta };
}
@@ -68,11 +68,21 @@ export function collectMediaStorageKeys(value: unknown, keys = new Set<string>()
}
function readVideoMeta(url: string) {
return new Promise<{ width: number; height: number }>((resolve) => {
return new Promise<{ width: number; height: number; durationMs?: number }>((resolve) => {
const video = document.createElement("video");
const done = () => resolve({ width: video.videoWidth || 1280, height: video.videoHeight || 720 });
const done = () => resolve({ width: video.videoWidth || 1280, height: video.videoHeight || 720, durationMs: Number.isFinite(video.duration) ? Math.round(video.duration * 1000) : undefined });
video.onloadedmetadata = done;
video.onerror = done;
video.src = url;
});
}
function readAudioMeta(url: string) {
return new Promise<{ durationMs?: number }>((resolve) => {
const audio = document.createElement("audio");
const done = () => resolve({ durationMs: Number.isFinite(audio.duration) ? Math.round(audio.duration * 1000) : undefined });
audio.onloadedmetadata = done;
audio.onerror = done;
audio.src = url;
});
}