1

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);
sT0n3
  • 125
  • 2
  • 13
  • @toolic http://cpansearch.perl.org/src/ILYAZ/MP3-Tag-1.13/lib/MP3/Tag/ID3v2.pm in this source code if you can highlight any thing to me that can help me in my case that would be great its all a little too complex for me at this point. – sT0n3 Jan 04 '14 at 20:54
  • 6
    While id3v1 tags have are of fixed size at fixed offsets, id3v2 tags have a variable size and have no fixed offset. Also, strings can be in various character sets and then there are several minor versions of id3v2. If you really don't want to use on of the existing libraries I wish you much fun reading the format specification and reimplementing everything. – Steffen Ullrich Jan 04 '14 at 21:22
  • Why would you possibly try to do with without using a CPAN module? – Dave Cross Jan 06 '14 at 10:48

2 Answers2

1

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.

Adrian Frühwirth
  • 42,970
  • 10
  • 60
  • 71
Alun Jones
  • 11
  • 2
0

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;
}
sT0n3
  • 125
  • 2
  • 13