Main Menu

FMT File guide

Started by diplonics, September 09, 2020, 07:36:41 AM

Previous topic - Next topic

diplonics

Trying to create my own output format template file as a CSV and have been going through the Inverse Geotagging section of https://exiftool.org/geotag.html.
I can't seem to work out how to set the format for if/else checks for a tag that may or may-not exist in the file.
For the Roadhawk video format, which Phil helped me with before, it doesn't contain $gpsaltitude so the output file format fails and is empty.
However it works when I use the gpx.fmt file where it excludes the gpsaltitude element.
My csv output example is below so the question is can I if check the various altitude, speed etc.. tags for existence and if not replace with a 0..

#[IF]  $gpslatitude $gpslongitude
#[BODY]${gpsdatetime#;my ($ss)=/\.\d+/g;DateFmt("%Y-%m-%dT%H:%M:%SZ");s/Z/${ss}Z/ if $ss},$gpslatitude#,$gpslongitude#,$gpsaltitude#,$gpstrack#,$gpsspeed#

Thanks

Phil Harvey

What do you want to happen if GPSAltitude is missing?  There are various alternatives.  From the -p option section of the application documentation:

            If a specified tag does not exist, a minor warning is issued and
            the line with the missing tag is not printed.  However, the -f
            option may be used to set the value of missing tags to '-' (but
            this may be configured via the MissingTagValue API option), or the
            -m option may be used to ignore minor warnings and leave the
            missing values empty.


- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

diplonics

Basically replace the missing TAG with a 0.
Those options you mention look interesting I'll give them a try now.

Was thinking though that something like a set of if conditions but not sure of the whole logic.

#[IF]  $gpslatitude $gpslongitude,$gpsaltitude,$gpstrack,$gpsspeed                   //If all available then print this
#[BODY]${gpsdatetime#;my ($ss)=/\.\d+/g;DateFmt("%Y-%m-%dT%H:%M:%SZ");s/Z/${ss}Z/ if $ss},$gpslatitude#,$gpslongitude#,$gpsaltitude#,$gpstrack#,$gpsspeed#
#[IF]  $gpslatitude $gpslongitude,$gpstrack,$gpsspeed                                     //If only 4 available then print this line, has replaced altitude with 0
#[BODY]${gpsdatetime#;my ($ss)=/\.\d+/g;DateFmt("%Y-%m-%dT%H:%M:%SZ");s/Z/${ss}Z/ if $ss},$gpslatitude#,$gpslongitude#,0,$gpstrack#,$gpsspeed#
..
etc..

But that logic would probably see both lines printed I think..

Phil Harvey

Yes.  Easier to just add -f -api missingtagvalue=0

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

diplonics

Yep, perfect solution, thanks again.

diplonics

Couple of further questions here if you have time.

Having referenced the Tag Names docs (https://exiftool.org/TagNames/QuickTime.html#Accel360Fly) is there a direct correlation between the names shown and those I can use in a fmt file context.
For example the GPS360Fly TAG names include GPSLatitude, so in the fmt file I access this as $gpslatitude.
Basically is it that all tag names on this help page, if available after processing a video, will be lower case if using in an fmt file context?

Next, to use a tag like GyroYPR in the (https://exiftool.org/TagNames/QuickTime.html#Gyro360Fly) docs, I can access it as $gyroypr but can I change its output to be comma separated rather than space?
Further post-processing on my part could obviously sort this easy but just wondering if that formatting can be built into the fmt file?

Lastly, in using EXIFTool with an fmt file format control, I pass in -f -api missingtagvalue=0.
Is there a fmt file syntax example where output can be controlled if there is a missing TAG and/or it is set to 0.
The issue is that there are lots of redundant 0 GPS entries where the tag doesn't exist and is being set by the missingtagvalue to 0, however there are loads of metadata blocks where, for example, GYRO data exists.
Basically can I control in the fmt file for cases like if ((GPSLat AND GPSLong) not zero) OR (GYROYPR data not zero) then output, otherwise ignore.
Once again I can control for this in post processing but just wondering?

Thanks again.

Phil Harvey

Quote from: diplonics on December 02, 2020, 12:24:44 PM
Having referenced the Tag Names docs (https://exiftool.org/TagNames/QuickTime.html#Accel360Fly) is there a direct correlation between the names shown and those I can use in a fmt file context.

Yes.

Quotewill be lower case if using in an fmt file context?

From the application documentation:

-p FMTFILE or STR (-printFormat)
            Print output in the format specified by the given file or string.
            The argument is interpreted as a string unless a file of that name
            exists, in which case the string is loaded from the contents of
            the file.  Tag names in the format file or string begin with a "$"
            symbol and may contain leading group names and/or a trailing "#"
            (to disable print conversion).  Case is not significant.  Braces
            "{}" may be used around the tag name to separate it from
            subsequent text.  Use $$ to represent a "$" symbol, and $/ for a
            newline.

QuoteNext, to use a tag like GyroYPR in the (https://exiftool.org/TagNames/QuickTime.html#Gyro360Fly) docs, I can access it as $gyroypr but can I change its output to be comma separated rather than space?

Yes.  With the advanced formatting feature also described in the documentation, using ${gyroypr;tr/ /,/}

Quotecan I control in the fmt file for cases like if ((GPSLat AND GPSLong) not zero) OR (GYROYPR data not zero) then output, otherwise ignore.

You can conditionally process files using the -if option based on any condition you choose.  You can use this to process different files with different .fmt files if you aren't able to make one .fmt file to handle all cases.  The #[IF] directive in the .fmt file is simpler than this, and only allows skipping of sections for files that don't contain certain tags.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

diplonics

Once again thanks Phil, so much in exiftool docs and options..

diplonics

Coming across a difficulty rather than a problem with using the following fmt format when reading GPS from Video files.
#[IF]  $gpslatitude $gpslongitude
#[BODY]$gpslongitude#,$gpslatitude#,0,${gpsdatetime#;my ($ss)=/\.\d+/g;DateFmt("%Y-%m-%dT%H:%M:%SZ");s/Z/${ss}Z/ if $ss}$/

Calling the format file like this:

"exiftool(-k).exe" -p csv.fmt -ee -f -api missingtagvalue=0 Roadhawk_EX01.mp4 > Roadhawk_Output.txt

Its only an issue with the Roadhawk data as its reporting at 10hrz so I'm getting 10 records with the same time stamp like this.

-8.66935833333333,52.305695,0,2020-02-18T12:51:57Z
-8.669365,52.3056766666667,0,2020-02-18T12:51:57Z
-8.66937,52.3056583333333,0,2020-02-18T12:51:57Z
-8.66937666666667,52.3056416666667,0,2020-02-18T12:51:57Z
-8.66938166666667,52.3056233333333,0,2020-02-18T12:51:57Z
-8.66938833333333,52.305605,0,2020-02-18T12:51:57Z
-8.66939333333333,52.3055866666667,0,2020-02-18T12:51:57Z
-8.6694,52.3055683333333,0,2020-02-18T12:51:57Z
-8.669405,52.30555,0,2020-02-18T12:51:57Z
-8.66941166666667,52.3055316666667,0,2020-02-18T12:51:57Z
-8.66941666666667,52.3055133333333,0,2020-02-18T12:51:58Z
-8.66942333333333,52.305495,0,2020-02-18T12:51:58Z
-8.66942833333333,52.3054766666667,0,2020-02-18T12:51:58Z
-8.669435,52.3054583333333,0,2020-02-18T12:51:58Z
-8.66944,52.30544,0,2020-02-18T12:51:58Z
-8.66944666666667,52.3054216666667,0,2020-02-18T12:51:58Z
-8.66945333333333,52.3054033333333,0,2020-02-18T12:51:58Z
-8.66945833333333,52.305385,0,2020-02-18T12:51:58Z
-8.669465,52.3053666666667,0,2020-02-18T12:51:58Z
-8.66947166666667,52.3053483333333,0,2020-02-18T12:51:58Z

Other device formats either report at 1 hrz or report milliseconds but this data is somewhat less certain although the GPS ordering when mapped seems fine so far.

So I was just wondering if there's another TAG in the GPS group that I could pick up on that I could stitch onto the time output to get a millisecond regardless of whether its there or not?


Phil Harvey

#9
Here is a hack that will add 0.1 seconds to consecutive times that would otherwise be the same:

#[BODY]$gpslongitude#,$gpslatitude#,0,${gpsdatetime#;$UserDefined::ss = $UserDefined::lastTime && $_ eq $UserDefined::lastTime ? $UserDefined::ss+1 : 0;$UserDefined::lastTime=$_;my ($ss)=/\.\d+/g;$ss or $ss=($UserDefined::ss ? ".".$UserDefined::ss : "");DateFmt("%Y-%m-%dT%H:%M:%SZ");s/Z/${ss}Z/ if $ss}$/

- Phil

Edit: Use "UserDefined" namespace for permanent variables instead of risking collisions in Image::ExifTool namespace.
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

diplonics

Thanks Phil,
  That's the hint I needed...and a bit of re-learning perl syntax to adapt..but its working for my needs now.
1 slight adjustment to ensure .0 at minimum appears if no millisecond at all appears.

${gpsdatetime#;$UserDefined::ss = $UserDefined::lastTime && $_ eq $UserDefined::lastTime ? $UserDefined::ss+1 : 0;$UserDefined::lastTime=$_;my ($ss)=/\.\d+/g;$ss or $ss=($UserDefined::ss ? ".".$UserDefined::ss : ".0");DateFmt("%Y-%m-%dT%H:%M:%SZ");s/Z/${ss}Z/ if $ss}

Cheers,

Paul

Phil Harvey

Hi Paul,

Actually, I had to go out of my way so the ".0" didn't appear.  Adding it back again simplifies things more than you thought:

${gpsdatetime#;$UserDefined::ss = $UserDefined::lastTime && $_ eq $UserDefined::lastTime ? $UserDefined::ss+1 : 0;$UserDefined::lastTime=$_;my ($ss)=/\.\d+/g;$ss or $ss=".$UserDefined::ss";DateFmt("%Y-%m-%dT%H:%M:%SZ");s/Z/${ss}Z/}

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

diplonics

Hi Phil,
       Sorry about that but turns out I do need the .0!!!
So yea, I see that you removed the ternary check which is a bit neater alright.

Thanks again,

Paul