Download Delphi FFmpeg VCL Components

Interface of FFmpegVCL Component(Video Converter)

// Most of the members of TInputOptions and TOutputOptions are according to
// the parameters of ffmpeg command line tool.
// Please refer to http://www.ffmpeg.org/ffmpeg-doc.html for detail.

type
  PInputOptions = ^TInputOptions;
  TInputOptions = record
    FileName: WideString;

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

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

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

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

    // used for your special purpose
    Tag: Integer;
    Data: Pointer;
  end;

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

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

  POutputOptions = ^TOutputOptions;
  TOutputOptions = record
    FileName: WideString;
    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;
    // -apre preset: set the audio options to the indicated preset
    AudioPreset: 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;
    // -vpre preset: set the video options to the indicated preset
    VideoPreset: 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;
    // -vlang code: set the ISO 639 language code (3 letters) of the current video stream
    VideoLanguage: string;

    // -scodec codec: force subtitle codec ('copy' to copy stream)
    SubtitleCodec: string;
    // -spre preset: set the subtitle options to the indicated preset
    SubtitlePreset: string;
    // -sn: disable subtitle
    DisableSubtitle: Boolean;
    // -slang code: set the ISO 639 language code (3 letters) of the current subtitle stream
    SubtitleLanguage: string;

    // -copyts: copy timestamps
    CopyTimestamp: Boolean;
    // -ss position: set the start time offset
    TimeStart: Int64; // microsecond!!! differ with FFmpeg parameter
    // -t duration: record or transcode "duration" seconds of audio/video
    TimeLength: Int64; // microsecond!!! differ with FFmpeg parameter
    Info: TStreamInfo;

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

    // whether enable OnCustomHook event, this feature is an increment to
    //        create your onw custom video hook behavior.
    CustomHook: Boolean;

    // join all input files to this one output file
    Join: Boolean;

    // use max recording time for judgment of cutting clip TimeLength
    UseMaxRecordingTime: Boolean;

    // 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;

    // used for your special purpose
    Tag: Integer;
    Data: Pointer;
  end;

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

  PHookInfo = ^THookInfo;
  THookInfo = record
    TaskIndex: Integer;     // index of converting tasks
    Bitmap: TBitmap;        // 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!
    FrameNumber: Integer;   // frame index number, first is 1 not 0
    PTS: Int64;             // presentation time stamp of current picture, in microseconds
    Update: Boolean;        // whether update the bitmap back to original video picture, default True
    StopHook: Boolean;      // whether stop video hook, if true then CustomHook event will not
                            //  be triggered with this file, default False
  end;
  // only triggered with OutputOptions.CustomHook = True
  TCustomHookEvent = procedure(Sender: TObject; AHookInfo: PHookInfo) of object;

  TPreviewInfo = record
    TaskIndex: Integer;     // index of converting tasks
    Bitmap: TBitmap;        // bitmap filled with the target video picture, you can save it,
                            //  or paint it on any canvas(or any other control) which you want.
    FrameNumber: Integer;   // frame index number, first is 1 not 0
    PTS: Int64;             // presentation time stamp of current picture, in microseconds
  end;
  // only triggered with property PreviewBitmap = True
  TPreviewBitmapEvent = procedure(Sender: TObject; const APreviewInfo: TPreviewInfo) of object;

  PProgressInfo = ^TProgressInfo;
  TProgressInfo = record
    TaskIndex: Integer;     // index of converting tasks
    FileIndex: Integer;     // index of input files in the current task
    FrameNumber: Integer;   // current frame number
    FPS: Integer;           // video converting speed, frames per second, not valid when only audio output
    Quality: Single;        // quality
    BitRate: Single;        // bitrate
    CurrentSize: Int64;     // current output file size in bytes
    CurrentDuration: Int64; // current duration time in microsecond
    TotalDuration: Int64;   // total output duration time in microsecond
  end;
  TProgressEvent = procedure(Sender: TObject; AProgressInfo: PProgressInfo) of object;

  TTerminateInfo = record
    TaskIndex: Integer;     // index of converting tasks, (-1) means all tasks are terminated
    Finished: Boolean;      // True means converted success, False means converting breaked
    Exception: Boolean;     // True means Exception occured, False please ignore
    ExceptionMsg: string;   // Exception message 
  end;
  TTerminateEvent = procedure(Sender: TObject; const ATerminateInfo: TTerminateInfo) of object;

  TCustomFFmpegVCL = class(TComponent)
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    function AVLibLoaded: Boolean;
    function LoadAVLib(const APath: TPathFileName): Boolean;
    procedure UnloadAVLib;
    procedure SetLicenseKey(const AKey: AnsiString; ASeed: LongWord; AHex: Boolean = True);

    function AddTask(const AFileName: WideString; AOptions: PInputOptions = nil): Integer; overload;
    function AddTask(const AFileName: WideString; const AExtOptions: string): Integer; overload;
    function AddTask(AStream: TStream; const APrivateData: string; AOptions: PInputOptions = nil): Integer; overload;
    function AddInputFile(ATaskIndex: Integer; const AFileName: WideString; AOptions: PInputOptions = nil): Boolean; overload;
    function AddInputFile(ATaskIndex: Integer; const AFileName: WideString; const AExtOptions: string): Boolean; overload;
//    function AddInputSubtitle(ATaskIndex: Integer; const AFileName: WideString; AOptions: PInputOptions = nil): Boolean;
    function SetOutputFile(ATaskIndex: Integer; const AFileName: WideString; AOptions: POutputOptions = nil): Boolean; overload;
    function SetOutputFile(ATaskIndex: Integer; const AFileName: WideString; const AExtOptions: string): Boolean; overload;
    function SetOutputStream(ATaskIndex: Integer; AStream: TStream; const APrivateData: string; AOptions: POutputOptions = nil): Boolean;
    procedure ClearTasks;
    procedure Exchange(ATaskIndex1, ATaskIndex2: Integer);
    procedure RemoveTask(ATaskIndex: Integer);

    procedure Start(AThreadCount: Integer = 0);
    procedure Pause;
    procedure Resume;
    procedure Stop(AWaitFor: Boolean = True);

    property AVProbe: TAVProbe read FAVProbe;
    property AVProbes[TaskIndex, FileIndex: Integer]: TAVProbe read GetAVProbes;
    property FFmpegs[TaskIndex: Integer]: TFFmpeg read GetFFmpegs;
    property InputFiles[TaskIndex, FileIndex: Integer]: PAVFormatContext read GetInputFiles;
    property InputOptions[TaskIndex, FileIndex: Integer]: TInputOptions read GetInputOptions;
    property LastErrMsg: string read FLastErrMsg;
    property OutputFiles[TaskIndex, FileIndex: Integer]: PAVFormatContext read GetOutputFiles;
    property OutputOptions[TaskIndex, FileIndex: Integer]: TOutputOptions read GetOutputOptions;
    property TasksCount: Integer read GetTasksCount;

    property Preview: Boolean read FPreview write SetPreview default False;
    property PreviewBitmap: Boolean read FPreviewBitmap write SetPreviewBitmap default False;
    property ProgressInterval: Integer read FProgressInterval write SetProgressInterval default CReportInterval;
    property ThreadPriority: TThreadPriority read FThreadPriority write FThreadPriority default tpNormal;
    property TriggerEventInMainThread: Boolean read FTriggerEventInMainThread write FTriggerEventInMainThread default True;
    property UserData: Pointer read FData write FData;
    property Verbose: Integer read FVerbose write FVerbose;

    property OnCustomHook: TCustomHookEvent read FOnCustomHook write FOnCustomHook;
    property OnPreviewBitmap: TPreviewBitmapEvent read FOnPreviewBitmap write FOnPreviewBitmap;
    property OnProgress: TProgressEvent read FOnProgress write FOnProgress;
    property OnTerminate: TTerminateEvent read FOnTerminate write FOnTerminate;
  published
    property About: string read FAbout write FAbout;
    property Version: string read GetVersion;
  end;

  TFFmpegVCL = class(TCustomFFmpegVCL)
  published
    property Preview;
    property PreviewBitmap;
    property ProgressInterval;
    property ThreadPriority;
    property TriggerEventInMainThread;

    property OnCustomHook;
    property OnPreviewBitmap;
    property OnProgress;
    property OnTerminate;
  end;

const
  AV_NOPTS_VALUE: Int64    = $8000000000000000;
  AV_TIME_BASE             = 1000000;

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

implementation

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

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

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

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

    VideoCodec := '';
    VideoPreset := '';
    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 := '';
    VideoLanguage := '';

    SubtitleCodec := '';
    SubtitlePreset := '';
    DisableSubtitle := False;
    SubtitleLanguage := '';

    CopyTimestamp := False;
    TimeStart := AV_NOPTS_VALUE;
    TimeLength := AV_NOPTS_VALUE;

    Info.TimeStamp := -1;
    Info.Year := -1;
    Info.Track := -1;
    Info.Title := '';
    Info.Author := '';
    Info.Copyright := '';
    Info.Comment := '';
    Info.Album := '';
    Info.Genre := '';

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

    CustomHook := False;

    Join := False;
    UseMaxRecordingTime := False;

    ExtOptions := '';

    Tag := 0;
    Data := nil;
  end;
end;