forked from abc874/ca2018
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ResultingTimes.pas
321 lines (280 loc) · 8.98 KB
/
ResultingTimes.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
unit ResultingTimes;
{$I Information.inc}
// basic review and reformatting: done
interface
uses
// Delphi
Winapi.ActiveX, Winapi.DirectShow9, System.Classes, Vcl.Forms, Vcl.ComCtrls, Vcl.StdCtrls, Vcl.Controls, Vcl.ExtCtrls,
// DSPack
DSPack, DXSUtils,
// CA
UCutlist, Movie;
type
TFResultingTimes = class(TForm)
lvTimeList: TListView;
cmdClose: TButton;
pnlMovieControl: TPanel;
lblDuration: TLabel;
pnlVideoWindow: TPanel;
VideoWindow: TVideoWindow;
FilterGraph: TFilterGraph;
tbVolume: TTrackBar;
Label8: TLabel;
cmdPause: TButton;
cmdPlay: TButton;
tbPosition: TDSTrackBar;
lblPosition: TLabel;
edtDuration: TEdit;
lblSeconds: TLabel;
udDuration: TUpDown;
procedure cmdCloseClick(Sender: TObject);
procedure lvTimeListDblClick(Sender: TObject);
procedure pnlVideoWindowResize(Sender: TObject);
procedure tbVolumeChange(Sender: TObject);
procedure cmdPlayClick(Sender: TObject);
procedure cmdPauseClick(Sender: TObject);
procedure JumpTo(NewPosition: Double);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure udDurationChanging(Sender: TObject; var AllowChange: Boolean);
procedure FormDestroy(Sender: TObject);
function FilterGraphSelectedFilter(Moniker: IMoniker; FilterName: WideString; ClassID: TGUID): Boolean;
procedure FormShow(Sender: TObject);
private
{ private declarations }
To_Array: array of Double;
seeking: IMediaSeeking;
FOffset: Integer;
current_filename: string;
FMovieInfo: TMovieInfo;
public
{ public declarations }
procedure calculate(Cutlist: TCutlist);
function loadMovie(FileName: string): Boolean;
end;
var
FResultingTimes: TFResultingTimes;
implementation
uses
// Delphi
Winapi.Windows, System.SysUtils, System.Math,
// CA
Main, Utils;
{$R *.dfm}
{ TFResultingTimes }
procedure TFResultingTimes.calculate(Cutlist: TCutlist);
var
icut: Integer;
cut: tcut;
cut_view: tlistitem;
i_column: Integer;
converted_cutlist: TCutlist;
time: Double;
begin
if cutlist.Count > 0 then
begin
if cutlist.Mode = clmTrim then
begin
lvTimeList.Clear;
time := 0;
SetLength(To_Array, cutlist.Count);
for icut := 0 to Pred(cutlist.Count) do
begin
cut := cutlist[icut];
cut_view := lvTimeList.Items.Add;
cut_view.Caption := IntToStr(icut);
cut_view.SubItems.Add(MovieInfo.FormatPosition(time));
time := time + cut.pos_to - cut.pos_from;
cut_view.SubItems.Add(MovieInfo.FormatPosition(time));
To_Array[iCut] := time;
cut_view.SubItems.Add(MovieInfo.FormatPosition(cut.pos_to - cut.pos_from));
time := time + MovieInfo.frame_Duration;
end;
// Auto-Resize columns
for i_column := 0 to Pred(lvTimeList.Columns.Count) do
lvTimeList.Columns[i_column].Width := -2;
end else
begin
Converted_Cutlist := cutlist.convert;
calculate(COnverted_cutlist);
FreeAndNil(Converted_Cutlist);
end;
end else
lvTimeList.Clear;
end;
procedure TFResultingTimes.cmdCloseClick(Sender: TObject);
begin
Close;
end;
procedure TFResultingTimes.lvTimeListDblClick(Sender: TObject);
var
target_Time: Double;
begin
if filtergraph.Active and (lvTimeList.ItemIndex >= 0) then
begin
target_Time := To_array[lvTimeList.ItemIndex] - FOffset;
if target_time <= MovieInfo.current_file_duration then
begin
if target_time < 0 then
target_time := 0;
JumpTo(Target_time);
FilterGraph.Play;
end;
end;
end;
procedure TFResultingTimes.JumpTo(NewPosition: Double);
var
_pos: Int64;
event: Integer;
begin
if Assigned(seeking) then
begin
NewPosition := EnsureRange(NewPosition, 0, MovieInfo.current_file_duration);
if isEqualGUID(MovieInfo.TimeFormat, TIME_FORMAT_MEDIA_TIME) then
_pos := Round(NewPosition * 10000000)
else
_pos := Round(NewPosition);
seeking.SetPositions(_pos, AM_SEEKING_AbsolutePositioning, _pos, AM_SEEKING_NoPositioning);
//filtergraph.State
MediaEvent.WaitForCompletion(500, event);
end;
end;
procedure TFResultingTimes.pnlVideoWindowResize(Sender: TObject);
var
movie_ar, my_ar: Double;
begin
movie_ar := MovieInfo.ratio;
my_ar := pnlVideoWindow.Width / pnlVideoWindow.Height;
if my_ar > movie_ar then
begin
VideoWindow.Height := pnlVideoWindow.Height;
VideoWindow.Width := Round(videowindow.Height * movie_ar);
end else
begin
VideoWindow.Width := pnlVideoWindow.Width;
VideoWindow.Height := Round(VideoWindow.Width / movie_ar);
end;
end;
function TFResultingTimes.loadMovie(FileName: string): Boolean;
var
AvailableFilters: TSysDevEnum;
SourceFilter, AviDecompressorFilter: IBAseFilter;
SourceAdded: Boolean;
PinList: TPinList;
IPin: Integer;
begin
Result := False;
FMovieInfo.target_filename := '';
if FMovieInfo.InitMovie(FileName) then
begin
filtergraph.Active := True;
AvailableFilters := TSysDevEnum.Create(CLSID_LegacyAmFilterCategory); // DirectShow Filters
try
// if MP4 then try to Add AviDecompressor
if (MovieInfo.MovieType in [mtMP4]) then
begin
AviDecompressorFilter := AvailableFilters.GetBaseFilter(CLSID_AVIDec); // Avi Decompressor
if Assigned(AviDecompressorFilter) then
CheckDSError((FilterGraph as IGraphBuilder).AddFilter(AviDecompressorFilter, 'Avi Decompressor'));
end;
SourceAdded := False;
if not (IsEqualGUID(Settings.GetPreferredSourceFilterByMovieType(MovieInfo.MovieType), GUID_NULL)) then
begin
SourceFilter := AvailableFilters.GetBaseFilter(Settings.GetPreferredSourceFilterByMovieType(MovieInfo.MovieType));
if Assigned(SourceFilter) then
begin
CheckDSError((SourceFilter as IFileSourceFilter).Load(StringToOleStr(FileName), nil));
CheckDSError((FilterGraph as IGraphBuilder).AddFilter(SourceFilter, StringToOleStr('Source Filter [' + ExtractFileName(FileName) + ']')));
SourceAdded := True;
end;
end;
finally
FreeAndNil(AvailableFilters);
end;
if not sourceAdded then
begin
CheckDSError(FilterGraph.RenderFile(FileName));
end else
begin
PinList := TPinList.Create(SourceFilter);
try
for iPin := 0 to Pred(PinList.Count) do
CheckDSError((FilterGraph as IGraphBuilder).Render(PinList.Items[iPin]));
finally
FreeAndNil(PinList);
end;
end;
if FilterGraph.Active then begin
if not Succeeded(FilterGraph.QueryInterface(IMediaSeeking, Seeking)) then begin
seeking := nil;
filtergraph.Active := False;
Result := False;
Exit;
end;
filtergraph.Pause;
filtergraph.Volume := tbVolume.Position;
current_filename := FileName;
tbPosition.Position := 0;
pnlVideoWindowResize(Self);
Result := True;
end;
end;
end;
procedure TFResultingTimes.tbVolumeChange(Sender: TObject);
begin
FilterGraph.Volume := tbVolume.Position;
end;
procedure TFResultingTimes.cmdPlayClick(Sender: TObject);
begin
if FilterGraph.Active then
FilterGraph.Play;
end;
procedure TFResultingTimes.cmdPauseClick(Sender: TObject);
begin
if FilterGraph.Active then
FilterGraph.Pause
end;
procedure TFResultingTimes.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
FilterGraph.Stop;
FilterGraph.ClearGraph;
FilterGraph.Active := False;
end;
procedure TFResultingTimes.FormCreate(Sender: TObject);
begin
AdjustFormConstraints(Self);
if ValidRect(Settings.PreviewFormBounds) then
begin
BoundsRect := Settings.PreviewFormBounds
end else
begin
Left := Max(0, FMain.Left + (FMain.Width - Width) div 2);
Top := Max(0, FMain.Top + (FMain.Height - Height) div 2);
end;
WindowState := Settings.PreviewFormWindowState;
udDuration.Position := settings.OffsetSecondsCutChecking;
FOffset := settings.OffsetSecondsCutChecking;
FMovieInfo := TMovieInfo.Create;
end;
procedure TFResultingTimes.udDurationChanging(Sender: TObject; var AllowChange: Boolean);
begin
FOffset := udDuration.Position;
end;
procedure TFResultingTimes.FormDestroy(Sender: TObject);
begin
Settings.OffsetSecondsCutChecking := FOffset;
Settings.PreviewFormBounds := BoundsRect;
Settings.PreviewFormWindowState := WindowState;
FreeAndNil(FMovieInfo);
end;
function TFResultingTimes.FilterGraphSelectedFilter(Moniker: IMoniker; FilterName: WideString; ClassID: TGUID): Boolean;
begin
Result := not settings.FilterIsInBlackList(ClassID);
end;
procedure TFResultingTimes.FormShow(Sender: TObject);
begin
// Show taskbar button for this form ...
SetWindowLong(Handle, GWL_ExStyle, WS_Ex_AppWindow);
end;
end.