Checkpoint

This commit is contained in:
Manav Rathi 2024-04-23 11:20:22 +05:30
parent 4a12774a3c
commit 1f5fbcae76
No known key found for this signature in database
2 changed files with 46 additions and 44 deletions

View file

@ -14,25 +14,26 @@ const maxThumbnailDimension = 720;
const maxThumbnailSize = 100 * 1024; // 100 KB
/**
* Generate a JPEG thumbnail for the given image or video data.
* Generate a JPEG thumbnail for the given image or video blob.
*
* The thumbnail has a smaller file size so that is quick to load. But more
* importantly, it uses a universal file format (JPEG in our case) so that the
* thumbnail itself can be opened in all clients, even those like the web client
* itself that might not yet have support for more exotic formats.
*
* @param blob The data (blob) of the file whose thumbnail we want to generate.
* @param fileTypeInfo The type information for the file.
* @param blob The image or video blob whose thumbnail we want to generate.
*
* @param fileTypeInfo The type information for the file this blob came from.
*
* @return The JPEG data of the generated thumbnail.
*/
export const generateThumbnail = async (
export const generateThumbnailWeb = async (
blob: Blob,
fileTypeInfo: FileTypeInfo,
): Promise<Uint8Array> =>
fileTypeInfo.fileType === FILE_TYPE.IMAGE
? await generateImageThumbnailUsingCanvas(blob, fileTypeInfo)
: await generateVideoThumbnail(blob);
: await generateVideoThumbnailWeb(blob);
const generateImageThumbnailUsingCanvas = async (
blob: Blob,
@ -74,12 +75,12 @@ const generateImageThumbnailUsingCanvas = async (
return await compressedJPEGData(canvas);
};
const generateVideoThumbnail = async (blob: Blob) => {
const generateVideoThumbnailWeb = async (blob: Blob) => {
try {
return await ffmpeg.generateVideoThumbnail(blob);
return await ffmpeg.generateVideoThumbnailWeb(blob);
} catch (e) {
log.error(
`Failed to generate video thumbnail using FFmpeg, will fallback to canvas`,
`Failed to generate video thumbnail using the wasm FFmpeg web worker, will fallback to canvas`,
e,
);
return generateVideoThumbnailUsingCanvas(blob);
@ -173,52 +174,35 @@ const percentageSizeDiff = (
) => ((oldThumbnailSize - newThumbnailSize) * 100) / oldThumbnailSize;
/**
* A fallback, black, thumbnail for use in cases where thumbnail generation
* fails.
*/
export const fallbackThumbnail = () =>
Uint8Array.from(atob(BLACK_THUMBNAIL_BASE64), (c) => c.charCodeAt(0));
/**
* Generate a JPEG thumbnail for the given file using native tools.
* Generate a JPEG thumbnail for the given file or path using native tools.
*
* This function only works when we're running in the context of our desktop
* app, and this dependency is enforced by the need to pass the {@link electron}
* object which we use to perform IPC with the Node.js side of our desktop app.
*
* @param fileOrPath Either the image or video File, or the path to the image or
* video file on the user's local filesystem, whose thumbnail we want to
* @param dataOrPath The image or video {@link File}, or the path to the image
* or video file on the user's local filesystem, whose thumbnail we want to
* generate.
*
* @param fileTypeInfo The type information for the file.
* @param fileTypeInfo The type information for {@link fileOrPath}.
*
* @return The JPEG data of the generated thumbnail.
*
* @see {@link generateThumbnail}.
* See also {@link generateThumbnailWeb}.
*/
export const generateThumbnailNative = async (
electron: Electron,
fileOrPath: File | string,
fileTypeInfo: FileTypeInfo,
): Promise<GeneratedThumbnail> => {
try {
const thumbnail =
fileTypeInfo.fileType === FILE_TYPE.IMAGE
? await generateImageThumbnailNative(electron, fileOrPath)
: await generateVideoThumbnail(blob);
if (thumbnail.length == 0) throw new Error("Empty thumbnail");
return { thumbnail, hasStaticThumbnail: false };
} catch (e) {
log.error(`Failed to generate ${fileTypeInfo.exactType} thumbnail`, e);
return { thumbnail: fallbackThumbnail(), hasStaticThumbnail: true };
}
};
): Promise<Uint8Array> =>
fileTypeInfo.fileType === FILE_TYPE.IMAGE
? await generateImageThumbnailNative(electron, fileOrPath)
: await generateVideoThumbnailNative(blob);
const generateImageThumbnailNative = async (
electron: Electron,
fileOrPath: File | string,
): Promise<Uint8Array> => {
) => {
const startTime = Date.now();
const jpegData = await electron.generateImageThumbnail(
fileOrPath instanceof File
@ -232,3 +216,19 @@ const generateImageThumbnailNative = async (
);
return jpegData;
};
const dataOrPath = (fileOrPath) => {
fileOrPath
}
const generateVideoThumbnailNative = async (
electron: Electron,
fileOrPath: File | string,
) => ffmpeg.generateVideoThumbnailNative(electron, )
/**
* A fallback, black, thumbnail for use in cases where thumbnail generation
* fails.
*/
export const fallbackThumbnail = () =>
Uint8Array.from(atob(BLACK_THUMBNAIL_BASE64), (c) => c.charCodeAt(0));

View file

@ -375,7 +375,6 @@ class ModuleState {
const moduleState = new ModuleState();
/**
* Read the given file or path into an in-memory representation.
*
@ -424,13 +423,19 @@ const moduleState = new ModuleState();
* we can do all the rest of the IPC operations using the path itself, and for
* the read during upload using a streaming IPC mechanism.
*/
async function readFile(
const readFileOrPath = async (
fileOrPath: File | string,
fileTypeInfo: FileTypeInfo,
): Promise<FileInMemory> {
): Promise<FileInMemory> => {
log.info(`Reading file ${fopLabel(fileOrPath)} `);
let thumbnail: Uint8Array
// If it's a file, read it into data
const dataOrPath =
fileOrPath instanceof File
? new Uint8Array(await fileOrPath.arrayBuffer())
: fileOrPath;
let thumbnail: Uint8Array;
const electron = globalThis.electron;
const available = !moduleState.isNativeThumbnailCreationNotAvailable;
@ -462,7 +467,6 @@ async function readFile(
filedata = await getUint8ArrayView(rawFile);
}
try {
const thumbnail =
fileTypeInfo.fileType === FILE_TYPE.IMAGE
@ -476,11 +480,9 @@ async function readFile(
return { thumbnail: fallbackThumbnail(), hasStaticThumbnail: true };
}
if (filedata instanceof Uint8Array) {
} else {
filedata.stream
filedata.stream;
}
log.info(`read file data successfully ${getFileNameSize(rawFile)} `);
@ -495,7 +497,7 @@ async function readFile(
thumbnail,
hasStaticThumbnail,
};
}
};
async function readLivePhoto(
fileTypeInfo: FileTypeInfo,