Main Menu

Recent posts

#1
Newbies / Re: How to extract the content...
Last post by StarGeek - Today at 04:34:29 PM
Use the -S (-veryShort) option or the -p (-printFormat) option.

I haven't been able to figure out how to make it work on more than one file at a time and am waiting to see if Phil can offer any insight, but I suspect the weather is very good in his area ATM and he's out birding.
#2
Newbies / Re: How to extract the content...
Last post by FixEUser - Today at 03:34:01 PM
Thanks for your detailed answer and your efforts.

QuoteThat sounds like you didn't save the complete config file.  Line 9675 in the code is checking for the the very last line of the config file
You are right! My fault, the last line was missing for unknown reasons.

Please remember that I really would prefer the content of the specified tag itself:
e5d018af-3a9d-4ed9-9593-a7b0b63c4579
not the output of the entire line:
[Composite]    MusicBrainzTRMId                : e5d018af-3a9d-4ed9-9593-a7b0b63c4579

Otherwise, I would still have to use an additional batch to strip away the part before the : (colon) to get the needed part after the : (colon) and the space.
#3
Newbies / Re: How to extract the content...
Last post by StarGeek - Today at 02:55:40 PM
Running the command on multiple files, I do see there is a problem where subsequent files will return an entry containing HASH(0x...) for previously defined tags, so I'll have to work on that.  But on single files, it works correctly.

Quote from: FixEUser on Today at 04:48:34 AMThere are at least 3 problems with your script:

1) It doesn't return any other value then without -config join_tags_ID3-config

I'm not quite sure what you mean here. It still extracts all the rest of the data normally and as I said, extracting just the data you want will probably require a config file. Maybe Phil can figure out some way of extracting just the data for a specific copy of the tag without requiring it to be the exact same copy location each time, but I can't think of any way to do that.

Quote2) It returns an error "join_tags_ID3.config did not return a true value at Image/ExifTool.pm line 9675."

That sounds like you didn't save the complete config file.  Line 9675 in the code is checking for the the very last line of the config file
1; #end
Quote3) For other readers: The config file needs to be named exactly the same as you use it in the command line:
exiftool -config join_tags_ID3.config -G1 -a -s -UserDefinedText Y:\temp\x\y\test.mp3

I'm not sure what your point is. If you're using a config file with the -Config option, you have to use the same name you use when you saved it to disk.

Quote@StarGeek: I'm not sure if you understand my initial question:

I asked for a solution to get 1 (one) specific tag content, for example "MusicBrainz Album Artist Id".
The idea would be a (not yet working) syntax like
exiftool -config specificID3.config -G1 -a -s -UserDefinedText("MusicBrainz Album Artist Id") music.mp3and then get only this value:
d87e52c5-bb8d-4da8-b941-9f4928627dc8

How could I achieve that?

That's what my config file attempts to do. At least, once I fix the bug. It would take the UserDefinedText that contains "(MusicBrainz Album Artist Id)" and return the contents of that as a tag called MusicBrainzAlbumArtistId.

It works correctly on a single file, just not in batch ATM.
Example, the UserDefinedText that contains "(MusicBrainz TRM Id)" creates a tag called MusicBrainzTRMId which containts the value of "e5d018af-3a9d-4ed9-9593-a7b0b63c4579".
C:\>exiftool -config join_tags_ID3.config -G1 -a -s -MusicBrainzTRMId "Y:/Music/Music/Sorted/Albums/Journey/Greatest_Hits/01-Only_the_Young.mp3"
[Composite]     MusicBrainzTRMId                : e5d018af-3a9d-4ed9-9593-a7b0b63c4579

Listing all the "MusicBrainz" tags created
C:\>exiftool -config join_tags_ID3.config -G1 -a -s -UserDefinedText -*Brainz* "Y:/Music/Music/Sorted/Albums/Journey/Greatest_Hits/01-Only_the_Young.mp3"
[ID3v2_3]       UserDefinedText                 : (MusicBrainz TRM Id) e5d018af-3a9d-4ed9-9593-a7b0b63c4579
[ID3v2_3]       UserDefinedText                 : (MusicBrainz Artist Id) abd506e1-6f2b-4d6f-b937-92c267f6f88b
[ID3v2_3]       UserDefinedText                 : (MusicBrainz Album Id) 43ca7ac8-bd36-4468-bab4-004a9a34de66
[ID3v2_3]       UserDefinedText                 : (MusicBrainz Album Type) compilation
[ID3v2_3]       UserDefinedText                 : (MusicBrainz Album Status) official
[ID3v2_3]       UserDefinedText                 : (MusicBrainz Album Artist Id)
[ID3v2_3]       UserDefinedText                 : (MusicBrainz Album Release Country) US
[Composite]     MusicBrainzAlbumReleaseCountry  : US
[Composite]     MusicBrainzTRMId                : e5d018af-3a9d-4ed9-9593-a7b0b63c4579
[Composite]     MusicBrainzArtistId             : abd506e1-6f2b-4d6f-b937-92c267f6f88b
[Composite]     MusicBrainzAlbumId              : 43ca7ac8-bd36-4468-bab4-004a9a34de66
[Composite]     MusicBrainzAlbumType            : compilation
[Composite]     MusicBrainzAlbumStatus          : official
[Composite]     MusicBrainzAlbumArtistId        :

QuoteAre you sure that
my $table = Image::ExifTool::GetTagTable('Image::ExifTool::Composite');
is the correct way to get the UserDefinedText content?

This isn't getting the UserDefinedText. This is the part that creates the new tags.  The new tags get added to the Composite group.

The parts that get the UserDefinedText are
my $nameTag = 'UserDefinedText';and
            Desire => {
                0 => $nameTag,

Final edit: I haven't been able to fix the HASH problem when using it on multiple files, so I'm bugging Phil about fixing it.
#4
Quote from: maxardis on Today at 02:21:13 PMJust one question.  I cannot seem to find any mention of ConvertUnixTime() in man pages nor by googling (only mentioned on some other threads on this forum).  And you also say that it is an internal function.  So I guess it means that it might "disappear" with some future version of exiftool right?  It is kind of a hack, sort of, right?

Yes, the only way to know about it is to dig through the source code or have seen Phil use it in the past.  I seriously doubt it will disappear, as it is a basic part of so much of the exiftool code and would most likely require a huge rewrite of a lot of code to remove it. And Phil strives hard to make sure any changes are backwards compatible. For example, the -AddTagsFromFile option no longer appears in the documentation, as it has been replaced with a different format, but it still will work if you use it.

Hack? I wouldn't say so. It's more of a function that isn't documented outside of the source code

Quote
Quote from: StarGeek on Today at 12:13:34 PMYou don't mention your OS, but you appear to be on Mac/Linux

I am on Linux if that is important, yes.  I can translate Windows CMD into Linux one no problem.  It's pretty much the same

It's important when it comes to quoting, as double quotes on Linux/Mac will change something like $DateTimeOriginal from an exiftool tag into a shell variable.  It's also important with something like the asterisk, as using it as an exiftool wildcard such as -*Date will cause file globbing on Mac/Linux unless single quotes are used '-*Date'
#5
That works perfectly.  Thank you very much.

Just one question.  I cannot seem to find any mention of ConvertUnixTime() in man pages nor by googling (only mentioned on some other threads on this forum).  And you also say that it is an internal function.  So I guess it means that it might "disappear" with some future version of exiftool right?  It is kind of a hack, sort of, right?

Quote from: StarGeek on Today at 12:13:34 PMYou don't mention your OS, but you appear to be on Mac/Linux

I am on Linux if that is important, yes.  I can translate Windows CMD into Linux one no problem.  It's pretty much the same
#6
Quote from: maxardis on Today at 06:52:02 AMI am trying to do this:

exiftool -p '${exif:DateTimeOriginal;ShiftTime(${exif:OffsetTimeOriginal}, -1)} ${directory}/${filename}' ./dir/*

And what I get is a warning:
Warning: Bareword "OffsetTimeOriginal" not allowed while "strict subs" in use for 'exif:DateTimeOriginal'.  I don't understand that message and I don't know what I am doing wrong, nor how to fix it.

Nice attempt, but it isn't that simple to access a different tag within the processing of another tag. The error message is directly from the underlying Perl processor. Accessing a second tag from within a tag can be done, but I think this would be a better way.

First, instead of using DateTimeOriginal, use SubSecDateTimeOriginal.  This is a Composite tag that combines DateTimeOriginal, OffsetTimeOriginal, and SubSecTimeOriginal.  Then the DateFmt helper function is used to convert that to a Unix time stamp, the internal exiftool function of ConvertUnixTime is used to convert that to a normal date in the standard EXIF format (colons instead of hyphens), and DateFmt is used again to convert that into the format you're looking for.

Example
C:\>exiftool -G1 -a -s -SubSecDateTimeOriginal y:\!temp\Test4.jpg
[Composite]     SubSecDateTimeOriginal          : 2024:05:20 12:00:00-07:00

C:\>exiftool -p "${SubSecDateTimeOriginal;DateFmt('%s');$_=ConvertUnixTime($_);DateFmt('%Y-%m-%dT%H:%M:%S')}" y:\!temp\Test4.jpg
2024-05-20T19:00:00

You don't mention your OS, but you appear to be on Mac/Linux.  The above command would be for Windows CMD, so you'll have to swap double/single quotes.
#7
Newbies / Re: How to extract the content...
Last post by FixEUser - Today at 08:56:52 AM
I think, I have found a workaround with a Windows batch file.
This may be a little bit more convenient for Windows users.

Write (copy & paste) this code in a batch file and name it like
ShowContentOfThisUndefinedText.cmd

ECHO OFF
@CLS
SETLOCAL enabledelayedexpansion
FOR /F "tokens=2 delims=)" %%M IN ('   
    exiftool.exe -a -UserDefinedText -ext mp3 -recurse . ^| findstr /c:%1 /i
    ') DO (   
          SET LeftTrimmedValue=%%M         
          ECHO !LeftTrimmedValue:~1!         
          )

This batch file assumes, that exiftool.exe is in the same directory as the batch.
Otherwise, you have to write the full path to your exiftool.exe like
C:\Path\To\My\exiftool.exe

Then copy the batch file to the root directory in which the mp3 files to be checked are stored.

Open a CMD window in this root directory.

Start the batch file and add the string you want to search for in the UndefinedText ID3 tag like this:
ShowContentOfThisUndefinedText "musicbrainz album artist id"and you get the wanted
d87e52c5-bb8d-4da8-b941-9f4928627dc8

Explanations for the batch code:
1) exiftool shows all the ID3 TXXX tags (aka "UserDefinedText") for all mp3 files recursively
2) the Windows command FINDSTR searches for all lines that contain the given string like "musicbrainz album artist id" case-IN-sensitive
3) to get only the tag content (neither "UserDefinedText" nor the tag name in brackets), only the second token after the closing bracket will be outputted
3) to left trim the found content, the first character will be stripped away

Remark:
This batch is only intended for MP3 files and the ID3 TXXX "UserDefinedText" tag.
#8
Hello,

What I would like is to generate dates(*) in UTC (in ISO format) from exif tags for all files in directory without modifying files.

Similarly to a tool like sha1sum I would like to write something like: exiftool (magic options here...) ./directory/* and get output to stdout like so:

2024-01-01T10:10:10  ./directory/file1.jpg
2024-01-01T10:11:10  ./directory/file2.jpg
2024-01-02T10:10:10  ./directory/file3.jpg
...

Output similar to sha1sum but instead of hashes I get dates.

(*) When I say dates what I mean exactly is combination of tags exif:DateTimeOriginal + exif:OffsetTimeOriginal.


What I was able to figure out is:

$ exiftool -d '%Y-%m-%dT%H:%M:%S' -p '${exif:DateTimeOriginal}${exif:OffsetTimeOriginal} ${directory}/${filename}' ./dir/*

This gives me almost what I want.  It gives me the information to stdout in format similar to sha1sum, it gives me dates in ISO format, but it doesn't give me the dates in UTC.

By googling around I can see that there is something like ShiftTime() function that maybe I could use, but unfortunately I cannot make it work.  So I am here for your help.


I am trying to do this:

exiftool -p '${exif:DateTimeOriginal;ShiftTime(${exif:OffsetTimeOriginal}, -1)} ${directory}/${filename}' ./dir/*

And what I get is a warning: Warning: Bareword "OffsetTimeOriginal" not allowed while "strict subs" in use for 'exif:DateTimeOriginal'.  I don't understand that message and I don't know what I am doing wrong, nor how to fix it.

Hope you can help me here.  Thank you in advance.
#9
Newbies / Re: How to extract the content...
Last post by FixEUser - Today at 04:48:34 AM
Thank you for your attempt.

There are at least 3 problems with your script:

1) It doesn't return any other value then without -config join_tags_ID3-config
2) It returns an error "join_tags_ID3.config did not return a true value at Image/ExifTool.pm line 9675."
3) For other readers: The config file needs to be named exactly the same as you use it in the command line:
exiftool -config join_tags_ID3.config -G1 -a -s -UserDefinedText Y:\temp\x\y\test.mp3

@StarGeek: I'm not sure if you understand my initial question:

I asked for a solution to get 1 (one) specific tag content, for example "MusicBrainz Album Artist Id".
The idea would be a (not yet working) syntax like
exiftool -config specificID3.config -G1 -a -s -UserDefinedText("MusicBrainz Album Artist Id") music.mp3and then get only this value:
d87e52c5-bb8d-4da8-b941-9f4928627dc8

How could I achieve that?

PS
Are you sure that
my $table = Image::ExifTool::GetTagTable('Image::ExifTool::Composite');
is the correct way to get the UserDefinedText content?
#10
Newbies / Re: Help requested - Syntax Co...
Last post by StarGeek - May 19, 2024, 08:40:48 PM
One thing that comes to mind is the sidecar files. They might (probably?) not have the same file system time stamps as the main files.

Also, you say "original create date on the file (not the last modified" but you are using CreateDate, not the file system tag, FileCreateDate. CreateDate is a tag embedded in the file and should just about always be exactly the same as DateTimeOriginal, though DateTimeOriginal is less likely to be in videos.

But then you run into the problem that the CreateDate in video files is set to UTC, not local time.  I believe that iPhones will set CreationDate to the local time, so you might put an entry for that to the right of CreateDate.

And you can always test things out by using Testname instead of Filename.  That will output what the file path/name would be without actually moving the file.