1
0
mirror of https://github.com/moex3/flac2mp3.pl synced 2024-11-28 05:26:40 -05:00

Add id3v2 tag escaping

This commit is contained in:
moex3 2022-12-20 17:00:17 +01:00
parent 1628834c1b
commit 63edb804ce
No known key found for this signature in database
GPG Key ID: ABC92E00CF59BB7A

View File

@ -29,10 +29,10 @@ my %genreMap = (
# Vorbis tag string => Mp3 tag value # Vorbis tag string => Mp3 tag value
# where mp3 tag value may be: # where mp3 tag value may be:
# undef -> Skip this tag # undef -> Skip this tag
# A string -> Use this as the mp3 tag, and use the vorbis tag value as value # A string -> Use this as the mp3 tag, and use the vorbis tag value as value (tags are escaped)
# code -> Execute this function. This should return an array, where [0] is the tag, [1] is the value. # code -> Execute this function. This should return an array, where [0] is the tag, [1] is the value. (tags are not escaped)
# An array (str, str) -> [0] is the mp3 tag to use, [1] is the value prefix # An array (str, str) -> [0] is the mp3 tag to use, [1] is the value prefix (tags are escaped)
# An array (str, code) -> [0] is the mp3 tag to use, [1] is a function that is executed, and the result is the tag value # An array (str, code) -> [0] is the mp3 tag to use, [1] is a function that is executed, and the result is the tag value (tags are not escaped)
# The code-s here will be called with the flac tags hashmap # The code-s here will be called with the flac tags hashmap
my %idLookup = ( my %idLookup = (
album => 'TALB', album => 'TALB',
@ -83,7 +83,7 @@ my %idLookup = (
date => sub { date => sub {
my $t = shift; my $t = shift;
my $date = $t->{date}[0]; my $date = $t->{date}[0];
if (length($date) == 4) { # Only year if (length($date) == 4 && $date =~ m/\d{4}/) { # Only year
return ["TYER", "$date"]; return ["TYER", "$date"];
} }
if (!($date =~ m/^\d{4}[\.-]\d{2}[\.-]\d{2}$/)) { if (!($date =~ m/^\d{4}[\.-]\d{2}[\.-]\d{2}$/)) {
@ -97,10 +97,10 @@ my %idLookup = (
'release date' => 'TDOR', # Also for 2.4 only 'release date' => 'TDOR', # Also for 2.4 only
isrc => 'TSRC', isrc => 'TSRC',
barcode => ['TXXX', 'BARCODE:'], barcode => ['TXXX', 'BARCODE:'],
catalog => ['TXXX', sub { return "CATALOGNUMBER:" . tagmap_catalogid(shift, 'catalog'); } ], catalog => ['TXXX', sub { return "CATALOGNUMBER:" . mp3TagEscapeOwn(tagmap_catalogid(shift, 'catalog')); } ],
catalognumber => ['TXXX', sub { return "CATALOGNUMBER:" . tagmap_catalogid(shift, 'catalognumber'); } ], catalognumber => ['TXXX', sub { return "CATALOGNUMBER:" . mp3TagEscapeOwn(tagmap_catalogid(shift, 'catalognumber')); } ],
catalogid => ['TXXX', sub { return "CATALOGNUMBER:" . tagmap_catalogid(shift, 'catalogid'); } ], catalogid => ['TXXX', sub { return "CATALOGNUMBER:" . mp3TagEscapeOwn(tagmap_catalogid(shift, 'catalogid')); } ],
labelno => ['TXXX', sub { return "CATALOGNUMBER:" . tagmap_catalogid(shift, 'labelno'); } ], labelno => ['TXXX', sub { return "CATALOGNUMBER:" . mp3TagEscapeOwn(tagmap_catalogid(shift, 'labelno')); } ],
#'encoded-by' => 'TENC', #'encoded-by' => 'TENC',
#encoder => 'TSSE', #encoder => 'TSSE',
#encoding => 'TSSE', #encoding => 'TSSE',
@ -112,16 +112,17 @@ my %idLookup = (
my $genreName = shift->{genre}[0]; my $genreName = shift->{genre}[0];
if (!exists($genreMap{lc($genreName)})) { if (!exists($genreMap{lc($genreName)})) {
# If no genre number exists, use the name # If no genre number exists, use the name
return $genreName; return mp3TagEscapeOwn($genreName);
} }
return $genreMap{$genreName}; return mp3TagEscapeOwn($genreMap{$genreName});
}], }],
#mood => ['TMOO', sub { #mood => ['TMOO', sub {
#}], #}],
bpm => 'TBPM', bpm => 'TBPM',
comment => ['COMM', sub { comment => ['COMM', sub {
return undef if (defined($opt_comment) && $opt_comment eq ""); return undef if (defined($opt_comment) && $opt_comment eq "");
return "Comment:" . shift->{comment}[0]; # Use the default empty description and default english language
return mp3TagEscapeOwn(shift->{comment}[0]);
}], }],
copyright => 'TCOP', copyright => 'TCOP',
language => 'TLAN', language => 'TLAN',
@ -247,7 +248,7 @@ sub iterFlac {
} }
#print(Dumper(\$mid3v2TagLine)); #print(Dumper(\$mid3v2TagLine));
my $mid3v2TagCmd = "mid3v2 $mid3v2TagLine -- '$dest'"; my $mid3v2TagCmd = "mid3v2 -e $mid3v2TagLine -- '$dest'";
#print("Mid3V2 Debug - CMD: [$mid3v2TagCmd]\n"); #print("Mid3V2 Debug - CMD: [$mid3v2TagCmd]\n");
qx($mid3v2TagCmd); qx($mid3v2TagCmd);
if ($? != 0) { if ($? != 0) {
@ -358,7 +359,6 @@ sub tagsToOpts {
my $tags = shift; my $tags = shift;
my @tagopts; my @tagopts;
# TODO escape stuff?
foreach my $currKey (keys (%$tags)) { foreach my $currKey (keys (%$tags)) {
if (!exists($idLookup{$currKey})) { if (!exists($idLookup{$currKey})) {
print("Tag: '$currKey' doesn't have a mapping, skipping\n"); print("Tag: '$currKey' doesn't have a mapping, skipping\n");
@ -369,6 +369,7 @@ sub tagsToOpts {
if ($type eq "" && defined($tagMapping)) { if ($type eq "" && defined($tagMapping)) {
# If tag name is defined and tag contents exists (aka not silenced) # If tag name is defined and tag contents exists (aka not silenced)
foreach my $tagCont (@{$tags->{$currKey}}) { foreach my $tagCont (@{$tags->{$currKey}}) {
mp3TagEscape(\$tagCont);
shellsan(\$tagCont); shellsan(\$tagCont);
push(@tagopts, ["$tagMapping", "$tagCont"]); push(@tagopts, ["$tagMapping", "$tagCont"]);
} }
@ -383,6 +384,7 @@ sub tagsToOpts {
if ($mapContType eq "") { if ($mapContType eq "") {
foreach my $tagValue (@{$tags->{$currKey}}) { foreach my $tagValue (@{$tags->{$currKey}}) {
mp3TagEscape(\$tagValue);
shellsan(\$tagValue); shellsan(\$tagValue);
push(@tagopts, ["$mapKey", "$mapCont$tagValue"]); push(@tagopts, ["$mapKey", "$mapCont$tagValue"]);
} }
@ -448,6 +450,16 @@ sub shellsan {
${$_[0]} =~ s/'/'\\''/g; ${$_[0]} =~ s/'/'\\''/g;
} }
# Escape ':', and '\' characters in mp3 tag values
sub mp3TagEscape {
${$_[0]} =~ s!([:\\])!\\$1!g;
}
sub mp3TagEscapeOwn {
my $s = shift;
mp3TagEscape(\$s);
return $s;
}
sub usage { sub usage {
print("Usage: flac2mp3.pl [-h | --help] [-r] [-3] [-g | --genre NUM] <input_dir> <output_dir>\n"); print("Usage: flac2mp3.pl [-h | --help] [-r] [-3] [-g | --genre NUM] <input_dir> <output_dir>\n");
exit 1; exit 1;