feat(media): extract workspace package
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
export interface MediaDimensions {
|
||||
height: number
|
||||
width: number
|
||||
}
|
||||
|
||||
const METADATA_TIMEOUT_MS = 10_000
|
||||
|
||||
function waitForDimensions(
|
||||
file: File,
|
||||
element: HTMLImageElement | HTMLVideoElement,
|
||||
successEvent: "load" | "loadedmetadata"
|
||||
): Promise<MediaDimensions | undefined> {
|
||||
return new Promise((resolve) => {
|
||||
const objectUrl = URL.createObjectURL(file)
|
||||
let settled = false
|
||||
const timeout = window.setTimeout(finish, METADATA_TIMEOUT_MS)
|
||||
|
||||
function finish(dimensions?: MediaDimensions) {
|
||||
if (settled) return
|
||||
settled = true
|
||||
window.clearTimeout(timeout)
|
||||
URL.revokeObjectURL(objectUrl)
|
||||
resolve(dimensions)
|
||||
}
|
||||
|
||||
element.addEventListener(
|
||||
successEvent,
|
||||
() => {
|
||||
const width =
|
||||
element instanceof HTMLVideoElement
|
||||
? element.videoWidth
|
||||
: element.naturalWidth
|
||||
const height =
|
||||
element instanceof HTMLVideoElement
|
||||
? element.videoHeight
|
||||
: element.naturalHeight
|
||||
finish(width > 0 && height > 0 ? { height, width } : undefined)
|
||||
},
|
||||
{ once: true }
|
||||
)
|
||||
element.addEventListener("error", () => finish(), { once: true })
|
||||
element.src = objectUrl
|
||||
})
|
||||
}
|
||||
|
||||
/** Reads intrinsic dimensions before an adapter uploads an image or video. */
|
||||
export function readMediaDimensions(
|
||||
file: File
|
||||
): Promise<MediaDimensions | undefined> {
|
||||
if (file.type.startsWith("image/")) {
|
||||
return waitForDimensions(file, new Image(), "load")
|
||||
}
|
||||
if (file.type.startsWith("video/")) {
|
||||
const video = document.createElement("video")
|
||||
video.preload = "metadata"
|
||||
return waitForDimensions(file, video, "loadedmetadata")
|
||||
}
|
||||
return Promise.resolve(undefined)
|
||||
}
|
||||
Reference in New Issue
Block a user