在MP3文件Perl脚本ID3V2标记中编辑艺术家名称

在MP3文件Perl脚本ID3V2标记中编辑艺术家名称,perl,id3v2,Perl,Id3v2,我正在尝试编写一个Perl代码来编辑ID3V2标记,即开始时的艺术家名称,我可以查找和读取它,但当我尝试编写新的艺术家名称时,只需将文件的所有内容替换为新的艺术家名称,并损坏文件,我对此是新手,因此请给我一些指导,因为我不想使用下面的代码库试过了 #!/usr/bin/perl use Fcntl qw( SEEK_SET ); my($fh, $filename, $byte_position, $byte_value); $filename = $ARGV[0]; open(IN,

我正在尝试编写一个Perl代码来编辑ID3V2标记,即开始时的艺术家名称,我可以查找和读取它,但当我尝试编写新的艺术家名称时,只需将文件的所有内容替换为新的艺术家名称,并损坏文件,我对此是新手,因此请给我一些指导,因为我不想使用下面的代码库试过了

#!/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);

您的
open
调用将截断文件。您需要使用
++
打开文件,以便在不截断文件的情况下进行读写操作


有关更多信息,请参见
perldoc-f open

一些对我有用的东西,以防有人在这里寻找解决方案

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;
}
my$myFile=shift或die“用法:\n”;
my$newArtist=shift或die“用法:\n”;
my$newTitle=shift或die“用法:\n”;
#打包艺术家姓名和头衔的数据。正在创建大小为4字节的帧。
my$artist\u len=长度($newArtist);
我的$title\u len=长度($newTitle);
我的$artist=pack('N',$artist\u len);
我的$title=包装('N',$title\u len);
打印“\n新艺术家名称将为>>”$新艺术家。“\n”;
打印“\n新标题将为>>”$新标题。“\n”;
my$encoding=“:raw:bytes”;
打开myMP3,“+$encoding”、“new.mp3”或“die”错误!无法打开要写入的文件。\n”;
我的$length=512;
读取(myMP3,my$buffer,$length);
chomp($buffer);
#读取ID3v2头的前10个字节
my$tagheader=substr($buffer,0,10);
my($IDtag、$version、$revision、$flags、$size)=解包($A3 h N4',$tagheader);
打印出_文件$tagheader;
我的$len=0;
我的$ptr1=0;
我的$ptr2=0;
而(1)
{    
#每帧读取10字节,下一帧添加10字节
$ptr1+=10+$len;
$ptr2=$ptr1+10;
#读头
#4字节帧ID,
#4字节帧大小
#2字节标志
my$frameHeader=substr($buffer,$ptr1,10);
my($frameID,$frameSize,$flag)=解包($A4 N4 h2',$frameHeader);
#TALB:专辑名称,TCON:内容类型,TIT2:标题,TPE1:艺术家,TRCK:曲目编号,TYER:年份
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”)
{
打印出_文件$frameID;
打印出_文件$artist;
打印出_文件$flag;
打印出文件$newArtist;
}
elsif($frameID eq“TIT2”)
{
打印出_文件$frameID;
打印出_文件$title;
打印出_文件$flag;
打印出_文件$newTitle;
}
其他的
{
打印出_文件$frameHeader;
打印出_文件$readFrame;
}
}
其他的
{
my$leng=长度($buffer)-$ptr1;
my$music=substr($buffer,$ptr1,$leng);
打印出_文件$music;
搜索(myMP3,10,0);
寻道(OUT_文件,10,0);
while()
{
打印myMP3$;
}
取消链接“new.mp3”;
#关闭文件
关闭(myMP3);
关闭(输出文件);
死亡“\n更新成功!\n”;
}
$len=$frameSize;
}

@toolic在本源代码中,如果您能突出显示任何对我的情况有帮助的东西,那就太好了。目前对我来说,这一切都有点太复杂了。虽然id3v1标记在固定偏移量下具有固定大小,但id3v2标记具有可变大小,并且没有固定偏移量。此外,字符串可以在不同的字符集中,还有几个id3v2的次要版本。如果你真的不想在现有库的基础上使用,我希望你能从阅读格式规范和重新实现所有东西中获得乐趣。你为什么可能不使用CPAN模块就尝试使用它呢?