mirror of
https://github.com/immich-app/immich.git
synced 2024-11-24 08:52:28 +02:00
chore(server): update exiftool and migrate off deprecated method signatures (#10367)
* chore(server): update exiftool and migrate off deprecated method signatures * chore(server): update exiftool-vendored to 27.0.0 * chore(server): switch away from deprecated exiftool method signatures - options now includes read/writeArgs making the deprecated signatures with args array redundant - switch read call from file,args,options to file,options - switch write call from file,tags,args to file,tags,options * chore(server): move largefilesupport flags into exiftool constructor - options now includes read/writeArgs making it available to be set globally in constructor - switches back to instantiating an instance of exiftool * chore(server): consolidate exiftool config into constructor along with writeArgs * chore(server): move exiftool instantiation into MetadataRepository constructor
This commit is contained in:
parent
38e26fd67c
commit
1b67ea2d91
15
server/package-lock.json
generated
15
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.2.0",
|
"exiftool-vendored": "~27.0.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",
|
||||||
@ -9127,9 +9127,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/exiftool-vendored": {
|
"node_modules/exiftool-vendored": {
|
||||||
"version": "26.2.0",
|
"version": "27.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-26.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-27.0.0.tgz",
|
||||||
"integrity": "sha512-7P6jQ944or7ic2SJzW+uaWK4TLDXlaCppHrBayl4MpIrVcEeQjiQTez4/oOH0wULIRu4j4H6Xruz4SLrDaafUg==",
|
"integrity": "sha512-/jHX8Jjadj0YJzpqnuBo1Yy2ln2hnRbBIc+3jcVOLQ6qhHEKsLRlfJ145Ghn7k/EcnfpDzVX3V8AUCTC8juTow==",
|
||||||
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@photostructure/tz-lookup": "^10.0.0",
|
"@photostructure/tz-lookup": "^10.0.0",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
@ -22600,9 +22601,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"exiftool-vendored": {
|
"exiftool-vendored": {
|
||||||
"version": "26.2.0",
|
"version": "27.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-26.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/exiftool-vendored/-/exiftool-vendored-27.0.0.tgz",
|
||||||
"integrity": "sha512-7P6jQ944or7ic2SJzW+uaWK4TLDXlaCppHrBayl4MpIrVcEeQjiQTez4/oOH0wULIRu4j4H6Xruz4SLrDaafUg==",
|
"integrity": "sha512-/jHX8Jjadj0YJzpqnuBo1Yy2ln2hnRbBIc+3jcVOLQ6qhHEKsLRlfJ145Ghn7k/EcnfpDzVX3V8AUCTC8juTow==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@photostructure/tz-lookup": "^10.0.0",
|
"@photostructure/tz-lookup": "^10.0.0",
|
||||||
"@types/luxon": "^3.4.2",
|
"@types/luxon": "^3.4.2",
|
||||||
|
@ -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.2.0",
|
"exiftool-vendored": "~27.0.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 { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
import { InjectDataSource, 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';
|
||||||
@ -20,40 +20,39 @@ export class MetadataRepository implements IMetadataRepository {
|
|||||||
@Inject(ILoggerRepository) private logger: ILoggerRepository,
|
@Inject(ILoggerRepository) private logger: ILoggerRepository,
|
||||||
) {
|
) {
|
||||||
this.logger.setContext(MetadataRepository.name);
|
this.logger.setContext(MetadataRepository.name);
|
||||||
|
this.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'],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
private exiftool: ExifTool;
|
||||||
|
|
||||||
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}`);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user