Browse Source

Some fixes and some new features

Fix:
    - Use TXXX for arranger, performer (because mid3v2 doesn't recognize
      the TIPL and other tags for this. :(
    - Map lyricist tag
    - Map origin and origintype to TXXX fields
    - Remoeavbe comment tag

Adds:
    - Add option for embedded image art control
    - Enforce TXXX key uniqueness and merge them together with a ;
      character if there are more that one of them.
master
moex3 1 year ago
parent
commit
be6853c5da
No known key found for this signature in database GPG Key ID: ABC92E00CF59BB7A
1 changed files with 80 additions and 10 deletions
  1. +80
    -10
      flac2mp3.pl

+ 80
- 10
flac2mp3.pl View File

@@ -11,6 +11,7 @@ my $opt_no_genre;
my $opt_comment;
my $opt_catid;
my $opt_rg;
my $opt_embedcover;

# TODO fill this out
my %genreMap = (
@@ -46,14 +47,16 @@ my %idLookup = (
albumartistsort => 'TSO2', # Maybe?
artist => 'TPE1',
artistsort => 'TSOP',
arranger => ['TIPL', 'arranger:'],
# arranger => ['TIPL', 'arranger:'],
arranger => ['TXXX', 'ARRANGER:'],
author => 'TEXT',
composer => 'TCOM',
conductor => 'TPE3',
engineer => ['TIPL', 'engineer:'],
djmixer => ['TIPL', 'DJ-mix:'],
mixer => ['TIPL', 'mix:'],
#performer => 'TMCL', # This produces some really weird tags
# performer => ['TMCL', "instrument:"], # Should be like this, but mid3v2 says it doesn't have this tag.
performer => ['TXXX', "PERFORMER:"],
producer => ['TIPL', 'producer:'],
publisher => 'TPUB',
organization => 'TPUB',
@@ -141,10 +144,13 @@ my %idLookup = (
#replaygain_track_peak => 'TXXX=REPLAYGAIN_TRACK_PEAK',
script => ['TXXX', 'SCRIPT:'],
lyrics => 'USLT',
lyricist => 'TEXT',
circle => ['TXXX', 'CIRCLE:'],
event => ['TXXX', 'EVENT:'],
discid => ['TXXX', 'DISCID:'],
originaltitle => ['TXXX', 'ORIGINALTITLE:'],
origin => ['TXXX', 'ORIGIN:'],
origintype => ['TXXX', 'ORIGINTYPE:'],
);
sub tagmap_catalogid {
my $t = shift;
@@ -164,6 +170,7 @@ GetOptions(
"help|h" => \$opt_help,
"catid=s" => \$opt_catid,
"comment=s" => \$opt_comment,
"cover=s" => \$opt_embedcover,
"tagreplace|t=s" => \@opt_tagreplace,
"320|3" => \$opt_cbr,
) or die("Error in command line option");
@@ -213,6 +220,9 @@ sub iterFlac {
}
argsToTags($tags, $flac_o);
#foreach (%$tags) {
#print("Copying tag '$_->[0]=$_->[1]'\n");
#}
my $tagopts = tagsToOpts($tags);

#print("Debug: @$tagopts\n");
@@ -248,10 +258,25 @@ sub iterFlac {
embedImageFromFlac($flac, $dest);
}

sub getMimeType {
my $file = shift;
shellsan(\$file);
my $mime = qx(file -b --mime-type '$file');
chomp($mime);
return $mime;
}

sub embedImageFromFlac {
my $flac = shift;
my $mp3 = shift;

return if ($opt_embedcover eq "");
if ($opt_embedcover ne "") {
my $cmime = getMimeType($opt_embedcover);
qx(mid3v2 -p '${opt_embedcover}:cover:3:$cmime' -- '$mp3');
return;
}

# I can't get the automatic deletion working :c
my (undef, $fname) = tempfile();
# Export image from flac
@@ -278,8 +303,12 @@ sub argsToTags {
if (defined($opt_genre)) {
$argTags->{genre} = [$opt_genre];
}
if (defined($opt_comment) && $opt_comment ne "") {
$argTags->{comment} = [$opt_comment];
if (defined($opt_comment)) {
if ($opt_comment eq "") {
delete($argTags->{comment});
} else {
$argTags->{comment} = [$opt_comment];
}
}
if (defined($opt_catid) && $opt_catid ne "") {
$argTags->{catalognumber} = [$opt_catid];
@@ -295,10 +324,40 @@ sub argsToTags {
}
}

sub mergeDupeTxxx {
# Merge tags together, that we can't have multiples of
# Like TXXX with same key

my $tagsArr = shift;

for (my $i = 0; $i < scalar @$tagsArr; $i++) {
if (lc($tagsArr->[$i]->[0]) ne "txxx") {
next;
}

$tagsArr->[$i]->[1] =~ m/^(.*?):(.*)$/;
my $txkeyFirst = $1;
my $txvalFirst = $2;

for (my $j = $i + 1; $j < scalar @$tagsArr; $j++) {
next if (lc($tagsArr->[$j]->[0]) ne "txxx");
$tagsArr->[$j]->[1] =~ m/^(.*?):(.*)$/;
my $txkeySecond = $1;
my $txvalSecond = $2;

next if ($txkeyFirst ne $txkeySecond);
# TXXX keys are equal, append the second to the first, and delete this entry
$tagsArr->[$i]->[1] .= ';' . $txvalSecond;
#print("DDDDDDDDDDDDD: Deleted $j index $txkeySecond:$txvalSecond\n");
splice(@$tagsArr, $j, 1);
}
}
}

sub tagsToOpts {
my $tags = shift;
my @tagopts;
# TODO escape stuff?
foreach my $currKey (keys (%$tags)) {
if (!exists($idLookup{$currKey})) {
@@ -311,7 +370,7 @@ sub tagsToOpts {
# If tag name is defined and tag contents exists (aka not silenced)
foreach my $tagCont (@{$tags->{$currKey}}) {
shellsan(\$tagCont);
push(@tagopts, qq('--$tagMapping' '$tagCont'));
push(@tagopts, ["$tagMapping", "$tagCont"]);
}
} elsif ($type eq "ARRAY") {
my $mapKey = $tagMapping->[0];
@@ -325,12 +384,12 @@ sub tagsToOpts {
if ($mapContType eq "") {
foreach my $tagValue (@{$tags->{$currKey}}) {
shellsan(\$tagValue);
push(@tagopts, qq('--$mapKey' '$mapCont$tagValue'));
push(@tagopts, ["$mapKey", "$mapCont$tagValue"]);
}
} elsif ($mapContType eq "CODE") {
my $tagValue = $mapCont->($tags);
shellsan(\$tagValue);
push(@tagopts, qq('--$mapKey' '$tagValue'));
push(@tagopts, ["$mapKey", "$tagValue"]);
}
} elsif ($type eq 'CODE') {
# If we have just a code reference
@@ -345,10 +404,20 @@ sub tagsToOpts {
my $mapKey = $codeRet->[0];
my $mapCont = $codeRet->[1];
shellsan(\$mapCont);
push(@tagopts, qq('--$mapKey' '$mapCont'));
push(@tagopts, ["$mapKey", "$mapCont"]);
}
}
return \@tagopts;

mergeDupeTxxx(\@tagopts);

# Convert the tag array into an array of string to use with mid3v2
my @tagoptsStr;

foreach (@tagopts) {
push(@tagoptsStr, qq('--$_->[0]' '$_->[1]'));
}

return \@tagoptsStr;
}

sub getFlacTags {
@@ -395,6 +464,7 @@ Usage:
-r, --replay-gain use replay gain values
--catid STRING the catalog id to set (or "")
--comment STRING the comment to set (or "")
--cover STRING Use this image as cover (or "" to not copy from flac)
-t --tagreplace STR Replace flac tags for a specific file only
Like -t '02*flac/TITLE=Some other title'
-3, --320 Convert into CBR 320 instead into the default V0


Loading…
Cancel
Save