Here is a quick and dirty way to find out what tag name a tag ID was assigned in a (QuickTime) group:
#!/usr/bin/perl -w
use strict;
my $group = shift // 'ItemList';
my $id = shift // "\xa9day";
say STDOUT ref ? $_->{Name} : $_ for do
{
no strict 'refs';
require Image::ExifTool::QuickTime;
my $var = "Image::ExifTool::QuickTime::$group";
${$var}{$id};
};
Does the API provide a better way to get the tag name corresponding to a tag ID in a group?
Thanks
There is no way to do this in general. The tag name may depend on other metadata in the file, so you won't know the actual tag name until a file is processed.
But for simple tags (ie. when ${$var}{$id} returns a HASH reference and not an ARRAY reference, then what you are doing is close, but instead requiring the table, you should do this:
my $table = Image::ExifTool::GetTagTable("Image::ExifTool::QuickTime::$group");
to prepare the table for access.
- Phil
Excellent. Thanks. :) The Image::ExifTool::GetTagTable function ensures that tag IDs map, never to scalars, but always to hash references with a Name key, doesn't it? (So, there is no need to test for ref.)
#!/usr/bin/perl -w
use strict;
use Image::ExifTool;
my $type = shift // 'QuickTime';
my $group = shift // 'ItemList';
my $id = shift // "\xa9day";
my $table = Image::ExifTool::GetTagTable ( "Image::ExifTool::${type}::${group}" ) or exit;
my $tag = $table->{$id} or exit;
say STDOUT $tag->{Name};
Yes. After calling GetTagTable() the ID's will always map to a HASH ref or an ARRAY of HASH refs. And Name is guaranteed to exist. (Not that I recommend accessing ExifTool internals like this, but this is not likely to change.)
- Phil
Quote from: Phil Harvey on August 03, 2020, 09:44:23 PM
(Not that I recommend accessing ExifTool internals like this, but this is not likely to change.)
I understand the risks. Let me explain the situation. Although the family 7 group names approach is working --- thanks for that --- family 7 group names are... well,
group names; and so, an external app that only knows what IDs a file format uses, still needs to find out somehow what tag
name an ID corresponds to according to Image::ExifTool, in order to be able use family 7 group names at all.
In other words, family 7 group names can disambiguate a tag, but can't
specify a tag.
Ideally, I wish I could do without tag names, as I already have all the IDs. But I can't. What I can do now is either hard-code a table from IDs to names, or look up a table from GetTagTable() on the fly. Both ways, I'm making assumptions about ExifTool internals: after all, tag names may change just as much as GetTagTable().
For this reason, I'm writing an Image::ExifTool::ByID module with a
...ByID() family of wrapper methods that translate ID to names, ensure a group is specified, append
:ID-<tag_id> to the group name, and then invoke standard methods such as
SetNewValue().
Quote from: dae65 on August 04, 2020, 04:19:32 AM
an external app that only knows what IDs a file format uses, still needs to find out somehow what tag name an ID corresponds to according to Image::ExifTool, in order to be able use family 7 group names at all.
Knowing the ID, here is how you get the family 7 group name:
sub GetIDGroup($)
{
my $id = shift;
$id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge;
return "ID-$id";
}
- Phil
Thanks. I couldn't make myself understood. Knowing the ID (albm), and generating a 7 group name from it (ID-albm), is not enough. We need the ExifTool tag name (Album) also.
This doesn't work:
$ exiftool -ItemList:ID-albm=ABCDEF file.m4a
Warning: Tag 'ItemList:ID-albm' is not defined or has a bad language code
Nothing to do.
It should be:
$ exiftool -ItemList:ID-albm:Album=ABCDEF file.m4a
1 image files updated
As it seems, family 7 names may well disambiguate a tag, but they can't specify a tag. That's why I'm looking for a reliable way of getting names (Album) from IDs (albm).
Right. I understand now. Upon re-reading your post, this should have been clear.
- Phil