├── Forms ├── DownloadItemFrame.dfm ├── DownloadItemFrame.pas ├── FileListItemFrame.dfm ├── FileListItemFrame.pas ├── UnitAbout.dfm ├── UnitAbout.pas ├── UnitAdd.dfm ├── UnitAdd.pas ├── UnitAdvancedOptions.dfm ├── UnitAdvancedOptions.pas ├── UnitBatchAdd.dfm ├── UnitBatchAdd.pas ├── UnitDub.dfm ├── UnitDub.pas ├── UnitEffects.dfm ├── UnitEffects.pas ├── UnitImageAudioMerger.dfm ├── UnitImageAudioMerger.pas ├── UnitLogs.dfm ├── UnitLogs.pas ├── UnitMain.dfm ├── UnitMain.pas ├── UnitPreview.dfm ├── UnitPreview.pas ├── UnitProfileEditor.dfm ├── UnitProfileEditor.pas ├── UnitProperties.dfm ├── UnitProperties.pas ├── UnitRangeEditor.dfm ├── UnitRangeEditor.pas ├── UnitSettings.dfm ├── UnitSettings.pas ├── UnitVideotoGIF.dfm ├── UnitVideotoGIF.pas ├── UnitWatermark.dfm ├── UnitWatermark.pas ├── UnitYoutubedlUpdateChecker.dfm ├── UnitYoutubedlUpdateChecker.pas ├── VideoAdding.dfm └── VideoAdding.pas ├── Readme.md ├── Release └── Win64 │ └── ChangeLog.txt ├── TEncoder.dpr ├── TEncoderGroup.groupproj ├── TEncoder_Icon.ico ├── Units ├── DownloaderUnits │ ├── UnitCommonTypes.pas │ ├── UnitDownloadExtensionExtractor.pas │ ├── UnitFileNameExtractor.pas │ ├── UnitImageResize.pas │ ├── UnitImageTypeExtractor.pas │ ├── UnitYouTubeDlVersionReader.pas │ ├── UnitYouTubeVideoInfoExtractor.pas │ └── UnitYouTubeVideoInfoExtractorEx.pas ├── MediaInfoDLL.pas ├── UnitCommonMethods.pas ├── UnitDVDJob.pas ├── UnitDVDReader.pas ├── UnitDVDRipperProcess.pas ├── UnitDownloadProcess.pas ├── UnitEncoder.pas ├── UnitFFmpegCommandLineCreator.pas ├── UnitFFmpegMergeCMDCreator.pas ├── UnitFileInfo.pas ├── UnitFileInfoExtractor.pas ├── UnitFileInfoItem.pas ├── UnitFileItem.pas ├── UnitMencoderCommandLineCreator.pas ├── UnitPlayer.pas ├── UnitSubtitleTypes.pas └── windows7taskbar.pas ├── dvdrenametool.dpr ├── renametool.dpr └── version.txt /Forms/DownloadItemFrame.dfm: -------------------------------------------------------------------------------- 1 | object DownloadUIItem: TDownloadUIItem 2 | Left = 0 3 | Top = 0 4 | Width = 1116 5 | Height = 141 6 | Anchors = [akLeft, akTop, akRight] 7 | TabOrder = 0 8 | object sBevel1: TBevel 9 | Left = 0 10 | Top = 138 11 | Width = 1116 12 | Height = 3 13 | Align = alBottom 14 | Shape = bsBottomLine 15 | ExplicitTop = 91 16 | end 17 | object sPanel1: TPanel 18 | Left = 227 19 | Top = 0 20 | Width = 889 21 | Height = 138 22 | Align = alClient 23 | BevelOuter = bvNone 24 | TabOrder = 0 25 | DesignSize = ( 26 | 889 27 | 138) 28 | object ProgressLabel: TLabel 29 | Left = 55 30 | Top = 93 31 | Width = 67 32 | Height = 13 33 | Anchors = [akLeft, akBottom] 34 | Caption = 'ProgressLabel' 35 | ExplicitTop = 95 36 | end 37 | object ProgressBar: TGauge 38 | Left = 6 39 | Top = 110 40 | Width = 791 41 | Height = 19 42 | Anchors = [akLeft, akRight, akBottom] 43 | Progress = 0 44 | ExplicitTop = 109 45 | ExplicitWidth = 564 46 | end 47 | object FileNameLabel: TLabel 48 | Left = 6 49 | Top = 22 50 | Width = 68 51 | Height = 13 52 | Caption = 'FileNameLabel' 53 | end 54 | object LinkLabel: TLabel 55 | Left = 6 56 | Top = 3 57 | Width = 43 58 | Height = 13 59 | Cursor = crHandPoint 60 | Caption = 'LinkLabel' 61 | Font.Charset = DEFAULT_CHARSET 62 | Font.Color = clWindowText 63 | Font.Height = -11 64 | Font.Name = 'Tahoma' 65 | Font.Style = [fsUnderline] 66 | ParentFont = False 67 | end 68 | object Label1: TLabel 69 | Left = 5 70 | Top = 44 71 | Width = 43 72 | Height = 13 73 | Caption = 'Formats:' 74 | end 75 | object Label2: TLabel 76 | Left = 6 77 | Top = 72 78 | Width = 45 79 | Height = 13 80 | Caption = 'Subtitles:' 81 | end 82 | object FormatList: TComboBox 83 | Left = 55 84 | Top = 41 85 | Width = 817 86 | Height = 21 87 | Style = csDropDownList 88 | Anchors = [akLeft, akTop, akRight] 89 | DropDownCount = 16 90 | TabOrder = 0 91 | end 92 | object SubtitleList: TComboBox 93 | Left = 55 94 | Top = 68 95 | Width = 817 96 | Height = 21 97 | Style = csDropDownList 98 | Anchors = [akLeft, akTop, akRight] 99 | TabOrder = 1 100 | end 101 | object DeleteButton: TButton 102 | Left = 803 103 | Top = 107 104 | Width = 75 105 | Height = 25 106 | Anchors = [akRight, akBottom] 107 | Caption = 'Remove' 108 | TabOrder = 2 109 | end 110 | end 111 | object sPanel2: TPanel 112 | Left = 0 113 | Top = 0 114 | Width = 227 115 | Height = 138 116 | Align = alLeft 117 | TabOrder = 1 118 | object PrevievImg: TImage 119 | Left = 1 120 | Top = 1 121 | Width = 225 122 | Height = 136 123 | Align = alClient 124 | Center = True 125 | Picture.Data = {07544269746D617000000000} 126 | Proportional = True 127 | Transparent = True 128 | ExplicitWidth = 110 129 | ExplicitHeight = 110 130 | end 131 | end 132 | end 133 | -------------------------------------------------------------------------------- /Forms/DownloadItemFrame.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit DownloadItemFrame; 21 | 22 | interface 23 | 24 | uses 25 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 26 | System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, 27 | Vcl.StdCtrls, Vcl.Samples.Gauges; 28 | 29 | type 30 | TDownloadUIItem = class(TFrame) 31 | LinkLabel: TLabel; 32 | FileNameLabel: TLabel; 33 | FormatList: TComboBox; 34 | SubtitleList: TComboBox; 35 | ProgressLabel: TLabel; 36 | ProgressBar: TGauge; 37 | sPanel1: TPanel; 38 | DeleteButton: TButton; 39 | sPanel2: TPanel; 40 | PrevievImg: TImage; 41 | sBevel1: TBevel; 42 | Label1: TLabel; 43 | Label2: TLabel; 44 | private 45 | { Private declarations } 46 | public 47 | { Public declarations } 48 | procedure ResetProgressLabel; 49 | procedure Disable; 50 | procedure Enable; 51 | end; 52 | 53 | implementation 54 | 55 | {$R *.dfm} 56 | { TDownloadUIItem } 57 | 58 | procedure TDownloadUIItem.Disable; 59 | begin 60 | LinkLabel.Enabled := False; 61 | FileNameLabel.Enabled := False; 62 | FormatList.Enabled := False; 63 | SubtitleList.Enabled := False; 64 | DeleteButton.Enabled := False; 65 | end; 66 | 67 | procedure TDownloadUIItem.Enable; 68 | begin 69 | LinkLabel.Enabled := True; 70 | FileNameLabel.Enabled := True; 71 | FormatList.Enabled := True; 72 | SubtitleList.Enabled := True; 73 | DeleteButton.Enabled := True; 74 | end; 75 | 76 | procedure TDownloadUIItem.ResetProgressLabel; 77 | begin 78 | ProgressLabel.Caption := ''; 79 | ProgressBar.Progress := 0; 80 | end; 81 | 82 | end. -------------------------------------------------------------------------------- /Forms/FileListItemFrame.pas: -------------------------------------------------------------------------------- 1 | unit FileListItemFrame; 2 | 3 | interface 4 | 5 | uses 6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 7 | Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, 8 | Vcl.ComCtrls, System.ImageList, Vcl.ImgList; 9 | 10 | type 11 | TFileListFrame = class(TFrame) 12 | FileImage: TImage; 13 | FileNameLabel: TLabel; 14 | Label1: TLabel; 15 | Label2: TLabel; 16 | SubtitleList: TComboBox; 17 | AudioList: TComboBox; 18 | ProgressBar: TProgressBar; 19 | Panel1: TPanel; 20 | RemoveBtn: TButton; 21 | PreviewBtn: TButton; 22 | RangeBtn: TButton; 23 | SubtitleTypeList: TComboBox; 24 | FileInfoLabel: TLabel; 25 | Bevel1: TBevel; 26 | FileInfoBtn: TButton; 27 | OpenFolderBtn: TButton; 28 | ImageList1: TImageList; 29 | private 30 | { Private declarations } 31 | public 32 | { Public declarations } 33 | end; 34 | 35 | implementation 36 | 37 | {$R *.dfm} 38 | 39 | end. 40 | -------------------------------------------------------------------------------- /Forms/UnitAbout.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitAbout; 21 | 22 | interface 23 | 24 | uses 25 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 26 | Dialogs, StdCtrls, ExtCtrls, ShellAPI, Buttons, IniFiles, JvComponentBase, 27 | JvThread, JvUrlListGrabber, JvUrlGrabbers, Vcl.ComCtrls; 28 | 29 | type 30 | TAboutForm = class(TForm) 31 | Image1: TImage; 32 | OkBtn: TButton; 33 | HomepageBtn: TButton; 34 | 35 | sPageControl1: TPageControl; 36 | sTabSheet1: TTabSheet; 37 | sTabSheet2: TTabSheet; 38 | Label1: TLabel; 39 | Label2: TLabel; 40 | Label3: TLabel; 41 | Label4: TLabel; 42 | Label13: TLabel; 43 | Label10: TLabel; 44 | Label12: TLabel; 45 | Label5: TLabel; 46 | Label6: TLabel; 47 | Label7: TLabel; 48 | Label8: TLabel; 49 | Label9: TLabel; 50 | sLabel4: TLabel; 51 | procedure OkBtnClick(Sender: TObject); 52 | procedure Label6Click(Sender: TObject); 53 | procedure HomepageBtnClick(Sender: TObject); 54 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 55 | procedure Label14Click(Sender: TObject); 56 | procedure FormCreate(Sender: TObject); 57 | private 58 | { Private declarations } 59 | public 60 | { Public declarations } 61 | end; 62 | 63 | var 64 | AboutForm: TAboutForm; 65 | 66 | implementation 67 | 68 | uses UnitMain; 69 | 70 | {$R *.dfm} 71 | 72 | procedure TAboutForm.FormClose(Sender: TObject; var Action: TCloseAction); 73 | begin 74 | MainForm.Enabled := True; 75 | MainForm.BringToFront; 76 | end; 77 | 78 | procedure TAboutForm.FormCreate(Sender: TObject); 79 | begin 80 | {$IFDEF WIN32} 81 | Label2.Caption := Label2.Caption + ' Win32' 82 | {$ELSE} 83 | Label2.Caption := Label2.Caption + ' Win64' 84 | {$ENDIF} 85 | end; 86 | 87 | procedure TAboutForm.HomepageBtnClick(Sender: TObject); 88 | begin 89 | ShellExecute(0, 'open', 'http://www.ozok26.com/categories/1/tencoder-video-converter', nil, nil, SW_SHOWNORMAL); 90 | end; 91 | 92 | procedure TAboutForm.Label14Click(Sender: TObject); 93 | begin 94 | ShellExecute(0, 'open', PChar((Sender as TLabel).Caption), nil, nil, SW_SHOWNORMAL); 95 | end; 96 | 97 | procedure TAboutForm.Label6Click(Sender: TObject); 98 | begin 99 | 100 | ShellExecute(0, 'open', PChar((Sender as TLabel).Caption), nil, nil, SW_SHOWNORMAL); 101 | 102 | end; 103 | 104 | procedure TAboutForm.OkBtnClick(Sender: TObject); 105 | begin 106 | 107 | AboutForm.Close; 108 | 109 | end; 110 | 111 | end. -------------------------------------------------------------------------------- /Forms/UnitAdd.dfm: -------------------------------------------------------------------------------- 1 | object AddForm: TAddForm 2 | Left = 0 3 | Top = 0 4 | BorderIcons = [] 5 | BorderStyle = bsSingle 6 | Caption = 'TEncoder' 7 | ClientHeight = 65 8 | ClientWidth = 658 9 | Color = clBtnFace 10 | DoubleBuffered = True 11 | Font.Charset = DEFAULT_CHARSET 12 | Font.Color = clWindowText 13 | Font.Height = -11 14 | Font.Name = 'Tahoma' 15 | Font.Style = [] 16 | OldCreateOrder = False 17 | Position = poMainFormCenter 18 | ShowHint = True 19 | OnClose = FormClose 20 | OnCreate = FormCreate 21 | PixelsPerInch = 96 22 | TextHeight = 13 23 | object StatusLabel: TLabel 24 | Left = 8 25 | Top = 8 26 | Width = 642 27 | Height = 13 28 | Hint = 'What'#39's going on?' 29 | AutoSize = False 30 | Caption = 'Adding files please wait...' 31 | end 32 | object AbortBtn: TButton 33 | Left = 550 34 | Top = 27 35 | Width = 100 36 | Height = 30 37 | Hint = 'Abort current progress' 38 | Caption = 'Abort' 39 | TabOrder = 0 40 | OnClick = AbortBtnClick 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /Forms/UnitAdd.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitAdd; 21 | 22 | interface 23 | 24 | uses 25 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 26 | Dialogs, ComCtrls, StdCtrls, ExtCtrls, Buttons; 27 | 28 | type 29 | TAddForm = class(TForm) 30 | StatusLabel: TLabel; 31 | 32 | AbortBtn: TButton; 33 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 34 | procedure AbortBtnClick(Sender: TObject); 35 | procedure FormCreate(Sender: TObject); 36 | private 37 | { Private declarations } 38 | public 39 | { Public declarations } 40 | end; 41 | 42 | var 43 | AddForm: TAddForm; 44 | 45 | implementation 46 | 47 | uses UnitMain; 48 | 49 | {$R *.dfm} 50 | 51 | procedure TAddForm.AbortBtnClick(Sender: TObject); 52 | begin 53 | 54 | if MainForm.SearchVideo.Searching then 55 | begin 56 | MainForm.SearchVideo.Abort; 57 | end 58 | else 59 | begin 60 | MainForm.FFileAddingStoppedByUser := True; 61 | end; 62 | 63 | end; 64 | 65 | procedure TAddForm.FormClose(Sender: TObject; var Action: TCloseAction); 66 | begin 67 | 68 | StatusLabel.Caption := 'Adding files, please wait...'; 69 | 70 | MainForm.Enabled := True; 71 | MainForm.BringToFront; 72 | 73 | end; 74 | 75 | procedure TAddForm.FormCreate(Sender: TObject); 76 | begin 77 | 78 | StatusLabel.Caption := 'Adding files, please wait...'; 79 | 80 | end; 81 | 82 | end. -------------------------------------------------------------------------------- /Forms/UnitBatchAdd.dfm: -------------------------------------------------------------------------------- 1 | object BatchAddForm: TBatchAddForm 2 | Left = 0 3 | Top = 0 4 | Caption = 'Batch add' 5 | ClientHeight = 300 6 | ClientWidth = 635 7 | Color = 16708071 8 | DoubleBuffered = True 9 | Font.Charset = DEFAULT_CHARSET 10 | Font.Color = clWindowText 11 | Font.Height = -11 12 | Font.Name = 'Tahoma' 13 | Font.Style = [] 14 | OldCreateOrder = False 15 | Position = poMainFormCenter 16 | OnClose = FormClose 17 | OnShow = FormShow 18 | DesignSize = ( 19 | 635 20 | 300) 21 | PixelsPerInch = 96 22 | TextHeight = 13 23 | object Label1: TLabel 24 | Left = 8 25 | Top = 8 26 | Width = 80 27 | Height = 13 28 | Caption = 'One link per line:' 29 | end 30 | object LinksList: TMemo 31 | Left = 8 32 | Top = 27 33 | Width = 619 34 | Height = 234 35 | Anchors = [akLeft, akTop, akRight, akBottom] 36 | Color = clWhite 37 | Font.Charset = DEFAULT_CHARSET 38 | Font.Color = clBlack 39 | Font.Height = -11 40 | Font.Name = 'Tahoma' 41 | Font.Style = [] 42 | ParentFont = False 43 | ScrollBars = ssBoth 44 | TabOrder = 0 45 | end 46 | object CancelBtn: TButton 47 | Left = 471 48 | Top = 267 49 | Width = 75 50 | Height = 25 51 | Anchors = [akRight, akBottom] 52 | Caption = 'Cancel' 53 | TabOrder = 1 54 | OnClick = CancelBtnClick 55 | end 56 | object OkBtn: TButton 57 | Left = 552 58 | Top = 267 59 | Width = 75 60 | Height = 25 61 | Anchors = [akRight, akBottom] 62 | Caption = 'OK' 63 | TabOrder = 2 64 | OnClick = OkBtnClick 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /Forms/UnitBatchAdd.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitBatchAdd; 21 | 22 | interface 23 | 24 | uses 25 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 26 | Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; 27 | 28 | type 29 | TMode = (singlelink, playlist); 30 | 31 | type 32 | TBatchAddForm = class(TForm) 33 | LinksList: TMemo; 34 | Label1: TLabel; 35 | CancelBtn: TButton; 36 | OkBtn: TButton; 37 | procedure CancelBtnClick(Sender: TObject); 38 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 39 | procedure OkBtnClick(Sender: TObject); 40 | procedure FormShow(Sender: TObject); 41 | private 42 | { Private declarations } 43 | public 44 | { Public declarations } 45 | PMode: TMode; 46 | end; 47 | 48 | var 49 | BatchAddForm: TBatchAddForm; 50 | 51 | implementation 52 | 53 | {$R *.dfm} 54 | 55 | uses 56 | UnitMain; 57 | 58 | procedure TBatchAddForm.CancelBtnClick(Sender: TObject); 59 | begin 60 | Self.Close; 61 | end; 62 | 63 | procedure TBatchAddForm.FormClose(Sender: TObject; var Action: TCloseAction); 64 | begin 65 | MainForm.Enabled := True; 66 | MainForm.BringToFront; 67 | end; 68 | 69 | procedure TBatchAddForm.FormShow(Sender: TObject); 70 | begin 71 | LinksList.Lines.Clear; 72 | end; 73 | 74 | procedure TBatchAddForm.OkBtnClick(Sender: TObject); 75 | begin 76 | if LinksList.Lines.Count > 0 then 77 | begin 78 | Self.Close; 79 | case PMode of 80 | singlelink: 81 | MainForm.BatchAdd(LinksList.Lines, True); 82 | playlist: 83 | MainForm.BatchAdd(LinksList.Lines, False); 84 | end; 85 | end 86 | else 87 | begin 88 | Application.MessageBox('You need to add links to proceed.', 'Error', MB_ICONERROR); 89 | end; 90 | end; 91 | 92 | end. 93 | 94 | -------------------------------------------------------------------------------- /Forms/UnitDub.dfm: -------------------------------------------------------------------------------- 1 | object DubForm: TDubForm 2 | Left = 0 3 | Top = 0 4 | BorderIcons = [biSystemMenu] 5 | Caption = 'Dub' 6 | ClientHeight = 173 7 | ClientWidth = 635 8 | Color = 16708071 9 | DoubleBuffered = True 10 | Font.Charset = DEFAULT_CHARSET 11 | Font.Color = clWindowText 12 | Font.Height = -11 13 | Font.Name = 'Tahoma' 14 | Font.Style = [] 15 | OldCreateOrder = False 16 | Position = poMainFormCenter 17 | OnClose = FormClose 18 | OnCreate = FormCreate 19 | OnDestroy = FormDestroy 20 | OnShow = FormShow 21 | DesignSize = ( 22 | 635 23 | 173) 24 | PixelsPerInch = 96 25 | TextHeight = 13 26 | object ProgressLabel: TLabel 27 | Left = 8 28 | Top = 119 29 | Width = 619 30 | Height = 13 31 | Anchors = [akLeft, akRight, akBottom] 32 | AutoSize = False 33 | Caption = 'FFMpeg output' 34 | end 35 | object Label1: TLabel 36 | Left = 45 37 | Top = 12 38 | Width = 30 39 | Height = 13 40 | Caption = 'Video:' 41 | end 42 | object Label2: TLabel 43 | Left = 44 44 | Top = 39 45 | Width = 31 46 | Height = 13 47 | Caption = 'Audio:' 48 | end 49 | object Label3: TLabel 50 | Left = 8 51 | Top = 66 52 | Width = 67 53 | Height = 13 54 | Caption = 'Output name:' 55 | end 56 | object Label4: TLabel 57 | Left = 24 58 | Top = 93 59 | Width = 51 60 | Height = 13 61 | Caption = 'Container:' 62 | end 63 | object OutputEdit: TEdit 64 | Left = 81 65 | Top = 62 66 | Width = 546 67 | Height = 21 68 | Anchors = [akLeft, akTop, akRight] 69 | Color = clWhite 70 | Font.Charset = DEFAULT_CHARSET 71 | Font.Color = clBlack 72 | Font.Height = -11 73 | Font.Name = 'Tahoma' 74 | Font.Style = [] 75 | ParentFont = False 76 | TabOrder = 1 77 | end 78 | object ContainerList: TComboBox 79 | Left = 81 80 | Top = 89 81 | Width = 145 82 | Height = 21 83 | Style = csDropDownList 84 | Color = clWhite 85 | Font.Charset = DEFAULT_CHARSET 86 | Font.Color = clBlack 87 | Font.Height = -11 88 | Font.Name = 'Tahoma' 89 | Font.Style = [] 90 | ParentFont = False 91 | TabOrder = 3 92 | Items.Strings = ( 93 | 'AVI' 94 | 'MPEG' 95 | 'MP4' 96 | 'MOV' 97 | 'MKV' 98 | 'FLV' 99 | 'WMV' 100 | 'WEBM' 101 | '3GP') 102 | end 103 | object StopBtn: TBitBtn 104 | Left = 421 105 | Top = 140 106 | Width = 100 107 | Height = 25 108 | Anchors = [akRight, akBottom] 109 | Caption = 'Stop' 110 | Enabled = False 111 | TabOrder = 0 112 | OnClick = StopBtnClick 113 | end 114 | object StartBtn: TBitBtn 115 | Left = 527 116 | Top = 140 117 | Width = 100 118 | Height = 25 119 | Anchors = [akRight, akBottom] 120 | Caption = 'Start' 121 | TabOrder = 2 122 | OnClick = StartBtnClick 123 | end 124 | object VideoEdit: TJvFilenameEdit 125 | Left = 81 126 | Top = 8 127 | Width = 546 128 | Height = 21 129 | TabOrder = 4 130 | Text = '' 131 | end 132 | object AudioEdit: TJvFilenameEdit 133 | Left = 81 134 | Top = 35 135 | Width = 546 136 | Height = 21 137 | TabOrder = 5 138 | Text = '' 139 | end 140 | object PosTimer: TTimer 141 | Enabled = False 142 | Interval = 500 143 | OnTimer = PosTimerTimer 144 | Left = 312 145 | Top = 88 146 | end 147 | end 148 | -------------------------------------------------------------------------------- /Forms/UnitDub.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitDub; 21 | 22 | interface 23 | 24 | uses 25 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, 26 | Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, 27 | Vcl.ComCtrls, Vcl.Mask, UnitEncoder, Vcl.ExtCtrls, JvExMask, JvToolEdit; 28 | 29 | type 30 | TDubForm = class(TForm) 31 | OutputEdit: TEdit; 32 | ProgressLabel: TLabel; 33 | ContainerList: TComboBox; 34 | StopBtn: TBitBtn; 35 | StartBtn: TBitBtn; 36 | PosTimer: TTimer; 37 | VideoEdit: TJvFilenameEdit; 38 | AudioEdit: TJvFilenameEdit; 39 | Label1: TLabel; 40 | Label2: TLabel; 41 | Label3: TLabel; 42 | Label4: TLabel; 43 | procedure FormCreate(Sender: TObject); 44 | procedure FormDestroy(Sender: TObject); 45 | procedure FormShow(Sender: TObject); 46 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 47 | procedure StartBtnClick(Sender: TObject); 48 | procedure PosTimerTimer(Sender: TObject); 49 | procedure StopBtnClick(Sender: TObject); 50 | private 51 | { Private declarations } 52 | FEncoder: TEncodingProcess; 53 | FDuration: string; 54 | FOutputFile: string; 55 | procedure EncodingState; 56 | procedure NormalState; 57 | function CreateCMD: string; 58 | procedure DeleteTempFile; 59 | public 60 | { Public declarations } 61 | end; 62 | 63 | var 64 | DubForm: TDubForm; 65 | 66 | implementation 67 | 68 | {$R *.dfm} 69 | 70 | uses 71 | UnitLogs, UnitMain, UnitImageAudioMerger; 72 | 73 | function TDubForm.CreateCMD: string; 74 | var 75 | LExt: string; 76 | LCMD: string; 77 | LEncodeJob: TEncodeJob; 78 | begin 79 | 80 | // get video without the audio 81 | LCMD := ' -y -i "' + VideoEdit.Text + '" -an -c:v copy "' + MainForm.DirectoryEdit.Text + '\TEncoder_temp.mkv"'; 82 | LEncodeJob.CommandLine := LCMD; 83 | LEncodeJob.ProcessPath := MainForm.FFFMpegPath; 84 | LEncodeJob.ProcessType := ffmpeg; 85 | LEncodeJob.EncodingInformation := 'Dubbing'; 86 | LEncodeJob.EncodingOutputFilePath := FOutputFile; 87 | LEncodeJob.SourceFileName := ''; 88 | FEncoder.EncodeJobs.Add(LEncodeJob); 89 | 90 | LCMD := ' -y -i "' + AudioEdit.Text + '" -i "' + MainForm.DirectoryEdit.Text + '\TEncoder_temp.mkv" -c:v copy -c:a copy '; 91 | case ContainerList.ItemIndex of 92 | 0: 93 | begin 94 | LCMD := LCMD + ' -f avi '; 95 | LExt := '.avi'; 96 | end; 97 | 1: 98 | begin 99 | LCMD := LCMD + ' -f mpeg '; 100 | LExt := '.mpeg'; 101 | end; 102 | 2: 103 | begin 104 | LCMD := LCMD + ' -f mp4 '; 105 | LExt := '.mp4'; 106 | end; 107 | 3: 108 | begin 109 | LCMD := LCMD + ' -f mov '; 110 | LExt := '.mov'; 111 | end; 112 | 4: 113 | begin 114 | LCMD := LCMD + ' -f matroska '; 115 | LExt := '.mkv'; 116 | end; 117 | 5: 118 | begin 119 | LCMD := LCMD + ' -f flv '; 120 | LExt := '.flv'; 121 | end; 122 | 6: 123 | begin 124 | LCMD := LCMD + ' -f wmv '; 125 | LExt := '.wmv'; 126 | end; 127 | 7: 128 | begin 129 | LCMD := LCMD + ' -f webm '; 130 | LExt := '.webm'; 131 | end; 132 | 8: 133 | begin 134 | Result := Result + ' -f 3gp '; 135 | LExt := '.3gp'; 136 | end; 137 | end; 138 | LCMD := LCMD + ' "' + ImageAudiotoVideoForm.CreateFileName(OutputEdit.Text, LExt) + '"'; 139 | LEncodeJob.CommandLine := LCMD; 140 | LEncodeJob.ProcessPath := MainForm.FFFMpegPath; 141 | LEncodeJob.ProcessType := ffmpeg; 142 | LEncodeJob.EncodingInformation := 'Dubbing'; 143 | LEncodeJob.EncodingOutputFilePath := FOutputFile; 144 | LEncodeJob.SourceFileName := ''; 145 | FEncoder.EncodeJobs.Add(LEncodeJob); 146 | end; 147 | 148 | procedure TDubForm.DeleteTempFile; 149 | begin 150 | if FileExists(MainForm.DirectoryEdit.Text + '\TEncoder_temp.mkv') then 151 | begin 152 | DeleteFile(MainForm.DirectoryEdit.Text + '\TEncoder_temp.mkv') 153 | end; 154 | end; 155 | 156 | procedure TDubForm.EncodingState; 157 | begin 158 | StartBtn.Enabled := False; 159 | StopBtn.Enabled := True; 160 | AudioEdit.Enabled := False; 161 | VideoEdit.Enabled := False; 162 | OutputEdit.Enabled := False; 163 | end; 164 | 165 | procedure TDubForm.FormClose(Sender: TObject; var Action: TCloseAction); 166 | begin 167 | if FEncoder.ProcessID > 0 then 168 | begin 169 | FEncoder.Stop; 170 | end; 171 | DeleteTempFile; 172 | MainForm.Enabled := True; 173 | MainForm.BringToFront; 174 | end; 175 | 176 | procedure TDubForm.FormCreate(Sender: TObject); 177 | begin 178 | FEncoder := TEncodingProcess.Create; 179 | VideoEdit.Dialog.Filter := 'Video Files|*.flv;*.m2v;*.avi;*.mkv;*.mpeg;*.mpg;*.mov;*.wmv;*.mp4;' + '*.m4v;*.dat;*.vob;*.rmvb;*.mts;*.mxf'; 180 | AudioEdit.Dialog.Filter := 'Audio Files|*.mp3;*.wav;*.aac;*.m4a;*.m4b;*.ac3;*.ogg;*.flac;*.mp2;*.opus;*.spx'; 181 | DeleteTempFile; 182 | end; 183 | 184 | procedure TDubForm.FormDestroy(Sender: TObject); 185 | begin 186 | FEncoder.Free; 187 | end; 188 | 189 | procedure TDubForm.FormShow(Sender: TObject); 190 | begin 191 | FEncoder.ResetValues; 192 | AudioEdit.Text := ''; 193 | VideoEdit.Text := ''; 194 | OutputEdit.Text := ''; 195 | ProgressLabel.Caption := 'FFMpeg output'; 196 | FDuration := '0'; 197 | end; 198 | 199 | procedure TDubForm.NormalState; 200 | begin 201 | StartBtn.Enabled := True; 202 | StopBtn.Enabled := False; 203 | AudioEdit.Enabled := True; 204 | VideoEdit.Enabled := True; 205 | OutputEdit.Enabled := True; 206 | LogForm.OtherLog.Lines.Add('Dubbing:'); 207 | if FEncoder.CommandCount > 0 then 208 | begin 209 | LogForm.OtherLog.Lines.AddStrings(FEncoder.GetConsoleOutput); 210 | end; 211 | LogForm.OtherLog.Lines.AddStrings(FEncoder.GetConsoleOutput); 212 | end; 213 | 214 | procedure TDubForm.PosTimerTimer(Sender: TObject); 215 | begin 216 | if FEncoder.FilesDone = FEncoder.CommandCount then 217 | begin 218 | PosTimer.Enabled := False; 219 | ProgressLabel.Caption := 'FFMpeg output'; 220 | FDuration := '0'; 221 | DeleteTempFile; 222 | NormalState; 223 | Self.BringToFront; 224 | Application.MessageBox('Finished dubbing.', 'Info', MB_ICONINFORMATION); 225 | end 226 | else 227 | begin 228 | ProgressLabel.Caption := FEncoder.ConsoleOutput; 229 | end; 230 | end; 231 | 232 | procedure TDubForm.StartBtnClick(Sender: TObject); 233 | var 234 | LCMD: string; 235 | begin 236 | if FileExists(AudioEdit.Text) then 237 | begin 238 | if FileExists(VideoEdit.Text) then 239 | begin 240 | if Length(OutputEdit.Text) > 0 then 241 | begin 242 | // todo: check file name for valid chars 243 | if MainForm.VideoEncoderList.ItemIndex < 10 then 244 | begin 245 | if (MainForm.AudioEncoderList.ItemIndex <> 10) then 246 | begin 247 | 248 | // reset 249 | FEncoder.ResetValues; 250 | ProgressLabel.Caption := 'FFMpeg output'; 251 | FDuration := '0'; 252 | FOutputFile := ''; 253 | DeleteTempFile; 254 | 255 | // create command line 256 | LCMD := CreateCMD; 257 | if FEncoder.CommandCount > 0 then 258 | begin 259 | FEncoder.Start; 260 | PosTimer.Enabled := True; 261 | EncodingState; 262 | end 263 | else 264 | begin 265 | Application.MessageBox('Cannot create command line.', 'Error', MB_ICONERROR) 266 | end; 267 | end 268 | else 269 | begin 270 | Application.MessageBox('Select an audio encoder.', 'Warning', MB_ICONWARNING) 271 | end; 272 | end 273 | else 274 | begin 275 | Application.MessageBox('Select an video encoder.', 'Warning', MB_ICONWARNING) 276 | end; 277 | 278 | end 279 | else 280 | begin 281 | Application.MessageBox('Enter a valid output name.', 'Error', MB_ICONERROR) 282 | end; 283 | end 284 | else 285 | begin 286 | Application.MessageBox('Cannot find the video file.', 'Error', MB_ICONERROR) 287 | end; 288 | end 289 | else 290 | begin 291 | Application.MessageBox('Cannot find the audio file.', 'Error', MB_ICONERROR) 292 | end; 293 | end; 294 | 295 | procedure TDubForm.StopBtnClick(Sender: TObject); 296 | begin 297 | if FEncoder.ProcessID > 0 then 298 | begin 299 | FEncoder.Stop; 300 | PosTimer.Enabled := False; 301 | ProgressLabel.Caption := 'FFMpeg Output'; 302 | FDuration := '0'; 303 | DeleteTempFile; 304 | NormalState; 305 | end; 306 | end; 307 | 308 | end. 309 | 310 | -------------------------------------------------------------------------------- /Forms/UnitEffects.dfm: -------------------------------------------------------------------------------- 1 | object EffectForm: TEffectForm 2 | Left = 0 3 | Top = 0 4 | BorderStyle = bsDialog 5 | Caption = 'Filters' 6 | ClientHeight = 217 7 | ClientWidth = 576 8 | Color = 16708071 9 | DoubleBuffered = True 10 | Font.Charset = DEFAULT_CHARSET 11 | Font.Color = clWindowText 12 | Font.Height = -11 13 | Font.Name = 'Tahoma' 14 | Font.Style = [] 15 | OldCreateOrder = False 16 | Position = poMainFormCenter 17 | OnClose = FormClose 18 | OnCreate = FormCreate 19 | DesignSize = ( 20 | 576 21 | 217) 22 | PixelsPerInch = 96 23 | TextHeight = 13 24 | object CloseBtn: TButton 25 | Left = 448 26 | Top = 184 27 | Width = 120 28 | Height = 25 29 | Anchors = [akRight, akBottom] 30 | Caption = 'Close' 31 | TabOrder = 0 32 | OnClick = CloseBtnClick 33 | end 34 | object PreviewBtn: TButton 35 | Left = 8 36 | Top = 184 37 | Width = 100 38 | Height = 25 39 | Anchors = [akLeft, akBottom] 40 | Caption = 'Preview' 41 | TabOrder = 1 42 | OnClick = PreviewBtnClick 43 | end 44 | object PreviewList: TComboBox 45 | Left = 168 46 | Top = 185 47 | Width = 274 48 | Height = 21 49 | Style = csDropDownList 50 | Anchors = [akLeft, akRight, akBottom] 51 | Color = clWhite 52 | Font.Charset = DEFAULT_CHARSET 53 | Font.Color = clBlack 54 | Font.Height = -11 55 | Font.Name = 'Tahoma' 56 | Font.Style = [] 57 | ParentFont = False 58 | TabOrder = 2 59 | end 60 | object sPageControl1: TPageControl 61 | Left = 8 62 | Top = 8 63 | Width = 560 64 | Height = 170 65 | ActivePage = sTabSheet1 66 | Anchors = [akLeft, akTop, akRight, akBottom] 67 | TabOrder = 3 68 | object sTabSheet1: TTabSheet 69 | Caption = 'Deinterlace' 70 | ExplicitLeft = 0 71 | ExplicitTop = 0 72 | ExplicitWidth = 0 73 | ExplicitHeight = 0 74 | object sLabel1: TLabel 75 | Left = 3 76 | Top = 72 77 | Width = 361 78 | Height = 13 79 | Caption = 80 | 'This options is for MEncoder. FFmpeg has only one option for dei' + 81 | 'nterlacing.' 82 | end 83 | object sLabel2: TLabel 84 | Left = 3 85 | Top = 91 86 | Width = 289 87 | Height = 13 88 | Caption = 'Preview may be different if you choose FFmpeg as encoder.' 89 | end 90 | object Label1: TLabel 91 | Left = 14 92 | Top = 43 93 | Width = 40 94 | Height = 13 95 | Caption = 'Method:' 96 | end 97 | object DeintEnblBtn: TCheckBox 98 | Left = 10 99 | Top = 16 100 | Width = 58 101 | Height = 19 102 | Caption = 'Enable' 103 | TabOrder = 0 104 | OnClick = DeintEnblBtnClick 105 | end 106 | object DeintMethodList: TComboBox 107 | Left = 60 108 | Top = 41 109 | Width = 145 110 | Height = 21 111 | Style = csDropDownList 112 | Color = clWhite 113 | Enabled = False 114 | Font.Charset = DEFAULT_CHARSET 115 | Font.Color = clBlack 116 | Font.Height = -11 117 | Font.Name = 'Tahoma' 118 | Font.Style = [] 119 | ItemIndex = 0 120 | ParentFont = False 121 | TabOrder = 1 122 | Text = 'Yadif=0' 123 | Items.Strings = ( 124 | 'Yadif=0' 125 | 'Yadif=1:1' 126 | 'Yadif=3:1' 127 | 'Linear Blend' 128 | 'Linear Interpole' 129 | 'Median Interlacer' 130 | 'Cubic Interpole' 131 | 'Kernel Deinterlace' 132 | 'Lavcdeint') 133 | end 134 | end 135 | object sTabSheet2: TTabSheet 136 | Caption = 'Crop' 137 | ExplicitLeft = 0 138 | ExplicitTop = 0 139 | ExplicitWidth = 0 140 | ExplicitHeight = 0 141 | object Label5: TLabel 142 | Left = 10 143 | Top = 68 144 | Width = 370 145 | Height = 13 146 | Caption = 147 | 'Make sure width and height values match with the values from ma' + 148 | 'in window.' 149 | end 150 | object Label2: TLabel 151 | Left = 8 152 | Top = 45 153 | Width = 32 154 | Height = 13 155 | Caption = 'Width:' 156 | end 157 | object Label3: TLabel 158 | Left = 115 159 | Top = 45 160 | Width = 35 161 | Height = 13 162 | Caption = 'Height:' 163 | end 164 | object Label4: TLabel 165 | Left = 224 166 | Top = 45 167 | Width = 10 168 | Height = 13 169 | Caption = 'X:' 170 | end 171 | object Label6: TLabel 172 | Left = 304 173 | Top = 45 174 | Width = 10 175 | Height = 13 176 | Caption = 'Y:' 177 | end 178 | object CropEnable: TCheckBox 179 | Left = 10 180 | Top = 16 181 | Width = 58 182 | Height = 19 183 | Caption = 'Enable' 184 | TabOrder = 0 185 | OnClick = CropEnableClick 186 | end 187 | object CropHeightEdit: TJvSpinEdit 188 | Left = 156 189 | Top = 41 190 | Width = 50 191 | Height = 21 192 | Color = clWhite 193 | Enabled = False 194 | Font.Charset = DEFAULT_CHARSET 195 | Font.Color = clBlack 196 | Font.Height = -11 197 | Font.Name = 'Tahoma' 198 | Font.Style = [] 199 | ParentFont = False 200 | TabOrder = 1 201 | end 202 | object CropWidthEdit: TJvSpinEdit 203 | Left = 46 204 | Top = 41 205 | Width = 50 206 | Height = 21 207 | Color = clWhite 208 | Enabled = False 209 | Font.Charset = DEFAULT_CHARSET 210 | Font.Color = clBlack 211 | Font.Height = -11 212 | Font.Name = 'Tahoma' 213 | Font.Style = [] 214 | ParentFont = False 215 | TabOrder = 2 216 | end 217 | object CropXEdit: TJvSpinEdit 218 | Left = 239 219 | Top = 41 220 | Width = 50 221 | Height = 21 222 | Color = clWhite 223 | Enabled = False 224 | Font.Charset = DEFAULT_CHARSET 225 | Font.Color = clBlack 226 | Font.Height = -11 227 | Font.Name = 'Tahoma' 228 | Font.Style = [] 229 | ParentFont = False 230 | TabOrder = 3 231 | end 232 | object CropYEdit: TJvSpinEdit 233 | Left = 330 234 | Top = 41 235 | Width = 50 236 | Height = 21 237 | Color = clWhite 238 | Enabled = False 239 | Font.Charset = DEFAULT_CHARSET 240 | Font.Color = clBlack 241 | Font.Height = -11 242 | Font.Name = 'Tahoma' 243 | Font.Style = [] 244 | ParentFont = False 245 | TabOrder = 4 246 | end 247 | end 248 | object sTabSheet3: TTabSheet 249 | Caption = 'Rotate' 250 | ExplicitLeft = 0 251 | ExplicitTop = 0 252 | ExplicitWidth = 0 253 | ExplicitHeight = 0 254 | object RotateList: TComboBox 255 | Left = 45 256 | Top = 16 257 | Width = 276 258 | Height = 21 259 | Style = csDropDownList 260 | Color = clWhite 261 | Font.Charset = DEFAULT_CHARSET 262 | Font.Color = clBlack 263 | Font.Height = -11 264 | Font.Name = 'Tahoma' 265 | Font.Style = [] 266 | ItemIndex = 0 267 | ParentFont = False 268 | TabOrder = 0 269 | Text = 'Do not rotate' 270 | Items.Strings = ( 271 | 'Do not rotate' 272 | 'Rotate by 90 degrees clockwise and flip (default).' 273 | 'Rotate by 90 degrees clockwise.' 274 | 'Rotate by 90 degrees counterclockwise.' 275 | 'Rotate by 90 degrees counterclockwise and flip.' 276 | 'Rotate by 180 degrees clockwise and flip (default).' 277 | 'Rotate by 180 degrees clockwise.' 278 | 'Rotate by 180 degrees counterclockwise.' 279 | 'Rotate by 180 degrees counterclockwise and flip.') 280 | end 281 | end 282 | object sTabSheet4: TTabSheet 283 | Caption = 'Volume' 284 | ExplicitLeft = 0 285 | ExplicitTop = 0 286 | ExplicitWidth = 0 287 | ExplicitHeight = 0 288 | object Label7: TLabel 289 | Left = 17 290 | Top = 44 291 | Width = 177 292 | Height = 13 293 | Caption = 'MEncoder volume level (-200/60 dB):' 294 | end 295 | object Label8: TLabel 296 | Left = 68 297 | Top = 71 298 | Width = 126 299 | Height = 13 300 | Caption = 'FFmpeg volume level (%):' 301 | end 302 | object VolumeEnableBtn: TCheckBox 303 | Left = 10 304 | Top = 16 305 | Width = 58 306 | Height = 19 307 | Caption = 'Enable' 308 | TabOrder = 0 309 | OnClick = VolumeEnableBtnClick 310 | end 311 | object VolumeMencoderEdit: TJvSpinEdit 312 | Left = 200 313 | Top = 40 314 | Width = 75 315 | Height = 21 316 | MaxValue = 60.000000000000000000 317 | MinValue = -200.000000000000000000 318 | Enabled = False 319 | Font.Charset = DEFAULT_CHARSET 320 | Font.Color = clWindowText 321 | Font.Height = -11 322 | Font.Name = 'Tahoma' 323 | Font.Style = [] 324 | ParentFont = False 325 | TabOrder = 1 326 | end 327 | object VolumeFFMpegEdit: TJvSpinEdit 328 | Left = 200 329 | Top = 67 330 | Width = 75 331 | Height = 21 332 | MaxValue = 100.000000000000000000 333 | Value = 100.000000000000000000 334 | Enabled = False 335 | Font.Charset = DEFAULT_CHARSET 336 | Font.Color = clWindowText 337 | Font.Height = -11 338 | Font.Name = 'Tahoma' 339 | Font.Style = [] 340 | ParentFont = False 341 | TabOrder = 2 342 | end 343 | end 344 | end 345 | end 346 | -------------------------------------------------------------------------------- /Forms/UnitEffects.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitEffects; 21 | 22 | interface 23 | 24 | uses 25 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 26 | Dialogs, ComCtrls, StdCtrls, Buttons, ExtCtrls, IniFiles, Vcl.Mask, JvExMask, 27 | JvSpin, Vcl.Samples.Spin; 28 | 29 | type 30 | TEffectForm = class(TForm) 31 | CloseBtn: TButton; 32 | PreviewBtn: TButton; 33 | PreviewList: TComboBox; 34 | DeintEnblBtn: TCheckBox; 35 | DeintMethodList: TComboBox; 36 | sLabel1: TLabel; 37 | sLabel2: TLabel; 38 | sPageControl1: TPageControl; 39 | sTabSheet1: TTabSheet; 40 | sTabSheet2: TTabSheet; 41 | Label5: TLabel; 42 | CropEnable: TCheckBox; 43 | CropHeightEdit: TJvSpinEdit; 44 | CropWidthEdit: TJvSpinEdit; 45 | CropXEdit: TJvSpinEdit; 46 | CropYEdit: TJvSpinEdit; 47 | sTabSheet3: TTabSheet; 48 | RotateList: TComboBox; 49 | sTabSheet4: TTabSheet; 50 | VolumeEnableBtn: TCheckBox; 51 | VolumeMencoderEdit: TJvSpinEdit; 52 | VolumeFFMpegEdit: TJvSpinEdit; 53 | Label1: TLabel; 54 | Label2: TLabel; 55 | Label3: TLabel; 56 | Label4: TLabel; 57 | Label6: TLabel; 58 | Label7: TLabel; 59 | Label8: TLabel; 60 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 61 | procedure CloseBtnClick(Sender: TObject); 62 | procedure FormCreate(Sender: TObject); 63 | procedure DeintEnblBtnClick(Sender: TObject); 64 | procedure PreviewBtnClick(Sender: TObject); 65 | procedure CropEnableClick(Sender: TObject); 66 | procedure VolumeEnableBtnClick(Sender: TObject); 67 | private 68 | { Private declarations } 69 | procedure SaveSettings(); 70 | procedure LoadSettings(); 71 | public 72 | { Public declarations } 73 | end; 74 | 75 | var 76 | EffectForm: TEffectForm; 77 | 78 | implementation 79 | 80 | uses 81 | UnitMain, UnitPreview; 82 | 83 | {$R *.dfm} 84 | 85 | procedure TEffectForm.CloseBtnClick(Sender: TObject); 86 | begin 87 | 88 | EffectForm.Close; 89 | 90 | end; 91 | 92 | procedure TEffectForm.CropEnableClick(Sender: TObject); 93 | begin 94 | 95 | CropWidthEdit.Enabled := CropEnable.Checked; 96 | CropHeightEdit.Enabled := CropEnable.Checked; 97 | CropXEdit.Enabled := CropEnable.Checked; 98 | CropYEdit.Enabled := CropEnable.Checked; 99 | 100 | end; 101 | 102 | procedure TEffectForm.DeintEnblBtnClick(Sender: TObject); 103 | begin 104 | 105 | DeintMethodList.Enabled := DeintEnblBtn.Checked; 106 | 107 | end; 108 | 109 | procedure TEffectForm.FormClose(Sender: TObject; var Action: TCloseAction); 110 | begin 111 | 112 | SaveSettings; 113 | 114 | PreviewList.Items.Clear; 115 | 116 | MainForm.Enabled := True; 117 | 118 | end; 119 | 120 | procedure TEffectForm.FormCreate(Sender: TObject); 121 | begin 122 | LoadSettings; 123 | end; 124 | 125 | procedure TEffectForm.LoadSettings; 126 | var 127 | SettingsFile: TIniFile; 128 | begin 129 | 130 | SettingsFile := TIniFile.Create(MainForm.FAppDataFolder + '\Settings.ini'); 131 | try 132 | DeintEnblBtn.Checked := SettingsFile.ReadBool('Effect', 'Deint', False); 133 | DeintMethodList.ItemIndex := SettingsFile.ReadInteger('Effects', 'Deint2', 0); 134 | DeintMethodList.Enabled := DeintEnblBtn.Checked; 135 | 136 | CropEnable.Checked := SettingsFile.ReadBool('Effect', 'Crop', False); 137 | CropWidthEdit.Text := SettingsFile.ReadString('Effect', 'CropW', '0'); 138 | CropHeightEdit.Text := SettingsFile.ReadString('Effect', 'CropH', '0'); 139 | CropXEdit.Text := SettingsFile.ReadString('Effect', 'CropX', '0'); 140 | CropYEdit.Text := SettingsFile.ReadString('Effect', 'CropY', '0'); 141 | CropEnable.OnClick(Self); 142 | 143 | VolumeEnableBtn.Checked := SettingsFile.ReadBool('Effects', 'Vol', False); 144 | VolumeMencoderEdit.Text := SettingsFile.ReadString('Effects', 'VolM', '0'); 145 | VolumeFFMpegEdit.Text := SettingsFile.ReadString('Effects', 'VolF', '100'); 146 | VolumeEnableBtnClick(Self); 147 | 148 | RotateList.ItemIndex := SettingsFile.ReadInteger('effect', 'rotate', 0); 149 | finally 150 | SettingsFile.Free; 151 | end; 152 | 153 | end; 154 | 155 | procedure TEffectForm.PreviewBtnClick(Sender: TObject); 156 | var 157 | FileIndex: Integer; 158 | FileName: string; 159 | begin 160 | 161 | FileIndex := PreviewList.ItemIndex; 162 | 163 | if FileIndex >= 0 then 164 | begin 165 | 166 | if FileIndex < MainForm.FMasterFileInfoList.Count then 167 | begin 168 | FileName := MainForm.FMasterFileInfoList[FileIndex].FilePath; 169 | 170 | with PreviewForm do 171 | begin 172 | VideoName := FileName; 173 | VideoIndex := FileIndex; 174 | SubIndex := MainForm.FMasterFileInfoList[FileIndex].SubtitleFileIndex; 175 | end; 176 | 177 | EffectForm.Enabled := False; 178 | PreviewForm.FromMainForm := False; 179 | PreviewForm.Show; 180 | end; 181 | 182 | end; 183 | 184 | end; 185 | 186 | procedure TEffectForm.SaveSettings; 187 | var 188 | SettingsFile: TIniFile; 189 | begin 190 | 191 | SettingsFile := TIniFile.Create(MainForm.FAppDataFolder + '\Settings.ini'); 192 | try 193 | SettingsFile.WriteBool('Effect', 'Deint', DeintEnblBtn.Checked); 194 | SettingsFile.WriteInteger('Effects', 'Deint2', DeintMethodList.ItemIndex); 195 | 196 | SettingsFile.WriteBool('Effect', 'Crop', CropEnable.Checked); 197 | SettingsFile.WriteString('Effect', 'CropW', CropWidthEdit.Text); 198 | SettingsFile.WriteString('Effect', 'CropH', CropHeightEdit.Text); 199 | SettingsFile.WriteString('Effect', 'CropX', CropXEdit.Text); 200 | SettingsFile.WriteString('Effect', 'CropY', CropYEdit.Text); 201 | 202 | SettingsFile.WriteBool('Effects', 'Vol', VolumeEnableBtn.Checked); 203 | SettingsFile.WriteString('Effects', 'VolM', VolumeMencoderEdit.Text); 204 | SettingsFile.WriteString('Effects', 'VolF', VolumeFFMpegEdit.Text); 205 | 206 | SettingsFile.WriteInteger('effect', 'rotate', RotateList.ItemIndex); 207 | finally 208 | SettingsFile.Free; 209 | end; 210 | 211 | end; 212 | 213 | procedure TEffectForm.VolumeEnableBtnClick(Sender: TObject); 214 | begin 215 | VolumeMencoderEdit.Enabled := VolumeEnableBtn.Checked; 216 | VolumeFFMpegEdit.Enabled := VolumeEnableBtn.Checked; 217 | end; 218 | 219 | end. 220 | 221 | -------------------------------------------------------------------------------- /Forms/UnitImageAudioMerger.dfm: -------------------------------------------------------------------------------- 1 | object ImageAudiotoVideoForm: TImageAudiotoVideoForm 2 | Left = 0 3 | Top = 0 4 | BorderIcons = [biSystemMenu] 5 | BorderStyle = bsSingle 6 | Caption = 'Image&Audio to Video' 7 | ClientHeight = 149 8 | ClientWidth = 645 9 | Color = 16708071 10 | DoubleBuffered = True 11 | Font.Charset = DEFAULT_CHARSET 12 | Font.Color = clWindowText 13 | Font.Height = -11 14 | Font.Name = 'Tahoma' 15 | Font.Style = [] 16 | OldCreateOrder = False 17 | Position = poMainFormCenter 18 | OnClose = FormClose 19 | OnCreate = FormCreate 20 | OnDestroy = FormDestroy 21 | OnShow = FormShow 22 | DesignSize = ( 23 | 645 24 | 149) 25 | PixelsPerInch = 96 26 | TextHeight = 13 27 | object sLabel1: TLabel 28 | Left = 8 29 | Top = 121 30 | Width = 404 31 | Height = 13 32 | Anchors = [akLeft, akBottom] 33 | Caption = 34 | 'Video/audio options set in the main window will be used (except ' + 35 | 'for encoder option).' 36 | end 37 | object ProgressLabel: TLabel 38 | Left = 601 39 | Top = 95 40 | Width = 36 41 | Height = 13 42 | Alignment = taCenter 43 | Anchors = [akRight, akBottom] 44 | AutoSize = False 45 | Caption = '0%' 46 | end 47 | object Label1: TLabel 48 | Left = 27 49 | Top = 12 50 | Width = 31 51 | Height = 13 52 | Caption = 'Audio:' 53 | end 54 | object Label2: TLabel 55 | Left = 24 56 | Top = 39 57 | Width = 34 58 | Height = 13 59 | Caption = 'Image:' 60 | end 61 | object Label3: TLabel 62 | Left = 20 63 | Top = 66 64 | Width = 38 65 | Height = 13 66 | Caption = 'Output:' 67 | end 68 | object OutputEdit: TEdit 69 | Left = 64 70 | Top = 62 71 | Width = 573 72 | Height = 21 73 | Anchors = [akLeft, akTop, akRight] 74 | Color = clWhite 75 | Font.Charset = DEFAULT_CHARSET 76 | Font.Color = clBlack 77 | Font.Height = -11 78 | Font.Name = 'Tahoma' 79 | Font.Style = [] 80 | ParentFont = False 81 | TabOrder = 1 82 | end 83 | object StartBtn: TBitBtn 84 | Left = 537 85 | Top = 116 86 | Width = 100 87 | Height = 25 88 | Anchors = [akRight, akBottom] 89 | Caption = 'Start' 90 | TabOrder = 3 91 | OnClick = StartBtnClick 92 | end 93 | object StopBtn: TBitBtn 94 | Left = 431 95 | Top = 116 96 | Width = 100 97 | Height = 25 98 | Anchors = [akRight, akBottom] 99 | Caption = 'Stop' 100 | Enabled = False 101 | TabOrder = 0 102 | OnClick = StopBtnClick 103 | end 104 | object ProgressBar: TProgressBar 105 | Left = 8 106 | Top = 93 107 | Width = 587 108 | Height = 17 109 | Anchors = [akLeft, akRight, akBottom] 110 | TabOrder = 2 111 | end 112 | object AudioEdit: TJvFilenameEdit 113 | Left = 64 114 | Top = 8 115 | Width = 573 116 | Height = 21 117 | TabOrder = 4 118 | Text = '' 119 | end 120 | object ImageEdit: TJvFilenameEdit 121 | Left = 64 122 | Top = 35 123 | Width = 573 124 | Height = 21 125 | TabOrder = 5 126 | Text = '' 127 | end 128 | object PosTimer: TTimer 129 | Enabled = False 130 | Interval = 500 131 | OnTimer = PosTimerTimer 132 | Left = 312 133 | Top = 72 134 | end 135 | end 136 | -------------------------------------------------------------------------------- /Forms/UnitLogs.dfm: -------------------------------------------------------------------------------- 1 | object LogForm: TLogForm 2 | Left = 0 3 | Top = 0 4 | BorderIcons = [biSystemMenu, biMaximize] 5 | Caption = 'Encoder Logs' 6 | ClientHeight = 402 7 | ClientWidth = 784 8 | Color = 16708071 9 | DoubleBuffered = True 10 | Font.Charset = DEFAULT_CHARSET 11 | Font.Color = clWindowText 12 | Font.Height = -11 13 | Font.Name = 'Tahoma' 14 | Font.Style = [] 15 | OldCreateOrder = False 16 | Position = poMainFormCenter 17 | ShowHint = True 18 | OnCreate = FormCreate 19 | OnDestroy = FormDestroy 20 | OnShow = FormShow 21 | DesignSize = ( 22 | 784 23 | 402) 24 | PixelsPerInch = 96 25 | TextHeight = 13 26 | object OkBtn: TButton 27 | Left = 656 28 | Top = 369 29 | Width = 120 30 | Height = 30 31 | Hint = 'Close this window' 32 | Anchors = [akRight, akBottom] 33 | Caption = 'Close' 34 | TabOrder = 0 35 | OnClick = OkBtnClick 36 | end 37 | object ClearBtn: TButton 38 | Left = 530 39 | Top = 369 40 | Width = 120 41 | Height = 30 42 | Hint = 'Clear current log' 43 | Anchors = [akRight, akBottom] 44 | Caption = 'Clear' 45 | TabOrder = 1 46 | OnClick = ClearBtnClick 47 | end 48 | object SaveBtn: TButton 49 | Left = 404 50 | Top = 369 51 | Width = 120 52 | Height = 30 53 | Hint = 'Save current log to a file' 54 | Anchors = [akRight, akBottom] 55 | Caption = 'Save' 56 | TabOrder = 2 57 | OnClick = SaveBtnClick 58 | end 59 | object Logs: TPageControl 60 | Left = 8 61 | Top = 8 62 | Width = 768 63 | Height = 355 64 | ActivePage = sTabSheet12 65 | Anchors = [akLeft, akTop, akRight, akBottom] 66 | TabOrder = 3 67 | object sTabSheet12: TTabSheet 68 | Caption = 'Main' 69 | object MainLog: TMemo 70 | Left = 0 71 | Top = 0 72 | Width = 760 73 | Height = 327 74 | Align = alClient 75 | Color = clWhite 76 | Font.Charset = DEFAULT_CHARSET 77 | Font.Color = clBlack 78 | Font.Height = -11 79 | Font.Name = 'Tahoma' 80 | Font.Style = [] 81 | ParentFont = False 82 | ReadOnly = True 83 | ScrollBars = ssBoth 84 | TabOrder = 0 85 | end 86 | end 87 | object sTabSheet1: TTabSheet 88 | Caption = 'Video/Audio Converter' 89 | ExplicitLeft = 0 90 | ExplicitTop = 0 91 | ExplicitWidth = 0 92 | ExplicitHeight = 0 93 | object VideoEncoderList: TMemo 94 | Left = 0 95 | Top = 21 96 | Width = 760 97 | Height = 306 98 | Align = alClient 99 | BorderStyle = bsNone 100 | Color = clWhite 101 | Font.Charset = DEFAULT_CHARSET 102 | Font.Color = clBlack 103 | Font.Height = -11 104 | Font.Name = 'Tahoma' 105 | Font.Style = [] 106 | ParentFont = False 107 | ReadOnly = True 108 | ScrollBars = ssBoth 109 | TabOrder = 0 110 | end 111 | object VideoEncoderLogsList: TComboBox 112 | Left = 0 113 | Top = 0 114 | Width = 760 115 | Height = 21 116 | Align = alTop 117 | Style = csDropDownList 118 | Color = clWhite 119 | Font.Charset = DEFAULT_CHARSET 120 | Font.Color = clBlack 121 | Font.Height = -11 122 | Font.Name = 'Tahoma' 123 | Font.Style = [] 124 | ItemIndex = 0 125 | ParentFont = False 126 | TabOrder = 1 127 | Text = 'Encoder 1' 128 | OnChange = VideoEncoderLogsListChange 129 | Items.Strings = ( 130 | 'Encoder 1' 131 | 'Encoder 2' 132 | 'Encoder 3' 133 | 'Encoder 4' 134 | 'Encoder 5' 135 | 'Encoder 6' 136 | 'Encoder 7' 137 | 'Encoder 8' 138 | 'Encoder 9' 139 | 'Encoder 10' 140 | 'Encoder 11' 141 | 'Encoder 12' 142 | 'Encoder 13' 143 | 'Encoder 14' 144 | 'Encoder 15' 145 | 'Encoder 16') 146 | end 147 | end 148 | object sTabSheet9: TTabSheet 149 | Caption = 'MPlayer' 150 | ExplicitLeft = 0 151 | ExplicitTop = 0 152 | ExplicitWidth = 0 153 | ExplicitHeight = 0 154 | object MPlayerLogList: TMemo 155 | Left = 0 156 | Top = 0 157 | Width = 760 158 | Height = 327 159 | Align = alClient 160 | ReadOnly = True 161 | ScrollBars = ssBoth 162 | TabOrder = 0 163 | end 164 | end 165 | object sTabSheet10: TTabSheet 166 | Caption = 'Others' 167 | ExplicitLeft = 0 168 | ExplicitTop = 0 169 | ExplicitWidth = 0 170 | ExplicitHeight = 0 171 | object OtherLog: TMemo 172 | Left = 0 173 | Top = 0 174 | Width = 760 175 | Height = 327 176 | Align = alClient 177 | Color = clWhite 178 | Font.Charset = DEFAULT_CHARSET 179 | Font.Color = clBlack 180 | Font.Height = -11 181 | Font.Name = 'Tahoma' 182 | Font.Style = [] 183 | ParentFont = False 184 | ReadOnly = True 185 | ScrollBars = ssBoth 186 | TabOrder = 0 187 | end 188 | end 189 | object sTabSheet11: TTabSheet 190 | Caption = 'Video Downloader' 191 | ExplicitLeft = 0 192 | ExplicitTop = 0 193 | ExplicitWidth = 0 194 | ExplicitHeight = 0 195 | object LogList: TComboBox 196 | Left = 0 197 | Top = 0 198 | Width = 760 199 | Height = 21 200 | Align = alTop 201 | Style = csDropDownList 202 | Color = clWhite 203 | Font.Charset = DEFAULT_CHARSET 204 | Font.Color = clBlack 205 | Font.Height = -11 206 | Font.Name = 'Tahoma' 207 | Font.Style = [] 208 | ParentFont = False 209 | TabOrder = 0 210 | OnChange = LogListChange 211 | Items.Strings = ( 212 | 'Download Process 1' 213 | 'Download Process 2' 214 | 'Download Process 3' 215 | 'Download Process 4' 216 | 'Download Process 5' 217 | 'Download Process 6' 218 | 'Download Process 7' 219 | 'Download Process 8' 220 | 'Command lines') 221 | end 222 | object DownloadLog: TMemo 223 | Left = 0 224 | Top = 21 225 | Width = 760 226 | Height = 306 227 | Align = alClient 228 | Color = clWhite 229 | Font.Charset = DEFAULT_CHARSET 230 | Font.Color = clBlack 231 | Font.Height = -11 232 | Font.Name = 'Tahoma' 233 | Font.Style = [] 234 | Lines.Strings = ( 235 | 'DownloadLog') 236 | ParentFont = False 237 | ReadOnly = True 238 | ScrollBars = ssBoth 239 | TabOrder = 1 240 | end 241 | end 242 | object sTabSheet2: TTabSheet 243 | Caption = 'DVD Ripper' 244 | ExplicitLeft = 0 245 | ExplicitTop = 0 246 | ExplicitWidth = 0 247 | ExplicitHeight = 0 248 | object DVDPages: TPageControl 249 | Left = 0 250 | Top = 0 251 | Width = 760 252 | Height = 327 253 | ActivePage = sTabSheet3 254 | Align = alClient 255 | TabOrder = 0 256 | object sTabSheet3: TTabSheet 257 | Caption = 'Console Output' 258 | ExplicitLeft = 0 259 | ExplicitTop = 0 260 | ExplicitWidth = 0 261 | ExplicitHeight = 0 262 | object DVDLog: TMemo 263 | Left = 0 264 | Top = 0 265 | Width = 752 266 | Height = 299 267 | Align = alClient 268 | Color = clWhite 269 | Font.Charset = DEFAULT_CHARSET 270 | Font.Color = clBlack 271 | Font.Height = -11 272 | Font.Name = 'Tahoma' 273 | Font.Style = [] 274 | ParentFont = False 275 | ReadOnly = True 276 | ScrollBars = ssBoth 277 | TabOrder = 0 278 | end 279 | end 280 | object sTabSheet4: TTabSheet 281 | Caption = 'Command lines' 282 | ExplicitLeft = 0 283 | ExplicitTop = 0 284 | ExplicitWidth = 0 285 | ExplicitHeight = 0 286 | object DVDCMDLog: TMemo 287 | Left = 0 288 | Top = 0 289 | Width = 752 290 | Height = 299 291 | Align = alClient 292 | Color = clWhite 293 | Font.Charset = DEFAULT_CHARSET 294 | Font.Color = clBlack 295 | Font.Height = -11 296 | Font.Name = 'Tahoma' 297 | Font.Style = [] 298 | ParentFont = False 299 | ReadOnly = True 300 | ScrollBars = ssBoth 301 | TabOrder = 0 302 | end 303 | end 304 | end 305 | end 306 | end 307 | object SaveDialog: TSaveDialog 308 | DefaultExt = '.txt' 309 | Filter = 'Text Files|*.txt|All Files|*.*' 310 | Options = [ofOverwritePrompt, ofHideReadOnly, ofEnableSizing] 311 | Left = 152 312 | Top = 200 313 | end 314 | object ClearPopup: TPopupMenu 315 | Left = 208 316 | Top = 104 317 | object ClearSelected1: TMenuItem 318 | Caption = 'Clear Selected' 319 | OnClick = ClearSelected1Click 320 | end 321 | object ClearAll1: TMenuItem 322 | Caption = 'Clear All' 323 | OnClick = ClearAll1Click 324 | end 325 | end 326 | end 327 | -------------------------------------------------------------------------------- /Forms/UnitLogs.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitLogs; 21 | 22 | interface 23 | 24 | uses 25 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 26 | Dialogs, StdCtrls, Buttons, ComCtrls, Menus, System.Types; 27 | 28 | type 29 | TLogForm = class(TForm) 30 | OkBtn: TButton; 31 | ClearBtn: TButton; 32 | SaveBtn: TButton; 33 | SaveDialog: TSaveDialog; 34 | ClearPopup: TPopupMenu; 35 | ClearSelected1: TMenuItem; 36 | ClearAll1: TMenuItem; 37 | VideoEncoderList: TMemo; 38 | MPlayerLogList: TMemo; 39 | Logs: TPageControl; 40 | sTabSheet1: TTabSheet; 41 | sTabSheet9: TTabSheet; 42 | sTabSheet10: TTabSheet; 43 | OtherLog: TMemo; 44 | sTabSheet11: TTabSheet; 45 | LogList: TComboBox; 46 | DownloadLog: TMemo; 47 | sTabSheet12: TTabSheet; 48 | MainLog: TMemo; 49 | VideoEncoderLogsList: TComboBox; 50 | sTabSheet2: TTabSheet; 51 | DVDPages: TPageControl; 52 | sTabSheet3: TTabSheet; 53 | sTabSheet4: TTabSheet; 54 | DVDLog: TMemo; 55 | DVDCMDLog: TMemo; 56 | procedure FormCreate(Sender: TObject); 57 | procedure OkBtnClick(Sender: TObject); 58 | procedure SaveBtnClick(Sender: TObject); 59 | procedure ClearAll1Click(Sender: TObject); 60 | procedure ClearBtnClick(Sender: TObject); 61 | procedure FormShow(Sender: TObject); 62 | procedure ClearSelected1Click(Sender: TObject); 63 | procedure LogListChange(Sender: TObject); 64 | procedure FormDestroy(Sender: TObject); 65 | procedure VideoEncoderLogsListChange(Sender: TObject); 66 | private 67 | { Private declarations } 68 | public 69 | { Public declarations } 70 | FEncoderLogs: array[0..15] of TStringList; 71 | end; 72 | 73 | var 74 | LogForm: TLogForm; 75 | 76 | implementation 77 | 78 | uses 79 | UnitMain; 80 | 81 | {$R *.dfm} 82 | 83 | procedure TLogForm.ClearAll1Click(Sender: TObject); 84 | var 85 | I: Integer; 86 | begin 87 | MainLog.Lines.Clear; 88 | for I := Low(FEncoderLogs) to High(FEncoderLogs) do 89 | begin 90 | FEncoderLogs[i].Clear; 91 | end; 92 | VideoEncoderList.Lines.Clear; 93 | MPlayerLogList.Lines.Clear; 94 | OtherLog.Lines.Clear; 95 | DownloadLog.Lines.Clear; 96 | DVDLog.Lines.Clear; 97 | DVDCMDLog.Lines.Clear; 98 | end; 99 | 100 | procedure TLogForm.ClearBtnClick(Sender: TObject); 101 | var 102 | P: TPoint; 103 | begin 104 | P := ClearBtn.ClientToScreen(Point(0, 0)); 105 | ClearPopup.Popup(P.X, P.Y + ClearBtn.Height) 106 | end; 107 | 108 | procedure TLogForm.ClearSelected1Click(Sender: TObject); 109 | begin 110 | case Logs.ActivePageIndex - 1 of 111 | 0: 112 | begin 113 | MainLog.Lines.Clear; 114 | end; 115 | 1: 116 | begin 117 | FEncoderLogs[VideoEncoderLogsList.ItemIndex].Clear; 118 | VideoEncoderList.Lines.Clear; 119 | end; 120 | 2: 121 | begin 122 | MPlayerLogList.Lines.Clear; 123 | end; 124 | 3: 125 | begin 126 | OtherLog.Lines.Clear; 127 | end; 128 | 4: 129 | begin 130 | DownloadLog.Lines.Clear; 131 | end; 132 | 5: 133 | begin 134 | case DVDPages.ActivePageIndex of 135 | 0: 136 | DVDLog.Lines.Clear; 137 | 1: 138 | DVDCMDLog.Lines.Clear; 139 | end; 140 | end; 141 | end; 142 | end; 143 | 144 | procedure TLogForm.FormCreate(Sender: TObject); 145 | var 146 | I: Integer; 147 | begin 148 | // encoder logs 149 | for I := Low(FEncoderLogs) to High(FEncoderLogs) do 150 | begin 151 | FEncoderLogs[i] := TStringList.Create; 152 | FEncoderLogs[i].Add(Format(' Encoder %d log', [i + 1])); 153 | end; 154 | 155 | MPlayerLogList.Lines.Add(' Mplayer Log'); 156 | end; 157 | 158 | procedure TLogForm.FormDestroy(Sender: TObject); 159 | var 160 | I: Integer; 161 | begin 162 | for I := Low(FEncoderLogs) to High(FEncoderLogs) do 163 | begin 164 | FEncoderLogs[i].Free; 165 | end; 166 | end; 167 | 168 | procedure TLogForm.FormShow(Sender: TObject); 169 | var 170 | I: Integer; 171 | begin 172 | Logs.Enabled := False; 173 | try 174 | // reset 175 | for I := Low(FEncoderLogs) to High(FEncoderLogs) do 176 | begin 177 | FEncoderLogs[i].Clear; 178 | end; 179 | // load command lines and console output 180 | VideoEncoderLogsListChange(Self); 181 | 182 | // generate logs first 183 | MainForm.SaveDownloadLogs; 184 | // load selected log if it exists 185 | LogListChange(Self); 186 | 187 | // dvd encoder log 188 | DVDLog.Lines.Clear; 189 | DVDLog.Lines.AddStrings(MainForm.FDVDRipperProcess.GetConsoleOutput); 190 | finally 191 | Logs.Enabled := True; 192 | Self.Width := Self.Width + 1; 193 | Self.Width := Self.Width - 1; 194 | end; 195 | end; 196 | 197 | procedure TLogForm.LogListChange(Sender: TObject); 198 | begin 199 | // load selected log 200 | DownloadLog.Lines.Clear; 201 | if LogList.ItemIndex = (LogList.Items.Count - 1) then 202 | begin 203 | if FileExists(MainForm.FLogFolder + '\cmd.txt') then 204 | begin 205 | DownloadLog.Lines.LoadFromFile(MainForm.FLogFolder + '\cmd.txt'); 206 | end; 207 | end 208 | else 209 | begin 210 | if FileExists(MainForm.FLogFolder + '\' + FloatToStr(LogList.ItemIndex + 1) + 'log.txt') then 211 | begin 212 | DownloadLog.Lines.LoadFromFile(MainForm.FLogFolder + '\' + FloatToStr(LogList.ItemIndex + 1) + 'log.txt'); 213 | end; 214 | end; 215 | end; 216 | 217 | procedure TLogForm.OkBtnClick(Sender: TObject); 218 | begin 219 | LogForm.Close; 220 | end; 221 | 222 | procedure TLogForm.SaveBtnClick(Sender: TObject); 223 | begin 224 | SaveDialog.FileName := 'EncoderLog' + FloatToStr(Logs.ActivePageIndex) + '.txt'; 225 | if SaveDialog.Execute then 226 | begin 227 | case Logs.ActivePageIndex - 1 of 228 | 0: 229 | begin 230 | MainLog.Lines.SaveToFile(SaveDialog.FileName, TEncoding.UTF8); 231 | end; 232 | 1: 233 | begin 234 | FEncoderLogs[VideoEncoderLogsList.ItemIndex].SaveToFile(SaveDialog.FileName, TEncoding.UTF8); 235 | end; 236 | 2: 237 | begin 238 | SaveDialog.FileName := 'MPlayerLog.txt'; 239 | MPlayerLogList.Lines.SaveToFile(SaveDialog.FileName, TEncoding.UTF8); 240 | end; 241 | 3: 242 | begin 243 | OtherLog.Lines.SaveToFile(SaveDialog.FileName, TEncoding.UTF8); 244 | end; 245 | 4: 246 | begin 247 | DownloadLog.Lines.SaveToFile(SaveDialog.FileName, TEncoding.UTF8); 248 | end; 249 | 5: 250 | begin 251 | case DVDPages.ActivePageIndex of 252 | 0: 253 | DVDLog.Lines.SaveToFile(SaveDialog.FileName, TEncoding.UTF8); 254 | 1: 255 | DVDCMDLog.Lines.SaveToFile(SaveDialog.FileName, TEncoding.UTF8); 256 | end; 257 | end; 258 | end; 259 | end; 260 | end; 261 | 262 | procedure TLogForm.VideoEncoderLogsListChange(Sender: TObject); 263 | var 264 | i: integer; 265 | begin 266 | VideoEncoderList.Lines.Clear; 267 | VideoEncoderList.Lines.Add(Format('Encoder %d log', [VideoEncoderLogsList.ItemIndex + 1])); 268 | VideoEncoderList.Lines.Add(Format('Encoder %d command lines:', [VideoEncoderLogsList.ItemIndex + 1])); 269 | for I := 0 to MainForm.FEncoders[VideoEncoderLogsList.ItemIndex].EncodeJobs.Count - 1 do 270 | begin 271 | VideoEncoderList.Lines.Add(MainForm.FEncoders[VideoEncoderLogsList.ItemIndex].EncodeJobs[i].CommandLine); 272 | end; 273 | VideoEncoderList.Lines.Add(''); 274 | VideoEncoderList.Lines.Add(Format('Encoder %d console outputs:', [VideoEncoderLogsList.ItemIndex + 1])); 275 | VideoEncoderList.Lines.AddStrings(MainForm.FEncoders[VideoEncoderLogsList.ItemIndex].GetConsoleOutput); 276 | end; 277 | 278 | end. 279 | 280 | -------------------------------------------------------------------------------- /Forms/UnitProperties.dfm: -------------------------------------------------------------------------------- 1 | object InfoForm: TInfoForm 2 | Left = 0 3 | Top = 0 4 | BorderIcons = [biSystemMenu] 5 | Caption = 'Properties' 6 | ClientHeight = 320 7 | ClientWidth = 604 8 | Color = 16708071 9 | DoubleBuffered = True 10 | Font.Charset = DEFAULT_CHARSET 11 | Font.Color = clWindowText 12 | Font.Height = -11 13 | Font.Name = 'Tahoma' 14 | Font.Style = [] 15 | OldCreateOrder = False 16 | Position = poMainFormCenter 17 | OnClose = FormClose 18 | OnCreate = FormCreate 19 | OnDestroy = FormDestroy 20 | OnResize = FormResize 21 | DesignSize = ( 22 | 604 23 | 320) 24 | PixelsPerInch = 96 25 | TextHeight = 13 26 | object OkBtn: TButton 27 | Left = 496 28 | Top = 287 29 | Width = 100 30 | Height = 25 31 | Anchors = [akRight, akBottom] 32 | Caption = 'Close' 33 | TabOrder = 0 34 | OnClick = OkBtnClick 35 | end 36 | object Infos: TListView 37 | Left = 8 38 | Top = 8 39 | Width = 588 40 | Height = 273 41 | Anchors = [akLeft, akTop, akRight, akBottom] 42 | Columns = < 43 | item 44 | Caption = 'Field' 45 | Width = 200 46 | end 47 | item 48 | Caption = 'Value' 49 | Width = 350 50 | end> 51 | Font.Charset = DEFAULT_CHARSET 52 | Font.Color = clBlack 53 | Font.Height = -11 54 | Font.Name = 'Tahoma' 55 | Font.Style = [] 56 | ReadOnly = True 57 | RowSelect = True 58 | ParentFont = False 59 | ShowWorkAreas = True 60 | TabOrder = 1 61 | ViewStyle = vsReport 62 | end 63 | object SaveBtn: TButton 64 | Left = 8 65 | Top = 287 66 | Width = 100 67 | Height = 25 68 | Anchors = [akLeft, akBottom] 69 | Caption = 'Save' 70 | TabOrder = 2 71 | OnClick = SaveBtnClick 72 | end 73 | object SaveDialog1: TSaveDialog 74 | FileName = 'TEncoderFileInfo.txt' 75 | Filter = 'Text Files|*.txt' 76 | Left = 176 77 | Top = 104 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /Forms/UnitProperties.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitProperties; 21 | 22 | interface 23 | 24 | uses 25 | Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 26 | Dialogs, StdCtrls, Buttons, Vcl.ComCtrls; 27 | 28 | type 29 | TInfoForm = class(TForm) 30 | OkBtn: TButton; 31 | Infos: TListView; 32 | SaveBtn: TButton; 33 | SaveDialog1: TSaveDialog; 34 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 35 | procedure OkBtnClick(Sender: TObject); 36 | procedure FormCreate(Sender: TObject); 37 | procedure FormDestroy(Sender: TObject); 38 | procedure SaveBtnClick(Sender: TObject); 39 | procedure FormResize(Sender: TObject); 40 | private 41 | { Private declarations } 42 | public 43 | InfoList: TStringList; 44 | end; 45 | 46 | var 47 | InfoForm: TInfoForm; 48 | 49 | implementation 50 | 51 | uses UnitMain; 52 | 53 | {$R *.dfm} 54 | 55 | procedure TInfoForm.FormClose(Sender: TObject; var Action: TCloseAction); 56 | begin 57 | 58 | InfoList.Clear; 59 | Infos.Items.Clear; 60 | 61 | MainForm.Enabled := True; 62 | MainForm.BringToFront; 63 | 64 | end; 65 | 66 | procedure TInfoForm.FormCreate(Sender: TObject); 67 | begin 68 | 69 | InfoList := TStringList.Create;; 70 | end; 71 | 72 | procedure TInfoForm.FormDestroy(Sender: TObject); 73 | begin 74 | 75 | FreeAndNil(InfoList); 76 | 77 | end; 78 | 79 | procedure TInfoForm.FormResize(Sender: TObject); 80 | begin 81 | Infos.Columns[1].Width := Infos.ClientWidth - Infos.Columns[0].Width; 82 | end; 83 | 84 | procedure TInfoForm.OkBtnClick(Sender: TObject); 85 | begin 86 | 87 | InfoForm.Close; 88 | 89 | end; 90 | 91 | procedure TInfoForm.SaveBtnClick(Sender: TObject); 92 | begin 93 | 94 | if SaveDialog1.Execute then 95 | begin 96 | InfoList.SaveToFile(SaveDialog1.FileName); 97 | end; 98 | 99 | end; 100 | 101 | end. -------------------------------------------------------------------------------- /Forms/UnitRangeEditor.pas: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozok/TEncoder/eecbd0c522c6de0887680eb0771eeccfaa4b71db/Forms/UnitRangeEditor.pas -------------------------------------------------------------------------------- /Forms/UnitVideotoGIF.dfm: -------------------------------------------------------------------------------- 1 | object VideoToGIFForm: TVideoToGIFForm 2 | Left = 0 3 | Top = 0 4 | BorderStyle = bsSizeToolWin 5 | Caption = 'Video to GIF' 6 | ClientHeight = 270 7 | ClientWidth = 784 8 | Color = 16708071 9 | DoubleBuffered = True 10 | Font.Charset = DEFAULT_CHARSET 11 | Font.Color = clWindowText 12 | Font.Height = -11 13 | Font.Name = 'Tahoma' 14 | Font.Style = [] 15 | OldCreateOrder = False 16 | Position = poMainFormCenter 17 | OnClose = FormClose 18 | OnCloseQuery = FormCloseQuery 19 | OnCreate = FormCreate 20 | OnDestroy = FormDestroy 21 | OnShow = FormShow 22 | DesignSize = ( 23 | 784 24 | 270) 25 | PixelsPerInch = 96 26 | TextHeight = 13 27 | object WidthEdit: TJvSpinEdit 28 | Left = 64 29 | Top = 62 30 | Width = 75 31 | Height = 21 32 | Value = 320.000000000000000000 33 | Color = clWhite 34 | Font.Charset = DEFAULT_CHARSET 35 | Font.Color = clBlack 36 | Font.Height = -11 37 | Font.Name = 'Tahoma' 38 | Font.Style = [] 39 | ParentFont = False 40 | TabOrder = 0 41 | end 42 | object HeightEdit: TJvSpinEdit 43 | Left = 184 44 | Top = 62 45 | Width = 75 46 | Height = 21 47 | Value = 240.000000000000000000 48 | Color = clWhite 49 | Font.Charset = DEFAULT_CHARSET 50 | Font.Color = clBlack 51 | Font.Height = -11 52 | Font.Name = 'Tahoma' 53 | Font.Style = [] 54 | ParentFont = False 55 | TabOrder = 1 56 | end 57 | object KeepAspectBtn: TCheckBox 58 | Left = 265 59 | Top = 62 60 | Width = 110 61 | Height = 19 62 | Caption = 'Keep aspect ratio' 63 | TabOrder = 2 64 | OnClick = KeepAspectBtnClick 65 | end 66 | object DelayEdit: TJvSpinEdit 67 | Left = 701 68 | Top = 62 69 | Width = 75 70 | Height = 21 71 | Value = 20.000000000000000000 72 | Color = clWhite 73 | Font.Charset = DEFAULT_CHARSET 74 | Font.Color = clBlack 75 | Font.Height = -11 76 | Font.Name = 'Tahoma' 77 | Font.Style = [] 78 | Anchors = [akTop, akRight] 79 | ParentFont = False 80 | TabOrder = 3 81 | end 82 | object StartBar: TTrackBar 83 | Left = 145 84 | Top = 116 85 | Width = 631 86 | Height = 25 87 | Anchors = [akLeft, akTop, akRight] 88 | ShowSelRange = False 89 | TabOrder = 4 90 | TickMarks = tmBoth 91 | TickStyle = tsNone 92 | OnChange = StartBarChange 93 | end 94 | object EndBar: TTrackBar 95 | Left = 145 96 | Top = 147 97 | Width = 631 98 | Height = 25 99 | Anchors = [akLeft, akTop, akRight] 100 | ShowSelRange = False 101 | TabOrder = 5 102 | TickMarks = tmBoth 103 | TickStyle = tsNone 104 | OnChange = EndBarChange 105 | end 106 | object StartEdit: TEdit 107 | Left = 64 108 | Top = 118 109 | Width = 75 110 | Height = 21 111 | Alignment = taCenter 112 | Color = clWhite 113 | Font.Charset = DEFAULT_CHARSET 114 | Font.Color = clBlack 115 | Font.Height = -11 116 | Font.Name = 'Tahoma' 117 | Font.Style = [] 118 | ParentFont = False 119 | ReadOnly = True 120 | TabOrder = 6 121 | Text = '00:00:00.000' 122 | end 123 | object EndEdit: TEdit 124 | Left = 64 125 | Top = 149 126 | Width = 75 127 | Height = 21 128 | Alignment = taCenter 129 | Color = clWhite 130 | Font.Charset = DEFAULT_CHARSET 131 | Font.Color = clBlack 132 | Font.Height = -11 133 | Font.Name = 'Tahoma' 134 | Font.Style = [] 135 | ParentFont = False 136 | ReadOnly = True 137 | TabOrder = 7 138 | Text = '00:00:00.000' 139 | end 140 | object StartBtn: TButton 141 | Left = 676 142 | Top = 232 143 | Width = 100 144 | Height = 30 145 | Anchors = [akRight, akBottom] 146 | Caption = 'Start' 147 | TabOrder = 8 148 | OnClick = StartBtnClick 149 | end 150 | object StopBtn: TButton 151 | Left = 570 152 | Top = 232 153 | Width = 100 154 | Height = 30 155 | Anchors = [akRight, akBottom] 156 | Caption = 'Stop' 157 | Enabled = False 158 | TabOrder = 9 159 | OnClick = StopBtnClick 160 | end 161 | object ResetBtn: TButton 162 | Left = 8 163 | Top = 232 164 | Width = 100 165 | Height = 30 166 | Anchors = [akLeft, akBottom] 167 | Caption = 'Reset' 168 | TabOrder = 10 169 | end 170 | object DurationEdit: TEdit 171 | Left = 701 172 | Top = 178 173 | Width = 75 174 | Height = 21 175 | Anchors = [akTop, akRight] 176 | Color = clWhite 177 | Font.Charset = DEFAULT_CHARSET 178 | Font.Color = clBlack 179 | Font.Height = -11 180 | Font.Name = 'Tahoma' 181 | Font.Style = [] 182 | ParentFont = False 183 | ReadOnly = True 184 | TabOrder = 11 185 | Text = '00:00:00.000' 186 | end 187 | object ConsoleEdit: TEdit 188 | Left = 8 189 | Top = 205 190 | Width = 768 191 | Height = 21 192 | Alignment = taCenter 193 | Anchors = [akLeft, akRight, akBottom] 194 | Color = clWhite 195 | Font.Charset = DEFAULT_CHARSET 196 | Font.Color = clBlack 197 | Font.Height = -11 198 | Font.Name = 'Tahoma' 199 | Font.Style = [] 200 | ParentFont = False 201 | ReadOnly = True 202 | TabOrder = 12 203 | end 204 | object InfoEdit: TEdit 205 | Left = 362 206 | Top = 237 207 | Width = 206 208 | Height = 21 209 | Alignment = taCenter 210 | Anchors = [akRight, akBottom] 211 | Color = clWhite 212 | Font.Charset = DEFAULT_CHARSET 213 | Font.Color = clBlack 214 | Font.Height = -11 215 | Font.Name = 'Tahoma' 216 | Font.Style = [] 217 | ParentFont = False 218 | ReadOnly = True 219 | TabOrder = 14 220 | end 221 | object MemoryEdit: TJvSpinEdit 222 | Left = 145 223 | Top = 89 224 | Width = 114 225 | Height = 21 226 | Value = 512.000000000000000000 227 | Color = clWhite 228 | Font.Charset = DEFAULT_CHARSET 229 | Font.Color = clBlack 230 | Font.Height = -11 231 | Font.Name = 'Tahoma' 232 | Font.Style = [] 233 | ParentFont = False 234 | TabOrder = 13 235 | end 236 | object FPSEdit: TJvSpinEdit 237 | Left = 701 238 | Top = 89 239 | Width = 75 240 | Height = 21 241 | Value = 5.000000000000000000 242 | Color = clWhite 243 | Font.Charset = DEFAULT_CHARSET 244 | Font.Color = clBlack 245 | Font.Height = -11 246 | Font.Name = 'Tahoma' 247 | Font.Style = [] 248 | Anchors = [akTop, akRight] 249 | ParentFont = False 250 | TabOrder = 15 251 | end 252 | object SourceEdit: TJvFilenameEdit 253 | Left = 64 254 | Top = 8 255 | Width = 712 256 | Height = 21 257 | TabOrder = 17 258 | Text = 'SourceEdit' 259 | end 260 | object DestEdit: TJvFilenameEdit 261 | Left = 64 262 | Top = 35 263 | Width = 712 264 | Height = 21 265 | TabOrder = 16 266 | Text = 'DestEdit' 267 | end 268 | object ProgressBar1: TProgressBar 269 | Left = 114 270 | Top = 232 271 | Width = 242 272 | Height = 30 273 | TabOrder = 18 274 | end 275 | object PosTimer: TTimer 276 | Enabled = False 277 | Interval = 500 278 | OnTimer = PosTimerTimer 279 | Left = 408 280 | Top = 8 281 | end 282 | end 283 | -------------------------------------------------------------------------------- /Forms/UnitWatermark.dfm: -------------------------------------------------------------------------------- 1 | object WatermarkForm: TWatermarkForm 2 | Left = 0 3 | Top = 0 4 | BorderIcons = [biSystemMenu] 5 | BorderStyle = bsSingle 6 | Caption = 'Watermark' 7 | ClientHeight = 170 8 | ClientWidth = 645 9 | Color = 16708071 10 | DoubleBuffered = True 11 | Font.Charset = DEFAULT_CHARSET 12 | Font.Color = clWindowText 13 | Font.Height = -11 14 | Font.Name = 'Tahoma' 15 | Font.Style = [] 16 | OldCreateOrder = False 17 | Position = poOwnerFormCenter 18 | OnClose = FormClose 19 | OnCreate = FormCreate 20 | OnDestroy = FormDestroy 21 | OnShow = FormShow 22 | DesignSize = ( 23 | 645 24 | 170) 25 | PixelsPerInch = 96 26 | TextHeight = 13 27 | object sLabel1: TLabel 28 | Left = 8 29 | Top = 142 30 | Width = 404 31 | Height = 13 32 | Anchors = [akLeft, akBottom] 33 | Caption = 34 | 'Video/audio options set in the main window will be used (except ' + 35 | 'for encoder option).' 36 | ExplicitTop = 320 37 | end 38 | object ProgressLabel: TLabel 39 | Left = 601 40 | Top = 116 41 | Width = 36 42 | Height = 13 43 | Alignment = taCenter 44 | Anchors = [akRight, akBottom] 45 | AutoSize = False 46 | Caption = '0%' 47 | ExplicitTop = 294 48 | end 49 | object PositionList: TComboBox 50 | Left = 56 51 | Top = 89 52 | Width = 121 53 | Height = 21 54 | Style = csDropDownList 55 | Color = clWhite 56 | Font.Charset = DEFAULT_CHARSET 57 | Font.Color = clBlack 58 | Font.Height = -11 59 | Font.Name = 'Tahoma' 60 | Font.Style = [] 61 | ParentFont = False 62 | TabOrder = 0 63 | OnChange = PositionListChange 64 | Items.Strings = ( 65 | 'Top left' 66 | 'Top centre' 67 | 'Top right' 68 | 'Centre left' 69 | 'Centre' 70 | 'Centre right' 71 | 'Bottom left' 72 | 'Bottom centre' 73 | 'Bottom right' 74 | 'Custom') 75 | end 76 | object XEdit: TJvSpinEdit 77 | Left = 232 78 | Top = 89 79 | Width = 75 80 | Height = 21 81 | Color = clWhite 82 | Enabled = False 83 | Font.Charset = DEFAULT_CHARSET 84 | Font.Color = clBlack 85 | Font.Height = -11 86 | Font.Name = 'Tahoma' 87 | Font.Style = [] 88 | ParentFont = False 89 | TabOrder = 1 90 | end 91 | object YEdit: TJvSpinEdit 92 | Left = 328 93 | Top = 89 94 | Width = 75 95 | Height = 21 96 | Color = clWhite 97 | Enabled = False 98 | Font.Charset = DEFAULT_CHARSET 99 | Font.Color = clBlack 100 | Font.Height = -11 101 | Font.Name = 'Tahoma' 102 | Font.Style = [] 103 | ParentFont = False 104 | TabOrder = 2 105 | end 106 | object OutputEdit: TEdit 107 | Left = 56 108 | Top = 62 109 | Width = 581 110 | Height = 21 111 | Anchors = [akLeft, akTop, akRight] 112 | Color = clWhite 113 | Font.Charset = DEFAULT_CHARSET 114 | Font.Color = clBlack 115 | Font.Height = -11 116 | Font.Name = 'Tahoma' 117 | Font.Style = [] 118 | ParentFont = False 119 | TabOrder = 4 120 | end 121 | object StartBtn: TBitBtn 122 | Left = 537 123 | Top = 137 124 | Width = 100 125 | Height = 25 126 | Anchors = [akRight, akBottom] 127 | Caption = 'Start' 128 | TabOrder = 5 129 | OnClick = StartBtnClick 130 | end 131 | object StopBtn: TBitBtn 132 | Left = 431 133 | Top = 137 134 | Width = 100 135 | Height = 25 136 | Anchors = [akRight, akBottom] 137 | Caption = 'Stop' 138 | Enabled = False 139 | TabOrder = 3 140 | OnClick = StopBtnClick 141 | end 142 | object VideoPathEdit: TJvFilenameEdit 143 | Left = 56 144 | Top = 8 145 | Width = 581 146 | Height = 21 147 | TabOrder = 7 148 | Text = '' 149 | end 150 | object ImagePathEdit: TJvFilenameEdit 151 | Left = 56 152 | Top = 35 153 | Width = 581 154 | Height = 21 155 | TabOrder = 6 156 | Text = '' 157 | end 158 | object ProgressBar: TProgressBar 159 | Left = 8 160 | Top = 114 161 | Width = 587 162 | Height = 17 163 | TabOrder = 8 164 | end 165 | object PosTimer: TTimer 166 | Enabled = False 167 | Interval = 500 168 | OnTimer = PosTimerTimer 169 | Left = 448 170 | Top = 56 171 | end 172 | end 173 | -------------------------------------------------------------------------------- /Forms/UnitYoutubedlUpdateChecker.dfm: -------------------------------------------------------------------------------- 1 | object YoutubedlUpdateChecker: TYoutubedlUpdateChecker 2 | Left = 0 3 | Top = 0 4 | BorderStyle = bsToolWindow 5 | Caption = 'Youtube-dl Update Checker' 6 | ClientHeight = 172 7 | ClientWidth = 645 8 | Color = clBtnFace 9 | DoubleBuffered = True 10 | Font.Charset = DEFAULT_CHARSET 11 | Font.Color = clWindowText 12 | Font.Height = -11 13 | Font.Name = 'Tahoma' 14 | Font.Style = [] 15 | OldCreateOrder = False 16 | Position = poMainFormCenter 17 | OnClose = FormClose 18 | OnShow = FormShow 19 | DesignSize = ( 20 | 645 21 | 172) 22 | PixelsPerInch = 96 23 | TextHeight = 13 24 | object OutputList: TMemo 25 | Left = 8 26 | Top = 8 27 | Width = 629 28 | Height = 125 29 | Anchors = [akLeft, akTop, akRight, akBottom] 30 | Color = clWhite 31 | Font.Charset = DEFAULT_CHARSET 32 | Font.Color = clBlack 33 | Font.Height = -11 34 | Font.Name = 'Tahoma' 35 | Font.Style = [] 36 | ParentFont = False 37 | ReadOnly = True 38 | ScrollBars = ssBoth 39 | TabOrder = 0 40 | end 41 | object CloseBtn: TButton 42 | Left = 562 43 | Top = 139 44 | Width = 75 45 | Height = 25 46 | Anchors = [akRight, akBottom] 47 | Caption = 'Close' 48 | TabOrder = 1 49 | OnClick = CloseBtnClick 50 | end 51 | object ProgressBar: TProgressBar 52 | Left = 8 53 | Top = 142 54 | Width = 537 55 | Height = 17 56 | TabOrder = 2 57 | end 58 | object Downloader: TIdHTTP 59 | IOHandler = IdSSLIOHandlerSocketOpenSSL1 60 | OnWork = DownloaderWork 61 | OnWorkBegin = DownloaderWorkBegin 62 | OnWorkEnd = DownloaderWorkEnd 63 | AllowCookies = True 64 | ProxyParams.BasicAuthentication = False 65 | ProxyParams.ProxyPort = 0 66 | Request.ContentLength = -1 67 | Request.ContentRangeEnd = -1 68 | Request.ContentRangeStart = -1 69 | Request.ContentRangeInstanceLength = -1 70 | Request.Accept = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' 71 | Request.BasicAuthentication = False 72 | Request.UserAgent = 73 | 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, l' + 74 | 'ike Gecko) Chrome/46.0.2490.86 Safari/537.36 OPR/33.0.1990.115' 75 | Request.Ranges.Units = 'bytes' 76 | Request.Ranges = <> 77 | HTTPOptions = [hoForceEncodeParams] 78 | Left = 176 79 | Top = 16 80 | end 81 | object IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL 82 | MaxLineAction = maException 83 | Port = 0 84 | DefaultPort = 0 85 | SSLOptions.Mode = sslmUnassigned 86 | SSLOptions.VerifyMode = [] 87 | SSLOptions.VerifyDepth = 0 88 | Left = 56 89 | Top = 16 90 | end 91 | object UpdateThread: TJvThread 92 | Exclusive = True 93 | MaxCount = 0 94 | RunOnCreate = True 95 | FreeOnTerminate = True 96 | OnExecute = UpdateThreadExecute 97 | Left = 280 98 | Top = 24 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /Forms/UnitYoutubedlUpdateChecker.pas: -------------------------------------------------------------------------------- 1 | unit UnitYoutubedlUpdateChecker; 2 | 3 | interface 4 | 5 | uses 6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 7 | System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, 8 | IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, 9 | IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, IdThreadComponent, 10 | JvComponentBase, JvThread, Vcl.ComCtrls, Vcl.Samples.Gauges; 11 | 12 | type 13 | TYoutubedlUpdateChecker = class(TForm) 14 | OutputList: TMemo; 15 | CloseBtn: TButton; 16 | Downloader: TIdHTTP; 17 | IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL; 18 | UpdateThread: TJvThread; 19 | ProgressBar: TProgressBar; 20 | 21 | procedure CloseBtnClick(Sender: TObject); 22 | procedure FormClose(Sender: TObject; var Action: TCloseAction); 23 | procedure FormShow(Sender: TObject); 24 | procedure UpdateThreadExecute(Sender: TObject; Params: Pointer); 25 | procedure DownloaderWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); 26 | procedure DownloaderWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); 27 | procedure DownloaderWorkEnd(ASender: TObject; AWorkMode: TWorkMode); 28 | private 29 | { Private declarations } 30 | FWorkSize: int64; 31 | public 32 | { Public declarations } 33 | Path: string; 34 | LocalVersion: string; 35 | end; 36 | 37 | var 38 | YoutubedlUpdateChecker: TYoutubedlUpdateChecker; 39 | 40 | const 41 | DOWNLOAD_PAGE_URL = 'https://rg3.github.io/youtube-dl/download.html'; 42 | 43 | implementation 44 | 45 | {$R *.dfm} 46 | 47 | uses 48 | UnitMain; 49 | 50 | procedure TYoutubedlUpdateChecker.DownloaderWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); 51 | var 52 | LPercent: integer; 53 | begin 54 | if FWorkSize > 0 then 55 | begin 56 | LPercent := (100 * AWorkCount) div FWorkSize; 57 | ProgressBar.Position := LPercent; 58 | end; 59 | end; 60 | 61 | procedure TYoutubedlUpdateChecker.DownloaderWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); 62 | begin 63 | FWorkSize := AWorkCountMax; 64 | end; 65 | 66 | procedure TYoutubedlUpdateChecker.DownloaderWorkEnd(ASender: TObject; AWorkMode: TWorkMode); 67 | var 68 | LPath: string; 69 | begin 70 | LPath := ChangeFileExt(Path, '.tmp'); 71 | if FileExists(LPath) then 72 | begin 73 | 74 | end; 75 | end; 76 | 77 | procedure TYoutubedlUpdateChecker.FormClose(Sender: TObject; var Action: TCloseAction); 78 | begin 79 | if Downloader.Connected then 80 | begin 81 | Downloader.Disconnect; 82 | end; 83 | MainForm.Enabled := True; 84 | end; 85 | 86 | procedure TYoutubedlUpdateChecker.FormShow(Sender: TObject); 87 | begin 88 | OutputList.Lines.Clear; 89 | ProgressBar.Position := 0; 90 | FWorkSize := 0; 91 | UpdateThread.Execute(nil); 92 | end; 93 | 94 | procedure TYoutubedlUpdateChecker.CloseBtnClick(Sender: TObject); 95 | begin 96 | Self.Close; 97 | end; 98 | 99 | procedure TYoutubedlUpdateChecker.UpdateThreadExecute(Sender: TObject; Params: Pointer); 100 | const 101 | MATCH_LINE = '">Windows exe'; 102 | VERSION_LINE = '

'; 104 | var 105 | LMS: TMemoryStream; 106 | LSR: TStreamReader; 107 | LLine: string; 108 | LPos: integer; 109 | LFS: TFileStream; 110 | LPath: string; // youtube-dl.tmp 111 | FContinue: Boolean; 112 | LExeLine: string; 113 | begin 114 | OutputList.Lines.Add('[' + DateTimeToStr(Now) + '] Starting the update process.'); 115 | CloseBtn.Enabled := False; 116 | try 117 | LMS := TMemoryStream.Create; 118 | try 119 | OutputList.Lines.Add('[' + DateTimeToStr(Now) + '] Checking for the update...'); 120 | Downloader.Get(DOWNLOAD_PAGE_URL, LMS); 121 | LMS.Seek(0, soBeginning); 122 | LSR := TStreamReader.Create(LMS); 123 | try 124 | FContinue := True; 125 | while not LSR.EndOfStream do 126 | begin 127 | Application.ProcessMessages; 128 | LLine := LSR.ReadLine; 129 | 130 | // get the version number 131 | if LLine.contains(VERSION_LINE) then 132 | begin 133 | // if this string is longer than 0 it means called from 134 | // backend launcher 135 | if Length(LocalVersion) > 0 then 136 | begin 137 | LLine := LLine.Replace(VERSION_LINE, ''); 138 | 139 | LPos := Pos(VERSION_LINE_END, LLine); 140 | if LPos > -1 then 141 | begin 142 | LLine := LLine.Substring(0, LPos - 1); 143 | OutputList.Lines.Add('[' + DateTimeToStr(Now) + '] The Latest Version: ' + LLine); 144 | OutputList.Lines.Add('[' + DateTimeToStr(Now) + '] The Local Version: ' + LocalVersion.Trim); 145 | FContinue := Trim(LLine) <> Trim(LocalVersion); 146 | end; 147 | end; 148 | end; 149 | 150 | // get the exe link 151 | if LLine.contains(MATCH_LINE) then 152 | begin 153 | LExeLine := LLine; 154 | end; 155 | end; 156 | if FContinue then 157 | begin 158 | if LExeLine.Length > 0 then 159 | begin 160 | LPos := Pos(MATCH_LINE, LExeLine); 161 | LExeLine := LExeLine.Substring(0, LPos - 1); 162 | LExeLine := StringReplace(LExeLine, ' 2 | 3 | {F72119FD-2B1C-42AB-84D6-47C40ED1F105} 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Default.Personality.12 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /TEncoder_Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ozok/TEncoder/eecbd0c522c6de0887680eb0771eeccfaa4b71db/TEncoder_Icon.ico -------------------------------------------------------------------------------- /Units/DownloaderUnits/UnitCommonTypes.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitCommonTypes; 21 | 22 | interface 23 | 24 | uses 25 | Generics.Collections, Classes; 26 | 27 | type 28 | TUserPass = record 29 | UserName: string; 30 | Password: string; 31 | end; 32 | 33 | type 34 | TLinkType = (general = 0, soundcloud = 1); 35 | 36 | Type 37 | TDownloadItem = class(TObject) 38 | private 39 | FFormats: TStringList; 40 | FFormatIndex: Integer; 41 | FFormatIntegers: TStringList; 42 | FOutputExtensions: TStringList; 43 | FOutputExtensionIndex: Integer; 44 | FSubtitles: TStringList; 45 | FSubIndex: integer; 46 | FImagePath: string; 47 | FOutputFileName: string; 48 | FType: TLinkType; 49 | public 50 | property Formats: TStringList read FFormats write FFormats; 51 | property FormatIndex: Integer read FFormatIndex write FFormatIndex; 52 | property FormatIntegers: TStringList read FFormatIntegers write FFormatIntegers; 53 | property OutputExtensions: TStringList read FOutputExtensions write FOutputExtensions; 54 | property OutputExtensionIndex: Integer read FOutputExtensionIndex write FOutputExtensionIndex; 55 | property ImagePath: string read FImagePath write FImagePath; 56 | property OutputFileName: string read FOutputFileName write FOutputFileName; 57 | property Subtitles: TStringList read FSubtitles write FSubtitles; 58 | property SubIndex: integer read FSubIndex write FSubIndex; 59 | property LinkType: TLinkType read FType write FType; 60 | 61 | constructor Create; 62 | destructor Destroy; override; 63 | end; 64 | 65 | TDownloadItemList = TList; 66 | 67 | implementation 68 | 69 | { TDownloadItem } 70 | 71 | constructor TDownloadItem.Create; 72 | begin 73 | FFormats := TStringList.Create; 74 | FFormatIntegers := TStringList.Create; 75 | FOutputExtensions := TStringList.Create; 76 | FSubtitles := TStringList.Create; 77 | FFormatIndex := -1; 78 | FSubIndex := -1; 79 | FType := general; 80 | end; 81 | 82 | destructor TDownloadItem.Destroy; 83 | begin 84 | FFormats.Free; 85 | FFormatIntegers.Free; 86 | FOutputExtensions.Free; 87 | FSubtitles.Free; 88 | inherited; 89 | end; 90 | 91 | end. 92 | -------------------------------------------------------------------------------- /Units/DownloaderUnits/UnitFileNameExtractor.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitFileNameExtractor; 21 | 22 | interface 23 | 24 | uses Classes, Windows, SysUtils, JvCreateProcess, Messages, StrUtils, Generics.Collections, UnitImageResize, UnitCommonTypes; 25 | 26 | type 27 | TStatusEx = (stReadingEx, stDoneEx); 28 | 29 | type 30 | TTypeInfo = record 31 | ID: string; 32 | Info: string; 33 | end; 34 | 35 | type 36 | TFileNameExtractor = class(TObject) 37 | private 38 | FProcess: TJvCreateProcess; 39 | FFormat: string; 40 | FStatus: TStatusEx; 41 | FFileName: string; 42 | FURL: string; 43 | FYouTubePath: string; 44 | FPass: TUserPass; 45 | 46 | procedure ProcessTerminate3(Sender: TObject; ExitCode: Cardinal); 47 | public 48 | property Status: TStatusEx read FStatus; 49 | property FileName: string read FFileName; 50 | property Format: string read FFormat write FFormat; 51 | 52 | constructor Create(const URL: string; const YouTube_dlPath: string; const UserPass: TUserPass); 53 | destructor Destroy(); override; 54 | 55 | procedure Start3(); 56 | end; 57 | 58 | implementation 59 | 60 | { TFileNameExtractor } 61 | 62 | constructor TFileNameExtractor.Create(const URL: string; const YouTube_dlPath: string; const UserPass: TUserPass); 63 | begin 64 | inherited Create; 65 | 66 | FProcess := TJvCreateProcess.Create(nil); 67 | with FProcess do 68 | begin 69 | OnTerminate := ProcessTerminate3; 70 | ConsoleOptions := [coRedirect]; 71 | CreationFlags := [cfUnicode]; 72 | Priority := ppIdle; 73 | 74 | with StartupInfo do 75 | begin 76 | DefaultPosition := False; 77 | DefaultSize := False; 78 | DefaultWindowState := False; 79 | ShowWindow := swHide; 80 | end; 81 | 82 | WaitForTerminate := true; 83 | end; 84 | 85 | FStatus := stReadingEx; 86 | FURL := URL; 87 | FYouTubePath := YouTube_dlPath; 88 | FPass := UserPass; 89 | end; 90 | 91 | destructor TFileNameExtractor.Destroy; 92 | begin 93 | inherited Destroy; 94 | FProcess.Free; 95 | end; 96 | 97 | procedure TFileNameExtractor.ProcessTerminate3(Sender: TObject; ExitCode: Cardinal); 98 | begin 99 | FStatus := stReadingEx; 100 | try 101 | FProcess.ConsoleOutput.Add(FProcess.CommandLine); 102 | if FProcess.ConsoleOutput.Count > 0 then 103 | begin 104 | FFileName := (FProcess.ConsoleOutput[0]); 105 | end; 106 | finally 107 | FStatus := stDoneEx; 108 | end; 109 | end; 110 | 111 | procedure TFileNameExtractor.Start3; 112 | var 113 | LPass: string; 114 | begin 115 | FProcess.ApplicationName := FYouTubePath; 116 | if (Length(FPass.UserName) > 0) and (Length(FPass.Password) > 0) then 117 | begin 118 | LPass := ' -u ' + FPass.UserName + ' -p ' + FPass.Password; 119 | end; 120 | FProcess.CommandLine := ' ' + LPass + ' -s --skip-download --no-playlist --get-filename -f ' + FFormat + ' -o "%(uploader)s - %(title)s.%(ext)s" "' + FURL + '"'; 121 | FProcess.Run; 122 | end; 123 | 124 | end. 125 | -------------------------------------------------------------------------------- /Units/DownloaderUnits/UnitImageResize.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitImageResize; 21 | 22 | interface 23 | 24 | uses Classes, Windows, SysUtils, Messages, StrUtils, Jpeg, Graphics, madGraphics, PNGImage; 25 | 26 | type 27 | TImageResizer = class(TObject) 28 | private 29 | FWidth: Integer; 30 | FHeight: Integer; 31 | FSourcePath: string; 32 | FDestPath: string; 33 | 34 | function ResizeJpg(const inFile, outFile: TFileName; const aQuality: TJPEGQualityRange = 95): Boolean; 35 | public 36 | property Width: Integer read FWidth write FWidth; 37 | property Height: Integer read FHeight write FHeight; 38 | 39 | constructor Create(const SourceImg: string; const DestImg: string); 40 | destructor Destroy; override; 41 | 42 | procedure Resize; 43 | end; 44 | 45 | implementation 46 | 47 | { TImageResizer } 48 | 49 | constructor TImageResizer.Create(const SourceImg, DestImg: string); 50 | begin 51 | FSourcePath := SourceImg; 52 | FDestPath := DestImg; 53 | end; 54 | 55 | destructor TImageResizer.Destroy; 56 | begin 57 | inherited; 58 | end; 59 | 60 | procedure TImageResizer.Resize; 61 | var 62 | LExt: string; 63 | begin 64 | if not FileExists(FSourcePath) then Exit; 65 | 66 | LExt := LowerCase(ExtractFileExt(FSourcePath)); 67 | if (LExt = '.jpeg') or (LExt = '.jpg') then 68 | begin 69 | ResizeJpg(FSourcePath, FDestPath) 70 | end; 71 | end; 72 | 73 | // code is from http://jetcracker.wordpress.com/2012/03/05/my-old-trash-resizing-images-in-delphi/ 74 | function TImageResizer.ResizeJpg(const inFile, outFile: TFileName; const aQuality: TJPEGQualityRange): Boolean; 75 | var 76 | LJpeg: TJPEGImage; 77 | LBMP: TBitmap; 78 | LJpegBMP: TBitmap; 79 | LOutJpeg: TJPEGImage; 80 | begin 81 | Result := FileExists(inFile); 82 | 83 | LJpeg := TJPEGImage.Create; 84 | LBMP := TBitmap.Create; 85 | LJpegBMP := TBitmap.Create; 86 | try 87 | // try to load jpg from file 88 | try 89 | LJpeg.LoadFromFile(inFile); 90 | except 91 | Result := False; 92 | Exit; 93 | end; 94 | // output bitmap 95 | LBMP.PixelFormat := pf24bit; 96 | LBMP.Width := 200; 97 | LBMP.Height := Round(LBMP.Width * (LJpeg.Height / LJpeg.Width)); 98 | // bitmap to hold data from jpeg 99 | LJpegBMP.PixelFormat := pf24bit; 100 | LJpegBMP.Width := LJpeg.Width; 101 | LJpegBMP.Height :=LJpeg.Height; 102 | LJpegBMP.Assign(LJpeg); 103 | 104 | try 105 | StretchBitmap(LJpegBMP, LBMP, nil, nil, sqVeryHigh); 106 | except 107 | Result := False; 108 | Exit; 109 | end; 110 | 111 | LOutJpeg := TJPEGImage.Create; 112 | try 113 | LOutJpeg.Assign(LBMP); 114 | try 115 | LOutJpeg.SaveToFile(outFile); 116 | except 117 | Result := False; 118 | Exit; 119 | end; 120 | finally 121 | LOutJpeg.Free; 122 | end; 123 | finally 124 | LJpeg.Free; 125 | LBMP.Free; 126 | LJpegBMP.Free; 127 | end; 128 | end; 129 | 130 | end. 131 | -------------------------------------------------------------------------------- /Units/DownloaderUnits/UnitImageTypeExtractor.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2014 ozok 3 | * 4 | * This file is part of TFlickrDownloader. 5 | * 6 | * TFlickrDownloader is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TFlickrDownloader is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TFlickrDownloader. If not, see . 18 | * 19 | * } 20 | 21 | unit UnitImageTypeExtractor; 22 | 23 | interface 24 | 25 | uses Classes, Windows, SysUtils, Messages, StrUtils; 26 | 27 | type 28 | TImageType = class(TObject) 29 | private 30 | FType: string; 31 | 32 | function ReadType(const ImagePath: string): string; 33 | public 34 | property ImageType: string read FType; 35 | 36 | constructor Create(const ImagePath: string); 37 | destructor Destroy; override; 38 | end; 39 | 40 | implementation 41 | 42 | const 43 | // taken from http://www.delphipages.com/forum/showthread.php?t=174008 44 | JPG_HEADER: array [0 .. 2] of byte = ($FF, $D8, $FF); 45 | GIF_HEADER: array [0 .. 2] of byte = ($47, $49, $46); 46 | BMP_HEADER: array [0 .. 1] of byte = ($42, $4D); 47 | PNG_HEADER: array [0 .. 3] of byte = ($89, $50, $4E, $47); 48 | TIF_HEADER: array [0 .. 2] of byte = ($49, $49, $2A); 49 | 50 | { TImageType } 51 | 52 | constructor TImageType.Create(const ImagePath: string); 53 | begin 54 | if FileExists(ImagePath) then 55 | begin 56 | FType := ReadType(ImagePath); 57 | end 58 | else 59 | begin 60 | FType := ''; 61 | end; 62 | end; 63 | 64 | destructor TImageType.Destroy; 65 | begin 66 | 67 | inherited; 68 | end; 69 | 70 | function TImageType.ReadType(const ImagePath: string): string; 71 | var 72 | LFS: TFileStream; 73 | LMS: TMemoryStream; 74 | begin 75 | Result := ''; 76 | LFS := TFileStream.Create(ImagePath, fmOpenRead); 77 | LMS := TMemoryStream.Create; 78 | try 79 | LMS.CopyFrom(LFS, 5); 80 | if LMS.Size > 4 then 81 | begin 82 | if CompareMem(LMS.Memory, @JPG_HEADER, SizeOf(JPG_HEADER)) then 83 | Result := '.jpg' 84 | else if CompareMem(LMS.Memory, @GIF_HEADER, SizeOf(GIF_HEADER)) then 85 | Result := '.gif' 86 | else if CompareMem(LMS.Memory, @PNG_HEADER, SizeOf(PNG_HEADER)) then 87 | Result := '.png' 88 | else if CompareMem(LMS.Memory, @BMP_HEADER, SizeOf(BMP_HEADER)) then 89 | Result := '.bmp' 90 | else if CompareMem(LMS.Memory, @TIF_HEADER, SizeOf(TIF_HEADER)) then 91 | Result := '.tiff'; 92 | end; 93 | finally 94 | LFS.Free; 95 | LMS.Free; 96 | end; 97 | end; 98 | 99 | end. 100 | -------------------------------------------------------------------------------- /Units/DownloaderUnits/UnitYouTubeDlVersionReader.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2014 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitYouTubeDlVersionReader; 21 | 22 | interface 23 | 24 | uses 25 | Classes, Windows, SysUtils, JvCreateProcess, Messages; 26 | 27 | type 28 | TYouTubedlVersionReader = class(TObject) 29 | private 30 | FProcess: TJvCreateProcess; 31 | FYouTube_dlPath: string; 32 | procedure ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 33 | function GetIsRunning: Boolean; 34 | public 35 | property IsRunning: Boolean read GetIsRunning; 36 | constructor Create(const YouTube_dlPath: string); 37 | destructor Destroy(); override; 38 | procedure Start(); 39 | procedure StopAll(); 40 | end; 41 | 42 | implementation 43 | 44 | uses 45 | UnitMain, UnitYoutubedlUpdateChecker; 46 | 47 | { TYouTubedlVersionReader } 48 | 49 | constructor TYouTubedlVersionReader.Create(const YouTube_dlPath: string); 50 | begin 51 | inherited Create; 52 | 53 | FProcess := TJvCreateProcess.Create(nil); 54 | with FProcess do 55 | begin 56 | OnTerminate := ProcessTerminate; 57 | ConsoleOptions := [coRedirect]; 58 | CreationFlags := [cfUnicode]; 59 | Priority := ppIdle; 60 | 61 | with StartupInfo do 62 | begin 63 | DefaultPosition := False; 64 | DefaultSize := False; 65 | DefaultWindowState := False; 66 | ShowWindow := swHide; 67 | end; 68 | 69 | WaitForTerminate := true; 70 | end; 71 | 72 | FYouTube_dlPath := YouTube_dlPath; 73 | end; 74 | 75 | destructor TYouTubedlVersionReader.Destroy; 76 | begin 77 | inherited Destroy; 78 | FreeAndNil(FProcess); 79 | end; 80 | 81 | function TYouTubedlVersionReader.GetIsRunning: Boolean; 82 | begin 83 | Result := FProcess.ProcessInfo.hProcess > 0; 84 | end; 85 | 86 | procedure TYouTubedlVersionReader.ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 87 | begin 88 | YoutubedlUpdateChecker.LocalVersion := FProcess.ConsoleOutput.Text; 89 | YoutubedlUpdateChecker.Path := MainForm.FYoutubedlPath; 90 | YoutubedlUpdateChecker.Show; 91 | MainForm.Enabled := False; 92 | end; 93 | 94 | procedure TYouTubedlVersionReader.Start; 95 | begin 96 | FProcess.ApplicationName := FYouTube_dlPath; 97 | FProcess.CommandLine := ' --version'; 98 | FProcess.Run; 99 | end; 100 | 101 | procedure TYouTubedlVersionReader.StopAll; 102 | begin 103 | if FProcess.ProcessInfo.hProcess > 0 then 104 | begin 105 | TerminateProcess(FProcess.ProcessInfo.hProcess, 0) 106 | end; 107 | end; 108 | 109 | end. 110 | 111 | -------------------------------------------------------------------------------- /Units/DownloaderUnits/UnitYouTubeVideoInfoExtractorEx.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitYouTubeVideoInfoExtractorEx; 21 | 22 | interface 23 | 24 | uses Classes, Windows, SysUtils, Messages, StrUtils, Generics.Collections, UnitYouTubeVideoInfoExtractor; 25 | 26 | type 27 | TStatusEx = (stReadingEx, stDoneEx); 28 | 29 | type 30 | TJob = record 31 | Url: string; 32 | Playlist: boolean; 33 | end; 34 | 35 | type 36 | TYouTubeVideoInfoExtractorEx = class(TObject) 37 | private 38 | FJobs: TList; 39 | FYIE: TYouTubeVideoInfoExtractor; 40 | FYouTubeDlPath: string; 41 | FTempFolder: string; 42 | FStatus: TStatusEx; 43 | public 44 | property Jobs: TList read FJobs write FJobs; 45 | property Status: TStatusEx read FStatus; 46 | 47 | constructor Create(const YouTubeDlPath: string; const TempFolder: string); 48 | destructor Destroy(); override; 49 | 50 | procedure Start(); 51 | end; 52 | 53 | implementation 54 | 55 | { TYouTubeVideoInfoExtractorEx } 56 | 57 | constructor TYouTubeVideoInfoExtractorEx.Create(const YouTubeDlPath: string; const TempFolder: string); 58 | begin 59 | inherited Create; 60 | FStatus := stReadingEx; 61 | FJobs := TList.Create; 62 | FYouTubeDlPath := YouTubeDlPath; 63 | FTempFolder := TempFolder; 64 | end; 65 | 66 | destructor TYouTubeVideoInfoExtractorEx.Destroy; 67 | begin 68 | inherited Destroy; 69 | FJobs.Free; 70 | end; 71 | 72 | procedure TYouTubeVideoInfoExtractorEx.Start; 73 | begin 74 | while FJobs.Count > 0 do 75 | begin 76 | FYIE := TYouTubeVideoInfoExtractor.Create(FJobs[0].Url, FYouTubeDlPath, FTempFolder); 77 | // if FJobs[0].Playlist then 78 | // begin 79 | // FYIE.GetPlayListInfo; 80 | // end 81 | // else 82 | // begin 83 | FYIE.Start; 84 | // end; 85 | while (FYIE.FormatStatus = stReading) or (FYIE.ThumbStatus = stReading) or (FYIE.TitleStatus = stReading) or (FYIE.SubtitleStatus = stReading) do 86 | begin 87 | Sleep(100); 88 | end; 89 | FJobs.Delete(0); 90 | end; 91 | FStatus := stDoneEx; 92 | end; 93 | 94 | end. 95 | -------------------------------------------------------------------------------- /Units/MediaInfoDLL.pas: -------------------------------------------------------------------------------- 1 | unit MediaInfoDll; 2 | 3 | { 4 | MediaInfoLib (MediaInfo.dll v0.7.7.6) Interface for Delphi 5 | (c)2008 by Norbert Mereg (Icebob) 6 | 7 | http://mediainfo.sourceforge.net 8 | } 9 | 10 | interface 11 | 12 | uses 13 | {$IFDEF WIN32} 14 | Windows; 15 | {$ELSE} 16 | Wintypes, WinProcs; 17 | {$ENDIF} 18 | 19 | type 20 | TMIStreamKind = (Stream_General, Stream_Video, Stream_Audio, Stream_Text, Stream_Chapters, Stream_Image, Stream_Menu, Stream_Max); 21 | 22 | type 23 | TMIInfo = (Info_Name, Info_Text, Info_Measure, Info_Options, Info_Name_Text, Info_Measure_Text, Info_Info, Info_HowTo, Info_Max); 24 | 25 | type 26 | TMIInfoOption = (InfoOption_ShowInInform, InfoOption_Reserved, InfoOption_ShowInSupported, InfoOption_TypeOfValue, InfoOption_Max); 27 | 28 | {$IFDEF STATIC} 29 | // Unicode methods 30 | function MediaInfo_New(): Cardinal cdecl {$IFDEF WIN32} stdcall 31 | {$ENDIF}; external 'MediaInfo.Dll'; 32 | procedure MediaInfo_Delete(Handle: Cardinal)cdecl {$IFDEF WIN32} stdcall 33 | {$ENDIF}; external 'MediaInfo.Dll'; 34 | function MediaInfo_Open(Handle: Cardinal; File__: PWideChar): Cardinal cdecl 35 | {$IFDEF WIN32} stdcall {$ENDIF}; external 'MediaInfo.Dll'; 36 | procedure MediaInfo_Close(Handle: Cardinal)cdecl {$IFDEF WIN32} stdcall 37 | {$ENDIF}; external 'MediaInfo.Dll'; 38 | function MediaInfo_Inform(Handle: Cardinal; Reserved: Integer): PWideChar cdecl 39 | {$IFDEF WIN32} stdcall {$ENDIF}; external 'MediaInfo.Dll'; 40 | function MediaInfo_GetI(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer; Parameter: Integer; KindOfInfo: TMIInfo): PWideChar cdecl {$IFDEF WIN32} stdcall 41 | {$ENDIF}; external 'MediaInfo.Dll'; 42 | // Default: KindOfInfo=Info_Text 43 | function MediaInfo_Get(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer; Parameter: PWideChar; KindOfInfo: TMIInfo; KindOfSearch: TMIInfo): PWideChar cdecl {$IFDEF WIN32} stdcall 44 | {$ENDIF}; external 'MediaInfo.Dll'; 45 | // Default: KindOfInfo=Info_Text, KindOfSearch=Info_Name 46 | function MediaInfo_Option(Handle: Cardinal; Option: PWideChar; Value: PWideChar): PWideChar cdecl {$IFDEF WIN32} stdcall {$ENDIF}; external 'MediaInfo.Dll'; 47 | function MediaInfo_State_Get(Handle: Cardinal): Integer cdecl 48 | {$IFDEF WIN32} stdcall {$ENDIF}; external 'MediaInfo.Dll'; 49 | function MediaInfo_Count_Get(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer): Integer cdecl {$IFDEF WIN32} stdcall 50 | {$ENDIF}; external 'MediaInfo.Dll'; 51 | 52 | // Ansi methods 53 | function MediaInfoA_New(): Cardinal cdecl {$IFDEF WIN32} stdcall 54 | {$ENDIF}; external 'MediaInfo.Dll'; 55 | procedure MediaInfoA_Delete(Handle: Cardinal)cdecl {$IFDEF WIN32} stdcall 56 | {$ENDIF}; external 'MediaInfo.Dll'; 57 | function MediaInfoA_Open(Handle: Cardinal; File__: PChar): Cardinal cdecl 58 | {$IFDEF WIN32} stdcall {$ENDIF}; external 'MediaInfo.Dll'; 59 | procedure MediaInfoA_Close(Handle: Cardinal)cdecl {$IFDEF WIN32} stdcall 60 | {$ENDIF}; external 'MediaInfo.Dll'; 61 | function MediaInfoA_Inform(Handle: Cardinal; Reserved: Integer): PChar cdecl 62 | {$IFDEF WIN32} stdcall {$ENDIF}; external 'MediaInfo.Dll'; 63 | function MediaInfoA_GetI(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer; Parameter: Integer; KindOfInfo: TMIInfo): PChar cdecl 64 | {$IFDEF WIN32} stdcall {$ENDIF}; external 'MediaInfo.Dll'; 65 | // Default: KindOfInfo=Info_Text 66 | function MediaInfoA_Get(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer; Parameter: PChar; KindOfInfo: TMIInfo; KindOfSearch: TMIInfo): PChar cdecl {$IFDEF WIN32} stdcall 67 | {$ENDIF}; external 'MediaInfo.Dll'; 68 | // Default: KindOfInfo=Info_Text, KindOfSearch=Info_Name 69 | function MediaInfoA_Option(Handle: Cardinal; Option: PChar; Value: PChar): PChar cdecl {$IFDEF WIN32} stdcall {$ENDIF}; external 'MediaInfo.Dll'; 70 | function MediaInfoA_State_Get(Handle: Cardinal): Integer cdecl 71 | {$IFDEF WIN32} stdcall {$ENDIF}; external 'MediaInfo.Dll'; 72 | function MediaInfoA_Count_Get(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer): Integer cdecl {$IFDEF WIN32} stdcall 73 | {$ENDIF}; external 'MediaInfo.Dll'; 74 | {$ELSE} 75 | 76 | var 77 | LibHandle: THandle = 0; 78 | 79 | // Unicode methods 80 | MediaInfo_New: function(): Cardinal cdecl stdcall; 81 | MediaInfo_Delete: procedure(Handle: Cardinal)cdecl stdcall; 82 | MediaInfo_Open: function(Handle: Cardinal; File__: PWideChar): Cardinal cdecl stdcall; 83 | MediaInfo_Close: procedure(Handle: Cardinal)cdecl stdcall; 84 | MediaInfo_Inform: function(Handle: Cardinal; Reserved: Integer): PWideChar cdecl stdcall; 85 | MediaInfo_GetI: function(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer; Parameter: Integer; KindOfInfo: TMIInfo): PWideChar cdecl stdcall; // Default: KindOfInfo=Info_Text, 86 | MediaInfo_Get: function(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer; Parameter: PWideChar; KindOfInfo: TMIInfo; KindOfSearch: TMIInfo): PWideChar cdecl stdcall; 87 | // Default: KindOfInfo=Info_Text, KindOfSearch=Info_Name 88 | MediaInfo_Option: function(Handle: Cardinal; Option: PWideChar; Value: PWideChar): PWideChar cdecl stdcall; 89 | MediaInfo_State_Get: function(Handle: Cardinal): Integer cdecl stdcall; 90 | MediaInfo_Count_Get: function(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer): Integer cdecl stdcall; 91 | 92 | // Ansi methods 93 | MediaInfoA_New: function(): Cardinal cdecl stdcall; 94 | MediaInfoA_Delete: procedure(Handle: Cardinal)cdecl stdcall; 95 | MediaInfoA_Open: function(Handle: Cardinal; File__: PChar): Cardinal cdecl stdcall; 96 | MediaInfoA_Close: procedure(Handle: Cardinal)cdecl stdcall; 97 | MediaInfoA_Inform: function(Handle: Cardinal; Reserved: Integer): PChar cdecl stdcall; 98 | MediaInfoA_GetI: function(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer; Parameter: Integer; KindOfInfo: TMIInfo): PChar cdecl stdcall; // Default: KindOfInfo=Info_Text 99 | MediaInfoA_Get: function(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer; Parameter: PChar; KindOfInfo: TMIInfo; KindOfSearch: TMIInfo): PChar cdecl stdcall; 100 | // Default: KindOfInfo=Info_Text, KindOfSearch=Info_Name 101 | MediaInfoA_Option: function(Handle: Cardinal; Option: PChar; Value: PChar): PChar cdecl stdcall; 102 | MediaInfoA_State_Get: function(Handle: Cardinal): Integer cdecl stdcall; 103 | MediaInfoA_Count_Get: function(Handle: Cardinal; StreamKind: TMIStreamKind; StreamNumber: Integer): Integer cdecl stdcall; 104 | 105 | function MediaInfoDLL_Load(LibPath: string): boolean; 106 | 107 | {$ENDIF} 108 | 109 | implementation 110 | 111 | {$IFNDEF STATIC} 112 | 113 | function MI_GetProcAddress(Name: PChar; var Addr: Pointer): boolean; 114 | begin 115 | Addr := GetProcAddress(LibHandle, Name); 116 | Result := Addr <> nil; 117 | end; 118 | 119 | function MediaInfoDLL_Load(LibPath: string): boolean; 120 | begin 121 | Result := False; 122 | 123 | if LibHandle = 0 then 124 | LibHandle := LoadLibrary(PChar(LibPath)); 125 | 126 | if LibHandle <> 0 then 127 | begin 128 | MI_GetProcAddress('MediaInfo_New', @MediaInfo_New); 129 | MI_GetProcAddress('MediaInfo_Delete', @MediaInfo_Delete); 130 | MI_GetProcAddress('MediaInfo_Open', @MediaInfo_Open); 131 | MI_GetProcAddress('MediaInfo_Close', @MediaInfo_Close); 132 | MI_GetProcAddress('MediaInfo_Inform', @MediaInfo_Inform); 133 | MI_GetProcAddress('MediaInfo_GetI', @MediaInfo_GetI); 134 | MI_GetProcAddress('MediaInfo_Get', @MediaInfo_Get); 135 | MI_GetProcAddress('MediaInfo_Option', @MediaInfo_Option); 136 | MI_GetProcAddress('MediaInfo_State_Get', @MediaInfo_State_Get); 137 | MI_GetProcAddress('MediaInfo_Count_Get', @MediaInfo_Count_Get); 138 | 139 | MI_GetProcAddress('MediaInfoA_New', @MediaInfoA_New); 140 | MI_GetProcAddress('MediaInfoA_Delete', @MediaInfoA_Delete); 141 | MI_GetProcAddress('MediaInfoA_Open', @MediaInfoA_Open); 142 | MI_GetProcAddress('MediaInfoA_Close', @MediaInfoA_Close); 143 | MI_GetProcAddress('MediaInfoA_Inform', @MediaInfoA_Inform); 144 | MI_GetProcAddress('MediaInfoA_GetI', @MediaInfoA_GetI); 145 | MI_GetProcAddress('MediaInfoA_Get', @MediaInfoA_Get); 146 | MI_GetProcAddress('MediaInfoA_Option', @MediaInfoA_Option); 147 | MI_GetProcAddress('MediaInfoA_State_Get', @MediaInfoA_State_Get); 148 | MI_GetProcAddress('MediaInfoA_Count_Get', @MediaInfoA_Count_Get); 149 | 150 | Result := True; 151 | end; 152 | end; 153 | 154 | {$ENDIF} 155 | 156 | end. 157 | -------------------------------------------------------------------------------- /Units/UnitCommonMethods.pas: -------------------------------------------------------------------------------- 1 | unit UnitCommonMethods; 2 | 3 | interface 4 | 5 | uses 6 | Classes, System.SysUtils; 7 | 8 | 9 | // checks if a given string is numeric 10 | function IsStringNumeric(const Str: string): Boolean; 11 | 12 | // converts hh:mm:ss to integer 13 | function TimeToInt(const TimeStr: string): Integer; 14 | 15 | function GenGUID: string; 16 | 17 | implementation 18 | 19 | function GenGUID: string; 20 | var 21 | LGUID: TGUID; 22 | begin 23 | CreateGUID(LGUID); 24 | Result := GUIDToString(LGUID); 25 | end; 26 | 27 | function IsStringNumeric(const Str: string): Boolean; 28 | var 29 | P: PChar; 30 | begin 31 | if Length(Str) < 1 then 32 | begin 33 | Result := False; 34 | Exit; 35 | end; 36 | P := PChar(Str); 37 | Result := False; 38 | while P^ <> #0 do 39 | begin 40 | if (not CharInSet(P^, ['0'..'9'])) then 41 | begin 42 | Exit; 43 | end; 44 | Inc(P); 45 | end; 46 | Result := True; 47 | end; 48 | 49 | function TimeToInt(const TimeStr: string): Integer; 50 | var 51 | LSplitList: TStringList; 52 | LHour: Integer; 53 | LMinute: Integer; 54 | LSecond: Integer; 55 | begin 56 | Result := 0; 57 | if Length(TimeStr) = 8 then 58 | begin 59 | LSplitList := TStringList.Create; 60 | try 61 | LSplitList.Delimiter := ':'; 62 | LSplitList.StrictDelimiter := True; 63 | LSplitList.DelimitedText := TimeStr; 64 | 65 | LHour := 0; 66 | LMinute := 0; 67 | LSecond := 0; 68 | 69 | if LSplitList.Count = 3 then 70 | begin 71 | if IsStringNumeric(LSplitList[0]) then 72 | begin 73 | LHour := StrToInt(LSplitList[0]); 74 | end; 75 | if IsStringNumeric(LSplitList[1]) then 76 | begin 77 | LMinute := StrToInt(LSplitList[1]); 78 | end; 79 | if IsStringNumeric(LSplitList[2]) then 80 | begin 81 | LSecond := StrToInt(LSplitList[2]); 82 | end; 83 | Result := (LHour * 3600) + (LMinute * 60) + LSecond; 84 | end; 85 | finally 86 | FreeAndNil(LSplitList); 87 | end; 88 | end; 89 | end; 90 | 91 | end. 92 | 93 | -------------------------------------------------------------------------------- /Units/UnitDVDJob.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitDVDJob; 21 | 22 | interface 23 | 24 | uses Classes, Windows, SysUtils, Messages, StrUtils, Generics.Collections, UnitDVDRipperProcess; 25 | 26 | type 27 | TDVDJob = class 28 | CMDs: TStringlist; 29 | Infos: TStringlist; 30 | EncoderPaths: TStringlist; 31 | FilePaths: TStringlist; 32 | OutputFiles: TStringlist; 33 | ProcessTypes: TList; 34 | ListItemIndexes: TList; 35 | TempFiles: TStringlist; 36 | FilesToCheck: TStringlist; 37 | constructor Create; 38 | destructor Destroy; override; 39 | end; 40 | 41 | TDVDJobs = TList; 42 | 43 | implementation 44 | 45 | { TDVDJob } 46 | 47 | constructor TDVDJob.Create; 48 | begin 49 | CMDs := TStringlist.Create; 50 | Infos := TStringlist.Create; 51 | EncoderPaths := TStringlist.Create; 52 | FilePaths := TStringlist.Create; 53 | OutputFiles := TStringlist.Create; 54 | TempFiles := TStringlist.Create; 55 | FilesToCheck := TStringlist.Create; 56 | ProcessTypes := TList.Create; 57 | ListItemIndexes := TList.Create; 58 | end; 59 | 60 | destructor TDVDJob.Destroy; 61 | begin 62 | CMDs.Free; 63 | ProcessTypes.Free; 64 | Infos.Free; 65 | EncoderPaths.Free; 66 | FilePaths.Free; 67 | OutputFiles.Free; 68 | TempFiles.Free; 69 | FilesToCheck.Free; 70 | ListItemIndexes.Free; 71 | inherited; 72 | end; 73 | 74 | end. 75 | -------------------------------------------------------------------------------- /Units/UnitDVDReader.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitDVDReader; 21 | 22 | interface 23 | 24 | uses 25 | Classes, Windows, SysUtils, JvCreateProcess, Messages, StrUtils, Generics.Collections, 26 | UnitCommonMethods; 27 | 28 | type 29 | TStatus = (fsReading, fsDone); 30 | 31 | type 32 | TAudioStream = record 33 | Name: string; 34 | ID: string; 35 | end; 36 | 37 | type 38 | TSubtitleStream = record 39 | Name: string; 40 | ID: string; 41 | end; 42 | 43 | type 44 | TTitle = class(TObject) 45 | private 46 | function GetDurationInt: integer; 47 | function GetFormattedDur: string; 48 | public 49 | AudioStreams: TList; 50 | SubtitleStreams: TList; 51 | Chapters: TStringList; 52 | ChapterDurations: TList; 53 | DurationStr: string; 54 | property DurationFormatedStr: string read GetFormattedDur; 55 | property DurationInt: integer read GetDurationInt; 56 | constructor Create; 57 | destructor Destroy; override; 58 | end; 59 | 60 | type 61 | TDVDTitleCountExtractor = class(TObject) 62 | private 63 | FProcess: TJvCreateProcess; 64 | FStatus: TStatus; 65 | FTitleCount: Integer; 66 | FMPlayerPath: string; 67 | FDVDFolder: string; 68 | procedure ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 69 | public 70 | property Status: TStatus read FStatus; 71 | property TitleCount: Integer read FTitleCount; 72 | constructor Create(const DVDFolder: string; const MplayerPath: string); 73 | destructor Destroy(); override; 74 | procedure Start(); 75 | end; 76 | 77 | type 78 | TDVDTitleInfoExtractor = class(TObject) 79 | private 80 | FProcess: TJvCreateProcess; 81 | FStatus: TStatus; 82 | FMPlayerPath: string; 83 | FDVDFolder: string; 84 | FTitleIndex: Integer; 85 | FTitle: TTitle; 86 | procedure ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 87 | public 88 | property Status: TStatus read FStatus; 89 | property Title: TTitle read FTitle; 90 | constructor Create(const DVDFolder: string; const MplayerPath: string; const TitleIndex: Integer); 91 | destructor Destroy(); override; 92 | procedure Start(); 93 | end; 94 | 95 | implementation 96 | 97 | uses 98 | UnitMain; 99 | 100 | { TTitle } 101 | 102 | constructor TTitle.Create; 103 | begin 104 | AudioStreams := TList.Create; 105 | SubtitleStreams := TList.Create; 106 | Chapters := TStringList.Create; 107 | ChapterDurations := TList.Create; 108 | DurationStr := '0'; 109 | end; 110 | 111 | destructor TTitle.Destroy; 112 | begin 113 | AudioStreams.Free; 114 | SubtitleStreams.Free; 115 | Chapters.Free; 116 | ChapterDurations.Free; 117 | end; 118 | 119 | function TTitle.GetDurationInt: integer; 120 | var 121 | lTmpStr: string; 122 | begin 123 | Result := 0; 124 | if Length(DurationStr) > 0 then 125 | begin 126 | lTmpStr := DurationStr; 127 | lTmpStr := StringReplace(lTmpStr, '.', '', [rfReplaceAll]); 128 | Result := StrToInt(lTmpStr) div 1000; 129 | end; 130 | end; 131 | 132 | function TTitle.GetFormattedDur: string; 133 | var 134 | LDurStr: string; 135 | lDurMSInt: Integer; 136 | LHour: string; 137 | LMin: string; 138 | LSec: string; 139 | LMinSec: string; 140 | begin 141 | Result := '00:00:00.000'; 142 | 143 | LDurStr := DurationStr; 144 | LDurStr := StringReplace(LDurStr, '.', '', [rfReplaceAll]); 145 | if TryStrToInt(LDurStr, lDurMSInt) then 146 | begin 147 | LHour := FloatToStr((lDurMSInt div 1000) div 3600); 148 | LMin := FloatToStr(((lDurMSInt div 1000) div 60 - (((lDurMSInt div 1000) div 3600) * 60))); 149 | LSec := FloatToStr(lDurMSInt mod 60); 150 | LMinSec := FloatToStr(lDurMSInt mod 1000); 151 | if Length(LHour) < 2 then 152 | begin 153 | LHour := '0' + LHour; 154 | end; 155 | if Length(LMin) < 2 then 156 | begin 157 | LMin := '0' + LMin; 158 | end; 159 | if Length(LSec) < 2 then 160 | begin 161 | LSec := '0' + LSec; 162 | end; 163 | Result := LHour + ':' + LMin + ':' + LSec + '.' + LMinSec; 164 | end; 165 | 166 | end; 167 | 168 | { TDVDTitleCountExtractor } 169 | 170 | constructor TDVDTitleCountExtractor.Create(const DVDFolder, MplayerPath: string); 171 | begin 172 | inherited Create; 173 | 174 | FProcess := TJvCreateProcess.Create(nil); 175 | with FProcess do 176 | begin 177 | OnTerminate := ProcessTerminate; 178 | ConsoleOptions := [coRedirect]; 179 | CreationFlags := [cfUnicode]; 180 | Priority := ppIdle; 181 | 182 | with StartupInfo do 183 | begin 184 | DefaultPosition := False; 185 | DefaultSize := False; 186 | DefaultWindowState := False; 187 | ShowWindow := swHide; 188 | end; 189 | 190 | WaitForTerminate := True; 191 | end; 192 | 193 | FStatus := fsReading; 194 | FMPlayerPath := MplayerPath; 195 | FDVDFolder := DVDFolder; 196 | end; 197 | 198 | destructor TDVDTitleCountExtractor.Destroy; 199 | begin 200 | FProcess.Free; 201 | end; 202 | 203 | procedure TDVDTitleCountExtractor.ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 204 | const 205 | TITLE_COUNT = 'ID_DVD_TITLES='; 206 | var 207 | I: Integer; 208 | LLine: string; 209 | lTmpStr: string; 210 | begin 211 | FStatus := fsReading; 212 | try 213 | if FProcess.ConsoleOutput.Count > 0 then 214 | begin 215 | // get dvd title count 216 | for I := 0 to FProcess.ConsoleOutput.Count - 1 do 217 | begin 218 | LLine := Trim(FProcess.ConsoleOutput[i]); 219 | if TITLE_COUNT = Copy(LLine, 1, Length(TITLE_COUNT)) then 220 | begin 221 | lTmpStr := StringReplace(LLine, TITLE_COUNT, '', [rfReplaceAll]); 222 | if not TryStrToInt(lTmpStr, FTitleCount) then 223 | begin 224 | FTitleCount := 0; 225 | end; 226 | end; 227 | end; 228 | end; 229 | finally 230 | FStatus := fsDone; 231 | end; 232 | 233 | end; 234 | 235 | procedure TDVDTitleCountExtractor.Start; 236 | begin 237 | FProcess.ApplicationName := FMPlayerPath; 238 | FProcess.CommandLine := ' -msglevel identify=6 -frames 0 -vo null -quiet dvd:// -dvd-device "' + FDVDFolder + '"'; 239 | FProcess.Run; 240 | end; 241 | 242 | { TDVDTitleInfoExtractor } 243 | 244 | constructor TDVDTitleInfoExtractor.Create(const DVDFolder, MplayerPath: string; const TitleIndex: Integer); 245 | begin 246 | FProcess := TJvCreateProcess.Create(nil); 247 | with FProcess do 248 | begin 249 | OnTerminate := ProcessTerminate; 250 | ConsoleOptions := [coRedirect]; 251 | CreationFlags := [cfUnicode]; 252 | Priority := ppIdle; 253 | 254 | with StartupInfo do 255 | begin 256 | DefaultPosition := False; 257 | DefaultSize := False; 258 | DefaultWindowState := False; 259 | ShowWindow := swHide; 260 | end; 261 | 262 | WaitForTerminate := True; 263 | end; 264 | 265 | FStatus := fsReading; 266 | FMPlayerPath := MplayerPath; 267 | FDVDFolder := DVDFolder; 268 | FTitleIndex := TitleIndex; 269 | FTitle := TTitle.Create; 270 | end; 271 | 272 | destructor TDVDTitleInfoExtractor.Destroy; 273 | begin 274 | inherited; 275 | FProcess.Free; 276 | end; 277 | 278 | procedure TDVDTitleInfoExtractor.ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 279 | const 280 | Audio = 'audio stream'; 281 | Subtitle = 'subtitle ( sid ):'; 282 | Chapter = 'CHAPTERS:'; 283 | var 284 | LLine: string; 285 | i: Integer; 286 | LAudioStream: TAudioStream; 287 | LSubStream: TSubtitleStream; 288 | LSplitList: TStringList; 289 | j: Integer; 290 | begin 291 | FStatus := fsReading; 292 | try 293 | // get title duration 294 | for I := 0 to FProcess.ConsoleOutput.Count - 1 do 295 | begin 296 | LLine := Trim(FProcess.ConsoleOutput[i]); 297 | if ('ID_DVD_TITLE_' + FloatToStr(FTitleIndex) + '_LENGTH=') = Copy(LLine, 1, Length('ID_DVD_TITLE_' + FloatToStr(FTitleIndex) + '_LENGTH=')) then 298 | begin 299 | FTitle.DurationStr := StringReplace(LLine, 'ID_DVD_TITLE_' + FloatToStr(FTitleIndex) + '_LENGTH=', '', [rfReplaceAll]); 300 | Break; 301 | end; 302 | end; 303 | // search for audio streams 304 | for I := 0 to FProcess.ConsoleOutput.Count - 1 do 305 | begin 306 | LLine := Trim(FProcess.ConsoleOutput[i]); 307 | if Length(LLine) > 0 then 308 | begin 309 | if Audio = Copy(LLine, 1, Length(Audio)) then 310 | begin 311 | LSplitList := TStringList.Create; 312 | try 313 | LSplitList.StrictDelimiter := True; 314 | LSplitList.Delimiter := ':'; 315 | LSplitList.DelimitedText := LLine; 316 | LAudioStream.Name := Trim(UpperCase(Trim(StringReplace(LSplitList[2], 'language', '', [rfReplaceAll])) + ', ' + Trim(StringReplace(LSplitList[3], 'aid', '', [rfReplaceAll])))); 317 | LAudioStream.ID := Trim(StringReplace(LSplitList[4], '.', '', [rfReplaceAll])); 318 | FTitle.AudioStreams.Add(LAudioStream); 319 | finally 320 | LSplitList.Free; 321 | end; 322 | end; 323 | end; 324 | end; 325 | // search for subtitle streams 326 | for I := 0 to FProcess.ConsoleOutput.Count - 1 do 327 | begin 328 | LLine := Trim(FProcess.ConsoleOutput[i]); 329 | if Length(LLine) > 0 then 330 | begin 331 | if Subtitle = Copy(LLine, 1, Length(Subtitle)) then 332 | begin 333 | LSplitList := TStringList.Create; 334 | try 335 | LSplitList.StrictDelimiter := True; 336 | LSplitList.Delimiter := ':'; 337 | LSplitList.DelimitedText := LLine; 338 | LSubStream.Name := Trim(UpperCase(LSplitList[2])); 339 | LSubStream.ID := Trim(StringReplace(LSplitList[1], 'language', '', [rfReplaceAll])); 340 | FTitle.SubtitleStreams.Add(LSubStream); 341 | finally 342 | LSplitList.Free; 343 | end; 344 | end; 345 | end; 346 | end; 347 | // chapters 348 | for I := 0 to FProcess.ConsoleOutput.Count - 1 do 349 | begin 350 | LLine := Trim(FProcess.ConsoleOutput[i]); 351 | if Length(LLine) > 0 then 352 | begin 353 | if Chapter = Copy(LLine, 1, Length(Chapter)) then 354 | begin 355 | LSplitList := TStringList.Create; 356 | try 357 | LSplitList.StrictDelimiter := True; 358 | LSplitList.Delimiter := ','; 359 | LSplitList.DelimitedText := LLine; 360 | LSplitList.Delete(0); // first item is "chapters" 361 | // remove empty lines 362 | for j := LSplitList.Count - 1 downto 0 do 363 | begin 364 | if Length(Trim(LSplitList[j])) < 1 then 365 | begin 366 | LSplitList.Delete(j); 367 | end; 368 | end; 369 | FTitle.Chapters.AddStrings(LSplitList); 370 | finally 371 | LSplitList.Free; 372 | end; 373 | end; 374 | end; 375 | end; 376 | // chapter durations 377 | for i := 0 to FTitle.Chapters.Count - 1 do 378 | begin 379 | LLine := FTitle.Chapters[i]; 380 | LLine := Copy(LLine, 1, Length(LLine) - 4); 381 | if i = 0 then 382 | begin 383 | FTitle.ChapterDurations.Add(TimeToInt(LLine)); 384 | end 385 | else 386 | begin 387 | FTitle.ChapterDurations.Add(TimeToInt(LLine) - FTitle.ChapterDurations[i - 1]); 388 | end; 389 | end; 390 | finally 391 | FStatus := fsDone; 392 | end; 393 | end; 394 | 395 | procedure TDVDTitleInfoExtractor.Start; 396 | begin 397 | FProcess.ApplicationName := FMPlayerPath; 398 | FProcess.CommandLine := ' -msglevel identify=6 -frames 0 -vo null -quiet dvd://' + FloatToStr(FTitleIndex) + ' -dvd-device "' + FDVDFolder + '"'; 399 | FProcess.Run; 400 | end; 401 | 402 | end. 403 | 404 | -------------------------------------------------------------------------------- /Units/UnitDVDRipperProcess.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitDVDRipperProcess; 21 | 22 | interface 23 | 24 | uses 25 | Classes, Windows, SysUtils, JvCreateProcess, Messages, StrUtils, UnitSettings, 26 | Generics.Collections, ComCtrls; 27 | 28 | // current state of the process 29 | type 30 | TEncoderStatus = (esEncoding, esStopped, esDone); 31 | 32 | type 33 | TDVDProcessType = (dvdmencoder, dvdffmpeg, dvdmp4box, dvdrenametool); 34 | 35 | type 36 | TDVDRipProcess = class(TObject) 37 | private 38 | // process 39 | FProcess: TJvCreateProcess; 40 | // list of command lines to be executed 41 | FCommandLines: TStringList; 42 | // list of executables 43 | FEncoderPaths: TStringList; 44 | // index of current command line. Also progress. 45 | FCommandIndex: integer; 46 | // last line backend has written to console 47 | FConsoleOutput: string; 48 | // encoder's state 49 | FEncoderStatus: TEncoderStatus; 50 | // flag to indicate if encoding is stopped by user 51 | FStoppedByUser: Boolean; 52 | // list of files to be processed. 53 | FFileNames: TStringList; 54 | // a list of types of encoders to be run. 55 | FProcessTypes: TList; 56 | // list of informations about steps. 57 | FInfos: TStringList; 58 | // a list of output files. generally to check if they are created. 59 | FOutputFiles: TStringList; 60 | FTerminateCounter: integer; 61 | FItem: TListItem; 62 | FListItemIndexes: TList; 63 | 64 | // process events 65 | procedure ProcessRead(Sender: TObject; const S: string; const StartsOnNewLine: Boolean); 66 | procedure ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 67 | 68 | // field variable read funcs 69 | function GetProcessID: integer; 70 | function GetFileName: string; 71 | function GetCurrentProcessType: TDVDProcessType; 72 | function GetInfo: string; 73 | function GetCommandCount: integer; 74 | function GetExeName: string; 75 | function GetPercentage: integer; 76 | public 77 | property ConsoleOutput: string read FConsoleOutput; 78 | property EncoderStatus: TEncoderStatus read FEncoderStatus; 79 | property CommandLines: TStringList read FCommandLines write FCommandLines; 80 | property EncoderPaths: TStringList read FEncoderPaths write FEncoderPaths; 81 | property FileNames: TStringList read FFileNames; 82 | property FilesDone: integer read FCommandIndex; 83 | property ProcessID: integer read GetProcessID; 84 | property CurrentFile: string read GetFileName; 85 | property ProcessTypes: TList read FProcessTypes write FProcessTypes; 86 | property CurrentProcessType: TDVDProcessType read GetCurrentProcessType; 87 | property Info: string read GetInfo; 88 | property Infos: TStringList read FInfos write FInfos; 89 | property CommandCount: integer read GetCommandCount; 90 | property ExeName: string read GetExeName; 91 | property OutputFiles: TStringList read FOutputFiles write FOutputFiles; 92 | property ListItemIndexes: TList read FListItemIndexes write FListItemIndexes; 93 | constructor Create(); 94 | destructor Destroy(); override; 95 | procedure Start(); 96 | procedure Stop(); 97 | procedure ResetValues(); 98 | function GetConsoleOutput(): TStrings; 99 | end; 100 | 101 | implementation 102 | 103 | { TDVDRipProcess } 104 | 105 | uses 106 | UnitMain; 107 | 108 | constructor TDVDRipProcess.Create; 109 | begin 110 | inherited Create; 111 | 112 | FProcess := TJvCreateProcess.Create(nil); 113 | with FProcess do 114 | begin 115 | OnRead := ProcessRead; 116 | OnTerminate := ProcessTerminate; 117 | ConsoleOptions := [coRedirect]; 118 | CreationFlags := [cfUnicode]; 119 | Priority := ppIdle; 120 | 121 | with StartupInfo do 122 | begin 123 | DefaultPosition := False; 124 | DefaultSize := False; 125 | DefaultWindowState := False; 126 | ShowWindow := swHide; 127 | end; 128 | 129 | WaitForTerminate := true; 130 | end; 131 | 132 | FCommandLines := TStringList.Create; 133 | FEncoderPaths := TStringList.Create; 134 | FFileNames := TStringList.Create; 135 | FEncoderStatus := esStopped; 136 | FStoppedByUser := False; 137 | FProcessTypes := TList.Create; 138 | FInfos := TStringList.Create; 139 | FCommandIndex := 0; 140 | FOutputFiles := TStringList.Create; 141 | FListItemIndexes := TList.Create; 142 | end; 143 | 144 | destructor TDVDRipProcess.Destroy; 145 | begin 146 | FreeAndNil(FCommandLines); 147 | FreeAndNil(FEncoderPaths); 148 | FreeAndNil(FInfos); 149 | FreeAndNil(FFileNames); 150 | FreeAndNil(FProcessTypes); 151 | FreeAndNil(FOutputFiles); 152 | FProcess.Free; 153 | FListItemIndexes.Free; 154 | 155 | inherited Destroy; 156 | end; 157 | 158 | function TDVDRipProcess.GetCommandCount: integer; 159 | begin 160 | Result := FCommandLines.Count; 161 | end; 162 | 163 | function TDVDRipProcess.GetConsoleOutput: TStrings; 164 | begin 165 | Result := FProcess.ConsoleOutput; 166 | end; 167 | 168 | function TDVDRipProcess.GetCurrentProcessType: TDVDProcessType; 169 | begin 170 | Result := dvdmencoder; 171 | if FCommandIndex < FProcessTypes.Count then 172 | Result := FProcessTypes[FCommandIndex]; 173 | end; 174 | 175 | function TDVDRipProcess.GetExeName: string; 176 | begin 177 | if FCommandIndex < FEncoderPaths.Count then 178 | Result := FEncoderPaths[FCommandIndex]; 179 | end; 180 | 181 | function TDVDRipProcess.GetFileName: string; 182 | begin 183 | if FCommandIndex < FFileNames.Count then 184 | Result := FFileNames[FCommandIndex]; 185 | end; 186 | 187 | function TDVDRipProcess.GetInfo: string; 188 | begin 189 | if FCommandIndex < FInfos.Count then 190 | Result := FInfos[FCommandIndex]; 191 | end; 192 | 193 | function TDVDRipProcess.GetPercentage: integer; 194 | var 195 | LPercentageStr: string; 196 | LPercentageInt: Integer; 197 | begin 198 | Result := 0; 199 | if Length(FConsoleOutput) > 0 then 200 | begin 201 | if FProcess.ProcessInfo.hProcess > 0 then 202 | begin 203 | // decide running process kind 204 | if (GetCurrentProcessType = dvdffmpeg) then 205 | begin 206 | LPercentageStr := '0'; 207 | // LPercentageStr := MainForm.GetFFmpegPosition(FConsoleOutput, GetCurrentDuration); 208 | end 209 | else if GetCurrentProcessType = dvdmencoder then 210 | begin 211 | LPercentageStr := MainForm.GetMencoderPosition(FConsoleOutput); 212 | end 213 | else if GetCurrentProcessType = dvdmp4box then 214 | begin 215 | LPercentageStr := MainForm.GetMp4Progress(FConsoleOutput); 216 | end; 217 | // make sure str is actually a number 218 | if TryStrToInt(LPercentageStr, LPercentageInt) then 219 | begin 220 | Result := LPercentageInt; 221 | end; 222 | end; 223 | end; 224 | end; 225 | 226 | function TDVDRipProcess.GetProcessID: integer; 227 | begin 228 | Result := FProcess.ProcessInfo.hProcess; 229 | end; 230 | 231 | procedure TDVDRipProcess.ProcessRead(Sender: TObject; const S: string; const StartsOnNewLine: Boolean); 232 | var 233 | LCurrVal: integer; 234 | begin 235 | Inc(FTerminateCounter); 236 | if (FTerminateCounter mod 5) = 0 then 237 | begin 238 | FConsoleOutput := Trim(S); 239 | try 240 | if TryStrToInt(FItem.SubItems[0], LCurrVal) then 241 | begin 242 | if GetPercentage > LCurrVal then 243 | begin 244 | try 245 | FItem.SubItems[0] := FloatToStr(GetPercentage); 246 | except 247 | on E: Exception do 248 | begin 249 | // ignored 250 | end; 251 | end; 252 | end; 253 | end; 254 | except 255 | on E: Exception do 256 | // ignored 257 | 258 | end; 259 | end; 260 | end; 261 | 262 | procedure TDVDRipProcess.ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 263 | begin 264 | FProcess.ConsoleOutput.Add('============================================='); 265 | FEncoderStatus := esStopped; 266 | MainForm.DVDProgressBar.Position := 0; 267 | if FStoppedByUser then 268 | begin 269 | try 270 | FItem.SubItems[0] := 'Stopped'; 271 | FItem.StateIndex := 3; 272 | except 273 | on E: Exception do 274 | // ignored 275 | 276 | end; 277 | FEncoderStatus := esStopped; 278 | end 279 | else 280 | begin 281 | 282 | // run next command 283 | inc(FCommandIndex); 284 | 285 | try 286 | FItem.SubItems[0] := '100'; 287 | FItem.StateIndex := 2; 288 | except 289 | on E: Exception do 290 | 291 | end; 292 | 293 | if FCommandIndex < FCommandLines.Count then 294 | begin 295 | FProcess.CommandLine := FCommandLines[FCommandIndex]; 296 | FProcess.ApplicationName := FEncoderPaths[FCommandIndex]; 297 | FEncoderStatus := esEncoding; 298 | FConsoleOutput := ''; 299 | try 300 | FItem := MainForm.DVDJobList.Items[FListItemIndexes[FCommandIndex]]; 301 | FItem.SubItems[0] := '0'; 302 | FItem.StateIndex := 0; 303 | FItem.MakeVisible(False); 304 | except 305 | on E: Exception do 306 | 307 | end; 308 | FProcess.Run; 309 | end 310 | else 311 | begin 312 | // done 313 | FFileNames.Clear; 314 | FEncoderStatus := esDone; 315 | end; 316 | end; 317 | end; 318 | 319 | procedure TDVDRipProcess.ResetValues; 320 | begin 321 | // reset all lists, indexes etc 322 | FCommandLines.Clear; 323 | FEncoderPaths.Clear; 324 | FCommandIndex := 0; 325 | FConsoleOutput := ''; 326 | FProcess.ConsoleOutput.Clear; 327 | FProcessTypes.Clear; 328 | FStoppedByUser := False; 329 | FInfos.Clear; 330 | FListItemIndexes.Clear; 331 | FItem := nil; 332 | end; 333 | 334 | procedure TDVDRipProcess.Start; 335 | begin 336 | if FProcess.ProcessInfo.hProcess = 0 then 337 | begin 338 | if FCommandLines.Count > 0 then 339 | begin 340 | FProcess.ApplicationName := FEncoderPaths[0]; 341 | FProcess.CommandLine := FCommandLines[0]; 342 | FEncoderStatus := esEncoding; 343 | 344 | try 345 | FItem := MainForm.DVDJobList.Items[FListItemIndexes[0]]; 346 | FItem.SubItems[0] := '0'; 347 | FItem.StateIndex := 0; 348 | except 349 | on E: Exception do 350 | 351 | end; 352 | FProcess.Run; 353 | end 354 | else 355 | FConsoleOutput := '0 cmd' 356 | end 357 | else 358 | FConsoleOutput := 'not 0' 359 | end; 360 | 361 | procedure TDVDRipProcess.Stop; 362 | begin 363 | if FProcess.ProcessInfo.hProcess > 0 then 364 | begin 365 | TerminateProcess(FProcess.ProcessInfo.hProcess, 0); 366 | FFileNames.Clear; 367 | FEncoderStatus := esStopped; 368 | FStoppedByUser := true; 369 | end; 370 | end; 371 | 372 | end. 373 | 374 | -------------------------------------------------------------------------------- /Units/UnitDownloadProcess.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2014 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitDownloadProcess; 21 | 22 | interface 23 | 24 | uses 25 | Classes, Windows, SysUtils, JvCreateProcess, Messages, StrUtils, UnitSettings, 26 | ComCtrls, Generics.Collections, Graphics; 27 | 28 | // current state of the process 29 | type 30 | TProcessState = (esEncoding, esStopped, esDone); 31 | 32 | type 33 | TProcessType = (youtubedl, ffmpeg, mp4box, subrenamer); 34 | 35 | type 36 | TRenameJob = record 37 | AudioFilePath: string; 38 | VideoFilePath: string; 39 | TempMuxedFilePath: string; 40 | end; 41 | 42 | type 43 | TDownloadJob = class 44 | ApplicationPath: string; 45 | CommandLine: string; 46 | FileName: string; 47 | ProcessType: TProcessType; 48 | ProcessInfo: string; 49 | FileIndex: integer; 50 | RenameJob: TRenameJob; 51 | SubtitleFilePath: string; 52 | IsWebm: Boolean; 53 | constructor Create(); 54 | end; 55 | 56 | TDownloadJobs = TList; 57 | 58 | type 59 | TDownloadProcess = class(TObject) 60 | private 61 | // process 62 | FProcess: TJvCreateProcess; 63 | FDownloadJobs: TDownloadJobs; 64 | // index of current command line. Also progress. 65 | FCommandIndex: integer; 66 | // encoder's state 67 | FEncoderStatus: TProcessState; 68 | // flag to indicate if encoding is stopped by user 69 | FStoppedByUser: Boolean; 70 | FErrorLog: TStringList; 71 | 72 | // process events 73 | procedure ProcessRead(Sender: TObject; const S: string; const StartsOnNewLine: Boolean); 74 | procedure ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 75 | // updates progress information shown in the list item 76 | procedure UpdateMainFormItem(const ProgressStr: string; const Progress: integer); 77 | 78 | // field variable read funcs 79 | function GetProcessID: integer; 80 | function GetFileName: string; 81 | function GetCurrentProcessType: TProcessType; 82 | function GetInfo: string; 83 | function GetCommandCount: integer; 84 | function GetExeName: string; 85 | function GetFileIndex: Integer; 86 | function GetProgress(const ConsoleOutput: string): Integer; 87 | procedure ProcessSubtitleFile(const FilePath: string); 88 | public 89 | property EncoderStatus: TProcessState read FEncoderStatus; 90 | property FilesDone: integer read FCommandIndex; 91 | property ProcessID: integer read GetProcessID; 92 | property CurrentFile: string read GetFileName; 93 | property CurrentProcessType: TProcessType read GetCurrentProcessType; 94 | property Info: string read GetInfo; 95 | property CommandCount: integer read GetCommandCount; 96 | property ExeName: string read GetExeName; 97 | property FileIndex: Integer read GetFileIndex; 98 | property DownloadJobs: TDownloadJobs read FDownloadJobs write FDownloadJobs; 99 | constructor Create(); 100 | destructor Destroy(); override; 101 | procedure Start(); 102 | procedure Stop(); 103 | procedure ResetValues(); 104 | function GetConsoleOutput(): TStrings; 105 | end; 106 | 107 | implementation 108 | 109 | { TDownloadProcess } 110 | 111 | uses 112 | UnitMain; 113 | 114 | constructor TDownloadProcess.Create; 115 | begin 116 | inherited Create; 117 | 118 | FProcess := TJvCreateProcess.Create(nil); 119 | with FProcess do 120 | begin 121 | OnRead := ProcessRead; 122 | OnTerminate := ProcessTerminate; 123 | ConsoleOptions := [coRedirect]; 124 | CreationFlags := [cfUnicode]; 125 | Priority := ppIdle; 126 | 127 | with StartupInfo do 128 | begin 129 | DefaultPosition := False; 130 | DefaultSize := False; 131 | DefaultWindowState := False; 132 | ShowWindow := swHide; 133 | end; 134 | 135 | WaitForTerminate := true; 136 | end; 137 | 138 | FDownloadJobs := TDownloadJobs.Create; 139 | FEncoderStatus := esStopped; 140 | FStoppedByUser := False; 141 | FCommandIndex := 0; 142 | FErrorLog := TStringList.Create; 143 | end; 144 | 145 | destructor TDownloadProcess.Destroy; 146 | begin 147 | inherited Destroy; 148 | FDownloadJobs.Free; 149 | FProcess.Free; 150 | FErrorLog.Free; 151 | end; 152 | 153 | function TDownloadProcess.GetCommandCount: integer; 154 | begin 155 | Result := FDownloadJobs.Count; 156 | end; 157 | 158 | function TDownloadProcess.GetConsoleOutput: TStrings; 159 | begin 160 | Result := FErrorLog; 161 | end; 162 | 163 | function TDownloadProcess.GetCurrentProcessType: TProcessType; 164 | begin 165 | Result := ffmpeg; 166 | if FCommandIndex < FDownloadJobs.Count then 167 | Result := FDownloadJobs[FCommandIndex].ProcessType; 168 | end; 169 | 170 | function TDownloadProcess.GetExeName: string; 171 | begin 172 | if FCommandIndex < FDownloadJobs.Count then 173 | Result := FDownloadJobs[FCommandIndex].ApplicationPath; 174 | end; 175 | 176 | function TDownloadProcess.GetFileIndex: Integer; 177 | begin 178 | Result := -1; 179 | if FCommandIndex < FDownloadJobs.Count then 180 | Result := FDownloadJobs[FCommandIndex].FileIndex; 181 | end; 182 | 183 | function TDownloadProcess.GetFileName: string; 184 | begin 185 | if FCommandIndex < FDownloadJobs.Count then 186 | Result := FDownloadJobs[FCommandIndex].FileName; 187 | end; 188 | 189 | function TDownloadProcess.GetInfo: string; 190 | begin 191 | if FCommandIndex < FDownloadJobs.Count then 192 | Result := FDownloadJobs[FCommandIndex].ProcessInfo; 193 | end; 194 | 195 | function TDownloadProcess.GetProcessID: integer; 196 | begin 197 | Result := FProcess.ProcessInfo.hProcess; 198 | end; 199 | 200 | function TDownloadProcess.GetProgress(const ConsoleOutput: string): Integer; 201 | var 202 | StrPos1, StrPos2: Integer; 203 | TmpStr: string; 204 | TmpInt: Integer; 205 | begin 206 | Result := 0; 207 | TmpStr := ConsoleOutput; 208 | StrPos1 := Pos('[download] ', TmpStr); 209 | StrPos2 := Pos('%', TmpStr); 210 | TmpStr := Trim(copy(TmpStr, StrPos1 + 10, StrPos2 - StrPos1 - 12)); 211 | if TryStrToInt(TmpStr, TmpInt) then 212 | begin 213 | Result := TmpInt; 214 | end; 215 | end; 216 | 217 | procedure TDownloadProcess.ProcessRead(Sender: TObject; const S: string; const StartsOnNewLine: Boolean); 218 | begin 219 | UpdateMainFormItem(GetInfo + ' ' + S.Replace('[download]', '').Trim, GetProgress(S)); 220 | end; 221 | 222 | procedure TDownloadProcess.ProcessSubtitleFile(const FilePath: string); 223 | const 224 | START_FLAG = 'Language:'; 225 | var 226 | LFileContent: TStringList; 227 | LOutputFile: TStringList; 228 | LOutputFilePath: string; 229 | LLine: string; 230 | I: integer; 231 | LStartIndex: integer; 232 | begin 233 | try 234 | if FileExists(FilePath) then 235 | begin 236 | try 237 | LFileContent := TStringList.Create; 238 | 239 | LFileContent.LoadFromFile(FilePath, TEncoding.UTF8); 240 | if LFileContent.Count > 0 then 241 | begin 242 | LStartIndex := -1; 243 | for I := 0 to LFileContent.Count - 1 do 244 | begin 245 | LLine := Trim(LFileContent[i]); 246 | if LLine.StartsWith(START_FLAG) then 247 | begin 248 | LStartIndex := i; 249 | Break; 250 | end; 251 | end; 252 | // means found start 253 | if LStartIndex > -1 then 254 | begin 255 | LOutputFile := TStringList.Create; 256 | try 257 | for I := LStartIndex + 1 to LFileContent.Count - 1 do 258 | begin 259 | LLine := Trim(LFileContent[i]); 260 | LOutputFile.Add(LLine); 261 | end; 262 | 263 | try 264 | LOutputFilePath := ChangeFileExt(FilePath, '.srt'); 265 | LOutputFile.SaveToFile(LOutputFilePath, TEncoding.UTF8); 266 | DeleteFile(FilePath); 267 | ExitCode := 0; 268 | except 269 | on E: Exception do 270 | begin 271 | MainForm.AddToLog(0, E.ClassName + ': ' + E.Message); 272 | ExitCode := 1; 273 | end; 274 | end; 275 | finally 276 | LOutputFile.Free; 277 | end; 278 | end 279 | else 280 | begin 281 | MainForm.AddToLog(0, 'Unable to find subtitle file start flag'); 282 | end; 283 | end; 284 | finally 285 | LFileContent.Free; 286 | end; 287 | end 288 | else 289 | begin 290 | MainForm.AddToLog(0, 'File not found: ' + FilePath); 291 | end; 292 | except 293 | on E: Exception do 294 | begin 295 | MainForm.AddToLog(0, E.ClassName + ': ' + E.Message); 296 | end; 297 | end; 298 | end; 299 | 300 | procedure TDownloadProcess.ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 301 | begin 302 | FEncoderStatus := esStopped; 303 | if FDownloadJobs[FCommandIndex].RenameJob.AudioFilePath <> '' then 304 | begin 305 | if FileExists(FDownloadJobs[FCommandIndex].RenameJob.AudioFilePath) then 306 | begin 307 | if not DeleteFile(FDownloadJobs[FCommandIndex].RenameJob.AudioFilePath) then 308 | begin 309 | MainForm.AddToLog(0, 'Unable to delete ' + ExtractFileName(FDownloadJobs[FCommandIndex].RenameJob.AudioFilePath)); 310 | end; 311 | end; 312 | if FileExists(FDownloadJobs[FCommandIndex].RenameJob.VideoFilePath) then 313 | begin 314 | if not DeleteFile(FDownloadJobs[FCommandIndex].RenameJob.VideoFilePath) then 315 | begin 316 | MainForm.AddToLog(0, 'Unable to delete ' + ExtractFileName(FDownloadJobs[FCommandIndex].RenameJob.VideoFilePath)); 317 | end; 318 | end; 319 | if not RenameFile(FDownloadJobs[FCommandIndex].RenameJob.TempMuxedFilePath, FDownloadJobs[FCommandIndex].RenameJob.VideoFilePath) then 320 | begin 321 | MainForm.AddToLog(0, 'Unable to rename ' + ExtractFileName(FDownloadJobs[FCommandIndex].RenameJob.TempMuxedFilePath) + ' to ' + ExtractFileName(FDownloadJobs[FCommandIndex].RenameJob.VideoFilePath)); 322 | end; 323 | end; 324 | 325 | if FileExists(FDownloadJobs[FCommandIndex].SubtitleFilePath) then 326 | begin 327 | ProcessSubtitleFile(FDownloadJobs[FCommandIndex].SubtitleFilePath); 328 | end; 329 | 330 | // if user has stopped downloading do not try the next item 331 | if FStoppedByUser then 332 | begin 333 | UpdateMainFormItem('Stopped', 0); 334 | FEncoderStatus := esStopped; 335 | end 336 | else 337 | begin 338 | // if process has not exited properly, add it to the log 339 | MainForm.AddToLog(0, ExtractFileName(FDownloadJobs[FCommandIndex].ApplicationPath) + ' has exited with ' + FloatToStr(ExitCode) + '.'); 340 | FErrorLog.AddStrings(FProcess.ConsoleOutput); 341 | FProcess.ConsoleOutput.Clear; 342 | if ExitCode <> 0 then 343 | begin 344 | UpdateMainFormItem('Error code: ' + FloatToStr(ExitCode), 0); 345 | // Inc(MainForm.FProcessErrorCount); 346 | end 347 | else 348 | begin 349 | UpdateMainFormItem('Done', 100); 350 | end; 351 | 352 | // run next command 353 | inc(FCommandIndex); 354 | if FCommandIndex < FDownloadJobs.Count then 355 | begin 356 | FProcess.CommandLine := FDownloadJobs[FCommandIndex].CommandLine; 357 | FProcess.ApplicationName := FDownloadJobs[FCommandIndex].ApplicationPath; 358 | FEncoderStatus := esEncoding; 359 | UpdateMainFormItem('Starting...', 0); 360 | FProcess.Run; 361 | end 362 | else 363 | begin 364 | // done 365 | FEncoderStatus := esDone; 366 | end; 367 | end; 368 | end; 369 | 370 | procedure TDownloadProcess.ResetValues; 371 | begin 372 | // reset all lists, indexes etc 373 | FDownloadJobs.Clear; 374 | FCommandIndex := 0; 375 | FProcess.ConsoleOutput.Clear; 376 | FStoppedByUser := False; 377 | FErrorLog.Clear; 378 | end; 379 | 380 | procedure TDownloadProcess.Start; 381 | begin 382 | // start with the first item if download is not already started 383 | if FProcess.ProcessInfo.hProcess = 0 then 384 | begin 385 | if FDownloadJobs.Count > 0 then 386 | begin 387 | FProcess.ApplicationName := FDownloadJobs[0].ApplicationPath; 388 | FProcess.CommandLine := FDownloadJobs[0].CommandLine; 389 | FEncoderStatus := esEncoding; 390 | UpdateMainFormItem('Starting...', 0); 391 | FProcess.Run; 392 | end 393 | end 394 | end; 395 | 396 | procedure TDownloadProcess.Stop; 397 | begin 398 | // terminate running process unless it's already stopped 399 | if FProcess.ProcessInfo.hProcess > 0 then 400 | begin 401 | TerminateProcess(FProcess.ProcessInfo.hProcess, 0); 402 | UpdateMainFormItem('Stopped', 0); 403 | FEncoderStatus := esStopped; 404 | FStoppedByUser := true; 405 | end; 406 | end; 407 | 408 | procedure TDownloadProcess.UpdateMainFormItem(const ProgressStr: string; const Progress: integer); 409 | begin 410 | if GetFileIndex < MainForm.FVideoDownloadListItems.Count then 411 | begin 412 | MainForm.FVideoDownloadListItems[GetFileIndex].ProgressLabel.Caption := ProgressStr; 413 | MainForm.FVideoDownloadListItems[GetFileIndex].ProgressBar.Progress := Progress; 414 | end; 415 | end; 416 | 417 | { TDownloadJob } 418 | 419 | constructor TDownloadJob.Create; 420 | begin 421 | inherited; 422 | ApplicationPath := ''; 423 | CommandLine := ''; 424 | FileName := ''; 425 | ProcessType := TProcessType.youtubedl; 426 | ProcessInfo := ''; 427 | FileIndex := -1; 428 | SubtitleFilePath := ''; 429 | IsWebm := false; 430 | end; 431 | 432 | end. 433 | 434 | -------------------------------------------------------------------------------- /Units/UnitEncoder.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitEncoder; 21 | 22 | interface 23 | 24 | uses Classes, Windows, SysUtils, JvCreateProcess, Messages, StrUtils, UnitSettings, ComCtrls, Generics.Collections; 25 | 26 | // current state of the process 27 | type 28 | TEncoderStatus = (esEncoding, esStopped, esDone); 29 | 30 | type 31 | TProcessType = (mencoder, ffmpeg, mp4box, renametool, imagemagick); 32 | 33 | type 34 | TEncodeJob = packed record 35 | CommandLine: string; 36 | ProcessPath: string; 37 | ProcessType: TProcessType; 38 | SourceFileName: string; 39 | SourceDuration: integer; 40 | EncodingInformation: string; 41 | FileListIndex: integer; 42 | EncodingOutputFilePath: string; 43 | FinalFilePath: string; 44 | IsMergeJob: Boolean; 45 | end; 46 | 47 | type 48 | TEncodeJobs = TList; 49 | 50 | type 51 | TEncodingProcess = class(TObject) 52 | private 53 | // process 54 | FProcess: TJvCreateProcess; 55 | FEncodeJobs: TEncodeJobs; 56 | // index of current command line. Also progress. 57 | FCommandIndex: integer; 58 | // last line backend has written to console 59 | FConsoleOutput: string; 60 | // encoder's state 61 | FEncoderStatus: TEncoderStatus; 62 | // flag to indicate if encoding is stopped by user 63 | FStoppedByUser: Boolean; 64 | // index of currently used duration 65 | FDurationIndex: integer; 66 | FItem: TListItem; 67 | FTerminateCounter: integer; 68 | 69 | // process events 70 | procedure ProcessRead(Sender: TObject; const S: string; const StartsOnNewLine: Boolean); 71 | procedure ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 72 | 73 | procedure UpdateProgressItem(const Msg: string; const Progress: string; const StateIndex: integer); 74 | 75 | // field variable read funcs 76 | function GetProcessID: integer; 77 | function GetFileName: string; 78 | function GetCurrentProcessType: TProcessType; 79 | function GetCurrentDuration: integer; 80 | function GetInfo: string; 81 | function GetCommandCount: integer; 82 | function GetExeName: string; 83 | function GetFileIndex: Integer; 84 | function GetPercentage: integer; 85 | public 86 | property ConsoleOutput: string read FConsoleOutput; 87 | property EncoderStatus: TEncoderStatus read FEncoderStatus; 88 | property FilesDone: integer read FCommandIndex; 89 | property ProcessID: integer read GetProcessID; 90 | property CurrentFile: string read GetFileName; 91 | property CurrentProcessType: TProcessType read GetCurrentProcessType; 92 | property CurrentDuration: integer read GetCurrentDuration; 93 | property Info: string read GetInfo; 94 | property CommandCount: integer read GetCommandCount; 95 | property ExeName: string read GetExeName; 96 | property FileIndex: Integer read GetFileIndex; 97 | property EncodeJobs: TEncodeJobs read FEncodeJobs write FEncodeJobs; 98 | 99 | constructor Create(); 100 | destructor Destroy(); override; 101 | 102 | procedure Start(); 103 | procedure Stop(); 104 | procedure ResetValues(); 105 | function GetConsoleOutput(): TStrings; 106 | end; 107 | 108 | implementation 109 | 110 | { TMyProcess } 111 | 112 | uses UnitMain; 113 | 114 | constructor TEncodingProcess.Create; 115 | begin 116 | inherited Create; 117 | 118 | FProcess := TJvCreateProcess.Create(nil); 119 | with FProcess do 120 | begin 121 | OnRead := ProcessRead; 122 | OnTerminate := ProcessTerminate; 123 | ConsoleOptions := [coRedirect]; 124 | CreationFlags := [cfUnicode]; 125 | Priority := ppIdle; 126 | 127 | with StartupInfo do 128 | begin 129 | DefaultPosition := False; 130 | DefaultSize := False; 131 | DefaultWindowState := False; 132 | ShowWindow := swHide; 133 | end; 134 | 135 | WaitForTerminate := true; 136 | end; 137 | 138 | FEncodeJobs := TEncodeJobs.Create; 139 | FEncoderStatus := esStopped; 140 | FStoppedByUser := False; 141 | FDurationIndex := 0; 142 | FCommandIndex := 0; 143 | end; 144 | 145 | destructor TEncodingProcess.Destroy; 146 | begin 147 | FreeAndNil(FEncodeJobs); 148 | FProcess.Free; 149 | inherited Destroy; 150 | 151 | end; 152 | 153 | function TEncodingProcess.GetCommandCount: integer; 154 | begin 155 | Result := FEncodeJobs.Count; 156 | end; 157 | 158 | function TEncodingProcess.GetConsoleOutput: TStrings; 159 | begin 160 | Result := FProcess.ConsoleOutput; 161 | end; 162 | 163 | function TEncodingProcess.GetCurrentDuration: integer; 164 | begin 165 | if FCommandIndex < FEncodeJobs.Count then 166 | Result := FEncodeJobs[FDurationIndex].SourceDuration; 167 | end; 168 | 169 | function TEncodingProcess.GetCurrentProcessType: TProcessType; 170 | begin 171 | Result := ffmpeg; 172 | if FCommandIndex < FEncodeJobs.Count then 173 | Result := FEncodeJobs[FCommandIndex].ProcessType; 174 | end; 175 | 176 | function TEncodingProcess.GetExeName: string; 177 | begin 178 | if FCommandIndex < FEncodeJobs.Count then 179 | Result := FEncodeJobs[FCommandIndex].ProcessPath; 180 | end; 181 | 182 | function TEncodingProcess.GetFileIndex: Integer; 183 | begin 184 | Result := 0; 185 | if FCommandIndex < FEncodeJobs.Count then 186 | Result := FEncodeJobs[FCommandIndex].FileListIndex; 187 | end; 188 | 189 | function TEncodingProcess.GetFileName: string; 190 | begin 191 | if FCommandIndex < FEncodeJobs.Count then 192 | Result := FEncodeJobs[FCommandIndex].SourceFileName; 193 | end; 194 | 195 | function TEncodingProcess.GetInfo: string; 196 | begin 197 | if FCommandIndex < FEncodeJobs.Count then 198 | Result := FEncodeJobs[FCommandIndex].EncodingInformation; 199 | end; 200 | 201 | function TEncodingProcess.GetPercentage: integer; 202 | var 203 | LPercentageStr: string; 204 | LPercentageInt: Integer; 205 | begin 206 | Result := 0; 207 | if Length(FConsoleOutput) > 0 then 208 | begin 209 | if FProcess.ProcessInfo.hProcess > 0 then 210 | begin 211 | // decide running process kind 212 | if (GetCurrentProcessType = ffmpeg) then 213 | begin 214 | LPercentageStr := MainForm.GetFFmpegPosition(FConsoleOutput, GetCurrentDuration); 215 | end 216 | else if GetCurrentProcessType = mencoder then 217 | begin 218 | LPercentageStr := MainForm.GetMencoderPosition(FConsoleOutput); 219 | end 220 | else if GetCurrentProcessType = mp4box then 221 | begin 222 | LPercentageStr := MainForm.GetMp4Progress(FConsoleOutput); 223 | end; 224 | // make sure str is actually a number 225 | if TryStrToInt(LPercentageStr, LPercentageInt) then 226 | begin 227 | Result := LPercentageInt; 228 | end; 229 | end; 230 | end; 231 | end; 232 | 233 | function TEncodingProcess.GetProcessID: integer; 234 | begin 235 | Result := FProcess.ProcessInfo.hProcess; 236 | end; 237 | 238 | procedure TEncodingProcess.ProcessRead(Sender: TObject; const S: string; const StartsOnNewLine: Boolean); 239 | var 240 | LCurrVal: integer; 241 | begin 242 | Inc(FTerminateCounter); 243 | if (FTerminateCounter mod 5) = 0 then 244 | begin 245 | FConsoleOutput := Trim(S); 246 | try 247 | if Assigned(FItem) then 248 | begin 249 | if TryStrToInt(FItem.SubItems[1], LCurrVal) then 250 | begin 251 | if GetPercentage > LCurrVal then 252 | begin 253 | UpdateProgressItem(FItem.SubItems[0], FloatToStr(GetPercentage), FItem.StateIndex); 254 | end; 255 | end; 256 | end; 257 | except 258 | on E: Exception do 259 | // ignored 260 | end; 261 | end; 262 | end; 263 | 264 | procedure TEncodingProcess.ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 265 | begin 266 | FEncoderStatus := esStopped; 267 | if FStoppedByUser then 268 | begin 269 | UpdateProgressItem('Stopped', '0', 3); 270 | FEncoderStatus := esStopped; 271 | // delete unfinished files. 272 | if SettingsForm.DeleteUnfinBtn.Checked then 273 | begin 274 | if FCommandIndex < FEncodeJobs.Count then 275 | begin 276 | if FileExists(FEncodeJobs[FCommandIndex].EncodingOutputFilePath) then 277 | begin 278 | if not DeleteFile(FEncodeJobs[FCommandIndex].EncodingOutputFilePath) then 279 | begin 280 | RaiseLastOSError; 281 | end 282 | else 283 | begin 284 | MainForm.AddToLog(0, 'Deleted unfinished file: ' + ExtractFileName(FEncodeJobs[FCommandIndex].EncodingOutputFilePath)); 285 | end; 286 | end; 287 | end; 288 | end; 289 | end 290 | else 291 | begin 292 | MainForm.UpdateProgress; 293 | // processed that need duration information 294 | if GetCurrentProcessType = ffmpeg then 295 | begin 296 | Inc(FDurationIndex); 297 | end; 298 | 299 | // run next command 300 | inc(FCommandIndex); 301 | UpdateProgressItem('Done', '100', 2); 302 | if FCommandIndex < FEncodeJobs.Count then 303 | begin 304 | FProcess.CommandLine := FEncodeJobs[FCommandIndex].CommandLine; 305 | FProcess.ApplicationName := FEncodeJobs[FCommandIndex].ProcessPath; 306 | FEncoderStatus := esEncoding; 307 | FConsoleOutput := ''; 308 | try 309 | FItem := MainForm.ProgressList.Items.Add; 310 | if Assigned(FItem) then 311 | begin 312 | FItem.Caption := ExtractFileName(FEncodeJobs[FCommandIndex].SourceFileName); 313 | FItem.SubItems.Add(FEncodeJobs[FCommandIndex].EncodingInformation); 314 | FItem.SubItems.Add('0'); 315 | FItem.StateIndex := 0; 316 | FItem.MakeVisible(False); 317 | end; 318 | except 319 | on E: Exception do 320 | // ignored 321 | end; 322 | FProcess.Run; 323 | end 324 | else 325 | begin 326 | // done 327 | FEncoderStatus := esDone; 328 | end; 329 | end; 330 | end; 331 | 332 | procedure TEncodingProcess.ResetValues; 333 | begin 334 | // reset all lists, indexes etc 335 | FEncodeJobs.Clear; 336 | FCommandIndex := 0; 337 | FDurationIndex := 0; 338 | FConsoleOutput := ''; 339 | FProcess.ConsoleOutput.Clear; 340 | FStoppedByUser := False; 341 | FItem := nil; 342 | FTerminateCounter := 0; 343 | end; 344 | 345 | procedure TEncodingProcess.Start; 346 | begin 347 | if FProcess.ProcessInfo.hProcess = 0 then 348 | begin 349 | if FEncodeJobs.Count > 0 then 350 | begin 351 | if FileExists(FEncodeJobs[0].ProcessPath) then 352 | begin 353 | FProcess.ApplicationName := FEncodeJobs[0].ProcessPath; 354 | FProcess.CommandLine := FEncodeJobs[0].CommandLine; 355 | FEncoderStatus := esEncoding; 356 | try 357 | FItem := MainForm.ProgressList.Items.Add; 358 | if Assigned(FItem) then 359 | begin 360 | FItem.Caption := ExtractFileName(GetFileName); 361 | FItem.SubItems.Add(GetInfo); 362 | FItem.SubItems.Add('0'); 363 | FItem.StateIndex := 0; 364 | FItem.MakeVisible(False); 365 | end; 366 | except 367 | on E: Exception do 368 | // ignored 369 | end; 370 | FProcess.Run; 371 | end 372 | else 373 | FConsoleOutput := 'encoder' 374 | end 375 | else 376 | FConsoleOutput := '0 cmd' 377 | end 378 | else 379 | FConsoleOutput := 'not 0' 380 | end; 381 | 382 | procedure TEncodingProcess.Stop; 383 | begin 384 | if FProcess.ProcessInfo.hProcess > 0 then 385 | begin 386 | TerminateProcess(FProcess.ProcessInfo.hProcess, 0); 387 | FEncoderStatus := esStopped; 388 | FStoppedByUser := true; 389 | end; 390 | end; 391 | 392 | procedure TEncodingProcess.UpdateProgressItem(const Msg: string; const Progress: string; const StateIndex: integer); 393 | begin 394 | try 395 | if Assigned(FItem) then 396 | begin 397 | FItem.SubItems[0] := Msg; 398 | FItem.SubItems[1] := Progress; 399 | FItem.StateIndex := StateIndex; 400 | end; 401 | except 402 | on E: Exception do 403 | // ignore 404 | end; 405 | end; 406 | 407 | end. 408 | -------------------------------------------------------------------------------- /Units/UnitFileInfo.pas: -------------------------------------------------------------------------------- 1 | {* 2 | * Copyright (C) 2011-2013 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TAudioConverter. If not, see . 18 | * 19 | *} 20 | 21 | unit UnitFileInfo; 22 | 23 | interface 24 | 25 | uses Classes, Windows, SysUtils, JvCreateProcess, Messages, StrUtils; 26 | 27 | type 28 | TStatus = (dsReading, dsDone); 29 | 30 | type 31 | TFileInfo = class(TObject) 32 | private 33 | FProcess: TJvCreateProcess; 34 | FStatus: TStatus; 35 | FFileName: string; 36 | FFFMpegPath: string; 37 | FAudioTrackIndexes: TStringList; 38 | FVideoIndex: string; 39 | 40 | procedure ProcessRead(Sender: TObject; const S: string; const StartsOnNewLine: Boolean); 41 | procedure ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 42 | public 43 | property FileInfoStatus: TStatus read FStatus; 44 | property AudioStreamIndexes: TStringList read FAudioTrackIndexes; 45 | property VideoIndex: string read FVideoIndex; 46 | 47 | constructor Create(const FileName: string; const FFMpegPath: string); 48 | destructor Destroy(); override; 49 | 50 | procedure Start(); 51 | end; 52 | 53 | implementation 54 | 55 | { TFileInfo } 56 | 57 | constructor TFileInfo.Create(const FileName: string; const FFMpegPath: string); 58 | begin 59 | inherited Create; 60 | 61 | FProcess := TJvCreateProcess.Create(nil); 62 | with FProcess do 63 | begin 64 | OnRead := ProcessRead; 65 | OnTerminate := ProcessTerminate; 66 | ConsoleOptions := [coRedirect]; 67 | CreationFlags := [cfUnicode]; 68 | Priority := ppIdle; 69 | 70 | with StartupInfo do 71 | begin 72 | DefaultPosition := False; 73 | DefaultSize := False; 74 | DefaultWindowState := False; 75 | ShowWindow := swHide; 76 | end; 77 | 78 | WaitForTerminate := true; 79 | end; 80 | 81 | FStatus := dsReading; 82 | FFileName := FileName; 83 | FFFMpegPath := FFMpegPath; 84 | FAudioTrackIndexes := TStringList.Create; 85 | 86 | end; 87 | 88 | destructor TFileInfo.Destroy; 89 | begin 90 | inherited Destroy; 91 | FProcess.Free; 92 | FreeAndNil(FAudioTrackIndexes); 93 | end; 94 | 95 | procedure TFileInfo.ProcessRead(Sender: TObject; const S: string; 96 | const StartsOnNewLine: Boolean); 97 | const 98 | Output = 'Output'; 99 | Input = 'Input'; 100 | begin 101 | 102 | end; 103 | 104 | procedure TFileInfo.ProcessTerminate(Sender: TObject; ExitCode: Cardinal); 105 | const 106 | InputStr = 'Input'; 107 | StreamStr = 'Stream'; 108 | var 109 | I: Integer; 110 | FLine: string; 111 | FStartIndex: integer; 112 | FEndIndex: integer; 113 | TmpLst: TStringList; 114 | FInfoLine: string; 115 | begin 116 | FStatus := dsReading; 117 | FStartIndex := -1; 118 | FEndIndex := -1; 119 | 120 | TmpLst := TStringList.Create; 121 | try 122 | TmpLst.Delimiter := ':'; 123 | TmpLst.StrictDelimiter := true; 124 | if FProcess.ConsoleOutput.Count > 0 then 125 | begin 126 | for I := 0 to FProcess.ConsoleOutput.Count - 1 do 127 | begin 128 | FLine := Trim(FProcess.ConsoleOutput[i]); 129 | if InputStr = Copy(FLine, 1, Length(InputStr)) then 130 | begin 131 | FStartIndex := i; 132 | FEndIndex := FProcess.ConsoleOutput.Count - 1; 133 | Break; 134 | end; 135 | end; 136 | 137 | if (FStartIndex <> -1) and (FEndIndex <> -1) then 138 | begin 139 | // get audio streams 140 | for I := FStartIndex to FEndIndex do 141 | begin 142 | FLine := Trim(FProcess.ConsoleOutput[i]); 143 | 144 | if StreamStr = Copy(FLine, 1, Length(StreamStr)) then 145 | begin 146 | TmpLst.DelimitedText := FLine; 147 | 148 | if TmpLst.Count >= 4 then 149 | begin 150 | FInfoLine := Trim(TmpLst[2]); 151 | 152 | if FInfoLine = 'Audio' then 153 | begin 154 | FAudioTrackIndexes.Add(Trim(TmpLst[1])); 155 | end; 156 | end; 157 | 158 | end; 159 | 160 | end; 161 | 162 | // get video stream 163 | for I := FStartIndex to FEndIndex do 164 | begin 165 | FLine := Trim(FProcess.ConsoleOutput[i]); 166 | 167 | if StreamStr = Copy(FLine, 1, Length(StreamStr)) then 168 | begin 169 | TmpLst.DelimitedText := FLine; 170 | 171 | if TmpLst.Count >= 4 then 172 | begin 173 | FInfoLine := Trim(TmpLst[2]); 174 | 175 | if FInfoLine = 'Video' then 176 | begin 177 | FVideoIndex := Trim(TmpLst[1]); 178 | Break; 179 | end; 180 | end; 181 | 182 | end; 183 | 184 | end; 185 | end; 186 | 187 | end; 188 | finally 189 | TmpLst.Free; 190 | FStatus := dsDone; 191 | end; 192 | 193 | end; 194 | 195 | procedure TFileInfo.Start; 196 | begin 197 | 198 | FProcess.ApplicationName := FFFMpegPath; 199 | FProcess.CommandLine := ' -i "' + FFileName + '"'; 200 | FProcess.Run; 201 | 202 | end; 203 | 204 | end. 205 | -------------------------------------------------------------------------------- /Units/UnitFileInfoItem.pas: -------------------------------------------------------------------------------- 1 | unit UnitFileInfoItem; 2 | 3 | interface 4 | 5 | uses 6 | Classes, Generics.Collections, System.SysUtils, UnitSubtitleTypes; 7 | 8 | type 9 | TFileDatePair = record 10 | CreateDate: TDateTime; 11 | ModifiedDate: TDateTime; 12 | end; 13 | 14 | type 15 | TVideoStream = record 16 | FFmpegId: integer; 17 | MEncoderId: integer; 18 | end; 19 | 20 | type 21 | TAudioStream = record 22 | TrackName: string; 23 | FFmpegId: integer; 24 | MEncoderId: integer; 25 | Extension: string; 26 | Delay: Extended; 27 | end; 28 | 29 | type 30 | TSubtitleEmbeddedStream = record 31 | TrackName: string; 32 | Id: integer; 33 | Delay: Extended; 34 | end; 35 | 36 | type 37 | TSubtitleFileStream = record 38 | Path: string; 39 | end; 40 | 41 | type 42 | TFileInfoItem = class(TObject) 43 | // Video ids 44 | FFMmpegVideoID: integer; 45 | MEncoderVideoID: integer; 46 | 47 | // subtitle 48 | SubtitleFileIndex: integer; 49 | SubtitleTrackIndex: integer; 50 | SubtitleEmbeddedStreams: TList; 51 | SubtitleFileStreams: TList; 52 | SelectedSubtitleType: TSubtitleType; 53 | 54 | // audio 55 | AudioIndex: integer; 56 | AudioStreams: TList; 57 | 58 | // range 59 | StartPosition: integer; 60 | EndPosition: integer; 61 | ConstDuration: integer; 62 | // general 63 | FilePath: string; 64 | FileDate: TFileDatePair; 65 | private 66 | function GetSubtitle: string; 67 | function GetAudioID: string; 68 | function GetAudioExt: string; 69 | function GetMencoderAudioID: string; 70 | function GetSubtitleTrackID: string; 71 | function GetSubTrackDelay: string; 72 | function GetAudioTrackDelayAsExtended: Extended; 73 | function GetSubTrackDelayAsExtended: Extended; 74 | function GetAudioTrackDelay: string; 75 | public 76 | property SelectedSubtitleFile: string read GetSubtitle; 77 | property SelectedSubtitleTrack: string read GetSubtitleTrackID; 78 | property SelectedFFmpegAudio: string read GetAudioID; 79 | property SelectedMEncoderAudio: string read GetMencoderAudioID; 80 | property SelectedAudioExt: string read GetAudioExt; 81 | property SelectedSubTrackDelay: string read GetSubTrackDelay; 82 | property SelectedSubTrackDelayAsExtended: Extended read GetSubTrackDelayAsExtended; 83 | property SelectedAudioTrackDelayAsExtended: Extended read GetAudioTrackDelayAsExtended; 84 | property SelectedAudioTrackDelay: string read GetAudioTrackDelay; 85 | constructor Create; 86 | destructor Destroy; override; 87 | procedure SetSelectedAudioTrackDelay(const Value: Extended); 88 | procedure SetSelectedSubTrackDelay(const Value: Extended); 89 | end; 90 | 91 | TFileInfoList = TList; 92 | 93 | implementation 94 | 95 | { TFileInfoItem } 96 | 97 | constructor TFileInfoItem.Create; 98 | begin 99 | inherited; 100 | SubtitleEmbeddedStreams := TList.Create; 101 | SubtitleFileStreams := TList.Create; 102 | AudioStreams := TList.Create; 103 | end; 104 | 105 | destructor TFileInfoItem.Destroy; 106 | begin 107 | inherited; 108 | SubtitleEmbeddedStreams.Free; 109 | SubtitleFileStreams.Free; 110 | AudioStreams.Free; 111 | end; 112 | 113 | function TFileInfoItem.GetAudioExt: string; 114 | begin 115 | Result := '.wav'; 116 | if AudioIndex > -1 then 117 | begin 118 | if AudioIndex < AudioStreams.Count then 119 | begin 120 | Result := AudioStreams[AudioIndex].Extension; 121 | end; 122 | end; 123 | end; 124 | 125 | function TFileInfoItem.GetAudioID: string; 126 | begin 127 | Result := '1'; 128 | if AudioIndex > -1 then 129 | begin 130 | if AudioIndex < AudioStreams.Count then 131 | begin 132 | Result := FloatToStr(AudioStreams[AudioIndex].FFmpegId); 133 | end; 134 | end; 135 | end; 136 | 137 | function TFileInfoItem.GetAudioTrackDelay: string; 138 | begin 139 | Result := '0'; 140 | if AudioIndex > -1 then 141 | begin 142 | if AudioIndex < AudioStreams.Count then 143 | begin 144 | Result := FloatToStr(AudioStreams[AudioIndex].Delay); 145 | end; 146 | end; 147 | end; 148 | 149 | function TFileInfoItem.GetAudioTrackDelayAsExtended: Extended; 150 | begin 151 | Result := 0; 152 | if AudioIndex > -1 then 153 | begin 154 | if AudioIndex < AudioStreams.Count then 155 | begin 156 | Result := AudioStreams[AudioIndex].Delay; 157 | end; 158 | end; 159 | end; 160 | 161 | function TFileInfoItem.GetMencoderAudioID: string; 162 | begin 163 | Result := '1'; 164 | if AudioIndex > -1 then 165 | begin 166 | if AudioIndex < AudioStreams.Count then 167 | begin 168 | Result := FloatToStr(AudioStreams[AudioIndex].MEncoderId); 169 | end; 170 | end; 171 | end; 172 | 173 | function TFileInfoItem.GetSubtitle: string; 174 | begin 175 | Result := ''; 176 | if SubtitleFileIndex > -1 then 177 | begin 178 | if SubtitleFileIndex < SubtitleFileStreams.Count then 179 | begin 180 | Result := SubtitleFileStreams[SubtitleFileIndex].Path; 181 | end; 182 | end; 183 | end; 184 | 185 | function TFileInfoItem.GetSubtitleTrackID: string; 186 | begin 187 | Result := ''; 188 | if SubtitleTrackIndex > -1 then 189 | begin 190 | if SubtitleTrackIndex < SubtitleEmbeddedStreams.Count then 191 | begin 192 | Result := FloatToStr(SubtitleEmbeddedStreams[SubtitleTrackIndex].Id); 193 | end; 194 | end; 195 | end; 196 | 197 | function TFileInfoItem.GetSubTrackDelay: string; 198 | begin 199 | Result := '0'; 200 | if SubtitleTrackIndex > -1 then 201 | begin 202 | if SubtitleTrackIndex < SubtitleEmbeddedStreams.Count then 203 | begin 204 | Result := FloatToStr(SubtitleEmbeddedStreams[SubtitleTrackIndex].Delay); 205 | end; 206 | end; 207 | end; 208 | 209 | function TFileInfoItem.GetSubTrackDelayAsExtended: Extended; 210 | begin 211 | Result := 0; 212 | if SubtitleTrackIndex > -1 then 213 | begin 214 | if SubtitleTrackIndex < SubtitleEmbeddedStreams.Count then 215 | begin 216 | Result := SubtitleEmbeddedStreams[SubtitleTrackIndex].Delay; 217 | end; 218 | end; 219 | end; 220 | 221 | procedure TFileInfoItem.SetSelectedAudioTrackDelay(const Value: Extended); 222 | var 223 | LTrack: TAudioStream; 224 | begin 225 | if AudioIndex > -1 then 226 | begin 227 | if AudioIndex < AudioStreams.Count then 228 | begin 229 | LTrack := AudioStreams[AudioIndex]; 230 | LTrack.Delay := Value; 231 | AudioStreams[AudioIndex] := LTrack; 232 | end; 233 | end; 234 | end; 235 | 236 | procedure TFileInfoItem.SetSelectedSubTrackDelay(const Value: Extended); 237 | var 238 | LTrack: TSubtitleEmbeddedStream; 239 | begin 240 | if SubtitleTrackIndex > -1 then 241 | begin 242 | if SubtitleTrackIndex < SubtitleEmbeddedStreams.Count then 243 | begin 244 | LTrack := SubtitleEmbeddedStreams[SubtitleTrackIndex]; 245 | LTrack.Delay := Value; 246 | SubtitleEmbeddedStreams[SubtitleTrackIndex] := LTrack; 247 | end; 248 | end; 249 | end; 250 | 251 | end. 252 | 253 | -------------------------------------------------------------------------------- /Units/UnitFileItem.pas: -------------------------------------------------------------------------------- 1 | { * 2 | * Copyright (C) 2011-2016 ozok 3 | * 4 | * This file is part of TEncoder. 5 | * 6 | * TEncoder is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 2 of the License. 9 | * 10 | * 11 | * TEncoder is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with TEncoder. If not, see . 18 | * 19 | * } 20 | unit UnitFileItem; 21 | 22 | interface 23 | 24 | uses Classes, Windows, SysUtils, Messages, StrUtils, Generics.Collections; 25 | 26 | type 27 | TFileItem = class 28 | private 29 | function GetSelectedSub: string; 30 | function GetSelectedFFmpegAudio: Integer; 31 | function GetAudioDelayStr: string; 32 | function GetSubCount: Integer; 33 | public 34 | FullFilePath: string; 35 | FileDuration: Integer; 36 | StartPos: Integer; 37 | EndPos: Integer; 38 | SubtitleFiles: TStringList; 39 | SubtitleFileIndex: Integer; 40 | FFMpegAudioStreams: TStringList; 41 | FFMpegAudioStreamIndexList: TList; 42 | FFMpegSelectedAudioStreamIndex: Integer; 43 | MEncoderAudioStreams: TStringList; 44 | MEncoderAudioStreamIndexList: TList; 45 | MEncoderSelectedAudioStreamIndex: Integer; 46 | AudioDelay: Extended; 47 | SubtitleDelay: Extended; 48 | CopyID: string; 49 | CopyExt: string; 50 | AudioExt: string; 51 | property SelectedSubtitleFile: string read GetSelectedSub; 52 | property SelectedFFmpegAudio: Integer read GetSelectedFFmpegAudio; 53 | property AudioDelayStr: string read GetAudioDelayStr; 54 | property SubtitleCount: Integer read GetSubCount; 55 | 56 | constructor Create; 57 | destructor Destroy; override; 58 | end; 59 | 60 | PFileItem = ^TFileItem; 61 | TFileItemList = TList; 62 | 63 | implementation 64 | 65 | { TFileItem } 66 | 67 | constructor TFileItem.Create; 68 | begin 69 | SubtitleFiles := TStringList.Create; 70 | FFMpegAudioStreams := TStringList.Create; 71 | FFMpegAudioStreamIndexList := TList.Create; 72 | MEncoderAudioStreams := TStringList.Create; 73 | MEncoderAudioStreamIndexList := TList.Create; 74 | FFMpegSelectedAudioStreamIndex := -1; 75 | MEncoderSelectedAudioStreamIndex := -1; 76 | SubtitleFileIndex := -1; 77 | end; 78 | 79 | destructor TFileItem.Destroy; 80 | begin 81 | inherited; 82 | SubtitleFiles.Free; 83 | FFMpegAudioStreams.Free; 84 | FFMpegAudioStreamIndexList.Free; 85 | MEncoderAudioStreams.Free; 86 | MEncoderAudioStreamIndexList.Free; 87 | end; 88 | 89 | function TFileItem.GetAudioDelayStr: string; 90 | begin 91 | Result := FloatToStr(AudioDelay); 92 | end; 93 | 94 | function TFileItem.GetSelectedFFmpegAudio: Integer; 95 | begin 96 | Result := FFMpegAudioStreamIndexList[FFMpegSelectedAudioStreamIndex]; 97 | end; 98 | 99 | function TFileItem.GetSelectedSub: string; 100 | begin 101 | Result := SubtitleFiles[SubtitleFileIndex]; 102 | end; 103 | 104 | function TFileItem.GetSubCount: Integer; 105 | begin 106 | Result := SubtitleFiles.Count; 107 | end; 108 | 109 | end. 110 | -------------------------------------------------------------------------------- /Units/UnitSubtitleTypes.pas: -------------------------------------------------------------------------------- 1 | unit UnitSubtitleTypes; 2 | 3 | interface 4 | type 5 | TSubtitleType = (embedded = 0, subfile = 1); 6 | 7 | type 8 | TSubtitleTrack = packed record 9 | Info: string; 10 | ID: integer; 11 | end; 12 | 13 | 14 | implementation 15 | 16 | end. 17 | -------------------------------------------------------------------------------- /Units/windows7taskbar.pas: -------------------------------------------------------------------------------- 1 | { 2 | Note: All Global Funtions Return Types are BOOLEAN. 3 | this will return TRUE or FALSE according to whether 4 | the function was succesful or insuccesful. 5 | 6 | -Captain Muscles. 7 | } 8 | unit windows7taskbar; 9 | 10 | interface 11 | 12 | uses Forms, Windows; 13 | 14 | type 15 | THUMBBUTTON = record 16 | dwMask: DWORD; 17 | iId: UINT; 18 | iBitmap: UINT; 19 | hIcon: hIcon; 20 | szTip: packed array [0 .. 259] of WCHAR; 21 | dwFlags: DWORD; 22 | end; 23 | {$EXTERNALSYM THUMBBUTTON} 24 | 25 | tagTHUMBBUTTON = THUMBBUTTON; 26 | {$EXTERNALSYM tagTHUMBBUTTON} 27 | TThumbButton = THUMBBUTTON; 28 | PThumbButton = ^TThumbButton; 29 | 30 | // THUMBBUTTON flags 31 | const 32 | THBF_ENABLED = $0000; 33 | {$EXTERNALSYM THBF_ENABLED} 34 | THBF_DISABLED = $0001; 35 | {$EXTERNALSYM THBF_DISABLED} 36 | THBF_DISMISSONCLICK = $0002; 37 | {$EXTERNALSYM THBF_DISMISSONCLICK} 38 | THBF_NOBACKGROUND = $0004; 39 | {$EXTERNALSYM THBF_NOBACKGROUND} 40 | THBF_HIDDEN = $0008; 41 | {$EXTERNALSYM THBF_HIDDEN} 42 | THBF_NONINTERACTIVE = $10; 43 | {$EXTERNALSYM THBF_NONINTERACTIVE} 44 | // THUMBBUTTON mask 45 | THB_BITMAP = $0001; 46 | {$EXTERNALSYM THB_BITMAP} 47 | THB_ICON = $0002; 48 | {$EXTERNALSYM THB_ICON} 49 | THB_TOOLTIP = $0004; 50 | {$EXTERNALSYM THB_TOOLTIP} 51 | THB_FLAGS = $0008; 52 | {$EXTERNALSYM THB_FLAGS} 53 | THBN_CLICKED = $1800; 54 | {$EXTERNALSYM THBN_CLICKED} 55 | TBATF_USEMDITHUMBNAIL = $1; 56 | {$EXTERNALSYM TBATF_USEMDITHUMBNAIL} 57 | TBATF_USEMDILIVEPREVIEW = $2; 58 | 59 | const 60 | TBPF_NOPROGRESS = 0; 61 | TBPF_INDETERMINATE = $1; 62 | TBPF_NORMAL = 2; 63 | TBPF_ERROR = 4; 64 | TBPF_PAUSED = 8; 65 | 66 | type 67 | TTaskBarProgressState = (tbpsNone, tbpsIndeterminate, tbpsNormal, tbpsError, tbpsPaused); 68 | 69 | function SetProgressState(hwnd: THandle; const AState: TTaskBarProgressState): boolean; 70 | function SetProgressValue(hwnd: THandle; const ACurrent, AMax: UInt64): boolean; 71 | function AddTab(hwnd: THandle): boolean; 72 | function deleteTab(hwnd: THandle): boolean; 73 | function ThumbBarAddButtons(hwnd: THandle; cButtons: Cardinal; pButtons: PThumbButton): boolean; 74 | function ThumbBarUpdateButtons(hwnd: THandle; cButtons: Cardinal; pButtons: PThumbButton): boolean; 75 | function ThumbBarSetImageList(hwnd: THandle; himl: THandle): boolean; 76 | function SetOverlayIcon(hwnd: THandle; hIcon: THandle; pszDescription: PChar): boolean; 77 | function InitializeTaskbarAPI: boolean; stdcall; 78 | 79 | implementation 80 | 81 | uses 82 | ComObj, Types; 83 | 84 | const 85 | TASKBAR_CID: TGUID = '{56FDF344-FD6D-11d0-958A-006097C9A090}'; 86 | 87 | type 88 | { Definition for Windows 7 ITaskBarList3 } 89 | ITaskBarList3 = interface(IUnknown) 90 | ['{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}'] 91 | procedure HrInit(); stdcall; 92 | procedure AddTab(hwnd: THandle); stdcall; 93 | procedure deleteTab(hwnd: THandle); stdcall; 94 | procedure ActivateTab(hwnd: THandle); stdcall; 95 | procedure SetActiveAlt(hwnd: THandle); stdcall; 96 | procedure MarkFullscreenWindow(hwnd: THandle; fFullscreen: boolean); stdcall; 97 | procedure SetProgressValue(hwnd: THandle; ullCompleted: UInt64; ullTotal: UInt64); stdcall; 98 | procedure SetProgressState(hwnd: THandle; tbpFlags: Cardinal); stdcall; 99 | procedure RegisterTab(hwnd: THandle; hwndMDI: THandle); stdcall; 100 | procedure UnregisterTab(hwndTab: THandle); stdcall; 101 | procedure SetTabOrder(hwndTab: THandle; hwndInsertBefore: THandle); stdcall; 102 | procedure SetTabActive(hwndTab: THandle; hwndMDI: THandle; tbatFlags: Cardinal); stdcall; 103 | procedure ThumbBarAddButtons(hwnd: THandle; cButtons: Cardinal; pButtons: PThumbButton); stdcall; 104 | procedure ThumbBarUpdateButtons(hwnd: THandle; cButtons: Cardinal; pButtons: PThumbButton); stdcall; 105 | procedure ThumbBarSetImageList(hwnd: THandle; himl: THandle); stdcall; 106 | procedure SetOverlayIcon(hwnd: THandle; hIcon: THandle; pszDescription: PChar); stdcall; 107 | procedure SetThumbnailTooltip(hwnd: THandle; pszDescription: PChar); stdcall; 108 | procedure SetThumbnailClip(hwnd: THandle; var prcClip: TRect); stdcall; 109 | end; 110 | 111 | var 112 | { Global variable storing the COM interface } 113 | GlobalTaskBarInterface: ITaskBarList3; 114 | 115 | { TFormHelper } 116 | 117 | function SetProgressState(hwnd: THandle; const AState: TTaskBarProgressState): boolean; 118 | const 119 | Flags: array [TTaskBarProgressState] of Cardinal = (0, $1, 2, 4, 8); 120 | begin 121 | result := true; 122 | if GlobalTaskBarInterface = nil then 123 | result := false; 124 | if result = true then 125 | GlobalTaskBarInterface.SetProgressState(hwnd, Flags[AState]); 126 | end; 127 | 128 | function SetProgressValue(hwnd: THandle; const ACurrent, AMax: UInt64): boolean; 129 | begin 130 | result := true; 131 | if GlobalTaskBarInterface = nil then 132 | result := false; 133 | if result = true then 134 | GlobalTaskBarInterface.SetProgressValue(hwnd, ACurrent, AMax); 135 | end; 136 | 137 | function AddTab(hwnd: THandle): boolean; 138 | begin 139 | result := true; 140 | if GlobalTaskBarInterface = nil then 141 | result := false; 142 | if result = true then 143 | GlobalTaskBarInterface.AddTab(hwnd); 144 | end; 145 | 146 | function deleteTab(hwnd: THandle): boolean; 147 | begin 148 | result := true; 149 | if GlobalTaskBarInterface = nil then 150 | result := false; 151 | if result = true then 152 | GlobalTaskBarInterface.deleteTab(hwnd); 153 | end; 154 | 155 | function ThumbBarAddButtons(hwnd: THandle; cButtons: Cardinal; pButtons: PThumbButton): boolean; 156 | begin 157 | result := true; 158 | if GlobalTaskBarInterface = nil then 159 | result := false; 160 | if result = true then 161 | GlobalTaskBarInterface.ThumbBarAddButtons(hwnd, cButtons, pButtons); 162 | end; 163 | 164 | function ThumbBarUpdateButtons(hwnd: THandle; cButtons: Cardinal; pButtons: PThumbButton): boolean; 165 | begin 166 | result := true; 167 | if GlobalTaskBarInterface = nil then 168 | result := false; 169 | if result = true then 170 | GlobalTaskBarInterface.ThumbBarUpdateButtons(hwnd, cButtons, pButtons); 171 | end; 172 | 173 | function ThumbBarSetImageList(hwnd: THandle; himl: THandle): boolean; 174 | begin 175 | result := true; 176 | if GlobalTaskBarInterface = nil then 177 | result := false; 178 | if result = true then 179 | GlobalTaskBarInterface.ThumbBarSetImageList(hwnd, himl); 180 | end; 181 | 182 | function SetOverlayIcon(hwnd: THandle; hIcon: THandle; pszDescription: PChar): boolean; 183 | begin 184 | result := true; 185 | if GlobalTaskBarInterface = nil then 186 | result := false; 187 | if result = true then 188 | GlobalTaskBarInterface.SetOverlayIcon(hwnd, hIcon, pszDescription); 189 | end; 190 | 191 | function InitializeTaskbarAPI(): boolean; stdcall; 192 | var 193 | Unk: IInterface; 194 | 195 | begin 196 | { Make sure that COM is initialized } 197 | CoInitializeEx(nil, 0); 198 | 199 | result := true; 200 | try 201 | { Obtain an IUnknown } 202 | Unk := CreateComObject(TASKBAR_CID); 203 | 204 | if Unk = nil then 205 | Exit; 206 | 207 | { Cast to the required interface } 208 | GlobalTaskBarInterface := Unk as ITaskBarList3; 209 | 210 | { Initialize } 211 | GlobalTaskBarInterface.HrInit(); 212 | except 213 | GlobalTaskBarInterface := nil; 214 | result := false; 215 | end; 216 | 217 | end; 218 | 219 | end. 220 | -------------------------------------------------------------------------------- /dvdrenametool.dpr: -------------------------------------------------------------------------------- 1 | program dvdrenametool; 2 | {$IFOPT D-}{$WEAKLINKRTTI ON}{$ENDIF} 3 | {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} 4 | {$APPTYPE CONSOLE} 5 | 6 | {$R *.res} 7 | 8 | uses 9 | System.SysUtils, 10 | System.Classes; 11 | 12 | var 13 | // old file (original) 14 | // new file (renamed to original) 15 | FRenameFile: TStringList; 16 | begin 17 | WriteLn('DVDRenameTool 1.0'); 18 | try 19 | if ParamCount = 1 then 20 | begin 21 | FRenameFile := TStringList.Create; 22 | try 23 | FRenameFile.LoadFromFile(ParamStr(1), TEncoding.UTF8); 24 | if FRenameFile.Count = 2 then 25 | begin 26 | if FileExists(FRenameFile[0]) and FileExists(FRenameFile[1]) then 27 | begin 28 | // delete original file 29 | if FileExists(FRenameFile[0]) then 30 | begin 31 | DeleteFile(FRenameFile[0]); 32 | end; 33 | if FileExists(FRenameFile[1]) then 34 | begin 35 | if RenameFile(FRenameFile[1], FRenameFile[0]) then 36 | begin 37 | Writeln('Successfully renamed.'); 38 | ExitCode := 0; 39 | end 40 | else 41 | begin 42 | Writeln('Cannot rename'); 43 | ExitCode := 5; 44 | end; 45 | end 46 | else 47 | begin 48 | Writeln('Dest doesnt exist.'); 49 | ExitCode := 2; 50 | end; 51 | end; 52 | end 53 | else 54 | begin 55 | Writeln('Only 2 lines'); 56 | ExitCode := 3; 57 | end; 58 | finally 59 | FRenameFile.Free; 60 | end; 61 | end 62 | else 63 | begin 64 | Writeln('Not enough params: ' + FloatToStr(ParamCount)); 65 | ExitCode := 4; 66 | end; 67 | except 68 | on E: Exception do 69 | Writeln(E.ClassName, ': ', E.Message); 70 | end; 71 | end. 72 | -------------------------------------------------------------------------------- /renametool.dpr: -------------------------------------------------------------------------------- 1 | program renametool; 2 | {$IFOPT D-}{$WEAKLINKRTTI ON}{$ENDIF} 3 | {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} 4 | {$APPTYPE CONSOLE} 5 | {$R *.res} 6 | 7 | uses 8 | System.SysUtils, 9 | System.Classes; 10 | 11 | var 12 | // audio 13 | // video 14 | // muxed 15 | FRenameFile: TStringList; 16 | 17 | begin 18 | WriteLn('RenameTool 1.1'); 19 | try 20 | if ParamCount = 1 then 21 | begin 22 | FRenameFile := TStringList.Create; 23 | try 24 | if FileExists(ParamStr(1)) then 25 | begin 26 | FRenameFile.LoadFromFile(ParamStr(1), TEncoding.UTF8); 27 | if FRenameFile.Count = 3 then 28 | begin 29 | if FileExists(FRenameFile[0]) and FileExists(FRenameFile[1]) then 30 | begin 31 | // delete files 32 | if FileExists(FRenameFile[0]) then 33 | begin 34 | DeleteFile(FRenameFile[0]); 35 | Writeln('Deleted ' + FRenameFile[0]); 36 | end; 37 | if FileExists(FRenameFile[1]) then 38 | begin 39 | DeleteFile(FRenameFile[1]); 40 | Writeln('Deleted ' + FRenameFile[1]); 41 | end; 42 | if FileExists(FRenameFile[2]) then 43 | begin 44 | if RenameFile(FRenameFile[2], FRenameFile[1]) then 45 | begin 46 | Writeln('Successfully renamed.'); 47 | ExitCode := 0; 48 | end 49 | else 50 | begin 51 | Writeln('Cannot rename'); 52 | ExitCode := 5; 53 | end; 54 | end 55 | else 56 | begin 57 | Writeln('Dest doesnt exist.'); 58 | ExitCode := 2; 59 | end; 60 | end; 61 | end 62 | else 63 | begin 64 | Writeln('Only 3 lines'); 65 | ExitCode := 3; 66 | end; 67 | end 68 | else 69 | begin 70 | Writeln('Unable to find rename text file'); 71 | ExitCode := 4; 72 | end; 73 | finally 74 | FRenameFile.Free; 75 | end; 76 | end 77 | else 78 | begin 79 | Writeln('Not enough params: ' + FloatToStr(ParamCount)); 80 | ExitCode := 4; 81 | end; 82 | except 83 | on E: Exception do 84 | Writeln(E.ClassName, ': ', E.Message); 85 | end; 86 | 87 | end. 88 | -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 5129 --------------------------------------------------------------------------------