@firstform/caprecorder
v1.0.0
Published
A headless screen recording library powered by Cap, built with Rust and exposed to Node.js via NAPI. High-performance screen and window capture with system audio recording support.
Maintainers
Readme
caprecorder
A headless screen recording library powered by Cap, built with Rust and exposed to Node.js via NAPI.
Features
- 🎥 High-performance screen recording
- 🖥️ Support for both screen and window capture
- 🔊 System audio recording
- 🎯 Cross-platform (macOS, Windows, Linux)
- ⚡ Native Rust performance
- 🚀 Async/await API
- 🎮 Headless operation (no GUI required)
- ⏸️ Pause/resume functionality
Installation
npm install caprecorderQuick Start
const { CapRecorder, listAvailableScreens, hasScreenCapturePermission } = require('caprecorder');
async function recordScreen() {
// Check permissions first
if (!hasScreenCapturePermission()) {
console.error('Screen capture permission required');
return;
}
// List available screens
const screens = listAvailableScreens();
console.log('Available screens:', screens);
const recorder = new CapRecorder();
try {
// Start recording
await recorder.startRecording({
outputPath: './recordings/my-recording',
screenId: screens[0].id,
captureSystemAudio: true,
fps: 30
});
console.log('Recording started!');
// Record for 10 seconds
await new Promise(resolve => setTimeout(resolve, 10000));
// Stop recording
const outputPath = await recorder.stopRecording();
console.log('Recording saved to:', outputPath);
} catch (error) {
console.error('Recording failed:', error);
// Cleanup on error
try {
await recorder.cancelRecording();
} catch (e) {
// Ignore cleanup errors
}
}
}
recordScreen();setTimeout(async () => {
const outputPath = await recorder.stopRecording();
console.log('Recording saved to:', outputPath);
}, 10000);} catch (error) { console.error('Recording failed:', error); } }
recordScreen();
## API Reference
### CapRecorder
The main recording class.
#### Constructor
```javascript
const recorder = new CapRecorder();Methods
startRecording(config: RecordingConfig): Promise<void>
Starts a new recording session.
Parameters:
config.outputPath(string): Directory where the recording will be savedconfig.screenId(number, optional): ID of screen to recordconfig.windowId(number, optional): ID of window to recordconfig.captureSystemAudio(boolean, optional): Whether to capture system audio (default: false)config.fps(number, optional): Recording frame rate
Note: Either screenId or windowId must be specified.
stopRecording(): Promise<string>
Stops the current recording and returns the path to the saved recording.
pauseRecording(): Promise<void>
Pauses the current recording.
resumeRecording(): Promise<void>
Resumes a paused recording.
cancelRecording(): Promise<void>
Cancels the current recording without saving.
Utility Functions
listAvailableScreens(): ScreenInfo[]
Returns a list of available screens for recording.
const screens = listAvailableScreens();
// Returns: [{ id: 1, name: "Built-in Display", refreshRate: 60 }, ...]listAvailableWindows(): WindowInfo[]
Returns a list of available windows for recording.
const windows = listAvailableWindows();
// Returns: [{ id: 123, title: "Terminal", ownerName: "Terminal" }, ...]hasScreenCapturePermission(): boolean
Checks if the application has permission to capture the screen.
if (!hasScreenCapturePermission()) {
console.log('Please grant screen recording permission');
}Examples
For more detailed examples, see the examples.js file or run:
# Run all examples
node examples.js
# Run specific examples
node examples.js screen # Screen recording
node examples.js window # Window recording
node examples.js audio # Audio recording
node examples.js pause # Pause/resume exampleScreen Recording
const { CapRecorder, listAvailableScreens } = require('caprecorder');
const recorder = new CapRecorder();
const screens = listAvailableScreens();
await recorder.startRecording({
outputPath: './recordings/screen-recording',
screenId: screens[0].id,
captureSystemAudio: true, // Include system audio
fps: 30
});
// Record for 30 seconds
setTimeout(async () => {
const output = await recorder.stopRecording();
console.log('Screen recording saved:', output);
}, 30000);Window Recording
const { CapRecorder, listAvailableWindows } = require('caprecorder');
const recorder = new CapRecorder();
const windows = listAvailableWindows();
// Find a specific window or use the first one
const targetWindow = windows.find(w => w.title.includes('VS Code')) || windows[0];
await recorder.startRecording({
outputPath: './recordings/window-recording',
windowId: targetWindow.id,
captureSystemAudio: true, // You can include audio for window recording
fps: 30
});
// Record for 30 seconds
setTimeout(async () => {
const output = await recorder.stopRecording();
console.log('Window recording saved:', output);
}, 30000);Audio-Only Recording
const recorder = new CapRecorder();
const screens = listAvailableScreens();
await recorder.startRecording({
outputPath: './recordings/audio-only',
screenId: screens[0].id,
captureSystemAudio: true,
fps: 1 // Very low fps to minimize video file size
});
// Record audio for 60 seconds
setTimeout(async () => {
const output = await recorder.stopRecording();
console.log('Audio recording saved:', output);
// Check the segments folder for the .ogg audio file
}, 60000);Pause and Resume Recording
const recorder = new CapRecorder();
await recorder.startRecording({
outputPath: './recordings/pause-resume-test',
screenId: screens[0].id,
captureSystemAudio: false,
fps: 30
});
// Record for 5 seconds
setTimeout(() => recorder.pauseRecording(), 5000);
// Resume after 2 seconds
setTimeout(() => recorder.resumeRecording(), 7000);
// Stop after another 5 seconds
setTimeout(() => recorder.stopRecording(), 12000);Testing
Run the test suite to verify functionality:
# Run all tests
node tests/index.js
# Run specific test suites
node tests/index.js basic # Basic functionality tests
node tests/index.js audio # Audio recording tests
node tests/index.js advanced # Advanced features and error handlingOutput Format
Recordings are saved in a structured format:
your-recording/
├── project-config.json # Recording metadata
└── content/
├── cursors/ # Cursor data (if enabled)
└── segments/
└── segment-0/
├── display.mp4 # Video recording
└── system_audio.ogg # Audio recording (if enabled)Key Points:
- Video: Saved as MP4 files with H.264 encoding
- Audio: Saved as OGG files with Opus encoding
- Multiple segments: Long recordings may be split into multiple segments
- Metadata:
project-config.jsoncontains recording settings and timestamps
Configuration Options
Recording Configuration
{
outputPath: string, // Required: Output directory path
screenId?: number, // Screen ID (from listAvailableScreens)
windowId?: number, // Window ID (from listAvailableWindows)
captureSystemAudio?: boolean, // Default: false
fps?: number // Default: 30
}Audio Capture Notes
- System Audio: Captures all system audio output (music, notifications, etc.)
- Window Recording: Audio capture works for both screen and window recording
- Permissions: May require additional audio permissions on some systems
- Quality: Audio is encoded with Opus codec in OGG container
Troubleshooting
Common Issues
Permission Denied
# Check permissions
if (!hasScreenCapturePermission()) {
console.log('Please grant screen recording permission in System Preferences');
}No Screens/Windows Found
const screens = listAvailableScreens();
const windows = listAvailableWindows();
if (screens.length === 0) console.log('No screens detected');
if (windows.length === 0) console.log('No windows available');Recording Timeout
- Some longer recordings may timeout during stop operation
- Try shorter recording durations or use pause/resume functionality
- Check system resources and available disk space
Audio Issues
- Ensure system audio is playing during recording
- Check that
captureSystemAudio: trueis set - Verify audio permissions in system settings
FFmpeg Warnings
You may see warnings like:
[ogg @ 0x...] Timestamps are unset in a packet for stream 0These are deprecation warnings from FFmpeg and don't affect functionality, but indicate areas for future improvement in the audio encoding pipeline.
Performance Tips
- Use appropriate FPS settings (30 fps is usually sufficient)
- Consider audio-only recording for long sessions where video isn't needed
- Use pause/resume to avoid large continuous recordings
- Monitor disk space during long recordings
Platform Support
- macOS: Full support with hardware acceleration
- Windows: Full support with hardware acceleration
- Linux: Full support
Requirements
- Node.js 16 or higher
- Screen recording permissions (will be requested on first use)
- Sufficient disk space for recordings
- For audio recording: system audio output
License
MIT License - see LICENSE file for details.
Contributing
This package is part of the larger Cap project. For contributing guidelines, please see the main Cap repository.
