#!/usr/bin/perl # # flacconv # # AUTHOR: # Dan Harkless # # COPYRIGHT: # This file is Copyright (C) 2017 by Dan Harkless, and is released under the # GNU General Public License . # # USAGE: # % flacconv [-A] [...] # # DESCRIPTION: # Converts FLAC files to ALAC or AAC TVBR 127, preserving metadata. AAC is # the default format; to use ALAC, use the -A option, which must be specified # as the first parameter. Note that this script does not currently do any # error handling. For instance, it assumes that input filenames do not # include any " characters, which is generally true on Windows, but may not be # on UNIX-based OSes. Also, if you have files with the same names as the FLAC # files in the working directory, but with a .wav extension instead of .flac, # the .wav files will be overwritten and deleted in the process of conversion. # However, this script does not delete the original .flac files, so if you no # longer need them, you'll need to delete them yourself after conversion. # # REQUIREMENTS: # flac: https://xiph.org/flac/ # gettags: http://www.kevinboone.net/README_gettags.html # qaac: https://sites.google.com/site/qaacpage/ # # DATE MODIFICATION # ========== ================================================================== # 2017-08-26 Preserve timestamp with timecopy and increment with timestamp++. # TBD: Do it natively in Perl with stat() before uploading to www. # 2017-06-20 Original. ## Modules / pragmas used ###################################################### # -no_match_vars avoids a performance penalty in Perl versions before 5.17.7: use English qw(-no_match_vars); # allow use of names like @ARG rather than @_ use warnings; # get warnings for this script but not modules ## Subroutines ################################################################# sub execho(@) { print "% "; foreach $arg (@ARG) { if ($arg =~ / /) { print '"' . $arg . '"'; } else { print $arg; } print " "; } print "\n"; system @ARG; print "\n"; } ## Main ######################################################################## if (scalar(@ARGV) > 0 and $ARGV[0] eq "-A") { @encoder_opts = ("-A"); shift(@ARGV); } else { @encoder_opts = ("-V", 127); } if (scalar(@ARGV) < 1) { print STDERR "Usage: flacconv [...]\n"; exit(1); } foreach $flac_file (@ARGV) { # TBD: Handle permission and other errors. Switch to a program that # supports Vorbis tags in addition to ID3? print "Processing \"$flac_file\".\n\n"; ## Get tags: @gettags_common = ("album", "artist", "comment", "composer", "genre", "title", "track", "year"); # TBD: Artwork? @tag_opts = (); foreach $tag_name (@gettags_common) { # Doing this with backquotes and " should normally be safe, since Win32 # interface doesn't allow " characters in filenames (though NTFS does). $gettags_out = `gettags -c $tag_name -s "$flac_file"`; # Goofy program always returns status 0, so need to use -s, then grep. if ($gettags_out =~ /^OK (.+)$/) { print "$tag_name = $1\n"; if ($tag_name eq "year") { push (@tag_opts, "--date"); } else { push (@tag_opts, "--$tag_name"); } push (@tag_opts, $1); } } print "\n"; ## FLAC to WAV: execho("flac", "-df", $flac_file); $wav_file = $flac_file; $wav_file =~ s/\.flac$/.wav/; ## WAV to AAC: execho("qaac", @encoder_opts, "--threading", "--verbose", @tag_opts, $wav_file); print "unlink(\"$wav_file\")\n"; unlink($wav_file); $aac_file = $flac_file; $aac_file =~ s/\.flac$/.m4a/; execho("timecopy", $flac_file, $aac_file); execho("timestamp++", $aac_file); print "\n"; }