pastebin - collaborative debugging tool
kpaste.net RSS


perl flac tag script
Posted by Admin on Thu 17th Mar 2011 15:12
raw | new post
modification of post by Admin (view diff)

  1. #!/opt/local/bin/perl
  2.  
  3. use 5.010;
  4. use strict;
  5. use warnings;
  6. use File::Find qw(find);
  7.  
  8. my $library = "F:/Music";
  9. #$library = "F:/FLAC/Downloaded/New";
  10. my %files;
  11.  
  12. find({ wanted => \&action, no_chdir => 1 }, $library);
  13.  
  14. sub action {
  15.         if (-d) {
  16.                 my $dn = $File::Find::name;
  17.                 %files = getfiles($dn);
  18.                 my $fc = keys %files;
  19. #               say $fc;
  20.                 unless ($fc == 0) {
  21.                         replaygain($dn);
  22.                         foreach my $fn (sort(keys %files)) {
  23.                                 rmtag($fn, 'discnumber', 'disctotal', 'rating', 'comment');
  24.                                 albumartist($fn, $fc);
  25.                                 track($fn);
  26.                                 totaltracks($fn, $fc);
  27. #                               empty($fn);
  28. #                               duplicate($fn);
  29.                         }
  30.                 }
  31.  
  32.  
  33.                 undef %files;
  34.         }
  35. }
  36. # Make this subroutine and the whole script so that each file name is stored in a hash and that each member contains an anonymous hash with the tags (the alltags hash).
  37. # This means it won't have to look up the tags again for the albumartist subroutine.
  38.  
  39. sub gettags {
  40.         my $fn = shift;
  41.         my %alltags;
  42.         open(OUTPUT, '-|', qq{metaflac --no-utf8-convert --export-tags-to=- "$fn"}) || die "can\'t run metaflac: $!";
  43.         local $_;
  44.         while (<OUTPUT>) {
  45.                 chomp;
  46.                 my @tag = split('=');
  47.                 my $tagname = lc($tag[0]);
  48.                 if ($tag[1]) {
  49.                         push @{$alltags{$tagname}}, $tag[1];
  50.                 } else {
  51.                         push @{$alltags{$tagname}}, 'null';
  52.                 }
  53.         }
  54.         close(OUTPUT) || die "couldn\'t close metaflac: $!";
  55.         return %alltags;
  56. }
  57.  
  58. sub getfiles {
  59.         my $dn = shift;
  60.         my %files;
  61.         opendir(my $dh, $dn) or die "Can\'t open directory '$dn': $!";
  62.         foreach (readdir $dh) {
  63.                 my $fn = "$dn/$_";
  64.                 if (/.flac$/ && -f $fn) {
  65.                         $files{$fn} = { gettags($fn) };
  66.                 }
  67.         }
  68.         closedir $dh or die "Can\'t close directory '$dn': $!";
  69.         return %files;
  70. }
  71.  
  72. sub replaygain {
  73.         my $dn = shift;
  74.         my $flist = "";
  75.         my %replaygain;
  76.  
  77.         foreach my $fn (sort(keys %files)) {
  78.                 if ($files{$fn}{replaygain_album_gain}) {
  79.                         $replaygain{$files{$fn}{replaygain_album_gain}->[0]}++;
  80.                 }
  81.                 $flist .= "\"$fn\" ";
  82.         }
  83.         if (keys(%replaygain) != 1) {
  84.                 say "$dn: adding ReplayGain";
  85.                 system('metaflac', '--add-replay-gain', $flist);
  86.         }
  87. }
  88.  
  89. sub albumartist {
  90.         my $fn = shift;
  91.         my $tracks = shift;
  92.         if (!$files{$fn}{albumartist}) {
  93.                 my $albumartist = 'Various Artists';
  94.                 my %artist;
  95.                 my $max;
  96.                 if ($tracks == 1) {
  97.                         $max = $tracks;
  98.                 }
  99.                 else {
  100.                         $max = $tracks / 2;
  101.                 }
  102.                 foreach my $fn (keys %files) {
  103.                         $artist{$files{$fn}{artist}->[0]}++
  104.                 }
  105.                 if (keys(%artist) <= $max) {
  106.                         my $ac = 0;
  107.                         foreach my $a (keys %artist) {
  108.                                 if ($artist{$a} > $ac) {
  109.                                         $ac = $artist{$a};
  110.                                         $albumartist = $a;
  111.                                 }
  112.                         }
  113.                 }
  114.                 say "$fn: adding albumartist tag";
  115.                 system('metaflac', "--set-tag=ALBUMARTIST=$albumartist", $fn);
  116.         }
  117. }
  118.  
  119. sub empty {
  120.         my $fn = shift;
  121.         foreach my $k (keys %{$files{$fn}}) {
  122.                 foreach (@{$files{$fn}{$k}}) {
  123.                         if ($_ eq 'null') {
  124.                                 say "$fn: WARNING: empty $k tag";
  125.                         }
  126.                 }
  127.         }
  128. }
  129.  
  130. sub duplicate {
  131.         my $fn = shift;
  132.         my %exists;
  133.         foreach my $k (keys %{$files{$fn}}) {
  134.                 foreach (@{$files{$fn}{$k}}) {
  135.                         my $tag = quotemeta($k . '=' . $_);
  136.                         if ($exists{$tag}) {
  137.                                 say "$fn: WARNING: duplicate $k tag";
  138.                         } else {
  139.                                 $exists{$tag} = 1;
  140.                         }
  141.                 }
  142.         }
  143. }
  144.  
  145. sub track {
  146.         my $fn = shift;
  147.         my $track = $files{$fn}{tracknumber}->[0];
  148.         if ($track =~ m/^0/ && $track != 0) {
  149.                 say "$fn: fixing tracknumber tag";
  150.                 $track =~ s/^0+//;
  151.                 system('metaflac', '--remove-tag=TRACKNUMBER', "--set-tag=TRACKNUMBER=$track", $fn);
  152.         }
  153. }
  154.  
  155. sub totaltracks {
  156.         my $fn = shift;
  157.         my $tracks = shift;
  158.         if (
  159.         !$files{$fn}{totaltracks} &&
  160.         !$files{$fn}{tracktotal}
  161.         ) {
  162.                 say "$fn: adding totaltracks tag";
  163.                 system('metaflac', "--set-tag=TOTALTRACKS=$tracks", $fn);
  164.         }
  165.         elsif (
  166.         $files{$fn}{tracktotal} &&
  167.         !$files{$fn}{totaltracks}
  168.         ) {
  169.                 say "$fn: replacing tracktotal tag with totaltracks";
  170.                 system('metaflac', '--remove-tag=TRACKTOTAL', "--set-tag=TOTALTRACKS=$files{$fn}{tracktotal}->[0]", $fn);
  171.         }      
  172. }
  173.  
  174. sub rmtag {
  175.         my $fn = shift;
  176.         foreach (@_) {
  177.                 if ($files{$fn}{$_}) {
  178.                         say "$fn: removing $_ tag";
  179.                         system('metaflac', "--remove-tag=$_", $fn);
  180.                 }
  181.         }
  182. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at