Interface of TFFmpegVCL class

// The members of TInputOptions and TOutputOptions are according to ffmpeg's
//   command line parameters.
// please refer to http://ffmpeg.mplayerhq.hu/ffmpeg-doc.html for detail.

type

  PInputOptions = ^TInputOptions;
  TInputOptions = record
    // -i filename: input file name
    FileName: string;
    // -f fmt: force format
    FileFormat: string;

    // -ss position: set the start time offset
    TimeStart: Integer; // millisecond!!! differ with FFmpeg parameter

    // -programid: desired program number
    ProgramID: Integer;

    ExtOptions: string; // refer to ExtOptions of TOutputOptions
  end;

  TOptionTargetType = (ttIgnore, ttVCD, ttSVCD, ttDVD);
  TOptionNormType = (ntAuto, ntPAL, ntNTSC);
  TOptionNormDefault = ntPAL..ntNTSC;

  (* stream info *)
  TStreamInfo = packed record
    // -timestamp time: set the timestamp
    TimeStamp: TDateTime;  // !!! differ with FFmpeg parameter
    // -year number: set the year
    Year: Integer;  (**< ID3 year, 0 if none *)
    // -track number: set the track
    Track: Integer; (**< track number, 0 if none *)
    // -title string: set the title
    Title: array[0..512-1] of AnsiChar;
    // -author string: set the author
    Author: array[0..512-1] of AnsiChar;
    // -copyright string: set the copyright
    Copyright: array[0..512-1] of AnsiChar;
    // -comment string: set the comment
    Comment: array[0..512-1] of AnsiChar;
    // -album string: set the album
    Album: array[0..512-1] of AnsiChar;
    // -genre string: set the genre
    Genre: array[0..32-1] of AnsiChar; (**< ID3 genre *)
  end;

  POutputOptions = ^TOutputOptions;
  TOutputOptions = record
    FileName: string;
    FileExt: string;

    // -f fmt: force format
    FileFormat: string;

    // -packetsize <int>: E.... set packet size
    PacketSize: Integer;
    // -muxrate <int>: E.... set mux rate
    MuxRate: Integer;
    // -muxdelay seconds: set the maximum demux-decode delay
    MuxDelay: Single;
    // -muxpreload seconds: set the initial demux-decode delay
    MuxPreload: Single;

    // -acodec codec: force audio codec ('copy' to copy stream)
    AudioCodec: string;
    // -an: disable audio
    DisableAudio: Boolean;
    // -vol volume: change audio volume (256=normal)
    AudioVolume: Integer;
    // -ac channels: set number of audio channels
    AudioChannels: Integer;
    // -ar rate: set audio sampling rate (in Hz)
    AudioSampleRate: Integer;
    // -ab bitrate: set bitrate (in bits/s)
    AudioBitrate: Integer;
    // -abt <int>: E.A.. set audio bitrate tolerance (in bits/s)
    AudioBitRateTolerance: Integer;
    // -alang code: set the ISO 639 language code (3 letters) of the current audio stream
    AudioLanguage: string;
    // -async: audio sync method
    AudioSyncMethod: Integer;
    // -atag fourcc/tag: force audio tag/fourcc
    AudioTag: string;

    // -vcodec codec: force video codec ('copy' to copy stream)
    VideoCodec: string;
    // -vn: disable video
    DisableVideo: Boolean;
    // -r fps: set frame rate (Hz value, fraction or abbreviation)
    FrameRate: string;
    // -s size: set frame size (WxH or abbreviation)
    FrameSize: string;
    // -aspect aspect: set aspect ratio (4:3, 16:9 or 1.3333, 1.7777)
    FrameAspectRatio: string;
    // -croptop size: set top crop band size (in pixels)
    CropTop: Integer;
    // -cropbottom size: set bottom crop band size (in pixels)
    CropBottom: Integer;
    // -cropleft size: set left crop band size (in pixels)
    CropLeft: Integer;
    // -cropright size: set right crop band size (in pixels)
    CropRight: Integer;
    // -padtop size: set top pad band size (in pixels)
    PadTop: Integer;
    // -padbottom size: set bottom pad band size (in pixels)
    PadBottom: Integer;
    // -padleft size: set left pad band size (in pixels)
    PadLeft: Integer;
    // -padright size: set right pad band size (in pixels)
    PadRight: Integer;
    // -padcolor color: set color of pad bands
    PadColor: TColor;

    // -g gop_size: set the group of pictures size
    GroupPictureSize: Integer;
    // -b/vb bitrate: set bitrate (in bits/s)
    VideoBitrate: Integer;
    // -maxrate bitrate: set max video bitrate (in bit/s)
    VideoMaxRate: Integer;
    // -minrate bitrate: Set min video bitrate (in bit/s)
    VideoMinRate: Integer;
    // -bt <int>: E.V.. set video bitrate tolerance (in bits/s)
    VideoBitRateTolerance: Integer;
    // -bufsize size: Set video buffer verifier buffer size (in bits)
    VideoBufSize: Integer;
    // -vsync: video sync method
    VideoSyncMethod: Integer;
    // -vtag fourcc/tag: force video tag/fourcc
    VideoTag: string;
    // -vfilters filter list: video filters
    VideoFilters: string;

    // -sn: disable subtitle
    DisableSubtitle: Boolean;
    // -slang code: set the ISO 639 language code of the current subtitle stream
    SubtitleLanguage: string;

    // -copyts: copy timestamps
    CopyTimestamp: Boolean;
    // -t duration: record or transcode "duration" seconds of audio/video
    TimeLength: Integer; // millisecond!!! differ with FFmpeg parameter
    Info: TStreamInfo;

    // -target type: specify target file type ("vcd", "svcd", "dvd", "pal-vcd", ...)
    TargetType: TOptionTargetType;
    NormType: TOptionNormType;
    NormDefault: TOptionNormDefault;

    // NOTICE: only one of the below three options will act in the same time.
    //        they come into effect in this priority order: CustomHook, BeforeHook,
    //        VideoHookPTSs
    // whether enable OnCustomHook event, this feature is an increment to
    //        create your onw custom video hook behavior.
    CustomHook: Boolean;
    // whether enable OnBeforeHook event, this feature is an increment to
    //        change the standard behavior of FFmpeg's vhook.
    BeforeHook: Boolean;
    // whether enable VideoHookPTSs option, this feature is an increment to
    //        change the standard behavior of FFmpeg's vhook.
    // enable Video Hook only in special periods, empty means disable this option.
    // format: [<pts1>-<pts2>[,pts3-pts4[,...]]]
    // example: to process video hook only in pts periods 0-5,10-15 (seconds)
    //          VideoHookPTS := '0-5000,10000-15000'; // millisecond!!!
    VideoHookPTSs: string; // millisecond!!!

    // extent options for flexibility
    // Format: name1=value1<CRLF>name2=value2<CRLF>...nameN=valueN<CRLF>
    //         name and value correspond to ffmpeg.exe's parameters
    //         e.g. "pix_fmt=yuv422p<CRLF>aspect=16:9<CRLF>"
    ExtOptions: string;
  end;

  // refer to libavutil_log.pas or ffmpeg's (libavutil)log.h
  TLogLevel = (llQuiet,
                //llFatal,
                llError,
                //llWarning,
                llInfo,
                //llVerbose,
                llDebug,
                llAll);

  // PCR - Program Clock Reference
  // STC - System Time Clock
  // SCR - System Clock Reference
  // PTS - Presentation Time Stamp
  // DTS - Decode Time Stamp

  // BeforeHookEvent parameters, only triggered with OutputOptions.BeforeHook = True
  // NOTICE: not thread safety
  // AIndex: index of input files
  // APTS: presentation time stamp of current picture, in microseconds
  // AHookAction: THookAction = (haContinue, haIgnore, haStop)
  //    haContinue: continue processing video hook
  //    haIgnore: ignore processing video hook
  //    haStop: stop video hook, and BeforeHook event will not be triggered with this file
  //    initial value is haContinue, and next time it will keep the previous value
  TBeforeHookEvent = procedure(const AIndex: Integer; const APTS: Int64;
    var AHookAction: THookAction) of object;

  // CustomHookEvent parameters, only triggered with OutputOptions.CustomHook = True
  // NOTICE: not thread safety
  // AIndex: index of input files
  // ABitmap: bitmap filled with the original video picture, you can save it,
  //          or change it by drawing text or image on bitmap.Canvas,
  //          but you must NOT change the size and the PixelFormat of the bitmap!
  // AFrameNumber: frame index number, first is 1 not 0
  // APTS: presentation time stamp of current picture, in microseconds
  // AUpdate: whether update the bitmap back to original video picture, default true
  // AStopHook: whether stop video hook, if true then CustomHook event will not
  //          be triggered with this file, default false
  TCustomHookEvent = procedure(const AIndex: Integer; ABitmap: TBitmap;
    const AFrameNumber: Integer; const APTS: Int64;
    var AUpdate, AStopHook: Boolean) of object;

  // LogEvent parameters
  // AIndex: index of input files, (-1) means index cannot be determined
  // TLogLevel = (llQuiet, llError, llInfo, llDebug, llAll);
  TLogEvent = procedure(const AIndex: Integer; const ALogLevel: TLogLevel;
    const AMsg: string) of object;

  // ProgressEvent parameters
  // AIndex: index of input files
  // AFrameNumber: current frame number
  // AFPS: video converting speed, frames per second, not valid when only audio output
  // ACurrentDuration: current duration time in millisecond
  // AQuality: <i don't know...>???
  // ABitRate: ...
  // ACurrentSize: current output file size in bytes
  // ATotalOutputDuration: total output duration time in millisecond
  TProgressEvent = procedure(const AIndex, AFrameNumber, AFPS, ACurrentDuration: Integer;
    const AQuality, ABitRate: Single; const ACurrentSize: Int64;
    const ATotalOutputDuration: Integer) of object;

  // TerminateEvent parameters
  // AIndex: index of input files, (-1) means all files are converted
  // AFinished: true means converted success, false means converting breaked
  // AException: true means Exception occured
  // AMessage: exception message
  TTerminateEvent = procedure(const AIndex: Integer; const AFinished, AException: Boolean;
    const AMessage: string) of object;

  TConvertPriority = tpIdle..tpNormal; //tpIdle, tpLowest, tpLower, tpNormal
  TCustomFFmpegVCL = class(TComponent)
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    function LoadAVLib(const APath: string; const AWithVerNum: Boolean): Boolean;
    procedure UnloadAVLib;

    function AddInputFile(const AFileName: string;
      const AOptions: PInputOptions = nil): Integer; overload;
    function AddInputFile(const AFileName: string;
      const AExtOptions: string): Integer; overload;
    function AddInputFile(const AInputIndex: Integer; const AFileName: string;
      const AOptions: PInputOptions = nil): Boolean; overload;
    function AddInputFile(const AInputIndex: Integer; const AFileName: string;
      const AExtOptions: string): Boolean; overload;
    function AddInputSubtitle(const AInputIndex: Integer; const AFileName: string;
      const AOptions: PInputOptions = nil): Boolean;
    function SetOutputFile(const AInputIndex: Integer; const AFileName: string;
      const AOptions: POutputOptions = nil): Boolean; overload;
    function SetOutputFile(const AInputIndex: Integer; const AFileName: string;
      const AExtOptions: string): Boolean; overload;
    function AddInputStream(const AStream: TStream; const APrivateData: string;
      const AOptions: PInputOptions = nil): Integer;
    function SetOutputStream(const AInputIndex: Integer; const AStream: TStream;
      const APrivateData: string; const AOptions: POutputOptions = nil): Boolean;
    procedure ClearInputFiles;
    procedure RemoveInputFile(const AInputIndex: Integer);

    procedure StartConvert(const AThreadCount: Integer = 0);
    procedure BreakConverting;
    procedure PauseConverting;
    procedure ResumeConverting;

    procedure SetLicenseKey(const AKey: AnsiString; const ASeed: LongWord;
      const AHex: Boolean = True);

    property AVProbe: TAVProbe read FAVProbe;
    property AVFileInfo[Index: Integer]: TAVProbe read GetAVProbes;
    property LastErrMsg: string read FLastErrMsg;
    property FilesCount: Integer read GetFilesCount;
    property InputFiles[Index: Integer]: PAVFormatContext read GetInputFiles;
    property InputOptions[Index: Integer]: TInputOptions read GetInputOptions;
    property OutputOptions[Index: Integer]: TOutputOptions read GetOutputOptions;
    property FFmpegs[Index: Integer]: TFFmpeg read GetFFmpegs;

    property LogLevel: TLogLevel read FLogLevel write SetLogLevel default llInfo;
    property ProgressInterval: Integer read FProgressInterval write SetProgressInterval
      default CReportInterval;
    property ThreadPriority: TConvertPriority read FThreadPriority write FThreadPriority
      default tpNormal;

    property Version: string read GetVersion;

    property OnBeforeHook: TBeforeHookEvent read FOnBeforeHook write FOnBeforeHook;
    property OnCustomHook: TCustomHookEvent read FOnCustomHook write FOnCustomHook;
    property OnLog: TLogEvent read FOnLog write FOnLog;
    property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
    property OnTerminate: TTerminateEvent read FOnTerminate write FOnTerminate;
  published
    property About: string read FAbout write FAbout;
  end;

  TFFmpegVCL = class(TCustomFFmpegVCL)
  published
    property LogLevel;
    property ProgressInterval;
    property ThreadPriority;
    property Version;
    property OnBeforeHook;
    property OnCustomHook;
    property OnLog;
    property OnProgress;
    property OnTerminate;
  end;

procedure InitInputOptions(P: PInputOptions);
procedure InitOutputOptions(P: POutputOptions);

implementation

procedure InitInputOptions(P: PInputOptions);
begin
  with P^ do
  begin
    FileName := '';
    FileFormat := '';
    TimeStart := -1;
    ProgramID := -1;
    ExtOptions := '';
  end;
end;

procedure InitOutputOptions(P: POutputOptions);
begin
  with P^ do
  begin
    FileName := '';
    FileExt := '';
    FileFormat := '';

    PacketSize := -1;
    MuxRate := -1;
    MuxDelay := -1;
    MuxPreload := -1;

    AudioCodec := '';
    DisableAudio := False;
    AudioVolume := -1;
    AudioChannels := -1;
    AudioSampleRate := -1;
    AudioBitrate := -1;
    AudioBitRateTolerance := -1;
    AudioLanguage := '';
    AudioSyncMethod := 0;
    AudioTag := '';

    VideoCodec := '';
    DisableVideo := False;
    FrameRate := '';
    FrameSize := '';
    FrameAspectRatio := '';
    CropTop := -1;
    CropBottom := -1;
    CropLeft := -1;
    CropRight := -1;
    PadTop := -1;
    PadBottom := -1;
    PadLeft := -1;
    PadRight := -1;
    PadColor := clBlack;

    GroupPictureSize := -1;
    VideoBitrate := -1;
    VideoMaxRate := -1;
    VideoMinRate := -1;
    VideoBitRateTolerance := -1;
    VideoBufSize := -1;
    VideoSyncMethod := -1;
    VideoTag := '';
    VideoFilters := '';

    DisableSubtitle := False;
    SubtitleLanguage := '';

    CopyTimestamp := False;
    TimeLength := -1;
    FillChar(Info, SizeOf(TStreamInfo), 0);
    Info.TimeStamp := -1;
    Info.Year := -1;
    Info.Track := -1;

    TargetType := ttIgnore;
    NormType := ntAuto;
    NormDefault := ntPAL;

    CustomHook := False;
    BeforeHook := False;
    VideoHookPTSs := '';

    ExtOptions := '';
  end;
end;