mirror of
https://github.com/immich-app/immich.git
synced 2024-11-24 08:52:28 +02:00
fix(deps): exiftool-vendored (#11338)
This commit is contained in:
parent
9e60c107ca
commit
9f6ef92f0b
@ -1137,7 +1137,7 @@ describe('/asset', () => {
|
|||||||
type: AssetTypeEnum.Image,
|
type: AssetTypeEnum.Image,
|
||||||
originalFileName: '14bit-uncompressed-(3_2).arw',
|
originalFileName: '14bit-uncompressed-(3_2).arw',
|
||||||
resized: true,
|
resized: true,
|
||||||
fileCreatedAt: '2016-01-08T15:08:01.000Z',
|
fileCreatedAt: '2016-01-08T14:08:01.000Z',
|
||||||
exifInfo: {
|
exifInfo: {
|
||||||
make: 'SONY',
|
make: 'SONY',
|
||||||
model: 'ILCE-7M2',
|
model: 'ILCE-7M2',
|
||||||
@ -1149,7 +1149,7 @@ describe('/asset', () => {
|
|||||||
iso: 100,
|
iso: 100,
|
||||||
lensModel: 'E 25mm F2',
|
lensModel: 'E 25mm F2',
|
||||||
fileSizeInByte: 49_512_448,
|
fileSizeInByte: 49_512_448,
|
||||||
dateTimeOriginal: '2016-01-08T15:08:01.000Z',
|
dateTimeOriginal: '2016-01-08T14:08:01.000Z',
|
||||||
latitude: null,
|
latitude: null,
|
||||||
longitude: null,
|
longitude: null,
|
||||||
orientation: '1',
|
orientation: '1',
|
||||||
|
46
server/package-lock.json
generated
46
server/package-lock.json
generated
@ -34,7 +34,7 @@
|
|||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.0",
|
"class-validator": "^0.14.0",
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"exiftool-vendored": "26.0.0",
|
"exiftool-vendored": "^28.1.0",
|
||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
"fluent-ffmpeg": "^2.1.2",
|
"fluent-ffmpeg": "^2.1.2",
|
||||||
"geo-tz": "^8.0.0",
|
"geo-tz": "^8.0.0",
|
||||||
@ -9549,9 +9549,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/exiftool-vendored": {
|
"node_modules/exiftool-vendored": {
|
||||||
"version": "26.0.0",
|
"version": "28.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-26.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-28.1.0.tgz",
|
||||||
"integrity": "sha512-2TRxx21ovD95VvdSzHb/sTYYcwhiizQIhhVAbrgua9KoL902QRieREGvaUtfBZNjsptdjonuyku2kUBJCPqsgw==",
|
"integrity": "sha512-Anlfl16gv0QuaNbkMuwutCfhzzPn/33Lio2fKCgIHk4m+udz5dsatwv1+tjk4eDMNT1Oj/zwG3hKhSX5zlHzAw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@photostructure/tz-lookup": "^10.0.0",
|
"@photostructure/tz-lookup": "^10.0.0",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
@ -9560,23 +9560,23 @@
|
|||||||
"luxon": "^3.4.4"
|
"luxon": "^3.4.4"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"exiftool-vendored.exe": "12.84.0",
|
"exiftool-vendored.exe": "12.89.0",
|
||||||
"exiftool-vendored.pl": "12.84.0"
|
"exiftool-vendored.pl": "12.89.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/exiftool-vendored.exe": {
|
"node_modules/exiftool-vendored.exe": {
|
||||||
"version": "12.84.0",
|
"version": "12.89.0",
|
||||||
"resolved": "https://registry.npmjs.org/exiftool-vendored.exe/-/exiftool-vendored.exe-12.84.0.tgz",
|
"resolved": "https://registry.npmjs.org/exiftool-vendored.exe/-/exiftool-vendored.exe-12.89.0.tgz",
|
||||||
"integrity": "sha512-9ocqJb0Pr9k0TownEMd75payF/XOQLF/swr/l0Ep49D+m609uIZsW09CtowhXmk1KrIFobS3+SkdXK04CSyUwQ==",
|
"integrity": "sha512-GyayTRwH6v/3SCV7g80zV5oMw66AQFnPJVfPc/At9PMAe90/9N7GCM1o6U1FGOpa1ZvmSm38RvvBEMr667vnnw==",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"win32"
|
"win32"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/exiftool-vendored.pl": {
|
"node_modules/exiftool-vendored.pl": {
|
||||||
"version": "12.84.0",
|
"version": "12.89.0",
|
||||||
"resolved": "https://registry.npmjs.org/exiftool-vendored.pl/-/exiftool-vendored.pl-12.84.0.tgz",
|
"resolved": "https://registry.npmjs.org/exiftool-vendored.pl/-/exiftool-vendored.pl-12.89.0.tgz",
|
||||||
"integrity": "sha512-TxvMRaVYtd24Vupn48zy24LOYItIIWEu4dgt/VlqLwxQItTpvJTV9YH04iZRvaNh9ZdPRgVKWMuuUDBBHv+lAg==",
|
"integrity": "sha512-pkkWBRmeylUEAfBOg/e6NO8dZ572yDA6kTsnw1gGiAhJUxgoLGP+ageuOD6Oxywag5/HFcT2syJ+L1/ch5hjfg==",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
"!win32"
|
"!win32"
|
||||||
@ -23433,29 +23433,29 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exiftool-vendored": {
|
"exiftool-vendored": {
|
||||||
"version": "26.0.0",
|
"version": "28.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-26.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-28.1.0.tgz",
|
||||||
"integrity": "sha512-2TRxx21ovD95VvdSzHb/sTYYcwhiizQIhhVAbrgua9KoL902QRieREGvaUtfBZNjsptdjonuyku2kUBJCPqsgw==",
|
"integrity": "sha512-Anlfl16gv0QuaNbkMuwutCfhzzPn/33Lio2fKCgIHk4m+udz5dsatwv1+tjk4eDMNT1Oj/zwG3hKhSX5zlHzAw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@photostructure/tz-lookup": "^10.0.0",
|
"@photostructure/tz-lookup": "^10.0.0",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
"batch-cluster": "^13.0.0",
|
"batch-cluster": "^13.0.0",
|
||||||
"exiftool-vendored.exe": "12.84.0",
|
"exiftool-vendored.exe": "12.89.0",
|
||||||
"exiftool-vendored.pl": "12.84.0",
|
"exiftool-vendored.pl": "12.89.0",
|
||||||
"he": "^1.2.0",
|
"he": "^1.2.0",
|
||||||
"luxon": "^3.4.4"
|
"luxon": "^3.4.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exiftool-vendored.exe": {
|
"exiftool-vendored.exe": {
|
||||||
"version": "12.84.0",
|
"version": "12.89.0",
|
||||||
"resolved": "https://registry.npmjs.org/exiftool-vendored.exe/-/exiftool-vendored.exe-12.84.0.tgz",
|
"resolved": "https://registry.npmjs.org/exiftool-vendored.exe/-/exiftool-vendored.exe-12.89.0.tgz",
|
||||||
"integrity": "sha512-9ocqJb0Pr9k0TownEMd75payF/XOQLF/swr/l0Ep49D+m609uIZsW09CtowhXmk1KrIFobS3+SkdXK04CSyUwQ==",
|
"integrity": "sha512-GyayTRwH6v/3SCV7g80zV5oMw66AQFnPJVfPc/At9PMAe90/9N7GCM1o6U1FGOpa1ZvmSm38RvvBEMr667vnnw==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"exiftool-vendored.pl": {
|
"exiftool-vendored.pl": {
|
||||||
"version": "12.84.0",
|
"version": "12.89.0",
|
||||||
"resolved": "https://registry.npmjs.org/exiftool-vendored.pl/-/exiftool-vendored.pl-12.84.0.tgz",
|
"resolved": "https://registry.npmjs.org/exiftool-vendored.pl/-/exiftool-vendored.pl-12.89.0.tgz",
|
||||||
"integrity": "sha512-TxvMRaVYtd24Vupn48zy24LOYItIIWEu4dgt/VlqLwxQItTpvJTV9YH04iZRvaNh9ZdPRgVKWMuuUDBBHv+lAg==",
|
"integrity": "sha512-pkkWBRmeylUEAfBOg/e6NO8dZ572yDA6kTsnw1gGiAhJUxgoLGP+ageuOD6Oxywag5/HFcT2syJ+L1/ch5hjfg==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"express": {
|
"express": {
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.0",
|
"class-validator": "^0.14.0",
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"exiftool-vendored": "26.0.0",
|
"exiftool-vendored": "^28.1.0",
|
||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
"fluent-ffmpeg": "^2.1.2",
|
"fluent-ffmpeg": "^2.1.2",
|
||||||
"geo-tz": "^8.0.0",
|
"geo-tz": "^8.0.0",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { DefaultReadTaskOptions, Tags, exiftool } from 'exiftool-vendored';
|
import { DefaultReadTaskOptions, ExifTool, Tags } from 'exiftool-vendored';
|
||||||
import geotz from 'geo-tz';
|
import geotz from 'geo-tz';
|
||||||
import { DummyValue, GenerateSql } from 'src/decorators';
|
import { DummyValue, GenerateSql } from 'src/decorators';
|
||||||
import { ExifEntity } from 'src/entities/exif.entity';
|
import { ExifEntity } from 'src/entities/exif.entity';
|
||||||
@ -12,6 +12,19 @@ import { Repository } from 'typeorm';
|
|||||||
@Instrumentation()
|
@Instrumentation()
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MetadataRepository implements IMetadataRepository {
|
export class MetadataRepository implements IMetadataRepository {
|
||||||
|
private exiftool = new ExifTool({
|
||||||
|
defaultVideosToUTC: true,
|
||||||
|
backfillTimezones: true,
|
||||||
|
inferTimezoneFromDatestamps: true,
|
||||||
|
useMWG: true,
|
||||||
|
numericTags: [...DefaultReadTaskOptions.numericTags, 'FocalLength'],
|
||||||
|
/* eslint unicorn/no-array-callback-reference: off, unicorn/no-array-method-this-argument: off */
|
||||||
|
geoTz: (lat, lon) => geotz.find(lat, lon)[0],
|
||||||
|
// Enable exiftool LFS to parse metadata for files larger than 2GB.
|
||||||
|
readArgs: ['-api', 'largefilesupport=1'],
|
||||||
|
writeArgs: ['-api', 'largefilesupport=1', '-overwrite_original'],
|
||||||
|
});
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(ExifEntity) private exifRepository: Repository<ExifEntity>,
|
@InjectRepository(ExifEntity) private exifRepository: Repository<ExifEntity>,
|
||||||
@Inject(ILoggerRepository) private logger: ILoggerRepository,
|
@Inject(ILoggerRepository) private logger: ILoggerRepository,
|
||||||
@ -20,37 +33,23 @@ export class MetadataRepository implements IMetadataRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async teardown() {
|
async teardown() {
|
||||||
await exiftool.end();
|
await this.exiftool.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
readTags(path: string): Promise<ImmichTags | null> {
|
readTags(path: string): Promise<ImmichTags | null> {
|
||||||
return exiftool
|
return this.exiftool.read(path).catch((error) => {
|
||||||
.read(path, undefined, {
|
this.logger.warn(`Error reading exif data (${path}): ${error}`, error?.stack);
|
||||||
...DefaultReadTaskOptions,
|
return null;
|
||||||
|
}) as Promise<ImmichTags | null>;
|
||||||
// Enable exiftool LFS to parse metadata for files larger than 2GB.
|
|
||||||
optionalArgs: ['-api', 'largefilesupport=1'],
|
|
||||||
defaultVideosToUTC: true,
|
|
||||||
backfillTimezones: true,
|
|
||||||
inferTimezoneFromDatestamps: true,
|
|
||||||
useMWG: true,
|
|
||||||
numericTags: [...DefaultReadTaskOptions.numericTags, 'FocalLength'],
|
|
||||||
/* eslint unicorn/no-array-callback-reference: off, unicorn/no-array-method-this-argument: off */
|
|
||||||
geoTz: (lat, lon) => geotz.find(lat, lon)[0],
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
this.logger.warn(`Error reading exif data (${path}): ${error}`, error?.stack);
|
|
||||||
return null;
|
|
||||||
}) as Promise<ImmichTags | null>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extractBinaryTag(path: string, tagName: string): Promise<Buffer> {
|
extractBinaryTag(path: string, tagName: string): Promise<Buffer> {
|
||||||
return exiftool.extractBinaryTagToBuffer(tagName, path);
|
return this.exiftool.extractBinaryTagToBuffer(tagName, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
async writeTags(path: string, tags: Partial<Tags>): Promise<void> {
|
async writeTags(path: string, tags: Partial<Tags>): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await exiftool.write(path, tags, ['-overwrite_original']);
|
await this.exiftool.write(path, tags);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.warn(`Error writing exif data (${path}): ${error}`);
|
this.logger.warn(`Error writing exif data (${path}): ${error}`);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { ExifDateTime, Tags } from 'exiftool-vendored';
|
import { ContainerDirectoryItem, ExifDateTime, Tags } from 'exiftool-vendored';
|
||||||
import { firstDateTime } from 'exiftool-vendored/dist/FirstDateTime';
|
import { firstDateTime } from 'exiftool-vendored/dist/FirstDateTime';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { Duration } from 'luxon';
|
import { Duration } from 'luxon';
|
||||||
@ -48,17 +48,6 @@ const EXIF_DATE_TAGS: Array<keyof Tags> = [
|
|||||||
'DateTimeCreated',
|
'DateTimeCreated',
|
||||||
];
|
];
|
||||||
|
|
||||||
interface DirectoryItem {
|
|
||||||
Length?: number;
|
|
||||||
Mime: string;
|
|
||||||
Padding?: number;
|
|
||||||
Semantic?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DirectoryEntry {
|
|
||||||
Item: DirectoryItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum Orientation {
|
export enum Orientation {
|
||||||
Horizontal = '1',
|
Horizontal = '1',
|
||||||
MirrorHorizontal = '2',
|
MirrorHorizontal = '2',
|
||||||
@ -362,13 +351,14 @@ export class MetadataService implements OnEvents {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawDirectory = tags.Directory;
|
|
||||||
const isMotionPhoto = tags.MotionPhoto;
|
const isMotionPhoto = tags.MotionPhoto;
|
||||||
const isMicroVideo = tags.MicroVideo;
|
const isMicroVideo = tags.MicroVideo;
|
||||||
const videoOffset = tags.MicroVideoOffset;
|
const videoOffset = tags.MicroVideoOffset;
|
||||||
const hasMotionPhotoVideo = tags.MotionPhotoVideo;
|
const hasMotionPhotoVideo = tags.MotionPhotoVideo;
|
||||||
const hasEmbeddedVideoFile = tags.EmbeddedVideoType === 'MotionPhoto_Data' && tags.EmbeddedVideoFile;
|
const hasEmbeddedVideoFile = tags.EmbeddedVideoType === 'MotionPhoto_Data' && tags.EmbeddedVideoFile;
|
||||||
const directory = Array.isArray(rawDirectory) ? (rawDirectory as DirectoryEntry[]) : null;
|
const directory = Array.isArray(tags.ContainerDirectory)
|
||||||
|
? (tags.ContainerDirectory as ContainerDirectoryItem[])
|
||||||
|
: null;
|
||||||
|
|
||||||
let length = 0;
|
let length = 0;
|
||||||
let padding = 0;
|
let padding = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user