Skip to content

Instantly share code, notes, and snippets.

@seungwon0
Created July 21, 2012 16:41
Show Gist options
  • Save seungwon0/3156372 to your computer and use it in GitHub Desktop.
Save seungwon0/3156372 to your computer and use it in GitHub Desktop.
changes MP3 tag encoding (CP949 -> UTF-8)
#!/usr/bin/env perl
#
# mp3tag.pl - changes MP3 tag encoding (CP949 -> UTF-8)
#
# Changes MP3 tag encoding from CP949 to UTF-8.
#
# Copyright (C) 2012 by Seungwon Jeong
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
# <http://www.gnu.org/licenses/>.
use perl5i::2;
use MP3::Tag;
use Encode;
use Text::UnicodeTable::Simple;
use Getopt::Long;
use IO::Prompt::Tiny qw< prompt >;
sub print_usage {
print <<'END_USAGE';
mp3tag.pl
Usage:
mp3tag.pl [OPTION]... MP3FILE...
Options:
-n, --no-update do not update MP3 file (default)
-u, --update update MP3 file (ignore -n)
-i, --interactive prompt before every update
-q, --quiet silence output
END_USAGE
return;
}
my $no_update = 1;
my $update = 0;
my $quiet = 0;
my $interactive = 0;
my $result = GetOptions(
no_update => \$no_update,
update => \$update,
interactive => \$interactive,
quiet => \$quiet,
);
if ( !$result || @ARGV == 0 ) {
print_usage();
exit 2;
}
my @tags = qw< title track artist album comment year genre >;
my @frames = qw< TIT2 TPE1 TPE2 TALB >;
my $tag_width = 12;
my $contents_width = 18;
my $first = 1;
MP3_FILE:
for my $mp3_file (@ARGV) {
if ( !$quiet && !$first ) {
say q{};
}
if ( !-f $mp3_file ) {
warn "$mp3_file: No such file\n";
next MP3_FILE;
}
my $mp3 = MP3::Tag->new($mp3_file);
my $table = Text::UnicodeTable::Simple->new;
$table->set_header(qw< Tag Before After >);
TAG:
for my $tag (@tags) {
my $before = $mp3->$tag;
next TAG if !defined $before;
my $after = try { decode( 'cp949', $before ); } catch { $before; };
$table->add_row(
$tag->ucfirst->wrap( width => $tag_width ),
$before->wrap( width => $contents_width ),
$after->wrap( width => $contents_width )
);
my $tag_set = $tag . '_set';
$mp3->$tag_set($after);
}
FRAME:
for my $frame (@frames) {
my ( $name, $before ) = $mp3->get_id3v2_frames($frame);
next FRAME if !defined $name;
my $after = try { decode( 'cp949', $before ); } catch { $before; };
$table->add_row(
$name->wrap( width => $tag_width ),
$before->wrap( width => $contents_width ),
$after->wrap( width => $contents_width )
);
$mp3->set_id3v2_frame( $frame, $after );
}
if ( !$quiet ) {
# Silence 'Wide character in ...' message.
no warnings 'utf8';
say $mp3_file;
print $table;
}
my $update_pending = 0;
if ($interactive) {
my $answer = prompt( 'Do you want to update? (y/n)', 'n' );
if ( lc $answer eq 'y' ) {
$update_pending = 1;
}
}
elsif ($update) {
$update_pending = 1;
}
if ($update_pending) {
# Silence 'Wide character in ...' message from MP3::Tag.
capture { $mp3->update_tags; };
}
$first = 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment