SmartFarm/SOURCE/SmartFarmHMI/SmartFarmHMI_VCL_RTSP_/UMainRTSP.pas
2026-09-04 10:53:44 +09:00

205 lines
5.5 KiB
ObjectPascal
Raw Permalink Blame History

unit UMainRTSP;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, MPVBasePlayer, Vcl.ExtCtrls, System.IniFiles,
Vcl.StdCtrls, System.IOUtils;
const
CLR_BG = TColor($002A170F); // #0F172A
CLR_PANEL = TColor($0045342D); // #1E293B (alpha overlay over #0F172A)
CLR_PANEL2 = TColor($0045342D); // consistent panel color
CLR_GREEN = TColor($0050AF4C); // #4CAF50
CLR_RED = TColor($005252FF); // #FF5252
CLR_WHITE = TColor($00FFFFFF);
CLR_GRAY = TColor($00B8A394); // #94A3B8
WIDGET_W = 380;
WIDGET_H = 220;
WIDGET_GAP = 16;
SIDEBAR_W = 350;
type
TfrmMainRTSP = class(TForm)
pnlCCTVButtons: TPanel;
pnlCCTVVideo: TPanel;
lstCameras: TListBox;
lblDateTime: TLabel;
btnFullscreen: TPanel;
lblFullscreenText: TLabel;
Panel1: TPanel;
lblCloseText: TLabel;
TimerTime: TTimer;
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure OnPlayCameraClick(Sender: TObject);
procedure TimerTimeTimer(Sender: TObject);
procedure lblFullscreenTextClick(Sender: TObject);
procedure lblCloseTextClick(Sender: TObject);
private
{ Private declarations }
FMpv: TMPVBasePlayer;
FActiveCameraIdx: Integer;
procedure BuildCCTVGrid;
procedure LoadSettings;
function MakeDynButton(AParent: TWinControl; const AText: string;
ATag: Integer; AEvent: TNotifyEvent): TPanel;
public
{ Public declarations }
end;
var
frmMainRTSP: TfrmMainRTSP;
implementation
{$R *.dfm}
procedure TfrmMainRTSP.FormCreate(Sender: TObject);
begin
lblCloseText.Align := alClient;
lblFullscreenText.Align := alClient;
lblDateTime.Caption := FormatDateTime('yyyy-mm-dd hh:nn:ss', Now);
LoadSettings;
BuildCCTVGrid;
WindowState := wsMaximized;
end;
function TfrmMainRTSP.MakeDynButton(AParent: TWinControl; const AText: string;
ATag: Integer; AEvent: TNotifyEvent): TPanel;
var P: TPanel; L: TLabel;
begin
P := TPanel.Create(Self);
P.Parent := AParent;
P.Left := 0; P.Top := 0; P.Width := 160; P.Height := 80;
P.Color := CLR_PANEL2; P.BevelOuter := bvNone;
P.ParentBackground := False; P.ParentColor := False; P.Caption := '';
P.Cursor := crHandPoint; P.Tag := ATag; P.OnClick := AEvent;
L := TLabel.Create(Self);
L.Parent := P;
L.Align := alClient;
L.Layout := tlCenter;
L.Caption := AText;
L.Font.Size := 20;
L.Font.Color := CLR_WHITE;
L.Font.Style := [fsBold];
L.Transparent := True;
L.AutoSize := False;
L.SetBounds(6, 6, 148, 65); L.Alignment := taCenter;
L.Tag := ATag; L.OnClick := AEvent;
Result := P;
end;
procedure TfrmMainRTSP.LoadSettings;
var Ini: TIniFile; i, Count: Integer; S, SP: string;
begin
SP := TPath.Combine(TPath.GetHomePath, 'SmartFarmHMI_settings.ini');
Ini := TIniFile.Create(SP);
try
lstCameras.Clear;
Count := Ini.ReadInteger('CCTV', 'Count', 0);
for i := 0 to Count-1 do
begin
S := Ini.ReadString('CCTV', 'Cam'+IntToStr(i), '');
if S <> '' then lstCameras.Items.Add(S);
end;
finally
Ini.Free;
end;
end;
procedure TfrmMainRTSP.OnPlayCameraClick(Sender: TObject);
var URL: string; VTag, k: Integer; ClickedBtn: TPanel;
begin
if Sender is TPanel then VTag := (Sender as TPanel).Tag
else if Sender is TLabel then VTag := (Sender as TLabel).Tag
else Exit;
// <20><><EFBFBD><EFBFBD> ī<>޶<EFBFBD> <20><>ư <20><> <20>ʱ<EFBFBD>ȭ <20><> Ŭ<><C5AC><EFBFBD><EFBFBD> <20><>ư <20><><EFBFBD><EFBFBD>
ClickedBtn := nil;
for k := 0 to pnlCCTVButtons.ControlCount-1 do
if pnlCCTVButtons.Controls[k] is TPanel then
begin
TPanel(pnlCCTVButtons.Controls[k]).Color := CLR_PANEL2;
if TPanel(pnlCCTVButtons.Controls[k]).Tag = VTag then
ClickedBtn := TPanel(pnlCCTVButtons.Controls[k]);
end;
if ClickedBtn <> nil then ClickedBtn.Color := TColor($00226622);
FActiveCameraIdx := VTag;
if (VTag >= 0) and (VTag < lstCameras.Count) then
begin
URL := lstCameras.Items[VTag];
// <20><><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7>̾<EFBFBD> <20><><EFBFBD><EFBFBD>
if FMpv <> nil then
begin
FMpv.Stop;
FreeAndNil(FMpv);
end;
if URL.StartsWith('rtsp://', True) or URL.StartsWith('http://', True) or URL.StartsWith('https://', True) then
begin
FMpv := TMPVBasePlayer.Create;
FMpv.InitPlayer(IntToStr(pnlCCTVVideo.Handle), '', '', '');
FMpv.SetMute(True);
FMpv.OpenFile(PChar(URL));
end
else
begin
try
except
on E: Exception do ShowMessage('<27>̵<EFBFBD><CCB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>: ' + E.Message);
end;
end;
end;
end;
procedure TfrmMainRTSP.TimerTimeTimer(Sender: TObject);
begin
lblDateTime.Caption := FormatDateTime('yyyy-mm-dd hh:nn:ss', Now);
end;
procedure TfrmMainRTSP.BuildCCTVGrid;
var i: Integer; Btn: TPanel; LText: string;
begin
for i := 0 to lstCameras.Count-1 do
begin
LText := 'Camera '+IntToStr(i+1);
Btn := MakeDynButton(pnlCCTVButtons, LText, i, OnPlayCameraClick);
Btn.Top := 8; Btn.Left := 10 + i*170;
if i = FActiveCameraIdx then
Btn.Color := TColor($00226622); // Ȱ<><C8B0> ī<>޶<EFBFBD> <20><>ư <20><><EFBFBD><EFBFBD>
end;
// <20><><EFBFBD>ϵ<EFBFBD> ī<>޶<EFBFBD><DEB6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ù <20><>° ī<>޶<EFBFBD> <20>ڵ<EFBFBD> <20><><EFBFBD><EFBFBD>
if lstCameras.Count > 0 then
OnPlayCameraClick(pnlCCTVButtons.Controls[0]);
end;
procedure TfrmMainRTSP.FormDestroy(Sender: TObject);
begin
if FMpv <> nil then begin FMpv.Stop; FreeAndNil(FMpv); end;
end;
procedure TfrmMainRTSP.lblCloseTextClick(Sender: TObject);
begin
Close;
end;
procedure TfrmMainRTSP.lblFullscreenTextClick(Sender: TObject);
begin
if WindowState = wsMaximized then begin WindowState := wsNormal; BorderStyle := bsSizeable; end
else begin BorderStyle := bsNone; WindowState := wsMaximized; end;
end;
end.