node-mac-recorder 2.18.1 → 2.18.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +79 -33
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -365,10 +365,10 @@ class MacRecorder extends EventEmitter {
365
365
  this.isRecording = true;
366
366
  this.recordingStartTime = Date.now();
367
367
 
368
- // Start unified cursor tracking for all recording types
369
- // Use the same standard cursor tracking logic that works best (display-relative)
368
+ // Start unified cursor tracking with video-relative coordinates
369
+ // This ensures cursor positions match exactly with video frames
370
370
  const standardCursorOptions = {
371
- displayRelative: true,
371
+ videoRelative: true,
372
372
  displayInfo: this.recordingDisplayInfo,
373
373
  recordingType: this.options.windowId ? 'window' :
374
374
  this.options.captureArea ? 'area' : 'display',
@@ -652,12 +652,14 @@ class MacRecorder extends EventEmitter {
652
652
  }
653
653
 
654
654
  /**
655
- * Unified cursor capture for all recording types - uses standardized display-relative coordinates
655
+ * Unified cursor capture for all recording types - uses video-relative coordinates
656
656
  * @param {string|number} intervalOrFilepath - Cursor data JSON dosya yolu veya interval
657
657
  * @param {Object} options - Cursor capture seçenekleri
658
- * @param {boolean} options.displayRelative - Use display-relative coordinates (recommended)
658
+ * @param {boolean} options.videoRelative - Use video-relative coordinates (recommended)
659
659
  * @param {Object} options.displayInfo - Display information for coordinate transformation
660
660
  * @param {string} options.recordingType - Type of recording: 'display', 'window', 'area'
661
+ * @param {Object} options.captureArea - Capture area for area recording coordinate transformation
662
+ * @param {number} options.windowId - Window ID for window recording coordinate transformation
661
663
  */
662
664
  async startCursorCapture(intervalOrFilepath = 100, options = {}) {
663
665
  let filepath;
@@ -679,16 +681,42 @@ class MacRecorder extends EventEmitter {
679
681
  throw new Error("Cursor capture is already running");
680
682
  }
681
683
 
682
- // Use standardized display-relative coordinate system for all recording types
683
- if (options.displayRelative && options.displayInfo) {
684
- // Standardized display-relative coordinates for all recording types
684
+ // Use video-relative coordinate system for all recording types
685
+ if (options.videoRelative && options.displayInfo) {
686
+ // Calculate video offset based on recording type
687
+ let videoOffsetX = 0;
688
+ let videoOffsetY = 0;
689
+ let videoWidth = options.displayInfo.width || options.displayInfo.logicalWidth;
690
+ let videoHeight = options.displayInfo.height || options.displayInfo.logicalHeight;
691
+
692
+ if (options.recordingType === 'window' && options.windowId) {
693
+ // For window recording: offset = window position in display
694
+ if (options.captureArea) {
695
+ videoOffsetX = options.captureArea.x;
696
+ videoOffsetY = options.captureArea.y;
697
+ videoWidth = options.captureArea.width;
698
+ videoHeight = options.captureArea.height;
699
+ }
700
+ } else if (options.recordingType === 'area' && options.captureArea) {
701
+ // For area recording: offset = area position in display
702
+ videoOffsetX = options.captureArea.x;
703
+ videoOffsetY = options.captureArea.y;
704
+ videoWidth = options.captureArea.width;
705
+ videoHeight = options.captureArea.height;
706
+ }
707
+ // For display recording: offset remains 0,0
708
+
685
709
  this.cursorDisplayInfo = {
686
710
  displayId: options.displayInfo.displayId || options.displayInfo.id,
687
- x: options.displayInfo.x || 0,
688
- y: options.displayInfo.y || 0,
689
- width: options.displayInfo.width || options.displayInfo.logicalWidth,
690
- height: options.displayInfo.height || options.displayInfo.logicalHeight,
691
- displayRelative: true,
711
+ displayX: options.displayInfo.x || 0,
712
+ displayY: options.displayInfo.y || 0,
713
+ displayWidth: options.displayInfo.width || options.displayInfo.logicalWidth,
714
+ displayHeight: options.displayInfo.height || options.displayInfo.logicalHeight,
715
+ videoOffsetX: videoOffsetX,
716
+ videoOffsetY: videoOffsetY,
717
+ videoWidth: videoWidth,
718
+ videoHeight: videoHeight,
719
+ videoRelative: true,
692
720
  recordingType: options.recordingType || 'display',
693
721
  // Store additional context for debugging
694
722
  captureArea: options.captureArea,
@@ -698,7 +726,15 @@ class MacRecorder extends EventEmitter {
698
726
  // Fallback: Use recording display info if available
699
727
  this.cursorDisplayInfo = {
700
728
  ...this.recordingDisplayInfo,
701
- displayRelative: true,
729
+ displayX: this.recordingDisplayInfo.x || 0,
730
+ displayY: this.recordingDisplayInfo.y || 0,
731
+ displayWidth: this.recordingDisplayInfo.width || this.recordingDisplayInfo.logicalWidth,
732
+ displayHeight: this.recordingDisplayInfo.height || this.recordingDisplayInfo.logicalHeight,
733
+ videoOffsetX: 0,
734
+ videoOffsetY: 0,
735
+ videoWidth: this.recordingDisplayInfo.width || this.recordingDisplayInfo.logicalWidth,
736
+ videoHeight: this.recordingDisplayInfo.height || this.recordingDisplayInfo.logicalHeight,
737
+ videoRelative: true,
702
738
  recordingType: options.recordingType || 'display'
703
739
  };
704
740
  } else {
@@ -738,26 +774,30 @@ class MacRecorder extends EventEmitter {
738
774
  const position = nativeBinding.getCursorPosition();
739
775
  const timestamp = Date.now() - this.cursorCaptureStartTime;
740
776
 
741
- // Standardized coordinate transformation for all recording types
777
+ // Video-relative coordinate transformation for all recording types
742
778
  let x = position.x;
743
779
  let y = position.y;
744
780
  let coordinateSystem = "global";
745
781
 
746
- // Apply display-relative transformation for all recording types
747
- if (this.cursorDisplayInfo && this.cursorDisplayInfo.displayRelative) {
748
- // Transform global → display-relative coordinates
749
- x = position.x - this.cursorDisplayInfo.x;
750
- y = position.y - this.cursorDisplayInfo.y;
751
- coordinateSystem = "display-relative";
752
-
753
- // Optional bounds check for display (don't skip, just note if outside)
754
- const outsideDisplay = x < 0 || y < 0 ||
755
- x >= this.cursorDisplayInfo.width ||
756
- y >= this.cursorDisplayInfo.height;
757
-
758
- // For debugging - add metadata if cursor is outside recording area
759
- if (outsideDisplay) {
760
- coordinateSystem = "display-relative-outside";
782
+ // Apply video-relative transformation for all recording types
783
+ if (this.cursorDisplayInfo && this.cursorDisplayInfo.videoRelative) {
784
+ // Step 1: Transform global → display-relative coordinates
785
+ const displayRelativeX = position.x - this.cursorDisplayInfo.displayX;
786
+ const displayRelativeY = position.y - this.cursorDisplayInfo.displayY;
787
+
788
+ // Step 2: Transform display-relative → video-relative coordinates
789
+ x = displayRelativeX - this.cursorDisplayInfo.videoOffsetX;
790
+ y = displayRelativeY - this.cursorDisplayInfo.videoOffsetY;
791
+ coordinateSystem = "video-relative";
792
+
793
+ // Bounds check for video area (don't skip, just note if outside)
794
+ const outsideVideo = x < 0 || y < 0 ||
795
+ x >= this.cursorDisplayInfo.videoWidth ||
796
+ y >= this.cursorDisplayInfo.videoHeight;
797
+
798
+ // For debugging - add metadata if cursor is outside video area
799
+ if (outsideVideo) {
800
+ coordinateSystem = "video-relative-outside";
761
801
  }
762
802
  }
763
803
 
@@ -769,12 +809,18 @@ class MacRecorder extends EventEmitter {
769
809
  cursorType: position.cursorType,
770
810
  type: position.eventType || "move",
771
811
  coordinateSystem: coordinateSystem,
772
- // Standardized metadata for all recording types
812
+ // Video-relative metadata for all recording types
773
813
  recordingType: this.cursorDisplayInfo?.recordingType || "display",
814
+ videoInfo: this.cursorDisplayInfo ? {
815
+ width: this.cursorDisplayInfo.videoWidth,
816
+ height: this.cursorDisplayInfo.videoHeight,
817
+ offsetX: this.cursorDisplayInfo.videoOffsetX,
818
+ offsetY: this.cursorDisplayInfo.videoOffsetY
819
+ } : null,
774
820
  displayInfo: this.cursorDisplayInfo ? {
775
821
  displayId: this.cursorDisplayInfo.displayId,
776
- width: this.cursorDisplayInfo.width,
777
- height: this.cursorDisplayInfo.height
822
+ width: this.cursorDisplayInfo.displayWidth,
823
+ height: this.cursorDisplayInfo.displayHeight
778
824
  } : null
779
825
  };
780
826
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.18.1",
3
+ "version": "2.18.2",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [