Re: [Lug-bg] кодировка на MP3 тагове и музикални плейъри
- Subject: Re: [Lug-bg] кодировка на MP3 тагове и музикални плейъри
- From: Момчил Иванов <idiotbg@xxxxxxxxx>
- Date: Sun, 10 Aug 2008 16:24:08 +0200
markucz@xxxxxxxxx написа:
>> Знаете ли за програмки, които решават горния проблем с кодировките в
>> таговете на mp3 файловете? Ако не ще почопля още малко по проблема и
>> накрая ще пусна скрипта върху колекцията си.
>
> Преди време и мен ме сполетя същия проблем. Тогава писах един безумно грозен
> скрипт, който работи, но: 1) изцяло зависи от ex, id3v2 и програмите, които
> вървят с id3lib; 2) имената на файловете трябва да са на латиница. Ако знаеш
> кои точно файлове са с CP1251 кодировка:
>
> id3v2 --TXXX CHARSET:CP1251 file
>
> После
>
> #!/bin/sh
> id3info "$1" > "$1.t"
> CHARSET=`grep CHARSET "$1.t" | awk -F: '{print $3}' | sed 's/ //g'`
> if [ -z $CHARSET ]; then
> exit 0
> fi
> ex - "$1.t" 1>&- <<EOF
> 1,2d
> /CHARSET/
> d
> /^\*\*\*/
> .,\$d
> 1,\$s/(.*):\ (/(/g
> 1,\$s/(.*)://g
> 1,\$s/\$/"/g
> 1,\$s/\ \ /\ "/g
> 1,\$s/^===\ /--/g
> 1,\$s/"/\\"/g
> 0a
> id3v2
> .
> w
> EOF
> echo "--TXXX \"CHARSET:UTF-8\"" >> "$1.t"
> echo "\"$1\"" >> "$1.t"
> tr "\n" " " < "$1.t" | iconv -f $CHARSET -t UTF-8 > "$1.sh"
> . "$1.sh"
> id3convert -s1 "$1" 1>&-
> rm "$1.t" "$1.sh"
>
> С това чудо обработих всичките си MP3-ки без проблеми. BTW интересно ми е как
> изглежда това на Perl :)
доста по-дълго е на perl :) в началото прочита всичко от таговете и се
опитва да познае кодировката, след което презаписва таговете с utf8 като
информацията от id3v1 записва в id3v2, ако файлът няма id3v2 таг. За да
го ползваш трябва да си инсталираш следните модули Encode,
Encode::Detect и MP3::Tag. На Encode::Detect може да му смениш детектора
с последния от mozilla
(http://mxr.mozilla.org/seamonkey/source/extensions/universalchardet/src/base/),
сваляш си кода и го слагаш в src директорията на модула на мястото на
стария, след което си компилираш и инсталираш модула (файловете, които
ти дават грешка при компилиране, трябва да изтриеш). С версията, която
идва с модула, не съм пробвал - реших че е малко стара, за това я
обнових ръчно.
цялото работи така:
find /path/ -type f -exec ./change_file_id_tag_encoding.pl {} \;
--
PGP KeyID: 0x3118168B
Keyserver: pgp.mit.edu
Key fingerprint BB50 2983 0714 36DC D02E 158A E03D 56DA 3118 168B
#!/usr/bin/perl
use strict;
use warnings;
use Encode;
use Encode::Detect;
use Encode::Detect::Detector;
use Encode::Alias;
use MP3::Tag;
binmode STDOUT, ":utf8";
define_alias( "x-mac-cyrillic" => "cp1251" );
my $filename = shift;
my @fields = qw(title artist album year comment track genre);
my $d = new Encode::Detect::Detector;
print "Processing $filename\n";
my $mp3 = MP3::Tag->new($filename);
$mp3->get_tags();
# guess encoding
if (exists $mp3->{ID3v1}) {
my $id3v1 = $mp3->{ID3v1};
map { if (defined $mp3->$_()) {$d->handle($mp3->$_() . 0x0);} } @fields;
}
if (exists $mp3->{ID3v2}) {
my $id3v2 = $mp3->{ID3v2};
my $frameIDs_hash = $id3v2->get_frame_ids('truename');
foreach my $frame (keys %$frameIDs_hash) {
my ($name, @info) = $id3v2->get_frame($frame);
for my $info (@info) {
if (ref $info) {
# TODO
print "$name ($frame):\n";
while(my ($key,$val)=each %$info) {
#print " * $key => $val\n";
}
} else {
if (defined $name) {
$d->handle($name);
}
}
}
}
}
$d->eof;
my $charset = $d->getresult;
$charset = 'Detect' unless defined $charset;
print "Charset: $charset\n";
# decode id3v2 and encode it in UTF-8
if (exists $mp3->{ID3v2}) {
my $id3v2 = $mp3->{ID3v2};
print ">>>>> ID3v2:\n";
my $frameIDs_hash = $id3v2->get_frame_ids('truename');
foreach my $frame (keys %$frameIDs_hash) {
my ($name, @info) = $id3v2->get_frame($frame);
for my $info (@info) {
if (ref $name) {
# TODO
print "$info ($frame):\n";
while(my ($key,$val)=each %$name) {
print " * $key => $val\n";
}
} else {
$name = '' unless defined $name;
$info = '' unless defined $info;
if ($charset ne 'UTF-8') {
$name = decode($charset, $name);
$id3v2->change_frame($frame, $name);
$id3v2->write_tag();
}
print $frame . " : " . $name . ": $info\n";
}
}
}
}
# decode id2v1, encode it in UTF-8 and save in id3v2
if (exists $mp3->{ID3v1} && ! exists $mp3->{ID3v2}) {
my $id3v1 = $mp3->{ID3v1};
print ">>>>> ID3v1:\n";
if ($charset ne 'UTF-8') {
my $id3v2 = $mp3->new_tag("ID3v2");
$id3v2->add_frame('TIT2', decode $charset, $id3v1->title()) unless ($id3v1->title() eq '');
$id3v2->add_frame('TPE1', decode $charset, $id3v1->artist()) unless ($id3v1->artist() eq '');
$id3v2->add_frame('TALB', decode $charset, $id3v1->album()) unless ($id3v1->album() eq '');
$id3v2->add_frame('TDRC', $id3v1->year());
$id3v2->add_frame('COMM', 'XXXX', '', decode($charset, $id3v1->comment())) unless ($id3v1->comment() eq '');
$id3v2->add_frame('TRCK', $id3v1->track());
$id3v2->add_frame('TCON', decode $charset, $id3v1->genre()) unless ($id3v1->genre() eq '');
$id3v2->write_tag();
my $frameIDs_hash = $id3v2->get_frame_ids('truename');
foreach my $frame (keys %$frameIDs_hash) {
my ($name, @info) = $id3v2->get_frame($frame);
for my $info (@info) {
if (ref $name) {
# TODO
print "$info ($frame):\n";
while(my ($key,$val)=each %$name) {
print " * $key => $val\n";
}
} else {
$name = '' unless defined $name;
$info = '' unless defined $info;
print $frame . " : " . $name . ": $info\n";
}
}
}
}
}
$mp3->close();
Attachment:
signature.asc
Description: OpenPGP digital signature
_______________________________________________
Lug-bg mailing list
Lug-bg@xxxxxxxxxxxxxxxxxx
http://linux-bulgaria.org/mailman/listinfo/lug-bg
|