Удалите или отредактируйте ID3Tag версии 2 из файла MP3 с помощью Delphi 7.

Я использую как старый добрый MPGTools, так и собственный, простой метод установки тега ID3 в моих файлах MP3. Но оба подхода слишком устарели для поддержки ID3Tag версии 2. Я ищу любое решение, которое позволило бы моему приложению, написанному на Delphi 7, либо удалять ID3Tag из каждого обрабатываемого файла, либо устанавливать для него точно такие же значения, как ID3Tag. установлена ​​версия 1.

В настоящее время я удаляю ID3Tagv2 вручную, используя быструю комбинацию клавиш в Winamp.

Я не использую v2, обложки альбомов или все эти «новые» дополнения, поэтому мне нужен самый быстрый способ избавиться от ID3Tagv2 (если он существует в конкретном файле).

Конечно, я пытался искать в Интернете с помощью Google, но либо у меня плохой день, либо я задаю неправильный вопрос, потому что все результаты, которые я получаю по вышеупомянутым вопросам, являются поддельными результатами поисковиков, таких как программное обеспечение. Информер и др.


person trejder    schedule 03.01.2013    source источник


Ответы (2)


Так случилось, что один из моих проектов, находящихся здесь, ожидает завершения (около 80%, я больше любитель, когда дело доходит до Delphi, и у меня были более неотложные дела, затем я нашел программу, которую я смог загрузить, которая подходит мои требования точно) является полноценным редактором тегов ID3 ​​для файлов MP3. В то время как v1 было очень легко, v2 намного сложнее. Вы можете обратиться к стандартному документу для версии 2.3 здесь. Но я ограничусь рассмотренными здесь моментами.

В зависимости от приложения вам могут понадобиться теги ID3v2. Мой портативный MP3-плеер принимает только теги v2, что в первую очередь и подтолкнуло меня к этому проекту.

Теги ID3v2 записываются в начале файлов переменной длины с переменным количеством тегов, которые могут присутствовать или отсутствовать. К счастью, полная длина данных должна быть в первой записи, если это файл с тегами ID3v2. Следовательно, прочитайте файл, найдите длину данных ID3v2, затем перепишите файл без данных ID3v2, и теги будут удалены. Наличие данных в начале делает это необходимым и действительно вызывает разочарование. Все, что я буду делать с кодом в будущем, будет связано с попыткой изменить данные на месте. Далее следует некоторый очень грязный код, который работал с AFAIR, но вам нужно будет очистить его, если вы его используете (я уверен, что некоторые из присутствующих сочтут нужным указать, как я должен). Но проверьте это хорошо, чтобы быть уверенным. Также не забудьте спросить, не пропустил ли я что-нибудь из модуля, из которого я скопировал это (это pas-файл размером 19,3 КБ), что вам может понадобиться:

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;

Полная возможность редактирования, которая работает практически во всех ситуациях, очевидно, является более сложной задачей, чем это, но все подробности есть в том документе, на который я дал ссылку. Надеюсь, это поможет вам.

person Glenn1234    schedule 05.01.2013
comment
Я только что перечитал это и вижу множество стилистических проблем (как я уже сказал, это нужно много почистить). Но я быстро проверил MP3, и это сработало — SHA1 вывода этого файла был таким же, как вывод Winamp. Во всяком случае, надеюсь, что это поможет. - person Glenn1234; 05.01.2013
comment
Glenn1234: Я более чем сказочно удивлен! Я искал просто совета, где искать или с чего начать, и вы дали мне полное решение, которое мне нужно (не важно, написан ли код на 100% с новейшими стандартами). Итак, тысячи благодарностей и очень жаль, что я могу выбрать ваш ответ только один раз. - person trejder; 06.01.2013

Есть несколько библиотек, которые отлично работают с ID3V2. Еще в 2006 году я провел большое исследование, чтобы найти библиотеку Delphi, которая поддерживает большую часть спецификации Id3V2 для Delphi 7. И я нашел эти 2:

  1. Библиотека аудио инструментов (была лучшей на тот момент). Я думаю, что он даже мог читать/писать теги в Unicode. Вот блок Id3V2.pas
  2. JVCL содержит компонент для работы с тегами Id3V2. Но в 2006 году не было поддержки Unicode для не-Unicode Delphi.

Кстати, если вы еще не используете JVCL, не стоит устанавливать более 600 компонентов только для того, чтобы получить поддержку Id3V2. Итак, взгляните на Библиотеку инструментов для работы со звуком.

person Aleksey Timohin    schedule 06.01.2013
comment
Большое спасибо за ваш ответ. Да, Audio Tools Library действительно выглядит круто. Я выбрал приведенный выше ответ (Glenn1234), потому что я такой гик (маньяк), который предпочитает решения с чистым кодом вместо готовых к использованию библиотек. Я знаю, что это противоречит стандартам и хорошей практике кодирования, но это только я, и что я могу с этим поделать? :] Кроме того, решение Glenn1234 готово для меня, так как я хочу удалить ID3Tagv2. Если бы я когда-нибудь рассматривал возможность полного редактирования, то я бы наверняка предпочел одну из ваших библиотек. Еще раз спасибо! - person trejder; 06.01.2013