#!/usr/bin/perl use strict; use warnings; use MP3::Tag; use File::Find; File::Find::find( \&wanted, '.' ); { my $cover; my @mp3; sub wanted { for ($File::Find::name) { -d && do { undef $cover; last; }; /\.(jpg|gif)$/ && do { $cover = [ $_, "image/$1" ]; if ( @mp3 ) { add_cover( $_, $cover ) for @mp3; @mp3 = (); } # if last; }; /\.mp3$/ && do { $cover ? add_cover( $_, $cover ) : push @mp3, $_; last; }; } # for } # wanted } sub add_cover { my( $file, $cover ) = @_; my $mp3 = MP3::Tag->new( $file ); $mp3->get_tags; my $id3v2 = exists $mp3->{'ID3v2'} ? $mp3->{'ID3v2'} : $mp3->new_tag('ID3v2'); open( my $in, '<', $cover->[0] ) or die "Cannot open file '$cover->[0]': $!"; binmode( $in ); my $data = do{ local $/=undef; <$in> }; unless ( $id3v2->get_frame('APIC') ) { $id3v2->add_frame( 'APIC', $cover->[1], 3, 'Cover Image', $data ); } # unless else { $id3v2->change_frame( 'APIC', $cover->[1], 3, 'Cover Image', $data ); } # else $id3v2->write_tag; close( $in ); $mp3->close; } # add_cover