使用Delphi 7从MP3文件中删除或编辑ID3Tag版本2

时间:2013-01-03 21:18:04

标签: delphi audio mp3 delphi-7 id3

我正在使用旧的MPGTools和自己的简单方法在我的MP3文件中设置ID3标签。但是这两种方法都太旧了,无法支持ID3Tag版本2.我正在寻找任何解决方案,允许我的应用程序(用Delphi 7编写)从其处理的每个文件中删除ID3Tag,或者将其设置为与ID3Tag完全相同的值版本1已设置。

目前我正在使用Winamp中的快速键盘组合手动删除ID3Tagv。

我不使用v2或专辑封面或所有这些“新”添加,因此摆脱ID3Tagv2(如果它存在于特定文件中)的最快捷方式将是我所需要的。

当然我试图用谷歌搜索互联网,但要么我度过了糟糕的一天,要么我提出了错误的问题,因为我上面提到的所有结果都是来自搜索引擎的假结果偷窃者如Software Informer等。

2 个答案:

答案 0 :(得分:3)

碰巧,我的一个项目正在等待完成(大约80%,对于Delphi来说我更像是一个业余爱好者,并且有更多紧迫的东西出现,然后我找到了一个程序,我能够精确下载符合我的要求)是一个完整的MP3文件标签编辑器。虽然v1非常简单,但v2更难。您可以参考standard document for v2.3 here。 但我将仅限于这里讨论的要点。

您可能需要ID3v2标签,具体取决于应用程序。我的便携式MP3播放器只接受v2标签,这促使我首先完成项目。

ID3v2标签以可变长度方式写入文件的开头,可变数量的标签可能存在也可能不存在。幸运的是,如果数据是ID3v2标记文件,则数据的全长应该在第一个记录中。因此,读取文件找到ID3v2数据的长度,然后重写没有ID3v2数据的文件,并删除标签。在开始时拥有数据使得这是必要的并且确实是令人沮丧的。我将来对代码所做的任何事情都涉及尝试更改数据。 AFAIR会使用一些非常脏的代码,但是如果你使用的话你将需要清理(我相信这里的一些内容会指出我应该如何)。但是要确保测试它。另外一定要问我是否遗漏了我所需要的任何东西(你的文件是一个19.3KB的文件):

type
  sarray = array[0..3] of byte;
  psarray = ^sarray;

  ID3v2Header = packed record
     identifier: array[0..2] of char;
     major_version: byte;
     minor_version: byte;
     flags: byte;
     size: DWord;
  end;

 function size_decodeh(insize: DWord): DWord;
   { decodes the size headers only, which does not use bit 7 in each byte,
     requires MSB conversion as well }
   var
     outdval: DWord;
     outd, ind: psarray;
     tnext2, pnext2: byte;

   begin
     outdval := 0;
     outd := @outdval;
     ind := @insize;
     tnext2 := ind^[2] shr 1;
     pnext2 := ind^[1] shr 2;

     outd^[0] := ind^[3] or ((ind^[2] and $01) shl 7);
     outd^[1] := tnext2 or ((ind^[1] and $03) shl 6);
     outd^[2] := pnext2 or ((ind^[0] and $07) shl 5);
     outd^[3] := ind^[0] shr 3;
     Result := outdval;
   end;

procedure ID3v2_LoadData(filename: string; var memrec: pointer;
                       var outsize: integer);
  { procedure loads ID3v2 data from "filename".  Returns outsize = 0 if
    there is no ID3v2 data }

var
  infile: file;
  v1h: ID3V2Header;
begin
  assign(infile, filename);
  reset(infile, 1);
// read main header to get id3v2 size
  blockread(infile, v1h, sizeof(v1h));
// detect if there is id3v2 data
  if v1h.identifier = 'ID3' then
    begin
      outsize := size_decodeh(v1h.size);
      // read ID3v2 header data
      getmem(memrec, outsize);
      blockread(infile, memrec^, outsize);
      Close(infile);
    end
  else
    outsize := 0;
  end;

 function id3v2_erase(infilestr: string): boolean;
  { erase all ID3v2 data.  Data are stored at the beginning of file, so file
    must be rewritten }
   const
     tempfilename = 'TMp@!0X.MP3';
   var
     memrec: pointer;
     outsize, dataread: integer;
     IsID3v2: boolean;
     databuffer: array[1..32768] of byte;
     newfile, origfile: file;
   begin
  // reuse service routine to get information
     Id3v2_loaddata(infilestr, memrec, outsize);
  // is there ID3v2 data?
     if outsize > 0 then
       begin
        // need to clean up after the service routine
         freemem(memrec);
        // get amount of data to erase
        outsize := outsize + sizeof(Id3v2Header);
        writeln('Data to delete is: ', outsize, ' bytes.');
        // now rewrite the file
        AssignFile(origfile, infilestr);
        reset(origfile, 1);
        AssignFile(newfile, tempfilename);
        rewrite(newfile, 1);
        Seek(origfile, outsize);
        repeat
          blockread(origfile, databuffer, sizeof(databuffer), dataread);
          blockwrite(newfile, databuffer, dataread);
        until dataread = 0;
        CloseFile(origfile);
        CloseFile(newfile);
       // rename temp file and delete original
        DeleteFile(infilestr);
        RenameFile(tempfilename, infilestr);
        IsID3v2 := true;
      end
  else
     IsID3v2 := false;
  Result := IsID3v2;
end;

在大多数情况下都能运行的完全编辑功能显然是比攀登更艰难的山峰,但所有细节都在我链接的文档中。希望这可以帮助你。

答案 1 :(得分:1)

很少有库可以与ID3V2一起使用。早在2006年,我做了一项大型研究,找到支持Delphi 7的大部分Id3V2规范的Delphi库。 我找到了这两个:

  1. Audio Tools Library(那是当下最好的)。我认为它甚至可以用Unicode读/写标签。这是单位Id3V2.pas
  2. JVCL包含可与Id3V2标记配合使用的组件。但它在2006年没有对非unicode Delphi的Unicode支持。
  3. 顺便说一下,如果你还没有使用JVCL,那么为了获得Id3V2支持,安装超过600个组件是不值得的。 因此,请查看音频工具库