unit RTSPRecorderService_;


interface

uses
    Windows,
    Classes,
    Vcl.SvcMgr,
    VidGrab;

const
   VIDEOGRABBERSCOUNT = 2;

type
  TRTSPRecordService = class(TService)
    procedure ServiceExecute(Sender: TService);
    procedure ServiceStart(Sender: TService; var Started: Boolean);
  private
    VideoGrabbers: array[1..VIDEOGRABBERSCOUNT] of TVideoGrabber;
  public
    function GetServiceController: TServiceController; override;
  end;

var
  RTSPRecordService: TRTSPRecordService;

implementation

{$R *.DFM}

uses
   SysUtils;

type
   TIPCameraInfo = record
      Name: string;
      URL: string;
   end;

const
   IPCAMERAS: array[1..VIDEOGRABBERSCOUNT] of TIPCameraInfo =
   (
      (Name: 'Camera1'; URL:'rtsp://192.168.0.210/axis-media/media.amp?videocodec=h264'),
      (Name: 'Camera2'; URL:'rtsp://192.168.0/211/axis-media/media.amp?videocodec=h264')
   );

   REPLACE "C:\YourFolder\" below by the real folder where the recorded files must be stored (don't forget the trailing slash)
   STORAGEFOLDER = 'C:\YourFolder\';

(*_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_*)
procedure ServiceController(CtrlCode: DWord); stdcall;
begin
  RTSPRecordService.Controller(CtrlCode);
end;

(*_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_*)
function TRTSPRecordService.GetServiceController: TServiceController;
begin
  Result := ServiceController;
end;

(*_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_*)
procedure TRTSPRecordService.ServiceStart(Sender: TService;
  var Started: Boolean);
var
   i: Integer;
   vg: TVideoGrabber;
begin
   for i := low(VideoGrabbers) to high(VideoGrabbers) do begin
      VideoGrabbers[i] := TVideoGrabber.Create(nil);
      Vg := VideoGrabbers[i];
      Vg.VideoRenderer := vr_None;
      Vg.FrameGrabber := fg_Disabled; // SAVES LOT OF CPU
      Vg.VideoSource := vs_IPCamera;
      Vg.IPCameraURL := IPCAMERAS[i].URL;
      Vg.RecordingMethod := rm_MP4;
      Vg.RecordingTimer := rt_RecordToNewFile;
      Vg.StoragePath := STORAGEFOLDER;
      Vg.RecordingTimerInterval := 10; // 10 seconds
      Vg.AutoFileName := fn_DateTime;
      Vg.AutoFilePrefix := IPCAMERAS[i].Name + '_';
      Vg.AutoFileSuffix := '_record';
      Vg.AutoFileNameDateTimeFormat := 'yyyy.mm.dd-hh.mm.ss.zzz';
      Vg.StartRecording();
   end;
end;

(*_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_*)

procedure TRTSPRecordService.ServiceExecute(Sender: TService);
var
   i: Integer;
   vg: TVideoGrabber;
begin
    while not Terminated do begin
       for i := low(VideoGrabbers) to high(VideoGrabbers) do begin
          VideoGrabbers[i].ContinueProcessing();
       end;
       Sleep(50);
       ServiceThread.ProcessRequests (false);
    end;

    // !!! Stopping and destroying the TVideoGrabber instances must be performed HERE (and not from OnStop event)
    for i := low(VideoGrabbers) to high(VideoGrabbers) do begin
       Vg := VideoGrabbers[i];
       Vg.Stop();
       Vg.ContinueProcessing();
       Vg.Free;
    end;
end;

end.

