HEIC convert

This commit is contained in:
Manav Rathi 2024-05-09 21:11:17 +05:30
parent 8167e353f0
commit ebb05e4bdf
No known key found for this signature in database
2 changed files with 36 additions and 5 deletions

View file

@ -2,8 +2,11 @@ import { FILE_TYPE } from "@/media/file-type";
import { isNonWebImageFileExtension } from "@/media/formats";
import { scaledImageDimensions } from "@/media/image";
import { decodeLivePhoto } from "@/media/live-photo";
import { createHEICConvertComlinkWorker } from "@/media/worker/heic-convert";
import type { DedicatedHEICConvertWorker } from "@/media/worker/heic-convert.worker";
import { nameAndExtension } from "@/next/file";
import log from "@/next/log";
import type { ComlinkWorker } from "@/next/worker/comlink-worker";
import { shuffled } from "@/utils/array";
import { ensure } from "@/utils/ensure";
import { wait } from "@/utils/promise";
@ -51,6 +54,12 @@ type RenderableImageURLPair = [url: string, nextURL: string];
*/
let isChromecast = false;
/**
* If we're using HEIC conversion, then this variable caches the comlink web
* worker we're using to perform the actual conversion.
*/
let heicWorker: ComlinkWorker<typeof DedicatedHEICConvertWorker> | undefined;
/**
* An async generator function that loops through all the files in the
* collection, returning renderable URLs to each that can be displayed in a
@ -285,8 +294,8 @@ const isFileEligible = (file: EnteFile) => {
const [, extension] = nameAndExtension(file.metadata.title);
if (isNonWebImageFileExtension(extension)) {
if (isChromecast) return false;
// TODO(MR): HEIC support otherwise
return false;
// HEIC support otherwise.
return isHEIC(extension);
}
return true;
@ -297,6 +306,17 @@ const isImageOrLivePhoto = (file: EnteFile) => {
return fileType == FILE_TYPE.IMAGE || fileType == FILE_TYPE.LIVE_PHOTO;
};
const isHEIC = (extension: string) => {
const ext = extension.toLowerCase();
return ext == "heic" || ext == "heif";
};
export const heicToJPEG = async (heicBlob: Blob) => {
let worker = heicWorker;
if (!worker) heicWorker = worker = createHEICConvertComlinkWorker();
return await (await worker.remote).heicToJPEG(heicBlob);
};
/**
* Create and return a new data URL that can be used to show the given
* {@link file} in our slideshow image viewer.
@ -311,12 +331,23 @@ const createRenderableURL = async (castToken: string, file: EnteFile) => {
};
const renderableImageBlob = async (castToken: string, file: EnteFile) => {
const fileName = file.metadata.title;
let fileName = file.metadata.title;
let blob = await downloadFile(castToken, file);
if (file.metadata.fileType === FILE_TYPE.LIVE_PHOTO) {
const { imageData } = await decodeLivePhoto(fileName, blob);
const { imageData, imageFileName } = await decodeLivePhoto(
fileName,
blob,
);
fileName = imageFileName;
blob = new Blob([imageData]);
}
const [, ext] = nameAndExtension(fileName);
if (isHEIC(ext)) {
blob = await heicToJPEG(blob);
}
const mimeType = await detectMediaMIMEType(new File([blob], fileName));
if (!mimeType)
throw new Error(`Could not detect MIME type for file ${fileName}`);

View file

@ -2,7 +2,7 @@ import { ComlinkWorker } from "@/next/worker/comlink-worker";
import type { DedicatedHEICConvertWorker } from "./heic-convert.worker";
export const createHEICConvertWebWorker = () =>
new Worker(new URL("worker/heic-convert.worker.ts", import.meta.url));
new Worker(new URL("heic-convert.worker.ts", import.meta.url));
export const createHEICConvertComlinkWorker = () =>
new ComlinkWorker<typeof DedicatedHEICConvertWorker>(