kyillische mp3-Tags nach utf konvertieren

Matthias Taube no_html.max50kb at nurfuerspam.de
Fre Dez 15 21:14:30 GMT 2006


mailing_lists at gmx.net schrieb:

> Allerdings muss man so jedes tag einzeln konvertieren.
> Daher werde ich mir id3v2 näher anschauen. Wenn möglich würde ich
> nämlich gerne batch-konvertieren.

Ich habe schon vor längerer Zeit dafür ein Perl-Script geschrieben.

Es verwendet Encode::from_to( $tags{$wert}, $opt_ie, "utf8" );


Wobei opt_ie die Input-Encoding ist.

Die entsprechenden Codeausschnitte, für eigene Scripts:

sub lese_tag {
    my $file = shift;
    unless ( -r $file ) { error("cant read $file\n"); return; }
    my ( $basename, $path, $art ) = &basename($file);
    unless ( defined $art ) { error("only ogg|flac|mp3 files\n"); return; }
    my (
        $title, $track, $artist,      $album,  $comment, $year,
        $genre, $part,  $sourcemedia, $discid, $encoding
    );
    my %tags = ();
    if ( $art eq "flac" ) {
        my $flac = Audio::FLAC->new($file) or return;
        my $flacTags = $flac->tags();
        foreach ( keys %$flacTags ) {
            my $tag = uc($_);
            $tags{$tag} = $flacTags->{$_};
        }
    }
    if ( $art eq "ogg" ) {
        my $ogg = Ogg::Vorbis::Header->new($file) or return;
        my @werte = $ogg->comment_tags;
        foreach my $wert (@werte) {
            my @inhalte = $ogg->comment($wert);
            my $inhalt  = shift(@inhalte);
            $wert = uc($wert);
            $tags{$wert} = $inhalt;
        }
    }
    if ( $art eq "mp3" ) {
        my $mp3 = MP3::Tag->new($file) or return;
        $mp3->get_tags;
        if ( exists $mp3->{ID3v2} ) {
            my $id3v2 = $mp3->{ID3v2};
            $title  = $id3v2->get_frame("TIT2");
            $track  = $id3v2->get_frame("TRCK");
            $artist = $id3v2->get_frame("TPE1");
            $album  = $id3v2->get_frame("TALB");
            my $comment_hash = $id3v2->get_frame("COMM");
            if ( defined $comment_hash ) {
                my %comments = %{$comment_hash};
                $comment = $comments{'Text'};
            }
            $year  = $id3v2->get_frame("TYER");
            $genre = $id3v2->get_frame("TCON");
            $part  = $id3v2->get_frame("TPOS");
            $sourcemedia = "mp3";    # $id3v2->get_frame("TMED");
            $discid   = $id3v2->get_frame( "MCDI", 'raw' );
            $encoding = $id3v2->get_frame("TENC");
        }
        if ( exists $mp3->{ID3v1} ) {
            my $id3v1 = $mp3->{ID3v1};
            $title   = $id3v1->title   unless ( defined $title );
            $track   = $id3v1->track   unless ( defined $track );
            $artist  = $id3v1->artist  unless ( defined $artist );
            $album   = $id3v1->album   unless ( defined $album );
            $comment = $id3v1->comment unless ( defined $comment );
            $year    = $id3v1->year    unless ( defined $year );
            $genre   = $id3v1->genre   unless ( defined $genre );
        }
        $mp3->close();
        %tags = (
            "ALBUM"       => $album,
            "ARTIST"      => $artist,
            "COMMENT"     => $comment,
            "DATE"        => $year,
            "DISCID"      => $discid,
            "ENCODING"    => $encoding,
            "GENRE"       => $genre,
            "PART"        => $part,
            "SOURCEMEDIA" => $sourcemedia,
            "TITLE"       => $title,
            "TRACKNUMBER" => $track
        );
    }
    foreach my $wert ( keys %tags ) {
        if ( ( not defined $tags{$wert} ) or ( $tags{$wert} eq "" ) ) {
            delete $tags{$wert};
        }
        else {
            if ( defined $opt_ie ) {
                if ( $opt_ie eq "" ) { $opt_ie = "latin1"; }
                Encode::from_to( $tags{$wert}, $opt_ie, "utf8" );
            }
        }
    }
    %tags = &check_genre(%tags);
    return (%tags);
}

sub schreibe_tag {
    my ( $file, %tags ) = @_;
    foreach my $wert ( keys %tags ) {
        if ( ( not defined $tags{$wert} ) or ( $tags{$wert} eq "" ) ) {
            delete $tags{$wert};
        }
        else {
            if ( defined $opt_oe ) {
                if ( $opt_oe eq "" ) { $opt_oe = "latin1"; }
                Encode::from_to( $tags{$wert}, "utf8", $opt_oe );
            }
        }
    }
    %tags = &check_genre(%tags);
    unless ( -w $file ) { error("cant write $file\n"); return; }
    my ( $basename, $path, $art ) = &basename($file);
    unless ( defined $art ) { error("only ogg|flac|mp3 files\n"); return; }
    if ( $art eq "ogg" ) {
        my $ogg = Ogg::Vorbis::Header->new($file) or return;
        foreach my $tag_bezeichnung ( sort keys %tags ) {
            my $tag_inhalt = $tags{$tag_bezeichnung};
            my @werte      = $ogg->comment_tags;
            foreach my $wert (@werte) {
                if ( $wert =~ m/^$tag_bezeichnung/i ) {
                    while ( defined $ogg->delete_comment("$wert") ) {

                        #   print "del_comment: $wert\n";
                    }
                }
            }
            $ogg->add_comments( $tag_bezeichnung, $tag_inhalt );

            #   print "add_comment $tag_bezeichnung, $tag_inhalt\n";
        }
        $ogg->write_vorbis;
    }
    if ( $art eq "flac" ) {
        my @zeilen     = `metaflac --export-tags-to=- \"$file\"`;
        my @zeilen_neu = ();
        foreach my $zeile (@zeilen) {
            chomp($zeile);
            my $zeile_neu = $zeile;
            my ( $tag, $inh ) = split( /=/, $zeile, 2 );
            if ( ( defined $tag ) and ( defined $inh ) ) {
                $tag = uc($tag);
                foreach my $tag_bezeichnung ( keys %tags ) {
                    if ( $tag_bezeichnung eq $tag ) {
                        $zeile_neu = "";
                    }
                }
                if ( $zeile_neu ne "" ) { push @zeilen_neu, $zeile_neu; }
            }

        }
        foreach my $tag_bezeichnung ( sort keys %tags ) {
            my $tag_inhalt = $tags{$tag_bezeichnung};
            push @zeilen_neu, "$tag_bezeichnung=$tag_inhalt";
        }
        my $file_name = "$basename.tag";
        my $sek       = "";
        my $tmp_file  = "/tmp/" . $sek . $file_name;
        while ( -e $tmp_file ) {
            $sek      = time;
            $tmp_file = "/tmp/" . $sek . $file_name;
        }
        open( TAGFILE, ">$tmp_file" ) or die("$!");
        foreach (@zeilen_neu) {
            print TAGFILE "$_\n";
        }
        close(TAGFILE) or die("$!");
        `metaflac --remove-all-tags --import-tags-from="$tmp_file" "$file"`;
        unlink($tmp_file);
    }
    if ( $art eq "mp3" ) {
        my $album       = $tags{ALBUM};
        my $artist      = $tags{ARTIST};
        my $comment     = $tags{COMMENT};
        my $year        = $tags{DATE};
        my $discid      = $tags{DISCID};
        my $encoding    = $tags{ENCODING};
        my $genre       = $tags{GENRE};
        my $genre_nr    = $tags{GENRE_NR};
        my $part        = $tags{PART};
        my $sourcemedia = $tags{SOURCEMEDIA};
        my $title       = $tags{TITLE};
        my $track       = $tags{TRACKNUMBER};

        my $mp3 = MP3::Tag->new("$file");
        $mp3->get_tags;
        $mp3->new_tag("ID3v1") unless ( exists $mp3->{ID3v1} );
        my $id3v1 = $mp3->{ID3v1};
        $id3v1->album($album)     if ( defined $album );
        $id3v1->artist($artist)   if ( defined $artist );
        $id3v1->comment($comment) if ( defined $comment );
        $id3v1->year($year)       if ( defined $year );

        # discid
        # encoding
        $id3v1->genre($genre) if ( defined $genre );

        # genre_nr
        # part
        # sourcemedia
        $id3v1->title($title) if ( defined $title );
        $id3v1->track($track) if ( defined $track );
        $id3v1->write_tag;

        $mp3->new_tag("ID3v2") unless ( exists $mp3->{ID3v2} );
        my $id3v2 = $mp3->{ID3v2};
        if ( defined $album ) {
            $id3v2->remove_frame("TALB");
            $id3v2->add_frame( "TALB", $album );
        }
        if ( defined $artist ) {
            $id3v2->remove_frame("TPE1");
            $id3v2->add_frame( "TPE1", $artist );
        }
        if ( defined $comment ) {
            $id3v2->remove_frame("COMM");
            $id3v2->add_frame( "COMM", "DE", "COMM", $comment );
        }
        if ( defined $year ) {
            $id3v2->remove_frame("TYER");
            $id3v2->add_frame( "TYER", $year );
        }
        if ( defined $discid ) {
            $id3v2->remove_frame("MCDI");
            $id3v2->add_frame( "MCDI", $discid );
        }
        if ( defined $title ) {
            $id3v2->remove_frame("TIT2");
            $id3v2->add_frame( "TIT2", $title );
        }
        if ( defined $track ) {
            $id3v2->remove_frame("TRCK");
            $id3v2->add_frame( "TRCK", $track );
        }
        if ( defined $genre ) {
            $id3v2->remove_frame("TCON");
            if ( defined $genre_nr ) {
                $id3v2->add_frame( "TCON", $genre_nr );
            }
            else {
                $id3v2->add_frame( "TCON", $genre );
            }
        }
        if ( defined $part ) {
            $id3v2->remove_frame("TPOS");
            $id3v2->add_frame( "TPOS", $part );
        }
        if ( defined $sourcemedia ) {
            $id3v2->remove_frame("TMED");
            $id3v2->add_frame( "TMED", $sourcemedia );
        }
        if ( defined $encoding ) {
            $id3v2->remove_frame("TENC");
            $id3v2->add_frame( "TENC", $encoding );
        }
        $id3v2->write_tag();
        $mp3->close();
    }
}