feat(server): generate all thumbnails for an asset in one job (#13012)

* wip

cleanup

add success logs, rename method

do thumbhash too

fixes

fix tests

handle `notify`

wip refactor

refactor

* update tests

* update sql

* pr feedback

* remove unused code

* formatting
This commit is contained in:
Mert
2024-09-28 13:47:24 -04:00
committed by GitHub
parent 995f0fda47
commit 2bcd27e166
22 changed files with 574 additions and 542 deletions

View File

@@ -141,6 +141,12 @@ export interface AssetUpdateDuplicateOptions {
duplicateIds: string[];
}
export interface UpsertFileOptions {
assetId: string;
type: AssetFileType;
path: string;
}
export type AssetPathEntity = Pick<AssetEntity, 'id' | 'originalPath' | 'isOffline'>;
export const IAssetRepository = 'IAssetRepository';
@@ -194,5 +200,6 @@ export interface IAssetRepository {
getDuplicates(options: AssetBuilderOptions): Promise<AssetEntity[]>;
getAllForUserFullSync(options: AssetFullSyncOptions): Promise<AssetEntity[]>;
getChangedDeltaSync(options: AssetDeltaSyncOptions): Promise<AssetEntity[]>;
upsertFile(options: { assetId: string; type: AssetFileType; path: string }): Promise<void>;
upsertFile(file: UpsertFileOptions): Promise<void>;
upsertFiles(files: UpsertFileOptions[]): Promise<void>;
}

View File

@@ -37,9 +37,7 @@ export enum JobName {
// thumbnails
QUEUE_GENERATE_THUMBNAILS = 'queue-generate-thumbnails',
GENERATE_PREVIEW = 'generate-preview',
GENERATE_THUMBNAIL = 'generate-thumbnail',
GENERATE_THUMBHASH = 'generate-thumbhash',
GENERATE_THUMBNAILS = 'generate-thumbnails',
GENERATE_PERSON_THUMBNAIL = 'generate-person-thumbnail',
// metadata
@@ -212,9 +210,7 @@ export type JobItem =
// Thumbnails
| { name: JobName.QUEUE_GENERATE_THUMBNAILS; data: IBaseJob }
| { name: JobName.GENERATE_PREVIEW; data: IEntityJob }
| { name: JobName.GENERATE_THUMBNAIL; data: IEntityJob }
| { name: JobName.GENERATE_THUMBHASH; data: IEntityJob }
| { name: JobName.GENERATE_THUMBNAILS; data: IEntityJob }
// User
| { name: JobName.USER_DELETE_CHECK; data?: IBaseJob }

View File

@@ -10,16 +10,44 @@ export interface CropOptions {
height: number;
}
export interface ImageOutputConfig {
export interface ImageOptions {
format: ImageFormat;
quality: number;
size: number;
}
export interface ThumbnailOptions extends ImageOutputConfig {
export interface RawImageInfo {
width: number;
height: number;
channels: 1 | 2 | 3 | 4;
}
interface DecodeImageOptions {
colorspace: string;
crop?: CropOptions;
processInvalidImages: boolean;
raw?: RawImageInfo;
}
export interface DecodeToBufferOptions extends DecodeImageOptions {
size: number;
}
export type GenerateThumbnailOptions = ImageOptions & DecodeImageOptions;
export type GenerateThumbnailFromBufferOptions = GenerateThumbnailOptions & { raw: RawImageInfo };
export type GenerateThumbhashOptions = DecodeImageOptions;
export type GenerateThumbhashFromBufferOptions = GenerateThumbhashOptions & { raw: RawImageInfo };
export interface GenerateThumbnailsOptions {
colorspace: string;
crop?: CropOptions;
preview?: ImageOptions;
processInvalidImages: boolean;
thumbhash?: boolean;
thumbnail?: ImageOptions;
}
export interface VideoStreamInfo {
@@ -78,6 +106,11 @@ export interface BitrateDistribution {
unit: string;
}
export interface ImageBuffer {
data: Buffer;
info: RawImageInfo;
}
export interface VideoCodecSWConfig {
getCommand(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream: AudioStreamInfo): TranscodeCommand;
}
@@ -93,8 +126,11 @@ export interface ProbeOptions {
export interface IMediaRepository {
// image
extract(input: string, output: string): Promise<boolean>;
generateThumbnail(input: string | Buffer, output: string, options: ThumbnailOptions): Promise<void>;
generateThumbhash(imagePath: string): Promise<Buffer>;
decodeImage(input: string, options: DecodeToBufferOptions): Promise<ImageBuffer>;
generateThumbnail(input: string, options: GenerateThumbnailOptions, outputFile: string): Promise<void>;
generateThumbnail(input: Buffer, options: GenerateThumbnailFromBufferOptions, outputFile: string): Promise<void>;
generateThumbhash(input: string, options: GenerateThumbhashOptions): Promise<Buffer>;
generateThumbhash(input: Buffer, options: GenerateThumbhashFromBufferOptions): Promise<Buffer>;
getImageDimensions(input: string): Promise<ImageDimensions>;
// video