node-mac-recorder 2.21.53 → 2.22.0

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.
@@ -48,7 +48,8 @@
48
48
  "Bash(grep:*)",
49
49
  "Bash(timeout 10 ffprobe:*)",
50
50
  "Bash(ffmpeg:*)",
51
- "Bash(timeout 30 node:*)"
51
+ "Bash(timeout 30 node:*)",
52
+ "Bash(MAC_RECORDER_DEBUG=1 node test-camera-audio-sync.js:*)"
52
53
  ],
53
54
  "deny": [],
54
55
  "ask": []
package/index.js CHANGED
@@ -1119,12 +1119,15 @@ class MacRecorder extends EventEmitter {
1119
1119
  try {
1120
1120
  console.log('🛑 SYNC: Stopping screen recording');
1121
1121
  const stopLimit = elapsedSeconds > 0 ? elapsedSeconds : 0;
1122
+ console.log(`📊 DEBUG: elapsedSeconds=${elapsedSeconds.toFixed(3)}, stopLimit=${stopLimit.toFixed(3)}`);
1123
+ console.log(`📊 DEBUG: typeof nativeBinding.stopRecording = ${typeof nativeBinding.stopRecording}`);
1124
+ console.log(`📊 DEBUG: nativeBinding.stopRecording = ${nativeBinding.stopRecording}`);
1122
1125
  success = nativeBinding.stopRecording(stopLimit);
1123
1126
  if (success) {
1124
1127
  console.log('✅ SYNC: Screen recording stopped');
1125
1128
  }
1126
1129
  } catch (nativeError) {
1127
- // console.log('Native stop failed:', nativeError.message);
1130
+ console.log('⚠️ Native stop failed:', nativeError.message);
1128
1131
  success = true; // Assume success to avoid throwing
1129
1132
  }
1130
1133
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.21.53",
3
+ "version": "2.22.0",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -538,11 +538,31 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
538
538
  }
539
539
  [self.writer startSessionAtSourceTime:kCMTimeZero]; // CRITICAL: t=0 timeline
540
540
  self.writerStarted = YES;
541
- self.startTime = timestamp;
541
+
542
+ // LIP SYNC FIX: Align camera startTime with audio's first timestamp for perfect lip sync
543
+ // This ensures camera and audio start from the same reference point
544
+ CMTime audioFirstTimestamp = MRSyncAudioFirstTimestamp();
545
+ CMTime alignmentOffset = MRSyncVideoAlignmentOffset();
546
+
547
+ if (CMTIME_IS_VALID(audioFirstTimestamp)) {
548
+ // Use audio's first timestamp as reference - this is the key to lip sync
549
+ self.startTime = audioFirstTimestamp;
550
+ CMTime offset = CMTimeSubtract(timestamp, audioFirstTimestamp);
551
+ double offsetMs = CMTimeGetSeconds(offset) * 1000.0;
552
+ MRLog(@"🎥 Camera writer started @ t=0 (aligned with audio first timestamp, offset: %.1fms)", offsetMs);
553
+ } else if (CMTIME_IS_VALID(alignmentOffset)) {
554
+ // If audio came first, use the alignment offset to sync
555
+ self.startTime = CMTimeSubtract(timestamp, alignmentOffset);
556
+ double offsetMs = CMTimeGetSeconds(alignmentOffset) * 1000.0;
557
+ MRLog(@"🎥 Camera writer started @ t=0 (using alignment offset: %.1fms)", offsetMs);
558
+ } else {
559
+ // Fallback: use camera's own timestamp (should not happen if sync is configured)
560
+ self.startTime = timestamp;
561
+ MRLog(@"🎥 Camera writer started @ t=0 (source PTS: %.3fs, no audio sync available)", CMTimeGetSeconds(timestamp));
562
+ }
563
+
542
564
  g_cameraStartTimestamp = CFAbsoluteTimeGetCurrent();
543
565
 
544
- MRLog(@"🎥 Camera writer started @ t=0 (source PTS: %.3fs)", CMTimeGetSeconds(timestamp));
545
-
546
566
  // Signal start completion
547
567
  [self completeStart:YES token:self.activeToken];
548
568
  }
@@ -553,12 +573,50 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
553
573
  }
554
574
 
555
575
  // TIMESTAMP NORMALIZATION (audio_recorder.mm pattern)
576
+ // LIP SYNC FIX: Use audio-aligned startTime for perfect synchronization
556
577
  CMTime adjustedTimestamp = kCMTimeZero;
557
578
  if (CMTIME_IS_VALID(self.startTime)) {
558
579
  adjustedTimestamp = CMTimeSubtract(timestamp, self.startTime);
559
580
  if (CMTIME_COMPARE_INLINE(adjustedTimestamp, <, kCMTimeZero)) {
560
581
  adjustedTimestamp = kCMTimeZero;
561
582
  }
583
+ } else {
584
+ // Fallback: if startTime not set, use current timestamp as base
585
+ // This should not happen if sync is working correctly
586
+ adjustedTimestamp = kCMTimeZero;
587
+ }
588
+
589
+ // LIP SYNC FIX: Check stopLimit OR elapsed time to drop frames after recording duration
590
+ // This prevents camera from recording longer than audio
591
+ double frameTime = CMTimeGetSeconds(adjustedTimestamp);
592
+ double stopLimit = MRSyncGetStopLimitSeconds();
593
+ double videoTolerance = 0.05; // 50ms tolerance for video frames (larger than audio's 20ms)
594
+
595
+ // CRITICAL FIX: Also check elapsed time since recording started
596
+ // This works even if stopLimit hasn't been set yet
597
+ double elapsedTime = (g_cameraStartTimestamp > 0) ? (CFAbsoluteTimeGetCurrent() - g_cameraStartTimestamp) : 0;
598
+ double maxDuration = (stopLimit > 0) ? stopLimit : elapsedTime + 1.0; // Use stopLimit if available, else allow 1s more
599
+
600
+ // DEBUG: Log every 30th frame
601
+ static int frameCounter = 0;
602
+ frameCounter++;
603
+ if (frameCounter % 30 == 0) {
604
+ MRLog(@"📹 Camera frame #%d: frameTime=%.3fs, elapsedTime=%.3fs, stopLimit=%.3fs, maxDuration=%.3fs",
605
+ frameCounter, frameTime, elapsedTime, stopLimit, maxDuration);
606
+ }
607
+
608
+ // Drop frame if it exceeds stopLimit (when set) or if elapsed time is suspiciously long
609
+ if (stopLimit > 0 && frameTime > stopLimit + videoTolerance) {
610
+ MRLog(@"🛑 Camera dropping frame #%d: frameTime %.3fs > stopLimit %.3fs + tolerance",
611
+ frameCounter, frameTime, stopLimit);
612
+ return;
613
+ }
614
+
615
+ // Safety check: Drop frames if recording has been going for too long (failsafe)
616
+ if (elapsedTime > maxDuration + 1.0) { // Allow 1s grace period
617
+ MRLog(@"🛑 Camera dropping frame #%d: elapsed %.3fs > maxDuration %.3fs (failsafe)",
618
+ frameCounter, elapsedTime, maxDuration);
619
+ return;
562
620
  }
563
621
 
564
622
  // Get pixel buffer from sample
@@ -847,6 +905,14 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
847
905
 
848
906
  // Finalize writer (audio_recorder.mm pattern)
849
907
  if (self.writer && self.writerStarted) {
908
+ // LIP SYNC FIX: End session at stopLimit to trim excess frames
909
+ double stopLimit = MRSyncGetStopLimitSeconds();
910
+ if (stopLimit > 0) {
911
+ CMTime endTime = CMTimeMakeWithSeconds(stopLimit, 600);
912
+ [self.writer endSessionAtSourceTime:endTime];
913
+ MRLog(@"🎯 Camera writer session ended at %.3fs (stopLimit)", stopLimit);
914
+ }
915
+
850
916
  if (self.writerInput) {
851
917
  [self.writerInput markAsFinished];
852
918
  }
@@ -786,14 +786,23 @@ Napi::Value StopRecording(const Napi::CallbackInfo& info) {
786
786
  }
787
787
 
788
788
  if (requestedStopLimit > 0) {
789
+ MRLog(@"🎯 SYNC FIX: Setting stopLimit = %.3f seconds", requestedStopLimit);
789
790
  MRStoreActiveStopLimit(requestedStopLimit);
790
791
  MRSyncSetStopLimitSeconds(requestedStopLimit);
791
792
  } else {
793
+ MRLog(@"⚠️ SYNC FIX: stopLimit NOT set (requestedStopLimit = %.3f)", requestedStopLimit);
792
794
  MRStoreActiveStopLimit(-1.0);
793
795
  MRSyncSetStopLimitSeconds(-1.0);
794
796
  }
795
797
  MRResetRecordingStartTimestamp();
796
-
798
+
799
+ // LIP SYNC FIX: Wait 150ms for camera/audio delegates to see stopLimit and drop excess frames
800
+ if (requestedStopLimit > 0 && (isCameraRecording() || isStandaloneAudioRecording())) {
801
+ MRLog(@"⏳ LIP SYNC: Waiting 150ms for delegates to process stopLimit...");
802
+ [NSThread sleepForTimeInterval:0.15];
803
+ MRLog(@"✅ LIP SYNC: Delegate processing time complete");
804
+ }
805
+
797
806
  // Try ScreenCaptureKit first
798
807
  if (@available(macOS 12.3, *)) {
799
808
  if ([ScreenCaptureKitRecorder isRecording]) {
@@ -1 +0,0 @@
1
- [{"x":1147,"y":408,"timestamp":25,"unixTimeMs":1765066231580,"cursorType":"text","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330},"_syncMetadata":{"videoStartTime":1765066228867,"cursorStartTime":1765066231555,"offsetMs":2688}},{"x":1147,"y":408,"timestamp":7015,"unixTimeMs":1765066238570,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1125,"y":410,"timestamp":7769,"unixTimeMs":1765066239324,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1068,"y":422,"timestamp":7787,"unixTimeMs":1765066239342,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":998,"y":440,"timestamp":7810,"unixTimeMs":1765066239365,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":835,"y":486,"timestamp":7829,"unixTimeMs":1765066239384,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":713,"y":525,"timestamp":7853,"unixTimeMs":1765066239408,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":606,"y":566,"timestamp":7872,"unixTimeMs":1765066239427,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":565,"y":581,"timestamp":7894,"unixTimeMs":1765066239449,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":596,"timestamp":7915,"unixTimeMs":1765066239470,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":586,"timestamp":8127,"unixTimeMs":1765066239682,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":564,"timestamp":8146,"unixTimeMs":1765066239701,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":528,"timestamp":8168,"unixTimeMs":1765066239723,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":513,"timestamp":8188,"unixTimeMs":1765066239743,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":501,"timestamp":8210,"unixTimeMs":1765066239765,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":531,"y":497,"timestamp":8230,"unixTimeMs":1765066239785,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":549,"y":497,"timestamp":8923,"unixTimeMs":1765066240478,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":574,"y":500,"timestamp":8944,"unixTimeMs":1765066240499,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":615,"y":506,"timestamp":8964,"unixTimeMs":1765066240519,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":696,"y":517,"timestamp":8986,"unixTimeMs":1765066240541,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":753,"y":526,"timestamp":9006,"unixTimeMs":1765066240561,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":838,"y":536,"timestamp":9027,"unixTimeMs":1765066240582,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":890,"y":547,"timestamp":9047,"unixTimeMs":1765066240602,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":920,"y":556,"timestamp":9069,"unixTimeMs":1765066240624,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":923,"y":557,"timestamp":9089,"unixTimeMs":1765066240644,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":922,"y":553,"timestamp":9277,"unixTimeMs":1765066240832,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":918,"y":538,"timestamp":9299,"unixTimeMs":1765066240854,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":917,"y":520,"timestamp":9320,"unixTimeMs":1765066240875,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":917,"y":466,"timestamp":9344,"unixTimeMs":1765066240899,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":918,"y":443,"timestamp":9363,"unixTimeMs":1765066240918,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":924,"y":415,"timestamp":9383,"unixTimeMs":1765066240938,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":929,"y":398,"timestamp":9403,"unixTimeMs":1765066240958,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":934,"y":387,"timestamp":9427,"unixTimeMs":1765066240982,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":937,"y":383,"timestamp":9446,"unixTimeMs":1765066241001,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":940,"y":377,"timestamp":9469,"unixTimeMs":1765066241024,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":943,"y":371,"timestamp":9487,"unixTimeMs":1765066241042,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":950,"y":361,"timestamp":9507,"unixTimeMs":1765066241062,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":958,"y":349,"timestamp":9529,"unixTimeMs":1765066241084,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":964,"y":341,"timestamp":9552,"unixTimeMs":1765066241107,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":971,"y":333,"timestamp":9570,"unixTimeMs":1765066241125,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":976,"y":327,"timestamp":9594,"unixTimeMs":1765066241149,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":985,"y":319,"timestamp":9612,"unixTimeMs":1765066241167,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1001,"y":303,"timestamp":9636,"unixTimeMs":1765066241191,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1001,"y":299,"timestamp":9864,"unixTimeMs":1765066241419,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1004,"y":293,"timestamp":9886,"unixTimeMs":1765066241441,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1008,"y":290,"timestamp":9906,"unixTimeMs":1765066241461,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1010,"y":287,"timestamp":9928,"unixTimeMs":1765066241483,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1012,"y":284,"timestamp":9948,"unixTimeMs":1765066241503,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1013,"y":281,"timestamp":9969,"unixTimeMs":1765066241524,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1014,"y":278,"timestamp":9993,"unixTimeMs":1765066241548,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}}]