unit OptionFrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ExtCtrls, FFmpegVCL, AVProbe;
type
TfrmOption = class(TForm)
lblOutPath: TLabel;
grpAVFileInfo: TGroupBox;
mmoAVFileInfo: TMemo;
grpFormats: TRadioGroup;
grpNorm: TRadioGroup;
grpAudioChannels: TRadioGroup;
grpAudioSampleRate: TRadioGroup;
grpAudioVolume: TGroupBox;
chkAudioVolume: TCheckBox;
edtAudioVolume: TEdit;
grpFrameSize: TGroupBox;
cboFrameSize: TComboBox;
grpFrameRate: TRadioGroup;
grpAspectRatio: TRadioGroup;
grpBitRate: TGroupBox;
chkVideoBitRate: TCheckBox;
edtVideoBitRate: TEdit;
chkAudioBitRate: TCheckBox;
edtAudioBitRate: TEdit;
grpAudioCodec: TRadioGroup;
grpVideoCodec: TRadioGroup;
grpPadCrop: TGroupBox;
lblTop: TLabel;
lblBottom: TLabel;
lblLeft: TLabel;
lblRight: TLabel;
chkCrop: TCheckBox;
edtCropTop: TEdit;
edtCropBottom: TEdit;
edtCropLeft: TEdit;
edtCropRight: TEdit;
chkPad: TCheckBox;
edtPadTop: TEdit;
edtPadBottom: TEdit;
edtPadLeft: TEdit;
edtPadRight: TEdit;
grpCutClip: TGroupBox;
lblPTS: TLabel;
Image1: TImage;
TrackBar1: TTrackBar;
btnStartTime: TButton;
edtStartTime: TEdit;
btnEndTime: TButton;
edtEndTime: TEdit;
btnNextFrame: TButton;
chkCutClip: TCheckBox;
grpVideoHook: TGroupBox;
rdoExternalHook: TRadioButton;
rdoCustomHook: TRadioButton;
pnlHook: TPanel;
chkImlib2Img: TCheckBox;
chkImgDancing: TCheckBox;
chkImlib2Txt: TCheckBox;
edtImlib2Txt: TEdit;
chkTxtScrolling: TCheckBox;
chkWaterMark: TCheckBox;
chkWaterMarkMode: TCheckBox;
chkDelphiHookImg: TCheckBox;
chkDelphiHookTxt: TCheckBox;
edtDelphiHookTxt: TEdit;
grpVideoFilter: TGroupBox;
chkVertFlip: TCheckBox;
chkHoriFlip: TCheckBox;
chkNegate: TCheckBox;
chkScale: TCheckBox;
edtScale: TEdit;
chkRotate: TCheckBox;
edtRotate: TEdit;
chkSetPTS: TCheckBox;
edtSetPTS: TEdit;
chkCopyTimestamp: TCheckBox;
chkOverwrite: TCheckBox;
edtOutPath: TEdit;
btnOutPath: TButton;
btnOk: TButton;
btnCancel: TButton;
procedure FormCreate(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormDestroy(Sender: TObject);
procedure chkAudioVolumeClick(Sender: TObject);
procedure chkVideoBitRateClick(Sender: TObject);
procedure chkAudioBitRateClick(Sender: TObject);
procedure Image1Click(Sender: TObject);
procedure TrackBar1Change(Sender: TObject);
procedure btnStartTimeClick(Sender: TObject);
procedure btnEndTimeClick(Sender: TObject);
procedure btnNextFrameClick(Sender: TObject);
procedure DoUpdateHook(Sender: TObject);
procedure btnOutPathClick(Sender: TObject);
procedure chkRotateClick(Sender: TObject);
procedure chkScaleClick(Sender: TObject);
procedure chkSetPTSClick(Sender: TObject);
procedure chkCropClick(Sender: TObject);
procedure chkPadClick(Sender: TObject);
private
FAVProbe: TAVProbe;
FBitmap: TBitmap;
FPosition: Double;
FDuration: Int64;
FFrames: Integer;
FChanging: Boolean;
FCurrentPTS: Int64;
FLastPosition: Integer;
FFirstPTS: Int64;
FStartTime: Int64;
FEndTime: Int64;
FVideoStreamIndex: Integer;
FAudioStreamIndex: Integer;
procedure UpdateHook;
procedure DoActualFormClick(Sender: TObject);
procedure ClearFrameView;
procedure SetupTrackBar;
procedure UpdatePosition(APTS: Int64);
procedure ReadAndDrawFrame(APTS: Int64);
function GetClipStartTime: Int64;
function GetClipTimeLength: Int64;
function GetInputOptions: TInputOptions;
function GetOutputOptions: TOutputOptions;
procedure SetAVProbe(const Value: TAVProbe);
public
property AVProbe: TAVProbe read FAVProbe write SetAVProbe;
property InputOptions: TInputOptions read GetInputOptions;
property OutputOptions: TOutputOptions read GetOutputOptions;
end;
implementation
uses
ShlObj,
ActiveX;
const
SHookText = 'FFVCL';
CHookPath = 'vhook\';
CImlib2DLL = 'imlib2.dll';
CImlib2Img = 'imlib2.jpg';
CImlib2DepDLL = 'libImlib2-1.dll';
CFreeTypeDLL = 'libfreetype-6.dll';
CWaterMarkDLL = 'watermark.dll';
CWaterMarkImg = 'watermark.gif';
CDelphiHookDLL= 'DelphiHook.dll';
CDelphiHookImg = 'DelphiHook.bmp';
SSameAsInput = '<same as input>';
SViewActual = 'Click to view current picture in actual size';
function DurationToStr(ADuration: Int64): string;
begin
Result := Format('%.2d:%.2d:%.2d.%.3d',
[ADuration div AV_TIME_BASE div 60 div 60,
ADuration div AV_TIME_BASE div 60 mod 60,
ADuration div AV_TIME_BASE mod 60,
ADuration mod AV_TIME_BASE * 1000 div AV_TIME_BASE]);
end;
function FitRect(ASrcRect, ADestRect: TRect): TRect;
var
LWFactor: Double;
LHFactor: Double;
LSpace: Integer;
begin
LWFactor := (ASrcRect.Right - ASrcRect.Left) / (ADestRect.Right - ADestRect.Left);
LHFactor := (ASrcRect.Bottom - ASrcRect.Top) / (ADestRect.Bottom - ADestRect.Top);
if LWFactor < LHFactor then
begin
Result.Top := ADestRect.Top;
Result.Bottom := ADestRect.Bottom;
LSpace := Round(((ADestRect.Right - ADestRect.Left) - (ASrcRect.Right - ASrcRect.Left) / LHFactor) / 2);
Result.Left := ADestRect.Left + LSpace;
Result.Right := ADestRect.Right - LSpace;
end
else
begin
Result.Left := ADestRect.Left;
Result.Right := ADestRect.Right;
LSpace := Round(((ADestRect.Bottom - ADestRect.Top) - (ASrcRect.Bottom - ASrcRect.Top) / LWFactor) / 2);
Result.Top := ADestRect.Top + LSpace;
Result.Bottom := ADestRect.Bottom - LSpace;
end;
end;
procedure FitDraw(ACanvas: TCanvas; ABitmap: TBitmap);
var
R: TRect;
begin
if ABitmap.Width * ABitmap.Height = 0 then Exit;
R := ACanvas.ClipRect;
InflateRect(R, -1, -1);
R := FitRect(ABitmap.Canvas.ClipRect, R);
ACanvas.StretchDraw(R, ABitmap);
ACanvas.Brush.Color := clGreen;
InflateRect(R, 1, 1);
ACanvas.FrameRect(R);
end;
function SelectDirCBEx(Wnd: HWND; uMsg: UINT; lParam, lpData: LPARAM): Integer stdcall;
var
LRect: TRect;
cx, cy, w, h, x, y: Integer;
begin
if (uMsg = BFFM_INITIALIZED) then
begin
if (lpData <> 0) then
SendMessage(Wnd, BFFM_SETSELECTION, Integer(True), lpData);
cx := GetSystemMetrics(SM_CXSCREEN);
cy := GetSystemMetrics(SM_CYSCREEN);
GetWindowRect(Wnd, LRect);
w := LRect.Right - LRect.Left;
h := LRect.Bottom - LRect.Top;
x := (cx - w) div 2;
y := (cy - h) div 2;
SetWindowPos(Wnd, 0, x, y, 0, 0, SWP_NOSIZE or SWP_NOZORDER);
end;
Result := 0;
end;
function SelectDirectoryEx(const Caption: string; const Root: WideString; var Directory: string): Boolean;
const
BIF_NEWDIALOGSTYLE = $0040;
BIF_USENEWUI = BIF_NEWDIALOGSTYLE or BIF_EDITBOX;
var
WindowList: Pointer;
BrowseInfo: TBrowseInfo;
Buffer: PChar;
OldErrorMode: Cardinal;
RootItemIDList, ItemIDList: PItemIDList;
ShellMalloc: IMalloc;
IDesktopFolder: IShellFolder;
Eaten, Flags: LongWord;
begin
Result := False;
if not DirectoryExists(Directory) then
Directory := '';
Directory := ExpandFileName(Directory);
FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then
begin
Buffer := ShellMalloc.Alloc(MAX_PATH);
try
RootItemIDList := nil;
if Root <> '' then
begin
SHGetDesktopFolder(IDesktopFolder);
IDesktopFolder.ParseDisplayName(Application.Handle, nil,
POleStr(Root), Eaten, RootItemIDList, Flags);
end;
with BrowseInfo do
begin
hwndOwner := Application.Handle;
pidlRoot := RootItemIDList;
pszDisplayName := Buffer;
lpszTitle := PChar(Caption);
ulFlags := BIF_RETURNONLYFSDIRS or BIF_DONTGOBELOWDOMAIN or BIF_USENEWUI;
lpfn := SelectDirCBEx;
if Directory <> '' then
lParam := Integer(PChar(Directory));
end;
WindowList := DisableTaskWindows(0);
OldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
try
ItemIDList := ShBrowseForFolder(BrowseInfo);
finally
SetErrorMode(OldErrorMode);
EnableTaskWindows(WindowList);
end;
Result := ItemIDList <> nil;
if Result then
begin
ShGetPathFromIDList(ItemIDList, Buffer);
ShellMalloc.Free(ItemIDList);
if Buffer <> '' then
Directory := IncludeTrailingPathDelimiter(Buffer)
else
Result := False;
end;
finally
ShellMalloc.Free(Buffer);
end;
end;
end;
procedure TfrmOption.FormCreate(Sender: TObject);
begin
Image1.Hint := SViewActual;
Image1.ShowHint := True;
edtImlib2Txt.Text := SHookText;
edtDelphiHookTxt.Text := SHookText;
edtOutPath.Text := SSameAsInput;
FBitmap := TBitmap.Create;
end;
procedure TfrmOption.FormShow(Sender: TObject);
begin
UpdateHook;
if grpFormats.CanFocus and (grpFormats.ItemIndex >= 0) then
grpFormats.SetFocus;
grpFormats.Buttons[grpFormats.ItemIndex].SetFocus;
end;
procedure TfrmOption.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
LDriveType: UINT;
begin
if Self.ModalResult = mrOk then
begin
if edtOutPath.Text = SSameAsInput then
LDriveType := GetDriveType(PChar(ExtractFileDrive(FAVProbe.FileName)))
else
LDriveType := GetDriveType(PChar(ExtractFileDrive(edtOutPath.Text)));
if LDriveType = DRIVE_CDROM then
begin
Application.MessageBox('Input folder is located in CD-ROM, please select output folder.',
PChar(Application.Title), MB_ICONINFORMATION);
btnOutPath.SetFocus;
CanClose := False;
end;
end;
end;
procedure TfrmOption.FormDestroy(Sender: TObject);
begin
FBitmap.Free;
end;
procedure TfrmOption.ClearFrameView;
begin
FPosition := 0;
FDuration := 0;
FFrames := 0;
FCurrentPTS := 0;
FFirstPTS := High(Int64);
FStartTime := High(Int64);
FEndTime := AV_NOPTS_VALUE;
FBitmap.Width := 0;
FBitmap.Height := 0;
Image1.Canvas.Brush.Color := clSkyBlue;
Image1.Canvas.FillRect(Image1.Canvas.ClipRect);
TrackBar1.Enabled := False;
TrackBar1.Position := 0;
SetupTrackBar;
TrackBar1.SelStart := 0;
TrackBar1.SelEnd := 0;
chkCutClip.Enabled := False;
chkCutClip.Checked := False;
edtStartTime.Text := 'N/A';
edtEndTime.Text := 'N/A';
lblPTS.Caption := DurationToStr(0);
end;
procedure TfrmOption.SetupTrackBar;
var
LEnabled: Boolean;
begin
LEnabled := TrackBar1.Enabled;
TrackBar1.Enabled := False;
if FFrames > 0 then
TrackBar1.Max := FFrames;
if TrackBar1.Max > 10 then
TrackBar1.Frequency := TrackBar1.Max div 10
else
TrackBar1.Frequency := 1;
if TrackBar1.Max < 10 then
TrackBar1.PageSize := 2
else if TrackBar1.Max < 100 then
TrackBar1.PageSize := 5
else
TrackBar1.PageSize := TrackBar1.Max div 20;
TrackBar1.Position := Round(TrackBar1.Max * FPosition);
FLastPosition := TrackBar1.Position;
TrackBar1.Enabled := LEnabled;
TrackBar1.SliderVisible := LEnabled;
end;
procedure TfrmOption.UpdatePosition(APTS: Int64);
var
LPosition: Integer;
begin
FCurrentPTS := APTS;
lblPTS.Caption := DurationToStr(FCurrentPTS);
if not FChanging and (FDuration <> 0) then
begin
FChanging := True;
try
LPosition := Round(TrackBar1.Max * FCurrentPTS / FDuration);
if LPosition > TrackBar1.Max then
LPosition := TrackBar1.Max;
TrackBar1.Position := LPosition;
finally
FChanging := False;
end;
end;
end;
procedure TfrmOption.ReadAndDrawFrame(APTS: Int64);
begin
while True do
begin
if FAVProbe.Decode then
begin
if FFirstPTS = High(Int64) then
FFirstPTS := FAVProbe.FrameInfo.PTS;
if (FAVProbe.FrameInfo.PTS >= APTS) or (APTS <= 0) then
begin
UpdatePosition(FAVProbe.FrameInfo.PTS);
if FAVProbe.CopyToBitmap(FBitmap) then
FitDraw(Image1.Canvas, FBitmap)
else
;
Break;
end;
end
else
begin
Break;
end;
end;
end;
procedure TfrmOption.UpdateHook;
var
LVideoHookPath: string;
begin
LVideoHookPath := ExtractFilePath(Application.ExeName) + CHookPath;
chkImlib2Img.Enabled := rdoExternalHook.Checked and
FileExists(LVideoHookPath + CImlib2DLL) and
FileExists(LVideoHookPath + CImlib2DepDLL) and
FileExists(LVideoHookPath + CFreeTypeDLL);
chkImlib2Txt.Enabled := chkImlib2Img.Enabled;
chkWaterMark.Enabled := rdoExternalHook.Checked and FileExists(LVideoHookPath + CWaterMarkDLL);
chkDelphiHookImg.Enabled := rdoExternalHook.Checked and FileExists(LVideoHookPath + CDelphiHookDLL);
chkDelphiHookTxt.Enabled := chkDelphiHookImg.Enabled;
chkImgDancing.Enabled := chkImlib2Img.Enabled and chkImlib2Img.Checked;
edtImlib2Txt.Enabled := chkImlib2Txt.Enabled and chkImlib2Txt.Checked;
chkTxtScrolling.Enabled := chkImlib2Txt.Enabled and chkImlib2Txt.Checked;
chkWaterMarkMode.Enabled := chkWatermark.Enabled and chkWatermark.Checked;
edtDelphiHookTxt.Enabled := chkDelphiHookTxt.Enabled and chkDelphiHookTxt.Checked;
end;
procedure TfrmOption.chkAudioVolumeClick(Sender: TObject);
begin
edtAudioVolume.Enabled := chkAudioVolume.Checked;
end;
procedure TfrmOption.chkCropClick(Sender: TObject);
begin
edtCropLeft.Enabled := chkCrop.Checked;
edtCropRight.Enabled := chkCrop.Checked;
edtCropTop.Enabled := chkCrop.Checked;
edtCropBottom.Enabled := chkCrop.Checked;
end;
procedure TfrmOption.chkPadClick(Sender: TObject);
begin
edtPadLeft.Enabled := chkPad.Checked;
edtPadRight.Enabled := chkPad.Checked;
edtPadTop.Enabled := chkPad.Checked;
edtPadBottom.Enabled := chkPad.Checked;
end;
procedure TfrmOption.chkRotateClick(Sender: TObject);
begin
edtRotate.Enabled := chkRotate.Checked;
end;
procedure TfrmOption.chkScaleClick(Sender: TObject);
begin
edtScale.Enabled := chkScale.Checked;
end;
procedure TfrmOption.chkSetPTSClick(Sender: TObject);
begin
edtSetPTS.Enabled := chkSetPTS.Checked;
end;
procedure TfrmOption.chkAudioBitRateClick(Sender: TObject);
begin
edtAudioBitRate.Enabled := chkAudioBitRate.Checked;
end;
procedure TfrmOption.chkVideoBitRateClick(Sender: TObject);
begin
edtVideoBitRate.Enabled := chkVideoBitRate.Checked;
end;
procedure TfrmOption.DoUpdateHook(Sender: TObject);
begin
UpdateHook;
end;
procedure TfrmOption.btnOutPathClick(Sender: TObject);
var
LPath: string;
begin
if edtOutPath.Text = SSameAsInput then
LPath := ExtractFilePath(FAVProbe.FileName)
else
LPath := edtOutPath.Text;
if SelectDirectoryEx('Select Output Folder', '', LPath) then
if GetDriveType(PChar(ExtractFileDrive(LPath))) = DRIVE_CDROM then
Application.MessageBox('Output folder cannot be located in CD-ROM.',
PChar(Application.Title), MB_ICONINFORMATION)
else
edtOutPath.Text := LPath;
end;
procedure TfrmOption.DoActualFormClick(Sender: TObject);
begin
if Assigned(Sender) and (Sender is TControl) and ((Sender as TControl).Parent is TForm) then
((Sender as TControl).Parent as TForm).Close;
end;
procedure TfrmOption.Image1Click(Sender: TObject);
var
F: TForm;
I: TImage;
B: TButton;
begin
if FBitmap.Width * FBitmap.Height = 0 then Exit;
F := TForm.Create(Self);
try
F.BorderIcons := [biSystemMenu];
B := TButton.Create(F);
B.Parent := F;
B.Default := True;
B.Cancel := True;
B.ModalResult := mrCancel;
B.Top := 0;
B.Left := 0;
B.Width := 0;
B.Height := 0;
B.Visible := True;
I := TImage.Create(F);
I.Parent := F;
I.OnClick := Self.DoActualFormClick;
I.Visible := True;
I.Left := 0;
I.Top := 0;
I.Width := FBitmap.Width;
I.Height := FBitmap.Height;
I.Picture.Assign(FBitmap);
F.Position := poScreenCenter;
F.BorderStyle := bsSingle;
F.Caption := Format('%dx%d @ %s', [FBitmap.Width, FBitmap.Height,
DurationToStr(FCurrentPTS)]);;
F.ClientWidth := I.Width;
F.ClientHeight := I.Height;
F.ShowModal;
finally
F.Free;
end;
end;
procedure TfrmOption.TrackBar1Change(Sender: TObject);
begin
if FLastPosition = TrackBar1.Position then
Exit;
if not FChanging and TrackBar1.Enabled and (FAVProbe.VideoStreamCount > 0) then
begin
if TrackBar1.Max > 0 then
FPosition := TrackBar1.Position / TrackBar1.Max
else
FPosition := 0;
FChanging := True;
try
if TrackBar1.Position = FLastPosition + 1 then
begin
ReadAndDrawFrame(-1);
end
else if TrackBar1.Position = FLastPosition - 1 then
begin
if FAVProbe.Seek(Round(FPosition * FDuration), [sfBackward]) or
FAVProbe.Seek(Round(FPosition * FDuration), [sfBackward, sfAny]) or
FAVProbe.Seek(Round(FPosition * FDuration)) or
FAVProbe.Seek(Round(FPosition * FDuration), [sfAny]) then
begin
ReadAndDrawFrame(Round(FPosition * FDuration));
end
else
;
end
else if FAVProbe.Seek(Round(FPosition * FDuration)) or
FAVProbe.Seek(Round(FPosition * FDuration), [sfBackward]) or
FAVProbe.Seek(Round(FPosition * FDuration), [sfAny]) then
begin
ReadAndDrawFrame(Round(FPosition * FDuration));
end
else
;
finally
FLastPosition := TrackBar1.Position;
FChanging := False;
end;
end;
end;
procedure TfrmOption.btnStartTimeClick(Sender: TObject);
begin
TrackBar1.SelStart := TrackBar1.Position;
edtStartTime.Text := DurationToStr(FCurrentPTS);
FStartTime := FCurrentPTS;
chkCutClip.Enabled := FEndTime > FStartTime;
end;
procedure TfrmOption.btnEndTimeClick(Sender: TObject);
begin
TrackBar1.SelEnd := TrackBar1.Position;
edtEndTime.Text := DurationToStr(FCurrentPTS);
FEndTime := FCurrentPTS;
chkCutClip.Enabled := FEndTime > FStartTime;
end;
procedure TfrmOption.btnNextFrameClick(Sender: TObject);
begin
ReadAndDrawFrame(-1);
end;
procedure TfrmOption.SetAVProbe(const Value: TAVProbe);
begin
ClearFrameView;
FAVProbe := Value;
mmoAVFileInfo.Text := FAVProbe.FileInfoText;
FVideoStreamIndex := FAVProbe.FirstVideoStreamIndex;
FAudioStreamIndex := FAVProbe.FirstAudioStreamIndex;
with FAVProbe do
begin
TrackBar1.Enabled := (FileStreamInfo.Duration <> AV_NOPTS_VALUE) and (FormatName <> 'image2');
if FileStreamInfo.Duration <> AV_NOPTS_VALUE then
FDuration := FileStreamInfo.Duration;
if (VideoStreamCount > 0) and (FirstVideoStreamInfo.FrameRate.den > 0) then
begin
if FirstVideoStreamInfo.DurationScaled > 0 then
FFrames := Round(FirstVideoStreamInfo.DurationScaled / AV_TIME_BASE *
FirstVideoStreamInfo.FrameRate.num / FirstVideoStreamInfo.FrameRate.den)
else if FileStreamInfo.Duration <> AV_NOPTS_VALUE then
FFrames := Round(FileStreamInfo.Duration / AV_TIME_BASE *
FirstVideoStreamInfo.FrameRate.num / FirstVideoStreamInfo.FrameRate.den);
end
else if FileStreamInfo.Duration <> AV_NOPTS_VALUE then
FFrames := Round(FileStreamInfo.Duration / AV_TIME_BASE * 10);
end;
if FAVProbe.VideoStreamCount > 0 then
ReadAndDrawFrame(0);
SetupTrackBar;
end;
function TfrmOption.GetClipStartTime: Int64;
begin
if (FFirstPTS <> High(Int64)) and (FFirstPTS < 0) then
Result := FStartTime - FFirstPTS
else
Result := FStartTime;
end;
function TfrmOption.GetClipTimeLength: Int64;
begin
Result := FEndTime - FStartTime;
end;
function TfrmOption.GetInputOptions: TInputOptions;
var
IO: TInputOptions;
begin
InitInputOptions(@IO);
IO.FileName := FAVProbe.FileName;
IO.FileFormat := FAVProbe.ForceFormat;
if chkCutClip.Enabled and chkCutClip.Checked and (FEndTime > FStartTime) then
IO.TimeStart := GetClipStartTime;
if Pos(LowerCase(grpFormats.Items.Strings[grpFormats.ItemIndex]),
'aac ac3 mp2 mp3 wav wma') > 0 then
IO.ExtOptions := 'vn=1';
Result := IO;
end;
function TfrmOption.GetOutputOptions: TOutputOptions;
var
OO: TOutputOptions;
LFileExt: string;
LTemp: string;
LBaseName: string;
LVideoCodec: string;
LAudioCodec: string;
I: Integer;
LHookDLL: string;
LHookImg: string;
LDelimiter: string;
X, Y: string;
LBitmap: TBitmap;
begin
InitOutputOptions(@OO);
LFileExt := '.' + LowerCase(grpFormats.Items.Strings[grpFormats.ItemIndex]);
if grpAudioChannels.ItemIndex > 0 then
OO.AudioChannels := grpAudioChannels.ItemIndex;
if grpAudioSampleRate.ItemIndex > 0 then
OO.AudioSampleRate := StrToIntDef(grpAudioSampleRate.Items.Strings[grpAudioSampleRate.ItemIndex], 22050);
if chkAudioVolume.Checked then
OO.AudioVolume := StrToIntDef(edtAudioVolume.Text, -1);
if cboFrameSize.ItemIndex > 0 then
begin
LTemp := cboFrameSize.Items.Strings[cboFrameSize.ItemIndex];
if Pos(' ', LTemp) > 1 then
LTemp := Copy(LTemp, 1, Pos(' ', LTemp) - 1);
OO.FrameSize := LTemp;
end;
if grpFrameRate.ItemIndex > 0 then
OO.FrameRate := grpFrameRate.Items.Strings[grpFrameRate.ItemIndex];
if grpAspectRatio.ItemIndex > 0 then
OO.FrameAspectRatio := grpAspectRatio.Items.Strings[grpAspectRatio.ItemIndex];
if chkVideoBitRate.Checked then
OO.VideoBitrate := 1000 * StrToIntDef(edtVideoBitRate.Text, 200)
else
begin
end;
if chkAudioBitRate.Checked then
OO.AudioBitrate := 1000 * StrToIntDef(edtAudioBitRate.Text, 64)
else
begin
end;
if grpVideoCodec.ItemIndex > 0 then
begin
LVideoCodec := LowerCase(grpVideoCodec.Items.Strings[grpVideoCodec.ItemIndex]);
if LVideoCodec = 'divx' then
begin
OO.VideoCodec := 'mpeg4';
OO.VideoTag := 'DIVX';
end
else if LVideoCodec = 'xvid' then
OO.VideoCodec := 'libxvid'
else if LVideoCodec = 'x264' then
begin
OO.VideoCodec := 'libx264';
OO.VideoPreset := 'libx264-default';
end;
end;
if grpAudioCodec.ItemIndex > 0 then
begin
LAudioCodec := LowerCase(grpAudioCodec.Items.Strings[grpAudioCodec.ItemIndex]);
if LAudioCodec = 'aac' then
OO.AudioCodec := 'libfaac'
else if LAudioCodec = 'ac3' then
OO.AudioCodec := 'ac3'
else if LAudioCodec = 'flac' then
OO.AudioCodec := 'flac'
else if LAudioCodec = 'mp3' then
OO.AudioCodec := 'libmp3lame';
end;
if chkCutClip.Enabled and chkCutClip.Checked and (FEndTime > FStartTime) then
OO.TimeStart := GetClipStartTime;
if chkCutClip.Enabled and chkCutClip.Checked and (FEndTime > FStartTime) then
OO.TimeLength := GetClipTimeLength;
if rdoExternalHook.Checked and chkImlib2Img.Checked and chkImlib2Img.Enabled then
begin
LHookDLL := ExtractFilePath(Application.ExeName) + CHookPath + CImlib2DLL;
LHookImg := ExtractFilePath(Application.ExeName) + CHookPath + CImlib2Img;
if (Pos(' ', LHookDLL) > 0) or (Pos(' ', LHookImg) > 0) then
LDelimiter := '|'
else
LDelimiter := ' ';
if chkImgDancing.Checked then
begin
X := '(W-w)*(0.5+0.5*sin(N/47*PI))';
Y := '(H-h)*(0.5+0.5*cos(N/97*PI))';
end
else
begin
X := 'W-w';
Y := 'H-h';
end;
OO.ExtOptions := OO.ExtOptions +
Format('vhook=%s%s%s%s%s%s%s%s%s%s%s%s%s'#13#10, [
LHookDLL, LDelimiter,
'-i', LDelimiter, LHookImg, LDelimiter,
'-x', LDelimiter, X, LDelimiter,
'-y', LDelimiter, Y]);
end;
if rdoExternalHook.Checked and chkImlib2Txt.Checked and chkImlib2Txt.Enabled then
begin
LHookDLL := ExtractFilePath(Application.ExeName) + CHookPath + CImlib2DLL;
if Pos(' ', LHookDLL) > 0 then
LDelimiter := '|'
else
LDelimiter := ' ';
if chkTxtScrolling.Checked then
begin
X := '10';
Y := '(H-25)*(0.5+0.50*cos(N/97*PI))';
end
else
begin
X := '10';
Y := '10';
end;
edtImlib2Txt.Text := Trim(edtImlib2Txt.Text);
if edtImlib2Txt.Text = '' then
edtImlib2Txt.Text := SHookText;
OO.ExtOptions := OO.ExtOptions +
Format('vhook=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s'#13#10, [
LHookDLL, LDelimiter,
'-R', LDelimiter, '255', LDelimiter,
'-G', LDelimiter, '255', LDelimiter,
'-B', LDelimiter, '255', LDelimiter,
'-F', LDelimiter, 'Tahoma.ttf/16', LDelimiter,
'-t', LDelimiter, edtImlib2Txt.Text, LDelimiter,
'-x', LDelimiter, X, LDelimiter,
'-y', LDelimiter, Y]);
end;
if rdoExternalHook.Checked and chkWaterMark.Checked and chkWaterMark.Enabled then
begin
LHookDLL := ExtractFilePath(Application.ExeName) + CHookPath + CWaterMarkDLL;
LHookImg := ExtractFilePath(Application.ExeName) + CHookPath + CWaterMarkImg;
if (Pos(' ', LHookDLL) > 0) or (Pos(' ', LHookImg) > 0) then
LDelimiter := '|'
else
LDelimiter := ' ';
OO.ExtOptions := OO.ExtOptions +
Format('vhook=%s%s%s%s%s%s%s%s%d'#13#10, [
LHookDLL, LDelimiter,
'-f', LDelimiter, LHookImg, LDelimiter,
'-m', LDelimiter, Ord(chkWaterMarkMode.Checked)]);
end;
if rdoExternalHook.Checked and chkDelphiHookImg.Checked and chkDelphiHookImg.Enabled then
begin
LHookDLL := ExtractFilePath(Application.ExeName) + CHookPath + CDelphiHookDLL;
LHookImg := ExtractFilePath(Application.ExeName) + CHookPath + CDelphiHookImg;
LBitmap := TBitmap.Create;
try
if FileExists(LHookImg) then
LBitmap.LoadFromFile(LHookImg)
else
begin
LBitmap.Width := 64;
LBitmap.Height := 64;
end;
if (Pos(' ', LHookDLL) > 0) or (Pos(' ', LHookImg) > 0) then
LDelimiter := '|'
else
LDelimiter := ' ';
OO.ExtOptions := OO.ExtOptions +
Format('vhook=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s'#13#10, [
LHookDLL, LDelimiter,
'-i', LDelimiter, LHookImg, LDelimiter,
'-mc', LDelimiter, 'FFFFFF', LDelimiter,
'-ix', LDelimiter, IntToStr(FAVProbe.VideoStreamInfos[FVideoStreamIndex].Width - LBitmap.Width - 10), LDelimiter,
'-iy', LDelimiter, IntToStr(FAVProbe.VideoStreamInfos[FVideoStreamIndex].Height - LBitmap.Height - 10)]);
finally
LBitmap.Free;
end;
end;
if rdoExternalHook.Checked and chkDelphiHookTxt.Checked and chkDelphiHookTxt.Enabled then
begin
LHookDLL := ExtractFilePath(Application.ExeName) + CHookPath + CDelphiHookDLL;
if Pos(' ', LHookDLL) > 0 then
LDelimiter := '|'
else
LDelimiter := ' ';
edtDelphiHookTxt.Text := Trim(edtDelphiHookTxt.Text);
if edtDelphiHookTxt.Text = '' then
edtDelphiHookTxt.Text := SHookText;
OO.ExtOptions := OO.ExtOptions +
Format('vhook=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s'#13#10, [
LHookDLL, LDelimiter,
'-t', LDelimiter, edtDelphiHookTxt.Text, LDelimiter,
'-tx', LDelimiter, '10', LDelimiter,
'-ty', LDelimiter, '10', LDelimiter,
'-fc', LDelimiter, 'FFFFFF', LDelimiter,
'-fn', LDelimiter, 'Tahoma', LDelimiter,
'-fs', LDelimiter, '16', LDelimiter,
'-fst', LDelimiter, 'BU']);
end;
OO.CustomHook := rdoCustomHook.Checked;
OO.CopyTimestamp := chkCopyTimestamp.Checked;
if chkVertFlip.Checked then
if OO.VideoFilters <> '' then
OO.VideoFilters := OO.VideoFilters + ',vflip'
else
OO.VideoFilters := 'vflip';
if chkHoriFlip.Checked then
if OO.VideoFilters <> '' then
OO.VideoFilters := OO.VideoFilters + ',hflip'
else
OO.VideoFilters := 'hflip';
if chkNegate.Checked then
if OO.VideoFilters <> '' then
OO.VideoFilters := OO.VideoFilters + ',negate'
else
OO.VideoFilters := 'negate';
if chkScale.Checked then
begin
LTemp := Trim(edtScale.Text);
if LTemp <> '' then
begin
if OO.VideoFilters <> '' then
OO.VideoFilters := OO.VideoFilters + ',scale=' + LTemp
else
OO.VideoFilters := 'scale=' + LTemp;
end;
end;
if chkRotate.Checked then
begin
LTemp := IntToStr(StrToIntDef(Trim(edtRotate.Text), 45));
if OO.VideoFilters <> '' then
OO.VideoFilters := OO.VideoFilters + ',rotate=' + LTemp
else
OO.VideoFilters := 'rotate=' + LTemp;
end;
if chkSetPTS.Checked then
begin
LTemp := Trim(edtSetPTS.Text);
if LTemp <> '' then
begin
if OO.VideoFilters <> '' then
OO.VideoFilters := OO.VideoFilters + ',setpts=' + LTemp
else
OO.VideoFilters := 'setpts=' + LTemp;
end;
end;
if (LFileExt = '.flv') or (LFileExt = '.swf') then
begin
if (OO.AudioSampleRate <> 11025) and (OO.AudioSampleRate <> 22050) and (OO.AudioSampleRate <> 44100) then
OO.AudioSampleRate := 22050;
end
else if LFileExt = '.ogg' then
begin
OO.AudioCodec := 'libvorbis';
OO.VideoCodec := 'libtheora';
end
else if LFileExt = '.psp' then
begin
OO.FileFormat := 'psp';
OO.VideoCodec := 'mpeg4';
OO.AudioCodec := 'libfaac';
OO.AudioSampleRate := 24000;
OO.FrameRate := '15000/1001';
LFileExt := '_psp.mp4';
end
else if LFileExt = '.ipod' then
begin
OO.VideoCodec := 'mpeg4';
OO.AudioCodec := 'libfaac';
OO.FrameSize := '320x240';
LFileExt := '_ipod.mp4';
end
else if LFileExt = '.rm10' then
begin
OO.VideoCodec := 'rv10';
LFileExt := '_rv10.rm';
end
else if LFileExt = '.rm20' then
begin
OO.VideoCodec := 'rv20';
LFileExt := '_rv20.rm';
end
else if LFileExt = '.mp4' then
begin
end
else if LFileExt = '.wmv' then
begin
OO.VideoCodec := 'wmv2';
OO.AudioCodec := 'wmav2';
end
else if LFileExt = '.mkv' then
begin
OO.VideoCodec := 'libx264';
OO.VideoPreset := 'libx264-default';
end
else if LFileExt = '.wma' then
begin
OO.DisableVideo := True;
OO.AudioCodec := 'wmav2';
end
else if LFileExt = '.3gp' then
begin
OO.AudioChannels := 1;
OO.AudioSampleRate := 8000;
,
,
,
,
,
,
,
,
};
*)
OO.AudioBitrate := 7400;
OO.FrameSize := '128x96';
end
else if Pos(LFileExt, '.vcd.svcd.dvd') > 0 then
begin
if LFileExt = '.vcd' then
OO.TargetType := ttVCD
else if LFileExt = '.svcd' then
OO.TargetType := ttSVCD
else
OO.TargetType := ttDVD;
if grpNorm.ItemIndex = 0 then
OO.NormType := ntAuto
else if grpNorm.ItemIndex = 1 then
OO.NormType := ntPAL
else
OO.NormType := ntNTSC;
OO.NormDefault := ntPAL;
end;
OO.Info.TimeStamp := 0;
if chkCrop.Checked then
begin
OO.CropTop := StrToIntDef(edtCropTop.Text, 0) div 2 * 2;
OO.CropBottom := StrToIntDef(edtCropBottom.Text, 0) div 2 * 2;
OO.CropLeft := StrToIntDef(edtCropLeft.Text, 0) div 2 * 2;
OO.CropRight := StrToIntDef(edtCropRight.Text, 0) div 2 * 2;
end;
if chkPad.Checked then
begin
OO.PadTop := StrToIntDef(edtPadTop.Text, 0) div 2 * 2;
OO.PadBottom := StrToIntDef(edtPadBottom.Text, 0) div 2 * 2;
OO.PadLeft := StrToIntDef(edtPadLeft.Text, 0) div 2 * 2;
OO.PadRight := StrToIntDef(edtPadRight.Text, 0) div 2 * 2;
OO.PadColor := clBlack;
end;
if Pos(LFileExt, '.vcd.svcd.dvd') > 0 then
begin
LFileExt := '_' + Copy(LFileExt, 2, MaxInt);
if OO.NormType = ntPAL then
LFileExt := LFileExt + '_pal.mpg'
else if OO.NormType = ntNTSC then
LFileExt := LFileExt + '_ntsc.mpg'
else
LFileExt := LFileExt + '_auto.mpg';
end;
OO.FileExt := LFileExt;
if edtOutPath.Text = SSameAsInput then
LBaseName := ChangeFileExt(FAVProbe.FileName, '')
else
LBaseName := edtOutPath.Text + ChangeFileExt(ExtractFileName(FAVProbe.FileName), '');
OO.FileName := LBaseName + '_(new)' + OO.FileExt;
if FileExists(OO.FileName) and not chkOverwrite.Checked then
begin
I := 1;
while FileExists(LBaseName + '_(new_' + IntToStr(I) + ')' + OO.FileExt) do
Inc(I);
OO.FileName := LBaseName + '_(new_' + IntToStr(I) + ')' + OO.FileExt;
end;
OO.DisableSubtitle := True;
Result := OO;
end;
end.