mirror of
https://github.com/moex3/flac2mp3.pl
synced 2024-11-21 11:35:19 -05:00
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.
This commit is contained in:
parent
6be59c9036
commit
be6853c5da
90
flac2mp3.pl
90
flac2mp3.pl
@ -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…
Reference in New Issue
Block a user