I'm attempting to create a composite tag to allow accessing the myriad of ways replaygain data is stored in different formats (well, 2 ways in the formats I've looked at so far). I've got the base case of directly copying the tag from FLAC files and just returning 0 if not set, but trying to access the ID3 tag has been presenting some difficulties. So far I have this:
%Image::ExifTool::UserDefined = (
'Image::ExifTool::Composite' => {
ReplaygainAlbumGainClean => {
Desire => {
0 => 'ReplaygainAlbumGain',
1 => 'UserDefinedText',
},
ValueConv => sub {
my $val = shift;
my @user = (@$val[1]);
my @gainTags = (@$val[0]);
foreach (@user) {
next unless $_ && $_ =~ /replaygain_album_gain/;
push (@gainTags, $_);
}
my $gain = 0;
foreach (@gainTags) {
next unless $_ && $_ =~ /([-+]?\d+(?:\.\d+))/;
$gain = $1;
}
return $gain;
},
},
},
);
1;
But that only gets one of the UserDefinedText values. Somehow I need to get all the duplicate values into @user so I can find the one I'm actually interested in.
If I understand correctly, there are duplicate UserDefinedText tags in the file and you want to scan through them all. This is a bit tricky since it gets into the ExifTool internals a bit. There may be better ways to do this, but the one that occurs to me is to do this in your ValueConv:
for (my $i=0; ; ++$i) {
my $tagKey = 'UserDefinedText';
$tagKey .= " ($i)" if $i;
my $val = Sself->GetValue($tagKey);
last unless defined $val;
# process value here
}
- Phil
That's exactly what I wanted to do. For some reason using GetValue wouldn't let me access the duplicates still, but GetInfo did :). My final ValueConv was:
my $val = shift;
my $self = shift;
my @gainTags = (@$val[0]);
my $userTags = $self->GetInfo("*:UserDefinedText");
foreach (values %$userTags) {
next unless $_ && $_ =~ /replaygain_album_gain/
push (@gainTags, $_);
}
my $gain = 0;
foreach (@gainTags) {
next unless $_ && $_ =~ /([+-]?\d+(?:\.\d+)?)/;
$gain = $1;
}
return $gain;
Thanks.
I would be careful using GetInfo from within a ValueConv because it will overwrite information in the ExifTool object that was retrieved from the previous GetInfo call. This is why I used my knowledge of the internal tag keys instead. I should think about this to see if there is a better solution.
- Phil