IPB

Добро пожаловать, гость ( Вход | Регистрация )

 
Reply to this topicStart new topic
> MP3Strip, do it yourself!
-=CHE@TER=-
Apr 25 2009, 15:40
Сообщение #1


Walter Sullivan
***

Группа: Root Admin
Сообщений: 1,353
Регистрация: 4-February 08
Пользователь №: 3
Спасибо сказали: 311 раз(а)



Помнится искал как-то программу.
Вот, сделал сам, т.к. все эти тупые программы как надо не умеют в виду врождённой кривизны рук разработчиков.
В общем на альбомчике из 19 композиций, у которых ID3v2 был приписан Winamp'ом 2.81 после обработки удалось съэкономить чуть более 18 Кб.

В общем см. документацию по ссылке в коде программы.
Никакие флаги, версии и прочие вещи не проверяются - так что на некоторых файлах может работать некорректно - проверяйте результат перед удалением оригинала!
Выкидывается асболютно всё, кроме описанных в коде тэгов.
Для удобства просмотра в HEX-редакторах выравнивается по 16-ти байтной границе (хотя и не обязательно).

To Do List:
- всякие копирайты, справка и нормальные сообщения об ошибках
- сделать проверки на "неожиданный конец файла" и прочие непредвиденные случаи (сейчас считается, что все файлы нормальные - т.е. нет такого, что в середине ID3v2 файл закончился)
- сохранение оригинальной даты создания/изменения/модификации файла
- возможность оставлять непустые блоки (обложки, URL и т.д.) - пустыми же считаются блоки, у которых размер данных 0, либо размер данных 1, но этот байт с данными равен 0x00 (пустая строчка).
- возможность указания кодировки для конвертирования текста в тэгах (UTF8->CP1251, UNICODE->CP1251 и т.д.)
- не создавать новый файл, если ничего не стрипнулось

CODE
Program mp3strip;
{$APPTYPE CONSOLE}
Type
     TFrameHdr = Packed Record
                       Name: Array[0..3] Of Char;
                       Size: Integer;
                   Encoding: Byte;
                      Flags: Word;
                 End;
     TID3 = Packed Record
                  ID3: Array[0..2] Of Char;
              Version: Word;
                Flags: Byte;
                 Size: Integer;
            End;

Const ID3_ALLOW = 'TRCKTIT2COMMTALBTYERTCONTPE1';

// http://www.id3.org/id3v2.3.0

{
TRCK - track number
TIT2 - song title
COMM - comments
TABL - album name
TYER - year
TCON - genre
TPE1 - artist
}

Function IsAllowedTag(const T: String): Boolean;
Begin
  result:=((Pos(T, ID3_ALLOW)-1) Mod 4 = 0);
End;

Function swap32(Const dw: longword): longword; Assembler;
Asm
  bswap  eax
End;

Function ID3_7BIT(X: Integer): Integer;
Var I: Byte;
Begin
  result:=0;
  For I:=0 To 3 Do
    Begin
      X:=X ShL 1;
      result:=result ShL 8;
      result:=result + ((X And $FF) ShR 1);
      X:=X ShR 8;
    End;
End;

Var
    Fl, F: File;
        H: TFrameHdr;
        M: TID3;
        P: Pointer;
Begin
  WriteLn('ID3v2 strip');
  WriteLn;
  If ParamCount = 0 Then Exit;
  AssignFile(Fl, ParamStr(1));
  {$I-}
  FileMode:=0;
  Reset(Fl, 1);
  FileMode:=2;
  {$I+}
  If IOResult<>0 Then
    Begin
      WriteLn('Can''t open input file.');
      Exit;
    End;
  BlockRead(Fl, M, SizeOf(M));
  If M.ID3 <> 'ID3' Then
    Begin
      WriteLn('Input don''t have ID3v2 tag.');
      CloseFile(Fl);
      Exit;
    End;

  AssignFile(F, '_' + ParamStr(1));
  ReWrite(F, 1);
  BlockWrite(F, M, SizeOf(M));

  Repeat
    BlockRead(Fl, H, SizeOf(H));
    M.Size:=swap32(H.Size) - 1;
//    If H.Name[0] <> #0 Then WriteLn(H.Name, ' - ', M.Size);
    If IsAllowedTag(H.Name) Then
      Begin
        BlockWrite(F, H, SizeOf(H));
        GetMem(P, M.Size);
        BlockRead(Fl, P^, M.Size);
        BlockWrite(F, P^, M.Size);
        FreeMem(P, M.Size);
      End
    Else
      Seek(Fl, FilePos(Fl) + M.Size);
  Until H.Name[0] = #0;

  // padding with zeros
  While FileSize(F) Mod 16 <> 0 Do BlockWrite(F, H, 1);
  // fix padding size
  M.Size:=ID3_7BIT(FileSize(F) - SizeOf(M));
  Seek(F, 0);
  BlockWrite(F, M, SizeOf(M));
  Seek(F, FileSize(F));

  Seek(Fl, FilePos(Fl) - SizeOf(H));
  While H.Name[0] <> #$FF Do BlockRead(Fl, H, 1);
  Seek(Fl, FilePos(Fl) - 1);

  H.Size:=FileSize(Fl)-FilePos(Fl);
  GetMem(P, H.Size);
  BlockRead(Fl, P^, H.Size);
  BlockWrite(F, P^, H.Size);
  FreeMem(P, H.Size);

  CloseFile(F);
  CloseFile(Fl);
End.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0 -

 



Упрощённая версия Сейчас: 28th March 2024 - 12:56