News:

2023-03-15 Major improvements to the new Geolocation feature

Main Menu

Delete Date tags if set as "0000:00:00 00:00:00"

Started by vicmarto, August 29, 2019, 10:53:23 AM

Previous topic - Next topic

vicmarto

Hello.

I have one weird mp4 file with this dates sets:

$ exiftool -s -time:all -a -G0:1 PDPQ8212.MP4
[File:System]   FileModifyDate                  : 2019:08:14 15:50:22+02:00
[File:System]   FileAccessDate                  : 2019:08:29 23:15:24+02:00
[File:System]   FileInodeChangeDate             : 2019:08:29 23:15:24+02:00
[QuickTime]     CreateDate                      : 0000:00:00 00:00:00
[QuickTime]     ModifyDate                      : 0000:00:00 00:00:00
[QuickTime:Track1] TrackCreateDate              : 0000:00:00 00:00:00
[QuickTime:Track1] TrackModifyDate              : 0000:00:00 00:00:00
[QuickTime:Track1] MediaCreateDate              : 0000:00:00 00:00:00
[QuickTime:Track1] MediaModifyDate              : 0000:00:00 00:00:00
[QuickTime:Track2] TrackCreateDate              : 0000:00:00 00:00:00
[QuickTime:Track2] TrackModifyDate              : 0000:00:00 00:00:00
[QuickTime:Track2] MediaCreateDate              : 0000:00:00 00:00:00
[QuickTime:Track2] MediaModifyDate              : 0000:00:00 00:00:00


There is one easy way to check for Date tags (all of them) that are set to "0000:00:00 00:00:00" and just... delete them?

Thanks.

Phil Harvey

None of those tags are deletable since they are part of binary data structures.  Essentially, the only way to "delete" these values is to set them to zero, which is what they already seem to be set to.

I should probably document this somehow, but any tag listed with an "Index" instead of a "Tag ID" in the Tag Name documenation is part of a binary data structure, and hence not individually deletable.

- Phil

Edit: I have updated the main page of the tag name documentation to add this note: "(Note that writable tags within binary data blocks are not individually deletable, and the alternative is to set them to a value of zero.)"
...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 ($).

StarGeek

edit: I'm too bullheaded not to post anyway just because Phil beats me by 40 seconds

I do not believe that the time data in video files can be removed completely.  If you run exiftool with a command like
exiftool -CreateDate= -ModifyDate= file.mp4
you'll see that doing so just sets the timestamps to 0000:00:00 00:00:00

Even FFMpeg just sets the values to 0 when you run a command to remove metadata
ffmpeg -i in.mp4 -map_metadata -1 -c:v copy -c:a copy out.mp4
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

vicmarto

Thanks to both, I see now where is the problem.

In that case, how can I avoid using this "0000:00:00 00:00:00" dates by mistake when mass tagging my files? Maybe something with -if?

Is this correct?:

-if 'not $CreateDate cmp 0 and not $CreationDate cmp 0'

Phil Harvey

Quote from: StarGeek on August 29, 2019, 11:19:10 AM
edit: I'm too bullheaded not to post anyway just because Phil beats me by 40 seconds

:)
...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 ($).

Phil Harvey

I can't give a comprehensive answer without seeing your command, but I would use an advanced formatting expression, like this:

'-createdate<${createdate;$_ = undef if /^0000/}'

The advantage is that any other tags you want could still be copied.

- 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 ($).

StarGeek

#6
Other options, since Phil is still faster than me.

That cmp won't work, as any time stamp is going to be greater than 0.  You'll have to use string comparison operators.

You're probably going to have to use eq (equal) or ne (not equal)
-if '$CreateDate ne "0000:00:00 00:00:00" and $CreationDate ne "0000:00:00 00:00:00" '
or gt (greater than) would work as well
-if ' not $CreateDate gt "0000:00:00 00:00:00" and not $CreationDate gt "0000:00:00 00:00:00" '

Edit:  Actually, since I believe that the video timestamps can't be earlier than 1970:01:01, you could use this to have a more compact command
-if ' not $CreateDate gt "0" and not $CreationDate gt "0" '
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

StarGeek

Quote from: Phil Harvey on August 29, 2019, 11:31:27 AM
'-createdate<${createdate;$_ = undef if /^0000/}'

Ah, I get that.  I like that, though it might be confusing for new users. 
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

vicmarto

Wow, really impressed with this forum, really. Both solutions worked. Thanks!!!

One more (unrelated) question please. I'm beginning to experiment with -if. Is this correct?:

-if 'not defined $SubSecTime and not defined $SubSecTimeDigitized and not defined $SubSecTimeOriginal' \

I only want to edit files that don't have any of these 3 tags.

Phil Harvey

...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 ($).

kennethmac2000

Quote from: Phil Harvey on August 29, 2019, 11:31:27 AM
I can't give a comprehensive answer without seeing your command, but I would use an advanced formatting expression, like this:

'-createdate<${createdate;$_ = undef if /^0000/}'

The advantage is that any other tags you want could still be copied.

- Phil

As far as I can tell, this only works if the API option QuickTimeUTC is not set, as otherwise a binary zero value gets converted to 1904-01-01 00:00:00. One could match on /^1904/ in that case, but that feels rather less elegant.

However, I need to use the API option QuickTimeUTC elsewhere in the same exiftool call.

Is it possible to apply an API option like QuickTimeUTC only to part of an exiftool call?

Eg, in the command exiftool -if '<expression>' '-y<z', I don't want QuickTimeUTC to be applied to the evaluation of <expression>, but I do want it to be applied to '-y<z' (or vice versa).

StarGeek

Quote from: kennethmac2000 on July 17, 2021, 08:32:43 AM
Is it possible to apply an API option like QuickTimeUTC only to part of an exiftool call?

No.  You would need to run it separately or split the command with an -execute option, which basically the same.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

kennethmac2000

Quote from: StarGeek on July 17, 2021, 10:33:42 AM
Quote from: kennethmac2000 on July 17, 2021, 08:32:43 AM
Is it possible to apply an API option like QuickTimeUTC only to part of an exiftool call?

No.  You would need to run it separately or split the command with an -execute option, which basically the same.

But unless I'm missing something, if I ran, say exiftool -if 'XXX' -execute YYY -common_args ., that wouldn't help, because exiftool would first execute every iteration of "-if 'XXX'" (effectively sending the result of each evaluation of that conditional into a black hole), and it would then execute every iteration of "YYY" (unconstrained by the conditional).

I need to intercept each iteration of the 'for loop' and then do something in another command depending on the initial result, but, again, unless I'm missing something, that's not possible with exiftool 'out of the box'.

As far as I can see, I would have to write some shell code to iterate through the contents of a directory and call exiftool -if 'XXX' on one file at a time, looking for either a 0 or a 2 exit status, and then in the case of a 0, making a second call to exiftool, also on that single file.

Am I right? (Or if not can anyone suggest some pseudocode that does what I want with a single exiftool call?)

StarGeek

Quote from: kennethmac2000 on July 17, 2021, 04:42:11 PM
But unless I'm missing something, if I ran, say exiftool -if 'XXX' -execute YYY -common_args ., that wouldn't help, because exiftool would first execute every iteration of "-if 'XXX'" (effectively sending the result of each evaluation of that conditional into a black hole), and it would then execute every iteration of "YYY" (unconstrained by the conditional).

Which is why I said it's basically the same as running two commands.

QuoteI need to intercept each iteration of the 'for loop' and then do something in another command depending on the initial result, but, again, unless I'm missing something, that's not possible with exiftool 'out of the box'.

Correct

QuoteAs far as I can see, I would have to write some shell code to iterate through the contents of a directory and call exiftool -if 'XXX' on one file at a time, looking for either a 0 or a 2 exit status, and then in the case of a 0, making a second call to exiftool, also on that single file.

You don't want to call exiftool on every file one at a time unless you want the processing time to be increased by a magnitude. This is Common Mistake #3.

Exiftool's biggest performance hit is the startup time and running exiftool once on every file twice will take significantly longer than running a two commands on all the files and filtering with the -if option.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

kennethmac2000

Quote from: StarGeek on July 17, 2021, 06:30:08 PM
You don't want to call exiftool on every file one at a time unless you want the processing time to be increased by a magnitude. This is Common Mistake #3.

Exiftool's biggest performance hit is the startup time and running exiftool once on every file twice will take significantly longer than running a two commands on all the files and filtering with the -if option.

Yes, I assumed this. :)

But then I still have two (related) questions:
1) What am I getting the first exiftool call to do (given that it's not actually going to modify the files in question at this stage)? In pseudocode terms, IF x THEN what?
2) How am I passing the result of the first call (for each file) to the second call? Is there a canonical way of doing this?

Phil Harvey

Quote from: kennethmac2000 on July 17, 2021, 08:32:43 AM
Quote from: Phil Harvey on August 29, 2019, 11:31:27 AM
'-createdate<${createdate;$_ = undef if /^0000/}'

As far as I can tell, this only works if the API option QuickTimeUTC is not set, as otherwise a binary zero value gets converted to 1904-01-01 00:00:00. One could match on /^1904/ in that case, but that feels rather less elegant.

This is perfectly elegant, and handles both cases:

'-createdate<${createdate;$_ = undef if /^(0000|1904)/}'

- 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 ($).

kennethmac2000

Quote from: Phil Harvey on July 18, 2021, 06:24:39 AM
Quote from: kennethmac2000 on July 17, 2021, 08:32:43 AM
Quote from: Phil Harvey on August 29, 2019, 11:31:27 AM
'-createdate<${createdate;$_ = undef if /^0000/}'

As far as I can tell, this only works if the API option QuickTimeUTC is not set, as otherwise a binary zero value gets converted to 1904-01-01 00:00:00. One could match on /^1904/ in that case, but that feels rather less elegant.

This is perfectly elegant, and handles both cases:

'-createdate<${createdate;$_ = undef if /^(0000|1904)/}'

- Phil

I get that I could do that. However, as a bit of an exercise/challenge, I would now like to understand how I could run exiftool once, store the result in some sort of intermediate 'scratch' file, and then run exiftool a second time with that scratch file as input (as described in my previous post).

That said, and as an aside, have you thought of allowing people to interact with the raw binary values of tags? (I know you can see them using the -v3 tag, but actually reference them in an -if for example.)

StarGeek

Quote from: kennethmac2000 on July 18, 2021, 09:17:46 AM
I get that I could do that. However, as a bit of an exercise/challenge, I would now like to understand how I could run exiftool once, store the result in some sort of intermediate 'scratch' file, and then run exiftool a second time with that scratch file as input (as described in my previous post).

You could use the -efile option.

QuoteThat said, and as an aside, have you thought of allowing people to interact with the raw binary values of tags? (I know you can see them using the -v3 tag, but actually reference them in an -if for example.)

You do with the -n (--printConv) option or its # shortcut.  The -api QuickTimeUTC option overrides that.  See details in that link.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

kennethmac2000

Quote from: StarGeek on July 18, 2021, 10:53:13 AM
You could use the -efile option.

Thanks. I'll try that.

Quote from: StarGeek on July 18, 2021, 10:53:13 AM
You do with the -n (--printConv) option or its # shortcut.  The -api QuickTimeUTC option overrides that.  See details in that link.

That doesn't seem to work for date/time values - they still appear formatted. I saw this being discussed on another thread on this forum, where it was noted that you could see the raw values with -v3, but you couldn't actually 'get hold of' them to do anything with.

kennethmac2000

Quote from: Phil Harvey on July 18, 2021, 06:24:39 AM
This is perfectly elegant, and handles both cases:

'-createdate<${createdate;$_ = undef if /^(0000|1904)/}'

- Phil

Checking for 1904 doesn't differentiate between the scenario where -api QuickTimeUTC has interpreted 0 as 1904-01-01T00:00:00+00:00 and the scenario where 1904-01-01T00:00:00+00:00 has actually been set explicitly. Could those be different (binary) values?

Interestingly, if f I run 'exiftool -api QuickTimeUTC -QuickTime:CreateDate mymovie.mp4, I get the following output:
Create Date                     : 1904:01:01 00:00:00+00:00

If I then run exiftool -api QuickTimeUTC -QuickTime:CreateDate='1904:01:01 00:00:00+00:00' mymovie.mp4 (ie, literally copying the value output by the command above), and then run 'exiftool -api QuickTimeUTC -QuickTime:CreateDate mymovie.mp4 again, I get the following output:
Create Date                     : 2004:01:01 00:00:00+00:00

If I check the value of QuickTime:CreateDate by running exiftool -v3 mymovie.mp4, I see it now has the value bc 19 13 80, whereas prior to running the above update command it had the value 00 00 00 00. Is it possible to actually get it back to 00 00 00 00?

StarGeek

#20
Quote from: kennethmac2000 on July 18, 2021, 01:57:23 PM
Checking for 1904 doesn't differentiate between the scenario where -api QuickTimeUTC has interpreted 0 as 1904-01-01T00:00:00+00:00 and the scenario where 1904-01-01T00:00:00+00:00 has actually been set explicitly. Could those be different (binary) values?

Phil will have to comment on the specifics, but it might be that the spec doesn't allow for timestamps earlier than 1970:01:01 00:00:01.  At least that's the earliest I can set it without problems.

Edit: The date is held as an unsigned 32 bit integer (see QuickTime MovieHeader Tags, so it probably can't be set before the start of epoch time.  Still just a guess on my part.

QuoteIs it possible to actually get it back to 00 00 00 00?

Delete the tag with
exiftool -QuickTime:CreateDate= mymovie.mp4

The tag itself cannot be completely removed and will still show 0s, but that's the equivalent to deleting it.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

The QuickTime epoch is 1904, but ExifTool has problems with dates before 1970 because it uses the standard C date/time library functions which have an epoch of 1970.

- 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 ($).