Interface ExifToolOptions

Options for the ExifTool constructor.

Defaults are defined in DefaultExifToolOptions.

interface ExifToolOptions {
    adjustTimeZoneIfDaylightSavings: ((tags: Tags, tz: string) => Maybe<number>);
    backfillTimezones: boolean;
    checkPerl: boolean;
    cleanupChildProcs: boolean;
    defaultVideosToUTC: boolean;
    endGracefulWaitTimeMillis: number;
    exiftoolArgs: string[];
    exiftoolEnv: ProcessEnv;
    exiftoolPath: string | Promise<string> | ((logger?: Logger) => string | Promise<string>);
    exitCommand?: string;
    fail: string | RegExp;
    geolocation: boolean;
    geoTz: ((lat: number, lon: number) => Maybe<string>);
    healthCheckCommand?: string;
    healthCheckIntervalMillis: number;
    ignoreMinorErrors: boolean;
    ignoreShebang: boolean;
    ignoreZeroZeroLatLon: boolean;
    imageHashType:
        | false
        | "MD5"
        | "SHA256"
        | "SHA512";
    includeImageDataMD5: undefined | boolean;
    inferTimezoneFromDatestamps: boolean;
    inferTimezoneFromDatestampTags: (keyof Tags)[];
    inferTimezoneFromTimeStamp: boolean;
    logger: (() => Logger);
    maxFailedTasksPerProcess: number;
    maxIdleMsPerProcess: number;
    maxProcAgeMillis: number;
    maxProcs: number;
    maxReasonableProcessFailuresPerMinute: number;
    maxTasksPerProcess: number;
    minDelayBetweenSpawnMillis: number;
    numericTags: string[];
    onIdleIntervalMillis: number;
    pass: string | RegExp;
    pidCheckIntervalMillis: number;
    preferTimezoneInferenceFromGps: boolean;
    processFactory: (() => ChildProcess | Promise<ChildProcess>);
    readArgs: string[];
    spawnTimeoutMillis: number;
    streamFlushMillis: number;
    struct:
        | 0
        | 1
        | 2
        | "undef";
    taskRetries: number;
    taskTimeoutMillis: number;
    useMWG: boolean;
    versionCommand: string;
    writeArgs: string[];
}

Hierarchy

  • BatchClusterOptions
  • BatchProcessOptions
  • ChildProcessFactory
    • ExifToolOptions

Properties

adjustTimeZoneIfDaylightSavings: ((tags: Tags, tz: string) => Maybe<number>)

The TimeZone tag normally represents the offset from UTC.

Unfortunately, at least for some Nikon cameras, the TimeZone tag and the DaylightSavings tag must be taken into account to find the UTC offset.

By default, this is a predicate that returns true if the Make tag is Nikon. If you find other makes and models that need this treatment, please open a ticket on GitHub with example images or videos and we can update the default predicate.

The return value is the number of minutes to adjust the timezone by.

backfillTimezones: boolean

Should we try to backfill timezones for date-times that don't have them? If set to true, and defaultVideosToUTC is also true, we'll try backfilling timezones for date-times that are UTC, as well.

Setting this to false removes all timezone inference--only those date-times with an explicit offset will have a defined timezone.

Prior versions of exiftool-vendored would use the file's .tz as a backstop even if this was set to false.

As of version 23, this now defaults to true, as it's more likely to be what people expect.

checkPerl: boolean

Should we check for a readable and executable perl file in $PATH? This defaults to false on Windows, and true everywhere else. Set this to false if you know perl is installed.

cleanupChildProcs: boolean

Should batch-cluster try to clean up after spawned processes that don't shut down?

Only disable this if you have another means of PID cleanup.

Defaults to true.

defaultVideosToUTC: boolean

Video file dates are assumed to be in UTC, rather than using timezone inference used in images. To disable this default, set this to false.

endGracefulWaitTimeMillis: number

When this.end() is called, or Node broadcasts the beforeExit event, this is the milliseconds spent waiting for currently running tasks to finish before sending kill signals to child processes.

Setting this value to 0 means child processes will immediately receive a kill signal to shut down. Any pending requests may be interrupted. Must be >= 0. Defaults to 500ms.

exiftoolArgs: string[]

Args only passed to exiftool on launch. You probably don't need to change this from the default.

exiftoolEnv: ProcessEnv

Environment variables passed to ExifTool (besides EXIFTOOL_HOME)

exiftoolPath: string | Promise<string> | ((logger?: Logger) => string | Promise<string>)

Allows for non-standard paths to ExifTool. Defaults to the perl or windows binaries provided by exiftool-vendored.pl or exiftool-vendored.exe.

This must be the full path to exiftool, not just the directory.

exitCommand?: string

Command to end the child batch process. If not provided (or undefined), stdin will be closed to signal to the child process that it may terminate, and if it does not shut down within endGracefulWaitTimeMillis, it will be SIGHUP'ed.

fail: string | RegExp

Expected text to print if a command fails. Cannot be blank. Strings will be interpreted as a regular expression fragment.

geolocation: boolean

When reading metadata, should we enable ExifTool's geolocation features? Note that this requires ExifTool version 12.78 or later.

geoTz: ((lat: number, lon: number) => Maybe<string>)

Override the default geo-to-timezone lookup service. Note that if geolocation is enabled, we'll use Tags.GeolocationTimeZone if it's not blank.

This defaults to @photostructure/tz-lookup, but if you have the resources, consider using geo-tz for more accurate results.

If your implementation throws an error, ExifTool will consider that given latitude/longitude as invalid.

Here's a snippet of how to use geo-tz instead of tz-lookup:

const geotz = require("geo-tz")
const { ExifTool } = require("exiftool-vendored")
const exiftool = new ExifTool({ geoTz: (lat, lon) => geotz.find(lat, lon)[0] })

Type declaration

    • (lat, lon): Maybe<string>
    • Parameters

      • lat: number
      • lon: number

      Returns Maybe<string>

      if the given latitude and longitude are invalid.

healthCheckCommand?: string

If provided, and healthCheckIntervalMillis is greater than 0, or the previous task failed, this command will be sent to child processes.

If the command outputs to stderr or returns a fail string, the process will be considered unhealthy and recycled.

healthCheckIntervalMillis: number

If healthCheckCommand is set, how frequently should we check for unhealthy child processes?

Set this to 0 to disable this feature.

ignoreMinorErrors: boolean

Should we ignore minor errors when reading metadata?

This defaults to true, as ExifTool can be quite chatty.

ignoreShebang: boolean

ExifTool has a shebang line that assumes a valid perl is installed at /usr/bin/perl.

Some environments may not include a valid /usr/bin/perl (like AWS Lambda), but perl may be available in your PATH some place else (like /opt/bin/perl), if you pull in a perl layer.

This will default to true in those environments as a workaround in these situations. Note also that perl will be spawned in a sub-shell.

ignoreZeroZeroLatLon: boolean

Some software uses a GPS position of (0,0) as a synonym for "unset". If this option is true, and GPSLatitude and GPSLongitude are both 0, then those values will be returned, but the TZ will not be inferred from that location.

If both this and geolocation are true, we will delete the Geolocation tags from the returned metadata object.

imageHashType:
    | false
    | "MD5"
    | "SHA256"
    | "SHA512"

If defined, ExifTool will attempt to calculate an "ImageDataHash" tag value with a checksum of image data.

Note that as of 2022-04-12, ExifTool supports JPEG, TIFF, PNG, CRW, CR3, MRW, RAF, X3F, IIQ, JP2, JXL, HEIC and AVIF images, MOV/MP4 videos, and some RIFF-based files such as AVI, WAV and WEBP.

This defaults to undefined, as it adds ~20ms of overhead to every read

includeImageDataMD5: undefined | boolean

Use imageHashType instead.

inferTimezoneFromDatestamps: boolean

We always look at Tags.TimeZone, Tags.OffsetTime, Tags.TimeZoneOffset, Tags.OffsetTimeOriginal, Tags.OffsetTimeDigitized, and GPS metadata to infer the timezone.

If these strategies fail, and this is enabled, we'll try to infer the timezone from non-UTC datestamps included in the inferTimezoneFromDatestampTags value.

This defaults to false as it both retains prior behavior and means fewer "fuzzy" heuristics are enabled by default.

inferTimezoneFromDatestampTags: (keyof Tags)[]

This is the list of tag names that will be used to infer the timezone as a backstop, if no explicit timezone is found in metadata. Note that datestamps with UTC offsets are ignored, as they are frequently incorrectly set.

This setting is only in play if inferTimezoneFromDatestamps has been overridden to be true.

This defaults to CapturedAtTagNames

inferTimezoneFromTimeStamp: boolean

Some cameras (Samsung Galaxy S7, for example) may not always include GPS metadata in photos if a fix can't be obtained. If this option is true, and GPS metadata is missing, we'll try to infer the timezone from the difference of the TimeStamp tag and the first defined tag value from inferTimezoneFromDatestampTags.

This heuristic is pretty sketchy, and used as a last resort. You shouldn't enable it unless you have to.

logger: (() => Logger)

A BatchCluster instance and associated BatchProcess instances will share this Logger. Defaults to the Logger instance provided to setLogger().

maxFailedTasksPerProcess: number

How many failed tasks should a process be allowed to process before it is recycled?

Set this to 0 to disable this feature.

maxIdleMsPerProcess: number

If a child process is idle for more than this value (in milliseconds), shut it down to reduce system resource consumption.

A value of ~10 seconds to a couple minutes would be reasonable. Set this to 0 to disable this feature.

maxProcAgeMillis: number

Child processes will be recycled when they reach this age.

This value must not be less than spawnTimeoutMillis or taskTimeoutMillis.

Defaults to 5 minutes. Set to 0 to disable.

maxProcs: number

The maximum number of ExifTool child processes to spawn when load merits.

Defaults to 1/4 the number of CPUs, minimally 1.

maxReasonableProcessFailuresPerMinute: number

If the initial versionCommand fails for new spawned processes more than this rate, end this BatchCluster and throw an error, because something is terribly wrong.

If this backstop didn't exist, new (failing) child processes would be created indefinitely.

Defaults to 10. Set to 0 to disable.

maxTasksPerProcess: number

The maximum number of requests a given ExifTool process will service before being retired.

Defaults to 500, to balance performance with memory usage.

minDelayBetweenSpawnMillis: number

If maxProcs > 1, spawning new child processes to process tasks can slow down initial processing, and create unnecessary processes.

Must be >= 0ms. Defaults to 1.5 seconds.

numericTags: string[]

Tag names (which can have '*' glob matchers) which you want numeric values, rather than ExifTool's "Print Conversion."

If you're using tag values only for human consumption, you may want to leave this blank.

The default includes "Duration", Tags.GPSAltitude, Tags.GPSLatitude, Tags.GPSLongitude, Tags.GPSPosition, and Tags.Orientation.

onIdleIntervalMillis: number

An interval timer is scheduled to do periodic maintenance of underlying child processes with this periodicity.

Defaults to 2 seconds.

pass: string | RegExp

Expected text to print if a command passes. Cannot be blank. Strings will be interpreted as a regular expression fragment.

pidCheckIntervalMillis: number

Verify child processes are still running by checking the OS process table.

Set this to 0 to disable this feature.

preferTimezoneInferenceFromGps: boolean

Timezone parsing requires a bunch of heuristics due to hardware and software companies not following metadata specifications similarly.

If GPS metadata is trustworthy, set this to true to override explicit values assigned to TimezoneOffsetTagnames.

Note that there are regions that have had their IANA timezone change over time--this will result incorrect timezones.

processFactory: (() => ChildProcess | Promise<ChildProcess>)

Expected to be a simple call to execFile. Platform-specific code is the responsibility of this thunk. Error handlers will be registered as appropriate.

If this function throws an error or rejects the promise after you've spawned a child process, the child process may continue to run and leak system resources.

readArgs: string[]

Any additional arguments that should be added by default to all read tasks, like ["-fast", "-api", "largefilesupport=1"]. The value provided to the ExifTool constructor can be overridden in the call to ()

spawnTimeoutMillis: number

Spawning new ExifTool processes must not take longer than spawnTimeoutMillis milliseconds before the child process is timed out and a new attempt is made. Be pessimistic here--windows can regularly take several seconds to spin up a process, thanks to antivirus shenanigans. This can't be set to a value less than 100ms.

Defaults to 30 seconds, to accommodate slow Windows machines.

streamFlushMillis: number

When a task sees a "pass" or "fail" from either stdout or stderr, it needs to wait for the other stream to finish flushing to ensure the task's Parser sees the entire relevant stream contents. A larger number may be required for slower computers to prevent internal errors due to lack of stream coercion.

Note that this puts a hard lower limit on task latency, so don't set this to a large number: no task will resolve faster than this value (in millis).

If you set this value too low, tasks may be erroneously resolved or rejected (depending on which stream is handled first).

Your system may support a smaller value: this is a pessimistic default. If this is set too low, you'll see noTaskData events.

Setting this to 0 makes whatever flushes first--stdout and stderr--and will most likely result in internal errors (due to stream buffers not being able to be associated to tasks that were just settled)

struct:
    | 0
    | 1
    | 2
    | "undef"

How should ExifTool handle nested structures?

Defaults to 1.

  • 0 = Read/copy flattened tags
  • 1 = Read/copy structures
  • 2 = Read/copy both flattened and structured tags, but flag flattened tags as "unsafe" for copying
  • "undef" = Same as 0 for reading and 2 for copying
taskRetries: number

The number of times a task can error or timeout and be retried.

Defaults to 1 (every task gets 2 chances).

taskTimeoutMillis: number

If requests to ExifTool take longer than this, presume the underlying process is dead and we should restart the task. This can't be set to a value less than 10ms, and really should be set to at more than a second unless taskRetries is sufficiently large or all writes will be to a fast local disk. Defaults to 10 seconds.

useMWG: boolean

Should ExifTool use MWG (Metadata Working Group) composite tags for reading and writing tags?

ExifTool recommends this to be set to true. This defaults to false to maintain consistency with prior versions.

Note that this can result in many tag value differences from ExifTool.read, and makes ExifTool.write write to "synonymous" MWG tags automatically.

versionCommand: string

Low-overhead command to verify the child batch process has started. Will be invoked immediately after spawn. This command must return before any tasks will be given to a given process.

writeArgs: string[]

Any additional arguments that should be added by default to all write tasks, like ["-overwrite_original"]. The value provided to the ExifTool constructor can be overridden in the call to ().