unit OptionFrm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ComCtrls, FFmpegVCL, AVProbe, libavcodec,
libavformat;
type
TfrmOption = class(TForm)
grpNorm: TRadioGroup;
grpAudioChannels: TRadioGroup;
edtStartTime: TEdit;
edtEndTime: TEdit;
edtAudioVolume: TEdit;
grpFormats: TRadioGroup;
grpAudioSampleRate: TRadioGroup;
grpAspectRatio: TRadioGroup;
grpAudioVolume: TGroupBox;
chkAudioVolume: TCheckBox;
grpCutClip: TGroupBox;
chkCutClip: TCheckBox;
btnOk: TButton;
btnCancel: TButton;
chkOverwrite: TCheckBox;
cboFrameSize: TComboBox;
grpFrameSize: TGroupBox;
grpVideoCodec: TRadioGroup;
grpAudioCodec: TRadioGroup;
chkCopyTimestamp: TCheckBox;
grpBitRate: TGroupBox;
edtVideoBitRate: TEdit;
edtAudioBitRate: TEdit;
grpFrameRate: TRadioGroup;
grpVideoHook: TGroupBox;
chkVideoBitRate: TCheckBox;
chkAudioBitRate: TCheckBox;
rdoExternalHook: TRadioButton;
pnlHook: TPanel;
chkWaterMark: TCheckBox;
chkImlib2Img: TCheckBox;
chkImgDancing: TCheckBox;
chkImlib2Txt: TCheckBox;
chkTxtScrolling: TCheckBox;
chkWaterMarkMode: TCheckBox;
edtPTSs: TEdit;
btnPTSs: TButton;
rdoCustomHook: TRadioButton;
rdoStandardHook: TRadioButton;
rdoBeforeHook: TRadioButton;
rdoPTSs: TRadioButton;
grpAVFileInfo: TGroupBox;
mmoAVFileInfo: TMemo;
edtImlib2Txt: TEdit;
chkDelphiHookImg: TCheckBox;
chkDelphiHookTxt: TCheckBox;
edtDelphiHookTxt: TEdit;
imgPreview: TImage;
trcPreview: TTrackBar;
btnStartTime: TButton;
btnEndTime: TButton;
lblPTS: TLabel;
grpVideoFilter: TGroupBox;
chkVertFlip: TCheckBox;
chkHoriFlip: TCheckBox;
edtOutPath: TEdit;
lblOutPath: TLabel;
btnOutPath: TButton;
chkNegate: TCheckBox;
chkRotate: TCheckBox;
edtRotate: TEdit;
chkScale: TCheckBox;
edtScale: TEdit;
chkSetPTS: TCheckBox;
edtSetPTS: TEdit;
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;
procedure chkAudioVolumeClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure chkVideoBitRateClick(Sender: TObject);
procedure chkAudioBitRateClick(Sender: TObject);
procedure btnPTSsClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure trcPreviewChange(Sender: TObject);
procedure btnStartTimeClick(Sender: TObject);
procedure btnEndTimeClick(Sender: TObject);
procedure DoUpdateHook(Sender: TObject);
procedure imgPreviewClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure btnOutPathClick(Sender: TObject);
procedure chkRotateClick(Sender: TObject);
procedure chkScaleClick(Sender: TObject);
procedure chkSetPTSClick(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure chkCropClick(Sender: TObject);
procedure chkPadClick(Sender: TObject);
private
FAVProbe: TAVProbe;
FTraceBarUpdating: Boolean;
FBitmap: TBitmap;
FPosFactor: Int64;
FVideoStreamIndex: Integer;
FAudioStreamIndex: Integer;
procedure DoActualFormClick(Sender: TObject);
procedure UpdateHook;
procedure DrawFramePicture;
function GetClipStartTime: Integer;
function GetClipTimeLength: Integer;
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';
SHelpPTSCaption = 'Video Hook PTS Periods';
SHelpPTSText =
'Enable Video Hook only in special periods, empty means whole duration enabled.'#13#10 +
'format: [<pts1>-<pts2>[,pts3-pts4[,...]]]'#13#10 +
'example: to process video hook only in pts periods 0-5,10-15 (seconds)'#13#10 +
' PTS Periosd(millisecond!!!) -> "0-5000,10000-15000"';
function FormatSeconds(const AMicroSeconds: Int64): string;
begin
Result := Format('%d.%.3d', [AMicroSeconds div 1000000, AMicroSeconds div 1000 mod 1000]);
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);
AImage.Canvas.Brush.Color := clGreen;
InflateRect(R, 1, 1);
AImage.Canvas.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
imgPreview.Hint := SViewActual;
imgPreview.ShowHint := True;
edtImlib2Txt.Text := SHookText;
edtDelphiHookTxt.Text := SHookText;
edtOutPath.Text := SSameAsInput;
FBitmap := TBitmap.Create;
end;
procedure TfrmOption.FormDestroy(Sender: TObject);
begin
FBitmap.Free;
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.FormHide(Sender: TObject);
begin
FTraceBarUpdating := True;
try
trcPreview.Max := 0;
finally
FTraceBarUpdating := False;
end;
end;
procedure TfrmOption.DrawFramePicture;
begin
if not FTraceBarUpdating and (FAVProbe.VideoStreamCount > 0) then
begin
if trcPreview.Position = trcPreview.Max then
FAVProbe.SeekFrame(FAVProbe.FileStreamInfo.Duration, FVideoStreamIndex)
else
FAVProbe.SeekFrame(trcPreview.Position * FPosFactor, FVideoStreamIndex);
FitDraw(imgPreview.Canvas, FAVProbe.ReadFramePicture(FVideoStreamIndex));
FBitmap.Assign(FAVProbe.FramePicture);
end;
if not FTraceBarUpdating then
lblPTS.Caption := 'PTS: ' + FormatSeconds(trcPreview.Position * FPosFactor);
end;
procedure TfrmOption.SetAVProbe(const Value: TAVProbe);
procedure SetupTraceBar;
var
LPosMax: Int64;
LLineSize: Integer;
begin
trcPreview.SliderVisible := (FAVProbe.FormatName <> 'image2'); ;
FTraceBarUpdating := True;
try
trcPreview.SelStart := 0;
trcPreview.SelEnd := 0;
chkCutClip.Enabled := False;
chkCutClip.Checked := False;
edtStartTime.Text := 'N/A';
edtEndTime.Text := 'N/A';
if trcPreview.SliderVisible then
begin
FPosFactor := 1;
repeat
FPosFactor := FPosFactor * 10;
LPosMax := FAVProbe.FileStreamInfo.Duration div FPosFactor;
until LPosMax < $8000;
trcPreview.Frequency := LPosMax div ((trcPreview.Width - 12) div 10);
trcPreview.Min := 0;
trcPreview.Max := LPosMax;
if LPosMax > 10000 then
LLineSize := 1000
else if LPosMax > 1000 then
LLineSize := 100
else if LPosMax > 100 then
LLineSize := 10
else
LLineSize := 1;
trcPreview.LineSize := LLineSize;
trcPreview.PageSize := LLineSize * 5;
trcPreview.Position := 0;
trcPreview.TickStyle := tsAuto;
end
else
begin
trcPreview.Min := 0;
trcPreview.Max := 0;
end;
finally
FTraceBarUpdating := False;
end;
end;
begin
FBitmap.Width := 0;
FBitmap.Height := 0;
imgPreview.Canvas.Brush.Color := clSkyBlue;
imgPreview.Canvas.FillRect(imgPreview.Canvas.ClipRect);
FAVProbe := Value;
FVideoStreamIndex := FAVProbe.FirstVideoStreamIndex;
FAudioStreamIndex := FAVProbe.FirstAudioStreamIndex;
SetupTraceBar;
DrawFramePicture;
mmoAVFileInfo.Text := FAVProbe.FileInfoText;
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;
rdoStandardHook.Enabled := (chkImlib2Img.Enabled and chkImlib2Img.Checked) or
(chkImlib2Txt.Enabled and chkImlib2Txt.Checked) or
(chkWaterMark.Enabled and chkWaterMark.Checked) or
(chkDelphiHookImg.Enabled and chkDelphiHookImg.Checked) or
(chkDelphiHookTxt.Enabled and chkDelphiHookTxt.Checked);
rdoBeforeHook.Enabled := rdoStandardHook.Enabled;
rdoPTSs.Enabled := rdoStandardHook.Enabled;
edtPTSs.Enabled := rdoPTSs.Enabled and rdoPTSs.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.btnPTSsClick(Sender: TObject);
begin
Application.MessageBox(SHelpPTSText, SHelpPTSCaption, MB_ICONINFORMATION);
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.imgPreviewClick(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 PTS: %s', [FBitmap.Width, FBitmap.Height,
FormatSeconds(trcPreview.Position * FPosFactor)]);;
F.ClientWidth := I.Width;
F.ClientHeight := I.Height;
F.ShowModal;
finally
F.Free;
end;
end;
procedure TfrmOption.trcPreviewChange(Sender: TObject);
begin
DrawFramePicture;
end;
procedure TfrmOption.btnStartTimeClick(Sender: TObject);
begin
trcPreview.SelStart := trcPreview.Position;
edtStartTime.Text := FormatSeconds(trcPreview.Position * FPosFactor);
chkCutClip.Enabled := (trcPreview.SelEnd > 0) and (trcPreview.SelEnd > trcPreview.SelStart);
end;
procedure TfrmOption.btnEndTimeClick(Sender: TObject);
begin
trcPreview.SelEnd := trcPreview.Position;
edtEndTime.Text := FormatSeconds(trcPreview.Position * FPosFactor);
chkCutClip.Enabled := (trcPreview.SelEnd > 0) and (trcPreview.SelEnd > trcPreview.SelStart);
end;
procedure CheckClipTime(const ATotalDuration: Integer; var AStartTime, AEndTime: Integer);
begin
if (AStartTime < 0) or (AStartTime >= ATotalDuration) then
AStartTime := 0;
if (AEndTime <= AStartTime) or (AEndTime > ATotalDuration) then
AEndTime := ATotalDuration;
end;
function TfrmOption.GetClipStartTime: Integer;
var
LStartTime: Integer;
LEndTime: Integer;
begin
LStartTime := trcPreview.SelStart * FPosFactor div 1000;
LEndTime := trcPreview.SelEnd * FPosFactor div 1000;
CheckClipTime(FAVProbe.FileStreamInfo.Duration div 1000, LStartTime, LEndTime);
Result := LStartTime;
end;
function TfrmOption.GetClipTimeLength: Integer;
var
LStartTime: Integer;
LEndTime: Integer;
begin
LStartTime := trcPreview.SelStart * FPosFactor div 1000;
LEndTime := trcPreview.SelEnd * FPosFactor div 1000;
CheckClipTime(FAVProbe.FileStreamInfo.Duration div 1000, LStartTime, LEndTime);
Result := LEndTime - LStartTime;
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
(trcPreview.SelEnd > 0) and (trcPreview.SelEnd > trcPreview.SelStart) 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
OO.VideoCodec := 'libx264';
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
(trcPreview.SelEnd > 0) and (trcPreview.SelEnd > trcPreview.SelStart) 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.BeforeHook := rdoExternalHook.Checked and
rdoBeforeHook.Checked and rdoBeforeHook.Enabled and
(chkImlib2Img.Checked or chkImlib2Txt.Checked or chkWaterMark.Checked or
chkDelphiHookImg.Checked or chkDelphiHookTxt.Checked);
if rdoExternalHook.Checked and rdoPTSs.Checked and rdoPTSs.Enabled and
(chkImlib2Img.Checked or chkImlib2Txt.Checked or chkWaterMark.Checked or
chkDelphiHookImg.Checked or chkDelphiHookTxt.Checked) then
begin
OO.VideoHookPTSs := edtPTSs.Text;
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.VideoCodec := 'libtheora';
OO.AudioCodec := 'flac';
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';
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.