exiftool-vendored
Version:
Efficient, cross-platform access to ExifTool
400 lines (399 loc) • 18.5 kB
TypeScript
import * as bc from "batch-cluster";
import { BinaryExtractionTaskOptions } from "./BinaryExtractionTask";
import { ExifToolOptions } from "./ExifToolOptions";
import { ExifToolTask, ExifToolTaskOptions } from "./ExifToolTask";
import { PreviewTag } from "./PreviewTag";
import { ReadRawTaskOptions } from "./ReadRawTask";
import { ReadTaskOptions } from "./ReadTask";
import { Tags } from "./Tags";
import { WriteTags } from "./WriteTags";
import { WriteTaskOptions, WriteTaskResult } from "./WriteTask";
export { retryOnReject } from "./AsyncRetry";
export { BinaryField } from "./BinaryField";
export { CapturedAtTagNames } from "./CapturedAtTagNames";
export { DefaultExifToolOptions } from "./DefaultExifToolOptions";
export { DefaultExiftoolArgs } from "./DefaultExiftoolArgs";
export { DefaultMaxProcs } from "./DefaultMaxProcs";
export { ExifDate } from "./ExifDate";
export type { ExifDateFull, ExifDatePartial, ExifDateYearMonth, ExifDateYearOnly, } from "./ExifDate";
export { ExifDateTime } from "./ExifDateTime";
export { ExifTime } from "./ExifTime";
export { ExifToolTask } from "./ExifToolTask";
export { exiftoolPath } from "./ExiftoolPath";
export { GeolocationTagNames, isGeolocationTag } from "./GeolocationTags";
export { parseJSON } from "./JSON";
export type { Lazy } from "./Lazy";
export { DefaultReadRawTaskOptions } from "./ReadRawTask";
export { DefaultReadTaskOptions } from "./ReadTask";
export { Setting, Settings } from "./Settings";
export { strEnum } from "./StrEnum";
export type { StrEnum, StrEnumHelpers, StrEnumKeys, StrEnumType, } from "./StrEnum";
export { ArchaicTimezoneOffsets, defaultVideosToUTC, equivalentZones, extractTzOffsetFromTags, extractTzOffsetFromUTCOffset, extractZone, inferLikelyOffsetMinutes, isUTC, isZone, isZoneUnset, isZoneValid, normalizeZone, offsetMinutesToZoneName, parseTimezoneOffsetMatch, parseTimezoneOffsetToMinutes, TimezoneOffsetRE, TimezoneOffsetTagnames, UnsetZone, UnsetZoneName, UnsetZoneOffsetMinutes, ValidTimezoneOffsets, validTzOffsetMinutes, zoneToShortOffset, } from "./Timezones";
export type { TimezoneOffset, TimezoneOffsetMatch, TzSrc } from "./Timezones";
export { DefaultWriteTaskOptions, WriteTaskOptionFields } from "./WriteTask";
export type { BinaryExtractionTaskOptions } from "./BinaryExtractionTask";
export type { ContainerDirectoryItem } from "./ContainerDirectoryItem";
export type { Defined, DefinedOrNullValued } from "./Defined";
export type { ErrorsAndWarnings } from "./ErrorsAndWarnings";
export type { ExifToolOptions } from "./ExifToolOptions";
export type { ExifToolTaskOptions } from "./ExifToolTask";
export type { ExifToolVendoredTags } from "./ExifToolVendoredTags";
export type { GeolocationTags } from "./GeolocationTags";
export type { ICCProfileTags } from "./ICCProfileTags";
export type { IPTCApplicationRecordTags as ApplicationRecordTags, IPTCApplicationRecordTags, } from "./IPTCApplicationRecordTags";
export type { ImageDataHashTag } from "./ImageDataHashTag";
export type { Json, Literal } from "./JSON";
export type { CollectionInfo, KeywordInfoStruct, KeywordStruct, MWGCollectionsTags, MWGKeywordTags, } from "./MWGTags";
export type { Maybe, Nullable } from "./Maybe";
export type { Omit } from "./Omit";
export type { RawTags } from "./RawTags";
export type { ReadRawTaskOptions } from "./ReadRawTask";
export type { ReadTaskOptions } from "./ReadTask";
export type { ResourceEvent } from "./ResourceEvent";
export type { UnsubscribeFunction } from "./Settings";
export type { ShortcutTags } from "./ShortcutTags";
export type { Struct } from "./Struct";
export type { APPTags, CompositeTags, EXIFTags, ExifToolTags, FileTags, FlashPixTags, IPTCTags, JFIFTags, MakerNotesTags, MetaTags, MPFTags, PanasonicRawTags, PhotoshopTags, PrintIMTags, QuickTimeTags, RAFTags, RIFFTags, Tags, XMPTags, } from "./Tags";
export type { Version } from "./Version";
export type { AdditionalWriteTags, EXIFStrictDateTags, ExpandedDateTags, GroupPrefixedTags, MutableTags, StructAppendTags, WritableGPSRefs, WriteTags, XMPPartialDateTags, } from "./WriteTags";
export type { WriteTaskOptions, WriteTaskResult } from "./WriteTask";
/**
* Manages delegating calls to a cluster of ExifTool child processes.
*
* **NOTE: Instances are expensive!**
*
* * use either the default exported singleton instance of this class,
* {@link exiftool}, or your own singleton
*
* * make sure you await {@link ExifTool.end} when you're done with an instance
* to clean up subprocesses
*
* * review the {@link ExifToolOptions} for configuration options--the default
* values are conservative to avoid overwhelming your system.
*
* @see https://photostructure.github.io/exiftool-vendored.js/ for more documentation.
*/
export declare class ExifTool {
#private;
readonly options: ExifToolOptions;
readonly batchCluster: bc.BatchCluster;
constructor(options?: Partial<ExifToolOptions>);
readonly exiftoolPath: import("./Lazy").Lazy<Promise<string>>;
/**
* Register life cycle event listeners. Delegates to BatchCluster.
*/
readonly on: bc.BatchCluster["on"];
/**
* Unregister life cycle event listeners. Delegates to BatchCluster.
*/
readonly off: bc.BatchCluster["off"];
/**
* @return a promise holding the version number of the vendored ExifTool
*/
version(): Promise<string>;
/**
* Read the tags in `file`.
*
* @param file the file to extract metadata tags from
*
* @param options overrides to the default ExifTool options provided to the
* ExifTool constructor.
*
* @returns A resolved Tags promise. If there are errors during reading, the
* `.errors` field will be present.
*/
read<T extends Tags = Tags>(file: string, options?: ReadTaskOptions): Promise<T>;
/**
* Read the tags in `file`.
*
* @param file the file to extract metadata tags from
*
* @param readArgs any additional ExifTool arguments, like `["-fast"]`,
* `["-fast2"]`, `["-g"]`, or `["-api", "largefilesupport=1"]`. Note that
* providing a value here will override the `readArgs` array provided to the
* ExifTool constructor. **Note that most other arguments will require you to
* use `readRaw`.** Note that the default is `["-fast"]`, so if you want
* ExifTool to read the entire file for metadata, you should pass an empty
* array as the second parameter. See https://exiftool.org/#performance for
* more information about `-fast` and `-fast2`.
*
* @param options overrides to the default ExifTool options provided to the
* ExifTool constructor.
*
* @returns A resolved Tags promise. If there are errors during reading, the
* `.errors` field will be present.
*
* @deprecated use
* {@link ExifTool.read(file: string, options?: ReadTaskOptions)} instead
* (move `readArgs` into your `options` hash)
*/
read<T extends Tags = Tags>(file: string, readArgs?: string[], options?: ReadTaskOptions): Promise<T>;
/**
* Read the tags in `file`.
*
* **You probably want `read`, not this method. READ THE REST OF THIS COMMENT
* CAREFULLY.**
*
* If you want to extract specific tag values from a file, you may want to use
* this, but all data validation and inference heuristics provided by `read`
* will be skipped.
*
* Note that performance will be very similar to `read`, and will actually be
* worse if you don't include `-fast` or `-fast2` (as the most expensive bits
* are the perl interpreter and scanning the file on disk).
*
* @param options any additional arguments other than the file path. Note that
* "-json", and the Windows unicode filename handler flags, "-charset
* filename=utf8", will be added automatically.
*
* @return Note that the return value will be similar to `Tags`, but with no
* date, time, or other rich type parsing that you get from `.read()`. The
* field values will be `string | number | string[]`.
*
* @see ExifTool.read() for the preferred method to read tags
*
* @see https://github.com/photostructure/exiftool-vendored.js/issues/44 for
* typing details.
*/
readRaw<T extends Tags = Tags>(file: string, options?: ReadRawTaskOptions): Promise<T>;
/**
* @deprecated use {@link ExifTool.readRaw(file: string, options?: ReadRawTaskOptions)}
*/
readRaw<T extends Tags = Tags>(file: string, readArgs?: string[], options?: ReadRawTaskOptions): Promise<T>;
/**
* Write the given `tags` to `file`.
*
* @param file an existing file to write `tags` to
*
* @param tags the tags to write to `file`.
*
* **IMPORTANT:** Partial dates (year-only or year-month) are only supported
* for XMP tags. Use group-prefixed tag names like `"XMP:CreateDate"` for
* partial date support. EXIF tags require complete dates.
*
* @param options overrides to the default ExifTool options provided to the
* ExifTool constructor.
*
* @return Either the promise will be resolved if the tags are written to
* successfully, or the promise will be rejected if there are errors or
* warnings.
*
* @see https://exiftool.org/exiftool_pod.html#overwrite_original
*/
write(file: string, tags: WriteTags, options?: WriteTaskOptions): Promise<WriteTaskResult>;
/**
* @param file an existing file to write `tags` to
*
* @param tags the tags to write to `file`.
*
* @param writeArgs any additional ExifTool arguments, like `-n`, or
* `-overwrite_original`.
*
* @param options overrides to the default ExifTool options provided to the
* ExifTool constructor.
*
* @returns Either the promise will be resolved if the tags are written to
* successfully, or the promise will be rejected if there are errors or
* warnings.
*
* @see https://exiftool.org/exiftool_pod.html#overwrite_original
*
* @deprecated use
* {@link ExifTool.write(file: string, tags: WriteTags, options?: WriteTaskOptions)}
* instead: move `writeArgs` into your `options` hash.
*/
write(file: string, tags: WriteTags, writeArgs?: string[], options?: WriteTaskOptions): Promise<WriteTaskResult>;
/**
* This will strip `file` of all metadata tags. The original file (with the
* name `${FILENAME}_original`) will be retained. Note that some tags, like
* stat information and image dimensions, are intrinsic to the file and will
* continue to exist if you re-`read` the file.
*
* @param {string} file the file to strip of metadata
*
* @param {(keyof Tags | string)[]} opts.retain optional. If provided, this is
* a list of metadata keys to **not** delete.
*/
deleteAllTags(file: string, opts?: {
retain?: (keyof Tags | string)[];
} & Partial<ExifToolTaskOptions>): Promise<WriteTaskResult>;
/**
* Extract the low-resolution thumbnail in `path/to/image.jpg` and write it to
* `path/to/thumbnail.jpg`.
*
* Note that these images can be less than .1 megapixels in size.
*
* @return a `Promise<void>`
*
* @throws if the file could not be read or the output not written
*/
extractThumbnail(imageFile: string, thumbnailFile: string, opts?: BinaryExtractionTaskOptions): Promise<void>;
/**
* Extract the "preview" image in `path/to/image.jpg` and write it to
* `path/to/preview.jpg`.
*
* The size of these images varies widely, and is present in dSLR images.
* Canon, Fuji, Olympus, and Sony use this tag.
*
* @return a `Promise<void>`
*
* @throws if the file could not be read or the output not written
*/
extractPreview(imageFile: string, previewFile: string, opts?: BinaryExtractionTaskOptions): Promise<void>;
/**
* Extract the "JpgFromRaw" image in `path/to/image.jpg` and write it to
* `path/to/fromRaw.jpg`.
*
* This size of these images varies widely, and is not present in all RAW
* images. Nikon and Panasonic use this tag.
*
* @return a `Promise<void>`
*
* @throws if the file could not be read or the output not written.
*/
extractJpgFromRaw(imageFile: string, outputFile: string, opts?: BinaryExtractionTaskOptions): Promise<void>;
/**
* Extract a given binary value from "tagname" tag associated to
* `path/to/image.jpg` and write it to `dest` (which cannot exist and whose
* directory must already exist).
*
* @return a `Promise<void>`
*
* @throws if the binary output cannot be written to `dest`.
*/
extractBinaryTag(tagname: string, src: string, dest: string, opts?: BinaryExtractionTaskOptions): Promise<void>;
/**
* Extract a given binary value from "tagname" tag associated to
* `path/to/image.jpg` as a `Buffer`. This has the advantage of not writing to
* a file, but if the payload associated to `tagname` is large, this can cause
* out-of-memory errors.
*
* @return a `Promise<Buffer>`
*
* @throws if the file or tag is missing.
*/
extractBinaryTagToBuffer(tagname: PreviewTag, imageFile: string, opts?: ExifToolTaskOptions): Promise<Buffer>;
/**
* Attempt to fix metadata problems in JPEG images by deleting all metadata
* and rebuilding from scratch. After repairing an image you should be able to
* write to it without errors, but some metadata from the original image may
* be lost in the process.
*
* This should only be applied as a last resort to images whose metadata is
* not readable via {@link ExifTool.read}.
*
* @see https://exiftool.org/faq.html#Q20
*
* @param {string} inputFile the path to the problematic image
* @param {string} outputFile the path to write the repaired image
* @param {boolean} opts.allowMakerNoteRepair if there are problems with MakerNote
* tags, allow ExifTool to apply heuristics to recover corrupt tags. See
* exiftool's `-F` flag.
* @return {Promise<void>} resolved after the outputFile has been written.
*/
rewriteAllTags(inputFile: string, outputFile: string, opts?: {
allowMakerNoteRepair?: boolean;
} & ExifToolTaskOptions): Promise<void>;
/**
* Shut down running ExifTool child processes. No subsequent requests will be
* accepted.
*
* This may need to be called in `after` or `finally` clauses in tests or
* scripts for them to exit cleanly.
*/
end(gracefully?: boolean): Promise<void>;
/**
* @return true if `.end()` has been invoked
*/
get ended(): boolean;
/**
* Most users will not need to use `enqueueTask` directly. This method
* supports submitting custom `BatchCluster` tasks.
*
* @param task a thunk to support retries by providing new instances on retries
* @param retriable whether to retry the task on failure (default: true)
* @returns a Promise resolving to the task result
*
* @see BinaryExtractionTask for an example task implementation
*/
enqueueTask<T>(task: () => ExifToolTask<T>, retriable?: boolean): Promise<T>;
/**
* @return the currently running ExifTool processes. Note that on Windows,
* these are only the process IDs of the directly-spawned ExifTool wrapper,
* and not the actual perl vm. This should only really be relevant for
* integration tests that verify processes are cleaned up properly.
*/
get pids(): number[];
/**
* @return the number of pending (not currently worked on) tasks
*/
get pendingTasks(): number;
/**
* @return the total number of child processes created by this instance
*/
get spawnedProcs(): number;
/**
* @return the current number of child processes currently servicing tasks
*/
get busyProcs(): number;
/**
* @return report why child processes were recycled
*/
childEndCounts(): Record<NonNullable<bc.ChildEndReason>, number>;
/**
* Shut down any currently-running child processes. New child processes will
* be started automatically to handle new tasks.
*/
closeChildProcesses(gracefully?: boolean): Promise<void>;
/**
* Implements the Disposable interface for automatic cleanup with the `using` keyword.
* This allows ExifTool instances to be automatically cleaned up when they go out of scope.
*
* Note: This is a synchronous disposal method that initiates graceful cleanup but doesn't
* wait for completion. If graceful cleanup times out, forceful cleanup is attempted.
* For guaranteed cleanup completion, use `await using` with the async disposal method instead.
*
* @example
* ```typescript
* {
* using et = new ExifTool();
* const tags = await et.read("photo.jpg");
* // ExifTool cleanup will be initiated when this block exits
* }
* ```
*/
[Symbol.dispose](): void;
/**
* Implements the AsyncDisposable interface for automatic async cleanup with the `await using` keyword.
* This allows ExifTool instances to be automatically cleaned up when they go out of scope.
*
* This method provides robust cleanup with timeout protection to prevent hanging.
* If graceful cleanup times out, forceful cleanup is attempted automatically.
*
* @example
* ```typescript
* {
* await using et = new ExifTool();
* const tags = await et.read("photo.jpg");
* // ExifTool will be automatically ended when this block exits
* }
* ```
*/
[Symbol.asyncDispose](): Promise<void>;
}
/**
* This is a convenience singleton.
*
* As of v3.0, its {@link ExifToolOptions.maxProcs} is set to 1/4 the number of
* CPUs on the current system; no more than `maxProcs` instances of `exiftool`
* will be spawned. You may want to experiment with smaller or larger values for
* `maxProcs`, depending on CPU and disk speed of your system and performance
* tradeoffs.
*
* Note that each child process consumes between 10 and 50 MB of RAM. If you
* have limited system resources you may want to use a smaller `maxProcs` value.
*
* See the source of {@link DefaultExifToolOptions} for more details about how
* this instance is configured.
*/
export declare const exiftool: ExifTool;