TMediaCapture component with screen recording capabilities added.

I added screen recording capabilities with recording region support to the TMediaCapture component. I use it to create voice over screen recording of sports analysis videos for students. It also fixes the camera recording issue of missing the duration in the video by including and adding the function using ysFixWebDuration JavaScript lib that can be downloaded for free. To use just replace the attached WEBlib.Devices files in both the "Components Library Source" and "Core Source" folders with the uploaded versions.

This is some sample code to setup and use the component and save the results to a local file.

procedure TMainForm.BtnScreenRecordStartClick(Sender: TObject);
var mr: TModalResult;
    l, t, w, h: Integer;
    r: TJSDOMRect;
    P1, P2: TPoint;
begin
   // prompt to start screen recording
    mr := TAwait.ExecP<TModalResult>(MessageDlgAsync('Press OK to Start Screen Recording', WEBLib.Dialogs.mtConfirmation, [mbOk, mbCancel]));
    if mr <> mrOk then
      exit;

    // get the rect of the component in the application to record
   // this case is a TWebPanel that contains a media play component
    r := VideoPanel.ElementHandle.getBoundingClientRect();
   
    // important: add some javascript to adjust the rect if the browser window is zoomed in or out
asm
  /* ---------- 1.  compute reliable scale ---------- */
  const dpr  = window.devicePixelRatio || 1;
  const zoom = (window.visualViewport && window.visualViewport.scale) || 1;
  const scale = dpr / zoom;              // <-- NEW

  /* ---------- 2.  convert CSS-px ? device-px ------ */
  l = Math.round(r.left   * scale);
  t = Math.round(r.top    * scale);
  w = Math.round(r.width  * scale);
  h = Math.round(r.height * scale);
end;

    // adjust the rect to get the screen location 
    P1.X := l;
    P1.Y := t;
    P2.X := w;
    P2.Y := h;
    P1 := VideoPanel.ClientToScreen(P1);
    P2 := VideoPanel.ClientToScreen(P2);

    // set the TMediaCapture Component to screen record mode
    ScreenRecorder.Capture := mctScreen;
   // set the region which may take a bit of adjustment based on how your screen is layed out
    ScreenRecorder.SetRegion(l + 10, P1.Y + ToolBarPanel.Height, w - 10, P2.Y - ToolBarPanel.Height-2);
   // set the seconds to skip so you do not include the browser prompt for the window to record
    ScreenRecorder.SetSkipSeconds(1);
   // start the screen recording
    ScreenRecorder.Start;
  
end

To save the result to a file use the OnStopCapture event.

procedure TMainForm.ScreenRecorderStopCapture(Sender: TObject; ABinary: TJSUint8Array; ABase: string);
var
  s, vidbase64: string;
  mr: TModalResult;
  blob: TJSBlob;
begin

  RecTimer.Visible := false;
  RecordTimer.Enabled := false;

  if Pos('data:', ABase) <> 1 then
    vidbase64 := 'data:video/mp4;base64,' + ABase
  else
    vidbase64 := ABase;

  if FSaveVideoToFile then
  begin
    FileRecSave.Filter.Add('Video Files','video/mp4','*.mp4');
    FileRecSave.Data := ABinary.buffer;

    try
      s := TAwait.ExecP<string>(FileRecSave.SaveAs());
      if s <> '' then
      begin
        mr := TAwait.ExecP<TModalResult>(MessageDlgAsync('Open new screen recording now?', WEBLib.Dialogs.mtConfirmation, [mbYes, mbNo]));
        if mr = mrNo then
          exit;

         MediaPlayer1.URL := vidbase64;

      end;
    except
      ShowMessage('File Not Saved ' + s);
    end;
  end;

  end

Here are the files:
CompLibSrc_WEBLib.Devices.zip (2.8 KB)
CoreSrc_WEBLib.Devices.zip (8.9 KB)

Thanks John,
We'll check these additional capabilities and when feasible, we'd adopt this in the framework code.

1 Like