ReNamer:Scripts:AVI video codec

From den4b Wiki
Jump to: navigation, search

Extract AVI video codec and insert it into the filename, as a suffix.

Tested

  • ReNamer 5.50

Code

Author: prologician. Date: 3 Aug 2009.

The simple version of the script, which should work for most of the AVI files:

var
  fourcc: string;
begin
  if WideSameText(WideExtractFileExt(FileName), '.avi') then
  begin
    fourcc := FileReadFragment(FilePath, 7*16, 4);
    FileName := WideExtractBaseName(FileName) +
      ' ' + fourcc + WideExtractFileExt(FileName);
  end
end.

More complicated version, which is parsing internal AVI structures:

function BigEndian(const bytestring: String): Integer;
var
  i: Integer;
begin
  result := 0;
  for i := 1 to Length(bytestring) do
    result := result * $100 + ord(bytestring[i])
end;

function LittleEndian(const bytestring: String): Integer;
var
  i: Integer;
begin
  result := 0;
  for i := Length(bytestring) downto 1 do
    result := result * $100 + ord(bytestring[i])
end;

function FileAssertString(var offset: integer; const actual: string): Boolean;
begin
  result := (WideCompareStr(actual, FileReadFragment(FilePath, offset, length(actual))) = 0)
  offset := offset + length(actual)
end;

procedure FileSkip(var fileoffset: integer; const amount: integer);
begin
  fileoffset := fileoffset + amount
end;

function IsStrhVids(offset: integer): Boolean;
begin
  result := false;
  if not fileassertstring(offset, 'strl') then exit;
  if not fileassertstring(offset, 'strh') then exit;
  FileSkip(offset, 4); //Size of the strh chunk
  if not fileassertstring(offset, 'vids') then exit;
  result := true;
end;

var
  fourcc: string;
  fileptr: integer;
  streams: integer;
  chunksize: integer;
  i: integer;
begin
  if WideSameText(WideExtractFileExt(FileName), '.avi') then
  begin
    fileptr := 0;
    chunksize := 0;
    if not widefileexists(filepath) then exit;
    if not fileassertstring(fileptr, 'RIFF') then exit;
    FileSkip(fileptr, 4); //Size of the RIFF chunk (most of the file)
    if not fileassertstring(fileptr, 'AVI ') then exit;
    if not fileassertstring(fileptr, 'LIST') then exit;
    FileSkip(fileptr, 4); //Size of the list
    if not fileassertstring(fileptr, 'hdrl') then exit;
    if not fileassertstring(fileptr, 'avih') then exit;
    streams := LittleEndian(FileReadFragment(FilePath, fileptr + 28, 4));
    FileSkip(fileptr, LittleEndian(FileReadFragment(FilePath, fileptr, 4)) + 4); //Skip over the 'avih' chunk.

    for i := 1 to streams do
    begin
      FileSkip(fileptr, chunksize);
      if not fileassertstring(fileptr, 'LIST') then exit;
      chunksize := LittleEndian(FileReadFragment(FilePath, fileptr, 4));
      FileSkip(fileptr, 4); //Size of the list
      if IsStrhVids(fileptr) then
      begin
        fourcc := FileReadFragment(FilePath, fileptr + 16, 4);
        FileName := WideExtractBaseName(FileName) + ' ' + fourcc + WideExtractFileExt(FileName);
        exit
      end
    end
  end
end.