Einzelnen Beitrag anzeigen

Benutzerbild von Amnon82
Amnon82

Registriert seit: 5. Jan 2005
186 Beiträge
 
FreePascal / Lazarus
 
#1

Wie kann man die Länge einer AVS-Datei ermitteln?

  Alt 5. Jan 2005, 22:50
Ich hab ein kleines Problem mit meinem Projekt.

Mir fehlt eine Funktion für mein Programm.
Es ist ein Videotool. Damit es einfacher wird bräuchte ich
eine Funktion um die Frames(Länge des Films in Frames) einer AVS-Datei zu ermitteln.

AVS >> www.avisynth.org

z.Z. benutze ich das Programm makeAVIS um aus der AVS eine
fakeAVI zu erstellen. Somit kann ich den Code von meinem Freund
benutzen:

Delphi-Quellcode:
unit VidInfo;
{
  Retrieves information for given filenames.
  Works with AVI and MPEG/VOB files as well as with
  DVDAVI (.d2v) project files (as they are tracked down
  to the source files, as you can see in getD2VVideo).
  (c) 2004 by Marcel
  last changes 2005-01-05 by Amnon82:
}


interface

Type

  TVideoInfo = Record
    Width, Height, //resolution of the video; might be different from
                    //correct display resolution (as NTSC SVCDs have a
                    //resolution of 480*480 but are displayed with e.g.
                    //640*480

    FPS1000, //Frames per second * 1000: for NTSC, FPS1000 = 29970

    MPEGversion, //1 for MPEG-1, 2 for MPEG-2, 0 for any other, like
                    //AVI files

    AspectRatio, //1 for square pixels (=AR_SQUARE_PIXEL)
                    //2 for 4:3 display aspect ratio, as for VCD and
                    // SVCD (=AR_4to3)
                    //3 for 16:9 display aspect ratio, as for most DVDs
                    // (=AR_16to9)

    Streams //Number of Streams (audio and video) - AVI only
    : Integer;

    FPS: Single; //Frames per second in floating point format

    Frames: LongInt;//Number of frames - only detected for AVI files

    PiDAR: Single; //Pixel Display Aspect Ratio:
                    //when displaying the video, the width of a pixel
                    //should be its height multiplied by PiDAR
  end;

Const
  AR_SQUARE_PIXEL = 1;
  AR_4to3 = 2;
  AR_16to9 = 3;

function getD2VVideo(sFileName: String): String;
function getVideoInfo(sFileName: String): TVideoInfo;

implementation

uses SysUtils, Classes;

function getD2VVideo(sFileName: String): String;
var slD2V: TStringList;
    sFn: String;
    iBlankPos: Integer;
begin
  Try
    slD2V := TStringList.Create;
    slD2V.Clear;
    slD2V.LoadFromFile(sFileName);
    if slD2V.Count > 2 then begin
      if (slD2V.Strings[0] = 'DGIndexProjectFile06')
      or (slD2V.Strings[0] = 'DVD2AVIProjectFile')
      then sFn := slD2V.Strings[2];
      iBlankPos := Pos(' ', sFn);
      if iBlankPos > 0
      then delete(sFn,1,iBlankPos)
      else sFn := '';
    end
    else sFn := '';
  Finally
    getD2VVideo := sFn;
    slD2V.Free;
  End;
end;

function getVideoInfo(sFileName: String): TVideoInfo;
var f: file of byte;
    i: integer;
    liMsPerFrame, liStreams, liWidth, liHeight, liFrames: LongInt;
    bByte: Byte;
    hex: Array [0..15] of Char;
    buf: String;
    FPS: Single;
    VI: TVideoInfo;
    booDone1B3, booDone1BA: Boolean;
    cnt: Integer;
begin
  for i := 0 to 9 do hex[i] := IntToStr(i)[1];
  hex[10]:='A'; hex[11]:='B'; hex[12]:='C'; hex[13]:='D'; hex[14]:='E'; hex[15]:='F';

  FPS := 0;
  cnt := 0;

  vi.AspectRatio := AR_SQUARE_PIXEL;
  vi.FPS := 0;
  vi.FPS1000 := 0;
  vi.MPEGversion := 0;
  vi.Width := 0;
  vi.Height := 0;
  vi.Frames := 0;
  vi.PiDAR := 1;
  vi.Streams := 2;

  if UpperCase(copy(sFileName, length(sFileName)-2,3)) = 'D2V'
  then sFileName := getD2Vvideo(sFileName);

  booDone1B3 := False;
  booDone1BA := False;

  AssignFile(f, sFileName);
  Reset(f);
  if UpperCase(copy(sFileName, length(sFileName)-2,3)) = 'AVI'
  then begin
    vi.MPEGversion := 0;
    vi.AspectRatio := AR_SQUARE_PIXEL;
    for i := 1 to 32 do if not EOF(f) then Read(f,bByte);
    if not EOF(f) then Read(f,bByte); liMsPerFrame := bByte;
    if not EOF(f) then Read(f,bByte); liMsPerFrame := liMsPerFrame + bByte * 256;
    if not EOF(f) then Read(f,bByte); liMsPerFrame := liMsPerFrame + bByte * 256 * 256;
    if not EOF(f) then Read(f,bByte); liMsPerFrame := liMsPerFrame + bByte * 256 * 256 * 256;
    vi.FPS := 1000000 / liMsPerFrame;
    for i := 1 to 12 do if not EOF(f) then Read(f,bByte);
    if not EOF(f) then Read(f,bByte); liFrames := bByte;
    if not EOF(f) then Read(f,bByte); liFrames := liFrames + bByte * 256;
    if not EOF(f) then Read(f,bByte); liFrames := liFrames + bByte * 256 * 256;
    if not EOF(f) then Read(f,bByte); liFrames := liFrames + bByte * 256 * 256 * 256;
    vi.Frames := liFrames;
    for i := 1 to 4 do if not EOF(f) then Read(f,bByte);
    if not EOF(f) then Read(f,bByte); liStreams := bByte;
    if not EOF(f) then Read(f,bByte); liStreams := liStreams + bByte * 256;
    if not EOF(f) then Read(f,bByte); liStreams := liStreams + bByte * 256 * 256;
    if not EOF(f) then Read(f,bByte); liStreams := liStreams + bByte * 256 * 256 * 256;
    vi.Streams := liStreams;
    for i := 1 to 4 do if not EOF(f) then Read(f,bByte);
    if not EOF(f) then Read(f,bByte); liWidth := bByte;
    if not EOF(f) then Read(f,bByte); liWidth := liWidth + bByte * 256;
    if not EOF(f) then Read(f,bByte); liWidth := liWidth + bByte * 256 * 256;
    if not EOF(f) then Read(f,bByte); liWidth := liWidth + bByte * 256 * 256 * 256;
    vi.Width := liWidth;
    if not EOF(f) then Read(f,bByte); liHeight := bByte;
    if not EOF(f) then Read(f,bByte); liHeight := liHeight + bByte * 256;
    if not EOF(f) then Read(f,bByte); liHeight := liHeight + bByte * 256 * 256;
    if not EOF(f) then Read(f,bByte); liHeight := liHeight + bByte * 256 * 256 * 256;
    vi.Height := liHeight;
  end;

  if (UpperCase(copy(sFileName, length(sFileName)-3,4)) = 'MPEG')
  or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = 'MPG')
  or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = 'MPE')
  or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = 'VOB')
  or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = 'M1V')
  or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = 'M2V')
  or (UpperCase(copy(sFileName, length(sFileName)-2,3)) = 'MPV')
  then begin
    vi.AspectRatio := AR_SQUARE_PIXEL;
    if length(buf) >= 8 then delete(buf,1,2);
    while (EOF(f)=false)
    and ((booDone1B3 = false) or (booDone1BA = false))
    do begin
      if length(buf) >= 8 then delete(buf,1,2);
      Read(f,bByte);
      Inc(cnt);
      buf := buf + hex[bByte DIV 16] + hex[bByte MOD 16];
      if buf = '000001B3then begin // FPS and Res
        if not EOF(f) then Read(f,bByte);
        vi.Width := bByte * 16;
        if not EOF(f) then Read(f,bByte);
        vi.Width := vi.Width + bByte DIV 16;
        vi.Height := (bByte MOD 16) * 256;
        if not EOF(f) then Read(f,bByte);
        vi.Height := vi.Height + bByte;
        if not EOF(f) then Read(f,bByte);
        vi.AspectRatio := bByte DIV 16;
        if vi.AspectRatio = 8 then vi.AspectRatio := 3;
        if vi.AspectRatio = 12 then vi.AspectRatio := 2;
        bByte := bByte MOD 16;
        Case bByte of
          1: vi.FPS := 23.976;
          2: vi.FPS := 24;
          3: vi.FPS := 25;
          4: vi.FPS := 29.97;
          5: vi.FPS := 30;
          6: vi.FPS := 50;
          7: vi.FPS := 59.94;
          8: vi.FPS := 60;
        end;
        booDone1B3 := True;
      end;
      if buf = '000001BAthen begin
        if not EOF(f) then Read(f,bByte) else bByte := 0;
        if bByte AND $F0 = $20 then vi.MPEGversion := 1;
        if bByte AND $C0 = $40 then vi.MPEGversion := 2;
        booDone1BA := True;
      end;
      if cnt > 16384 then begin
        booDone1B3 := True;
        booDone1BA := True;
      end;
    end;
  end;
  CloseFile(f);
  vi.FPS := round(vi.FPS*1000)/1000;
  vi.FPS1000 := round(vi.FPS*1000);
  case vi.AspectRatio of
    AR_SQUARE_PIXEL:
      vi.PiDAR := 1;
    AR_4to3:
      vi.PiDAR := (vi.Height * 4 / 3) / vi.Width;
    AR_16to9:
      vi.PiDAR := (vi.Height * 16 / 9) / vi.Width;
  end;
  getVideoInfo := vi;
end;

end.
Wenn Einer eine Idee hat würd ich mich freuen.
  Mit Zitat antworten Zitat