#! /usr/bin/perl # # name: m4a2mp3.pl # description: Convert m4a file to mp3 format. Attempts to convert tags. # developer: Nathan G. Marley # date: 2011Sep10 # # change history: # ======================================================================== # description: change description placeholder # developer: developer name goes here # date: YYYYMmmDD # ======================================================================== use strict; use Data::Dumper; use File::Basename; use Carp; use MP4::Info; use MP3::Tag; use Getopt::Long; sub get_m4a_tags; sub convert_m4a_2_mp3; sub tag_mp3_file; sub app_abort; # boilerplate my $progname = basename($0); my $usage = "usage: $progname ..."; if ( 0 == scalar(@ARGV) ) { print "$usage\n"; exit 2; } my @m4atags = qw ( YEAR ARTIST GENRE TRACKNUM TIME TITLE ALBUM ENCODING BITRATE ); sub main() { my @files; for my $arg ( @ARGV ) { push @files, $arg; } for my $file ( @files ) { my $m4atags = &get_m4a_tags( $file ); my $mp3file = &convert_m4a_2_mp3( $file ); my $rc = &tag_mp3_file( $mp3file , $m4atags ); } } &main(); sub get_m4a_tags($) { my $filename = shift; my $taginfo; my $tag = get_mp4tag($filename) or die "No TAG info"; for my $t ( @m4atags ) { $taginfo->{ $t } = $tag->{$t}; } return $taginfo; } sub convert_m4a_2_mp3($) { my $m4afile = shift; my $mp3file; ($mp3file = $m4afile) =~ s/\.m4a$/.mp3/; if ( -e $mp3file ) { &app_abort("error: MP3 file '$mp3file' already exists."); } my $faad_opts = "-q -o -"; my $lame_opts = "-S -v -V 0"; my $cmd = "faad $faad_opts \"$m4afile\" | lame $lame_opts - \"$mp3file\""; my $rc = system($cmd) >> 8; if ( 0 != $rc ) { die "error: Couldn't convert m4a file to mp3 format"; } return $mp3file; } sub tag_mp3_file($$) { my ( $mp3file , $tags ) = (@_)[0,1]; my $mp3 = MP3::Tag->new($mp3file); # scan file for existing tags $mp3->get_tags; if (exists $mp3->{ID3v1}) { $mp3->{ID3v1}->remove_tag; $mp3->new_tag("ID3v1"); } if (exists $mp3->{ID3v2}) { $mp3->{ID3v2}->remove_tag; $mp3->new_tag("ID3v2"); } $mp3->title_set( $tags->{TITLE} ); $mp3->artist_set( $tags->{ARTIST} ); $mp3->album_set( $tags->{ALBUM} ); $mp3->year_set( $tags->{YEAR} ); $mp3->genre_set( $tags->{GENRE} ); $mp3->track_set( $tags->{TRACKNUM} ); $mp3->update_tags(); # Commit to file $mp3->close(); return; } sub app_abort($) { my $msg = shift; print "$msg Aborting...\n"; exit 2; } __END__