Advertisement
HemulGM

Untitled

Jun 3rd, 2020
947
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 11.94 KB | None | 0 0
  1. unit VideoPlayer.Main;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, System.SysUtils, System.Types, System.Generics.Collections, System.UITypes, System.Classes,
  7.   System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects, FmxPasLibVlcPlayerUnit,
  8.   FMX.Layouts, FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base, FMX.Controls.Presentation,
  9.   FMX.StdCtrls, FMX.ListView, System.IOUtils, FMX.Ani, FMX.Effects, FMX.ScrollBox, FMX.Memo;
  10.  
  11. type
  12.   TArrayOfString = TArray<string>;
  13.  
  14.   TArrayOfStringHelper = record helper for TArrayOfString
  15.     function InArray(Value: string): Boolean;
  16.   end;
  17.  
  18.   TFormMain = class(TForm)
  19.     LayoutFiles: TLayout;
  20.     LayoutPlayer: TLayout;
  21.     ListViewFiles: TListView;
  22.     RectanglePlayer: TRectangle;
  23.     VlcPlayer: TFmxPasLibVlcPlayer;
  24.     StyleBook1: TStyleBook;
  25.     Layout1: TLayout;
  26.     Button1: TButton;
  27.     Button5: TButton;
  28.     LayoutControl: TLayout;
  29.     TimerHideControl: TTimer;
  30.     FloatAnimationHide: TFloatAnimation;
  31.     FloatAnimationShow: TFloatAnimation;
  32.     Rectangle1: TRectangle;
  33.     ButtonPlayPrev: TButton;
  34.     ButtonPlayNext: TButton;
  35.     ButtonFiles: TButton;
  36.     ButtonPlay: TButton;
  37.     LayoutTrackPos: TLayout;
  38.     TrackBarPos: TTrackBar;
  39.     TrackBarVolume: TTrackBar;
  40.     Splitter: TSplitter;
  41.     LabelTimeLeft: TLabel;
  42.     LabelTimeRight: TLabel;
  43.     TimerClick: TTimer;
  44.     procedure FormCreate(Sender: TObject);
  45.     procedure Button1Click(Sender: TObject);
  46.     procedure ListViewFilesItemClick(const Sender: TObject; const AItem: TListViewItem);
  47.     procedure TrackBarPosChange(Sender: TObject);
  48.     procedure VlcPlayerMediaPlayerPositionChanged(Sender: TObject; position: Single);
  49.     procedure TrackBarPosMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  50.     procedure TrackBarPosMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  51.     procedure ButtonPlayClick(Sender: TObject);
  52.     procedure TrackBarVolumeChange(Sender: TObject);
  53.     procedure ButtonFilesClick(Sender: TObject);
  54.     procedure VlcPlayerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
  55.     procedure TimerHideControlTimer(Sender: TObject);
  56.     procedure VlcPlayerMediaPlayerPaused(Sender: TObject);
  57.     procedure VlcPlayerMediaPlayerPlaying(Sender: TObject);
  58.     procedure ButtonPlayPrevClick(Sender: TObject);
  59.     procedure ButtonPlayNextClick(Sender: TObject);
  60.     procedure VlcPlayerMediaPlayerStopped(Sender: TObject);
  61.     procedure VlcPlayerMediaPlayerLengthChanged(Sender: TObject; time: Int64);
  62.     procedure FloatAnimationHideFinish(Sender: TObject);
  63.     procedure VlcPlayerDblClick(Sender: TObject);
  64.     procedure VlcPlayerClick(Sender: TObject);
  65.     procedure TimerClickTimer(Sender: TObject);
  66.   private
  67.     FStarting: Boolean;
  68.     FChangingPos: Boolean;
  69.     FUserChangePos: Boolean;
  70.     FDblClick: Boolean;
  71.     procedure FillDirectory(Dir: string);
  72.     procedure SetVideoFullScreen(const Value: Boolean);
  73.     function GetVideoFullScreen: Boolean;
  74.     procedure PlayNext(Handle: Boolean);
  75.     procedure PlayPrev(Handle: Boolean);
  76.     procedure Play(FileName: string);
  77.     procedure HideControls;
  78.     procedure ShowControls;
  79.   public
  80.     property VideoFullScreen: Boolean read GetVideoFullScreen write SetVideoFullScreen;
  81.   end;
  82.  
  83. var
  84.   FormMain: TFormMain;
  85.   AllowExts: TArrayOfString = ['.mp4', '.avi', '.flv', '.ts', '.mkv'];
  86.  
  87. implementation
  88.  
  89. uses
  90.   System.DateUtils;
  91.  
  92. {$R *.fmx}
  93.  
  94. function MsToTimeStr(Value: Int64): string;
  95. var
  96.   H, M, S: Integer;
  97. begin
  98.   Value := Value div MSecsPerSec;
  99.   H := Value div SecsPerHour;
  100.   Value := Value - (H * SecsPerHour);
  101.   M := Value div SecsPerMin;
  102.   Value := Value - (M * SecsPerMin);
  103.   S := Value;
  104.   Result := Format('%.2d:%.2d:%.2d', [H, M, S]);
  105. end;
  106.  
  107. function ExecuteProcess(const FileName, Params: string; Folder: string; WaitUntilTerminated, WaitUntilIdle, RunMinimized:
  108.   boolean; var ErrorCode: integer): boolean;
  109. const
  110.   ThreadWaitTimeOut = 10 * 1000;
  111. var
  112.   CmdLine: string;
  113.   WorkingDirP: PChar;
  114.   StartupInfo: TStartupInfo;
  115.   ProcessInfo: TProcessInformation;
  116. begin
  117.   Result := true;
  118.   CmdLine := FileName + ' ' + Params;
  119.   if Folder = '' then
  120.     Folder := ExcludeTrailingPathDelimiter(ExtractFilePath(FileName));
  121.   ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
  122.   StartupInfo.cb := SizeOf(StartupInfo);
  123.   if RunMinimized then
  124.   begin
  125.     StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  126.     StartupInfo.wShowWindow := SW_HIDE;
  127.   end;
  128.   if Folder <> '' then
  129.     WorkingDirP := PChar(Folder)
  130.   else
  131.     WorkingDirP := nil;
  132.   if not CreateProcess(nil, PChar(CmdLine), nil, nil, false, 0, nil, WorkingDirP, StartupInfo, ProcessInfo) then
  133.   begin
  134.     Result := false;
  135.     ErrorCode := GetLastError;
  136.     Exit;
  137.   end;
  138.   with ProcessInfo do
  139.   begin
  140.     CloseHandle(hThread);
  141.     if WaitUntilIdle then
  142.       WaitForInputIdle(hProcess, ThreadWaitTimeOut);
  143.     if WaitUntilTerminated then
  144.       WaitForSingleObject(hProcess, ThreadWaitTimeOut);
  145.     CloseHandle(hProcess);
  146.   end;
  147. end;
  148.  
  149. function GetThumbnail(VideoFile: string; var ThumbFile: string): Boolean;
  150. var
  151.   ErrorCode: Integer;
  152. begin
  153.   ThumbFile := 'cache/' + ExtractFileName(VideoFile) + '.png';
  154.   if not FileExists(ThumbFile) then
  155.   begin
  156.     Result := ExecuteProcess('ffmpeg', '-i "' + VideoFile + '" -ss 00:00:05.000 -vframes 1 "' + ThumbFile + '"',
  157.       ExtractFilePath(ParamStr(0)), True, True, True, ErrorCode) and FileExists(ThumbFile);
  158.   end
  159.   else
  160.     Result := True;
  161. end;
  162.  
  163. function SelectDirectory(var Dir: string): Boolean;
  164. begin
  165.   Result := FMX.Dialogs.SelectDirectory('', '', Dir);
  166. end;
  167.  
  168. procedure TFormMain.Button1Click(Sender: TObject);
  169. var
  170.   Dir: string;
  171. begin
  172.   if SelectDirectory(Dir) then
  173.   begin
  174.     FillDirectory(Dir);
  175.   end;
  176. end;
  177.  
  178. procedure TFormMain.ButtonFilesClick(Sender: TObject);
  179. begin
  180.   LayoutFiles.Visible := not LayoutFiles.Visible;
  181.   Splitter.Visible := LayoutFiles.Visible;
  182. end;
  183.  
  184. procedure TFormMain.ButtonPlayClick(Sender: TObject);
  185. begin
  186.   if VlcPlayer.IsPlay then
  187.     VlcPlayer.Pause
  188.   else if VlcPlayer.IsPause then
  189.     VlcPlayer.Resume;
  190. end;
  191.  
  192. procedure TFormMain.PlayNext(Handle: Boolean);
  193. begin
  194.   if ListViewFiles.ItemIndex < ListViewFiles.Items.Count - 1 then
  195.   begin
  196.     ListViewFiles.ItemIndex := ListViewFiles.ItemIndex + 1;
  197.     Play(ListViewFiles.Items[ListViewFiles.ItemIndex].Data['Path'].AsString);
  198.   end;
  199. end;
  200.  
  201. procedure TFormMain.PlayPrev(Handle: Boolean);
  202. begin
  203.   if ListViewFiles.ItemIndex > 0 then
  204.   begin
  205.     ListViewFiles.ItemIndex := ListViewFiles.ItemIndex - 1;
  206.     Play(ListViewFiles.Items[ListViewFiles.ItemIndex].Data['Path'].AsString);
  207.   end;
  208. end;
  209.  
  210. procedure TFormMain.ButtonPlayNextClick(Sender: TObject);
  211. begin
  212.   PlayNext(True);
  213. end;
  214.  
  215. procedure TFormMain.ButtonPlayPrevClick(Sender: TObject);
  216. begin
  217.   PlayPrev(True);
  218. end;
  219.  
  220. procedure TFormMain.FillDirectory(Dir: string);
  221. var
  222.   FileName: string;
  223.   Files: TArrayOfString;
  224. begin
  225.   Files := TDirectory.GetFiles(Dir, TSearchOption.soTopDirectoryOnly,
  226.     function(const Path: string; const SearchRec: TSearchRec): Boolean
  227.     begin
  228.       Result := AllowExts.InArray(ExtractFileExt(SearchRec.Name));
  229.     end);
  230.   ListViewFiles.BeginUpdate;
  231.   ListViewFiles.Items.Clear;
  232.   for FileName in Files do
  233.   begin
  234.     with ListViewFiles.Items.Add do
  235.     begin
  236.       Text := ExtractFileName(FileName);
  237.       Text := Text.Substring(0, Text.Length - 4);
  238.       Detail := '';
  239.       Data['Path'] := FileName;
  240.     end;
  241.   end;
  242.   ListViewFiles.EndUpdate;
  243.   TThread.CreateAnonymousThread(
  244.     procedure
  245.     var
  246.       i: Integer;
  247.       FN, S: string;
  248.       BMP: TBitmap;
  249.     begin
  250.       for i := 0 to ListViewFiles.Items.Count - 1 do
  251.       begin
  252.         FN := ListViewFiles.Items[i].Data['Path'].AsString;
  253.         if GetThumbnail(FN, S) then
  254.         begin
  255.           BMP := TBitmap.Create;
  256.           TThread.Synchronize(nil,
  257.             procedure
  258.             begin
  259.               BMP.LoadFromFile(S);
  260.             end);
  261.           ListViewFiles.Items[i].Bitmap := BMP;
  262.         end;
  263.       end;
  264.     end).Start;
  265. end;
  266.  
  267. procedure TFormMain.FloatAnimationHideFinish(Sender: TObject);
  268. begin
  269.   LayoutControl.Visible := False;
  270. end;
  271.  
  272. procedure TFormMain.FormCreate(Sender: TObject);
  273. begin
  274.   FDblClick := False;
  275.   FillDirectory('D:\Мультимедиа\Видео');
  276. end;
  277.  
  278. function TFormMain.GetVideoFullScreen: Boolean;
  279. begin
  280.   Result := FullScreen;
  281. end;
  282.  
  283. procedure TFormMain.Play(FileName: string);
  284. begin
  285.   FStarting := True;
  286.   TThread.CreateAnonymousThread(
  287.     procedure
  288.     begin
  289.       VlcPlayer.Play(FileName);
  290.       FStarting := False;
  291.     end).Start;
  292. end;
  293.  
  294. procedure TFormMain.ListViewFilesItemClick(const Sender: TObject; const AItem: TListViewItem);
  295. begin
  296.   Play(AItem.Data['Path'].AsString)
  297. end;
  298.  
  299. procedure TFormMain.SetVideoFullScreen(const Value: Boolean);
  300. begin
  301.   FullScreen := Value;
  302.   LayoutFiles.Visible := not Value;
  303.   Splitter.Visible := not Value;
  304. end;
  305.  
  306. procedure TFormMain.TrackBarPosChange(Sender: TObject);
  307. begin
  308.   if not FChangingPos and VlcPlayer.IsPlay then
  309.     VlcPlayer.SetVideoPosInPercent(TrackBarPos.Value);
  310.   TrackBarPos.Repaint;
  311. end;
  312.  
  313. procedure TFormMain.TrackBarPosMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  314. begin
  315.   FUserChangePos := True;
  316. end;
  317.  
  318. procedure TFormMain.TrackBarPosMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
  319. begin
  320.   FUserChangePos := False;
  321. end;
  322.  
  323. procedure TFormMain.TrackBarVolumeChange(Sender: TObject);
  324. begin
  325.   TrackBarVolume.Hint := Round(TrackBarVolume.Value).ToString;
  326.   VlcPlayer.SetAudioVolume(Round(TrackBarVolume.Value));
  327. end;
  328.  
  329. procedure TFormMain.VlcPlayerClick(Sender: TObject);
  330. begin
  331.   FDblClick := False;
  332.   TimerClick.Enabled := False;
  333.   TimerClick.Enabled := True;
  334. end;
  335.  
  336. procedure TFormMain.VlcPlayerDblClick(Sender: TObject);
  337. begin
  338.   FDblClick := True;
  339.   TimerClick.Enabled := False;
  340.   VideoFullScreen := not VideoFullScreen;
  341. end;
  342.  
  343. procedure TFormMain.VlcPlayerMediaPlayerLengthChanged(Sender: TObject; time: Int64);
  344. begin
  345.   LabelTimeRight.Text := MsToTimeStr(VlcPlayer.GetVideoLenInMs);
  346. end;
  347.  
  348. procedure TFormMain.VlcPlayerMediaPlayerPaused(Sender: TObject);
  349. begin
  350.   ButtonPlay.StyleLookup := 'playtoolbutton';
  351. end;
  352.  
  353. procedure TFormMain.VlcPlayerMediaPlayerPlaying(Sender: TObject);
  354. begin
  355.   ButtonPlay.StyleLookup := 'pausetoolbutton';
  356. end;
  357.  
  358. procedure TFormMain.VlcPlayerMediaPlayerPositionChanged(Sender: TObject; position: Single);
  359. begin
  360.   if not FUserChangePos then
  361.   begin
  362.     FChangingPos := True;
  363.     TrackBarPos.Value := VlcPlayer.GetVideoPosInPercent;
  364.     FChangingPos := False;
  365.   end;
  366.   LabelTimeLeft.Text := MsToTimeStr(VlcPlayer.GetVideoPosInMs);
  367. end;
  368.  
  369. procedure TFormMain.VlcPlayerMediaPlayerStopped(Sender: TObject);
  370. begin
  371.   PlayNext(False);
  372. end;
  373.  
  374. procedure TFormMain.TimerClickTimer(Sender: TObject);
  375. begin
  376.   TimerClick.Enabled := False;
  377.   if not FDblClick then
  378.     ButtonPlayClick(nil);
  379. end;
  380.  
  381. procedure TFormMain.HideControls;
  382. begin
  383.   FloatAnimationShow.Stop;
  384.   FloatAnimationHide.Start;
  385. end;
  386.  
  387. procedure TFormMain.TimerHideControlTimer(Sender: TObject);
  388. var
  389.   MPos: TPointF;
  390. begin
  391.   TimerHideControl.Enabled := False;
  392.   MPos := ScreenToClient(Screen.MousePos);
  393.   if not LayoutControl.PointInObject(MPos.X, MPos.Y) then
  394.   begin
  395.     HideControls;
  396.   end;
  397. end;
  398.  
  399. procedure TFormMain.ShowControls;
  400. begin
  401.   if not LayoutControl.Visible then
  402.     LayoutControl.Visible := True;
  403.   if (LayoutControl.Opacity < 1) and (not FloatAnimationShow.Running) then
  404.   begin
  405.     FloatAnimationShow.Start;
  406.   end;
  407. end;
  408.  
  409. procedure TFormMain.VlcPlayerMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
  410. begin
  411.   TimerHideControl.Enabled := False;
  412.   TimerHideControl.Enabled := True;
  413.   ShowControls;
  414. end;
  415.  
  416. { TArrayOfStringHelper }
  417.  
  418. function TArrayOfStringHelper.InArray(Value: string): Boolean;
  419. var
  420.   i: Integer;
  421. begin
  422.   Result := False;
  423.   for i := Low(Self) to High(Self) do
  424.     if Self[i] = Value then
  425.       Exit(True);
  426. end;
  427.  
  428. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement