mirror of
https://github.com/immich-app/immich.git
synced 2025-05-24 01:12:58 -04:00
don't fallback to exiftool for embedded image previews (#2747)
Given #2668 introduced support for imagemagick and libraw, this should no longer be necessary which allow for reduced code footprint and complexity. Fixes: #2744
This commit is contained in:
parent
1cbf9ff621
commit
3b4f6edbdb
@ -45,7 +45,6 @@ export interface TranscodeOptions {
|
|||||||
|
|
||||||
export interface IMediaRepository {
|
export interface IMediaRepository {
|
||||||
// image
|
// image
|
||||||
extractThumbnailFromExif(input: string, output: string): Promise<void>;
|
|
||||||
resize(input: string | Buffer, output: string, options: ResizeOptions): Promise<void>;
|
resize(input: string | Buffer, output: string, options: ResizeOptions): Promise<void>;
|
||||||
crop(input: string, options: CropOptions): Promise<Buffer>;
|
crop(input: string, options: CropOptions): Promise<Buffer>;
|
||||||
|
|
||||||
|
@ -81,28 +81,6 @@ describe(MediaService.name, () => {
|
|||||||
size: 1440,
|
size: 1440,
|
||||||
format: 'jpeg',
|
format: 'jpeg',
|
||||||
});
|
});
|
||||||
expect(mediaMock.extractThumbnailFromExif).not.toHaveBeenCalled();
|
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
|
||||||
id: 'asset-id',
|
|
||||||
resizePath: 'upload/thumbs/user-id/asset-id.jpeg',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should generate a thumbnail for an image from exif', async () => {
|
|
||||||
assetMock.getByIds.mockResolvedValue([assetEntityStub.image]);
|
|
||||||
mediaMock.resize.mockRejectedValue(new Error('unsupported format'));
|
|
||||||
|
|
||||||
await sut.handleGenerateJpegThumbnail({ id: assetEntityStub.image.id });
|
|
||||||
|
|
||||||
expect(storageMock.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id');
|
|
||||||
expect(mediaMock.resize).toHaveBeenCalledWith('/original/path.ext', 'upload/thumbs/user-id/asset-id.jpeg', {
|
|
||||||
size: 1440,
|
|
||||||
format: 'jpeg',
|
|
||||||
});
|
|
||||||
expect(mediaMock.extractThumbnailFromExif).toHaveBeenCalledWith(
|
|
||||||
'/original/path.ext',
|
|
||||||
'upload/thumbs/user-id/asset-id.jpeg',
|
|
||||||
);
|
|
||||||
expect(assetMock.save).toHaveBeenCalledWith({
|
expect(assetMock.save).toHaveBeenCalledWith({
|
||||||
id: 'asset-id',
|
id: 'asset-id',
|
||||||
resizePath: 'upload/thumbs/user-id/asset-id.jpeg',
|
resizePath: 'upload/thumbs/user-id/asset-id.jpeg',
|
||||||
|
@ -54,24 +54,18 @@ export class MediaService {
|
|||||||
this.storageRepository.mkdirSync(resizePath);
|
this.storageRepository.mkdirSync(resizePath);
|
||||||
const jpegThumbnailPath = join(resizePath, `${asset.id}.jpeg`);
|
const jpegThumbnailPath = join(resizePath, `${asset.id}.jpeg`);
|
||||||
|
|
||||||
if (asset.type == AssetType.IMAGE) {
|
switch (asset.type) {
|
||||||
try {
|
case AssetType.IMAGE:
|
||||||
await this.mediaRepository.resize(asset.originalPath, jpegThumbnailPath, {
|
await this.mediaRepository.resize(asset.originalPath, jpegThumbnailPath, {
|
||||||
size: JPEG_THUMBNAIL_SIZE,
|
size: JPEG_THUMBNAIL_SIZE,
|
||||||
format: 'jpeg',
|
format: 'jpeg',
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
break;
|
||||||
this.logger.warn(
|
case AssetType.VIDEO:
|
||||||
`Failed to generate jpeg thumbnail using sharp, trying with exiftool-vendored (asset=${asset.id}): ${error.message}`,
|
this.logger.log('Generating video thumbnail');
|
||||||
);
|
await this.mediaRepository.extractVideoThumbnail(asset.originalPath, jpegThumbnailPath, JPEG_THUMBNAIL_SIZE);
|
||||||
await this.mediaRepository.extractThumbnailFromExif(asset.originalPath, jpegThumbnailPath);
|
this.logger.log(`Successfully generated video thumbnail ${asset.id}`);
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (asset.type == AssetType.VIDEO) {
|
|
||||||
this.logger.log('Start Generating Video Thumbnail');
|
|
||||||
await this.mediaRepository.extractVideoThumbnail(asset.originalPath, jpegThumbnailPath, JPEG_THUMBNAIL_SIZE);
|
|
||||||
this.logger.log(`Generating Video Thumbnail Success ${asset.id}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.assetRepository.save({ id: asset.id, resizePath: jpegThumbnailPath });
|
await this.assetRepository.save({ id: asset.id, resizePath: jpegThumbnailPath });
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { CropOptions, IMediaRepository, ResizeOptions, TranscodeOptions, VideoInfo } from '@app/domain';
|
import { CropOptions, IMediaRepository, ResizeOptions, TranscodeOptions, VideoInfo } from '@app/domain';
|
||||||
import { exiftool } from 'exiftool-vendored';
|
|
||||||
import ffmpeg, { FfprobeData } from 'fluent-ffmpeg';
|
import ffmpeg, { FfprobeData } from 'fluent-ffmpeg';
|
||||||
import sharp from 'sharp';
|
import sharp from 'sharp';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
@ -19,10 +18,6 @@ export class MediaRepository implements IMediaRepository {
|
|||||||
.toBuffer();
|
.toBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
extractThumbnailFromExif(input: string, output: string): Promise<void> {
|
|
||||||
return exiftool.extractThumbnail(input, output);
|
|
||||||
}
|
|
||||||
|
|
||||||
async resize(input: string | Buffer, output: string, options: ResizeOptions): Promise<void> {
|
async resize(input: string | Buffer, output: string, options: ResizeOptions): Promise<void> {
|
||||||
switch (options.format) {
|
switch (options.format) {
|
||||||
case 'webp':
|
case 'webp':
|
||||||
|
@ -2,7 +2,6 @@ import { IMediaRepository } from '@app/domain';
|
|||||||
|
|
||||||
export const newMediaRepositoryMock = (): jest.Mocked<IMediaRepository> => {
|
export const newMediaRepositoryMock = (): jest.Mocked<IMediaRepository> => {
|
||||||
return {
|
return {
|
||||||
extractThumbnailFromExif: jest.fn(),
|
|
||||||
extractVideoThumbnail: jest.fn(),
|
extractVideoThumbnail: jest.fn(),
|
||||||
resize: jest.fn(),
|
resize: jest.fn(),
|
||||||
crop: jest.fn(),
|
crop: jest.fn(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user