Question

I am trying to write a Perl code for editing the ID3V2 tags i.e artist name for start i can seek and read it but when i try to write new it just replace all the content of the file with the new artist name and corrupt the file i am new to this so kindly give me some direction as i am not suppose to use library below is the code i have tried.

#!/usr/bin/perl

use Fcntl qw( SEEK_SET );

my($fh, $filename, $byte_position, $byte_value);

$filename = $ARGV[0];

open(IN, "+>", $filename);
#open IN, $filename;

seek(IN,0,SEEK_SET);
read IN, $temp, 128;

print $temp;
print "\n";

seek(IN,14,SEEK_SET);
read IN, $temp, 16;
print "Artist is :" .$temp;
print "\n";


sysseek(IN,14,SEEK_SET);
#want to replace the Artist Name with new one.
syswrite (IN,$newArtist);

print "\n";

close(IN);
Was it helpful?

Solution 2

Some thing that worked for me in case some one is looking for a solutions here.

my $myFile  = shift or die "Usage: <file.mp3> <artist> <title>\n";
my $newArtist   = shift or die "Usage: <file.mp3> <artist> <title>\n";
my $newTitle    = shift or die "Usage:<file.mp3> <artist> <title> \n";

#Pack data for artist name and title. creating frame of size 4byte.
my $artist_len = length($newArtist);
my $title_len = length($newTitle);
my $artist = pack('N',$artist_len);
my $title = pack('N',$title_len);

print"\n New artist name will be >>". $newArtist."\n";
print"\n New title will be >> ". $newTitle ."\n";

my $encoding = ":raw :bytes";
open myMP3, "+<$encoding",$myFile or die "Error!Can NOT open the MP3 file.\n";
open OUT_FILE, "+>$encoding", 'new.mp3' or die "Error!Can NOT open the file to write.\n";

my $length = 512;
read (myMP3, my $buffer, $length);
chomp($buffer);

#reading the first 10 bytes of the ID3v2 Header
my $tagheader = substr($buffer, 0, 10);
my ($IDtag, $version, $revision, $flags, $size) = unpack('A3 h h h N4',$tagheader);
print OUT_FILE $tagheader;

my $len = 0;
my $ptr1 = 0;
my $ptr2 = 0;

while(1)
{    
   #reading 10 bytes for each frame and adding 10 bytes for next frame  
    $ptr1 += 10+$len;
    $ptr2 = $ptr1+10;

   #reading header 
   #4bytes frame ID,
   #4bytes frame size
   #2bytes flags
    my $frameHeader = substr($buffer,$ptr1,10);
    my($frameID, $frameSize, $flag) = unpack('A4 N4 h2',$frameHeader);

    #TALB:album-name,TCON:content-type,TIT2:title,TPE1:Artist, TRCK:Track Number,TYER: year
    if (($frameID eq 'TALB') || ($frameID eq 'TCON') || ($frameID eq 'TIT2') || ($frameID eq  'TPE1') || ($frameID eq 'TRCK') || ($frameID eq  'TYER'))
    {

        my $readFrame = substr($buffer, $ptr2, $frameSize);
        my $myFrame = unpack('A*($frameSize)' ,$readFrame);
        if ($frameID eq "TPE1")
        {
                print OUT_FILE $frameID;
                print OUT_FILE $artist;
                print OUT_FILE $flag;
                print OUT_FILE $newArtist;
         }

        elsif ($frameID eq "TIT2") 
        {
                print OUT_FILE $frameID;
                print OUT_FILE $title;
                print OUT_FILE $flag;
                print OUT_FILE $newTitle;
        }

        else 
        {
            print OUT_FILE $frameHeader;
            print OUT_FILE $readFrame;
        }
    }
    else 
    {
         my $leng = length($buffer) - $ptr1;
         my $music = substr($buffer, $ptr1, $leng);
         print OUT_FILE $music;

         seek(myMP3 , 10 , 0);
         seek(OUT_FILE, 10 , 0);
         while(<OUT_FILE>)
         {
            print myMP3 $_;
         }
         unlink 'new.mp3';

        #close files
        close(myMP3);
        close(OUT_FILE);

        die "\n Update success!\n";

    }
    $len=$frameSize;
}

OTHER TIPS

Your open call truncates the file. You need to open the file using +< rather than +> to open it for reading and writing without truncating it.

See perldoc -f open for more information.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top