#1 2009-08-01 11:08

icerapids
Member
Registered: 2009-08-01
Posts: 6

Get AVI compression

hello all, i am new here so bare with me please, i just recently came across this program and cant say enough about it.. my friends are amazed at what it can do.. but ive recently ran into abit of a puzzle, i dont see an option in the AVI META to get the compression type of the file e.g. "XVID", "DIVX".. so my question is..   is there a way to pull such information from the file and insert it into a file or folder name with a script?

thank you in advance for reading and trying.  smile

Offline

#2 2009-08-01 13:23

Andrew
Senior Member
Registered: 2008-05-22
Posts: 542

Re: Get AVI compression

AVI is a container that can contain data streams encoded using many possible audio/video codecs. You can use the "detect using binary signature" rule or the TrID PascalScript to detect the correct file extension (i.e. AVI), but detection of the actual codecs used inside is not something I see being added anytime soon.

Offline

#3 2009-08-02 11:07

prologician
Member
Registered: 2009-01-30
Posts: 84

Re: Get AVI compression

Wow, people still use AVIs... <LOL> wink

Well, with a little bit of online rummaging, I might have something for you. One thing I came across online (a rather cheap answer), is to read the four bytes from offset 0x70 in the file, according to one site. Assuming that the website is correct (something I'm not checking at this time), you can brew a short and sweet PascalScript to do the job:

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

Considering that Denis has already introduced metatags that tell the width, height, and framecount of an AVI, it's not a stretch that he could introduce support for FourCC as well. But at this second, I'm not sure we need to dump this one on him. smile

Offline

#4 2009-08-02 22:33

icerapids
Member
Registered: 2009-08-01
Posts: 6

Re: Get AVI compression

BRILLIANT!!, thank you so much for your speedy replies..

Andrew: i tried that out.. and the binary signiture didnt make any changes to file name, i also took a look at the TrID PascalScript, and i have to say.. as much as i know about computers.. i was way in over my head..  i dont know Pascal, and ive been trying to learn it from the many examples i found on here and elsewhere.. but i am still very confused.

prologician: that script works GREAT!  smile   ..thank you so much, i have only to ask if theres a way to tweak the script abit..  for example.

the script does this..
Movie 1.avi  ->  Movie 1div3.avi
Movie 2.avi  ->  Movie 2xvid.avi
Movie 3.avi  ->  Movie 3xvid.avi

which is a great improvement from what i had before.. i can always add a few replace filters to clean it up abit, but i was wondering if you can possibly add a few things to the script itself so that the results could look like this..

Movie 1 Div3.avi  (would also be nice if it could auto rename results of div3 to DivX)
Movie 2 XviD.avi
Movie 3 XviD.avi

note: the space between the compression and the file name.. if this was added i think it would be an amazing peice of script i could use over and over again!  smile

Offline

#5 2009-08-02 23:35

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,067

Re: Get AVI compression

If you want to replace "div3" or "div4" with "DivX", and "xvid" or "XVID" with "XviD" - simply add a couple of Replace rules. To insert a space in front of codec a small modification is required to the script, here it is:

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.

Note: This script may not work for all AVI files, depending on the structure of the AVI container.

Offline

#6 2009-08-03 01:57

icerapids
Member
Registered: 2009-08-01
Posts: 6

Re: Get AVI compression

THANK YOU den4b!!!!!   big_smile:D:D   ..your program ROCKS dude!!!

i cant begin to tell you how amazing this is big_smile, and my appreciation for your knowledge has no bounds smile.. you guys are awesome..  with the push of a button, you saved me so many hours of work.   lol cool cool cool

works perfect!

Offline

#7 2009-08-03 03:05

narayan
Senior Member
Registered: 2009-02-08
Posts: 466

Re: Get AVI compression

icerapids wrote:

..  i dont know Pascal, and ive been trying to learn it from the many examples i found on here and elsewhere.. but i am still very confused.

If you are interested in the PascalScript, you can check out the new help here:
http://www.den4b.com/wiki/ReNamer:Pascal_Script

HTH

Offline

#8 2009-08-03 04:50

prologician
Member
Registered: 2009-01-30
Posts: 84

Re: Get AVI compression

@Denis:

Among your metatags, you have some meant for AVIs, like digging up the framerate and framecount. Am I correct in assuming that you parse the AVI header (at the very least, the 'hdrl' chunk) to retrieve that data, as compared to a constant offset like what was used in this case?

(The reason I ask is that I'm thinking of writing an updated version which actually does things properly, rather than using magic numbers. If nothing else, the additional helper functions for handling endianness could come in handy some other day.) smile

~*~

Edit: I went ahead and cooked up something anyways. I think this is suitably more robust than the other code, since this allows reordering of the streams within the AVI (though isn't the video stream always first?), and properly jumps over the 'avih' main header (whose size is always constant, according to Microsoft spec). So, assuming that the video stream is always Stream 0 within an AVI, then yes... a constant offset could work. smile

If you're paranoid.... here's an alternative, with helper functions to match:

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.

This doesn't really address OpenDML standards, and I didn't really find a nice doc that explained it down to the nitty-gritty details like the regular AVI spec. If someone finds a nice spec that explains things well enough.... do tell. smile Otherwise, stick a fork in me, I'm done. smile

Last edited by prologician (2009-08-03 08:22)

Offline

#9 2009-08-03 13:29

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,067

Re: Get AVI compression

Very nice, prologician!! big_smile

But I have bad news for you: I have added AVI_VideoCodec meta tag! wink

Basically, this tag does exactly the same thing, but it will work faster than the script, it parses only the necessary structures and doesn't continuously opens and closes file (each call to FileReadFragment). It will also enumerate all available streams until it finds video stream, so video stream doesn't have to be the first one in the list.

By the way, I found a good AVI File Format Specification:
http://www.alexander-noe.com/video/docu … on/avi.pdf

P.S. AVI_VideoCodec is available in the latest development version.

P.S.2. prologician, you should add your script to wiki/ReNamer:Scripts, it can serve as a good educational example!

Offline

#10 2009-08-10 07:14

icerapids
Member
Registered: 2009-08-01
Posts: 6

Re: Get AVI compression

den4b wrote:

I have added AVI_VideoCodec meta tag! wink


MEGA SWEEEEET!!!  big_smile big_smile big_smile

Offline

Board footer

Powered by FluxBB