# @elizaos/capacitor-screencapture
Cross-platform screen capture Capacitor plugin for elizaOS. Captures screenshots and records the screen on browser (Web API), iOS (ReplayKit + AVFoundation), and Android (MediaProjection).
## What it does
- **Screenshot:** Captures a single frame of the screen as a base64-encoded PNG, JPEG, or WebP image.
- **Screen recording:** Records the screen to a video file (WebM on browser, MP4 on native), with optional audio from the system, microphone, or both.
- **Pause / resume:** Pause and resume an active recording without creating a new file (Android requires API 24+).
- **Permission checks:** Query and request screen-capture and microphone permissions in a unified cross-platform API.
- **Live events:** Subscribe to `recordingState` and `error` events emitted during recording.
## Platform support
| Feature | Browser | iOS | Android |
|---------|---------|-----|---------|
| Screenshot | Yes (getDisplayMedia) | Yes (UIKit) | Yes (MediaProjection) |
| Screen recording | Yes (MediaRecorder) | Yes (ReplayKit) | Yes (MediaRecorder) |
| Pause/resume | Yes | Yes | API 24+ only |
| System audio | Browser-dependent | Yes (RPSampleBufferType.audioApp) | No (microphone only) |
| Microphone audio | Yes | Yes | Yes |
## Installation
```bash
npm install @elizaos/capacitor-screencapture
npx cap sync
```
For iOS, add to your app's `Info.plist`:
```xml
NSMicrophoneUsageDescription
Microphone is used to capture audio during screen recording.
```
For Android 14+ (API 34), declare in `AndroidManifest.xml`:
```xml
```
This is in addition to the `FOREGROUND_SERVICE` permission that this plugin's own `AndroidManifest.xml` already declares.
## Usage
```typescript
import { ScreenCapture } from '@elizaos/capacitor-screencapture';
// Check support
const { supported, features } = await ScreenCapture.isSupported();
// Take a screenshot
const shot = await ScreenCapture.captureScreenshot({ format: 'png', quality: 100 });
// shot.base64 contains the image data
// Record the screen
await ScreenCapture.startRecording({
quality: 'high', // 'low' | 'medium' | 'high' | 'highest'
fps: 30,
captureSystemAudio: true,
captureMicrophone: false,
maxDuration: 300, // seconds; undefined = unlimited
});
// Listen for state updates
const handle = await ScreenCapture.addListener('recordingState', (state) => {
console.log(`Recording: ${state.isRecording}, duration: ${state.duration}s`);
});
// Stop and get the result
const result = await ScreenCapture.stopRecording();
// result.path — blob: URL (browser) or filesystem path (native)
// result.mimeType — video/webm (browser) or video/mp4 (native)
await handle.remove();
```
## Permissions
Screen capture permission works differently per platform:
- **Browser:** `getDisplayMedia` always shows an OS-level picker dialog. There is no way to pre-grant or query this permission. `checkPermissions()` returns `"prompt"` when the API is available.
- **iOS:** Screenshots use UIKit only — no permission required. `startRecording` uses ReplayKit, which shows a system broadcast picker on first use.
- **Android:** `captureScreenshot` and `startRecording` both trigger a `MediaProjection` consent dialog. Microphone permission (`RECORD_AUDIO`) is requested at runtime when `captureMicrophone: true`.
```typescript
// Check permissions
const status = await ScreenCapture.checkPermissions();
// status.screenCapture: 'granted' | 'denied' | 'prompt' | 'not_supported'
// status.microphone: 'granted' | 'denied' | 'prompt'
// Request microphone permission before recording with audio
await ScreenCapture.requestPermissions();
```
## Output formats
| Platform | Screenshot | Recording |
|----------|-----------|-----------|
| Browser | PNG / JPEG / WebP | video/webm (VP9 preferred), blob: URL |
| iOS | PNG / JPEG / WebP (WebP requires iOS 14+) | video/mp4 (H.264 + AAC), file:// path |
| Android | PNG / JPEG / WebP (WebP lossy requires API 30+) | video/mp4 (H.264), file path |
## Recording options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `quality` | `'low' \| 'medium' \| 'high' \| 'highest'` | `'high'` | Quality preset (sets bitrate on iOS; sets fps + bitrate on Android) |
| `fps` | `number` | 30 | Frames per second (1–60; overrides quality preset) |
| `bitrate` | `number` | Estimated | Video bitrate in bits/s (overrides quality preset) |
| `maxDuration` | `number` | unlimited | Stop automatically after N seconds |
| `maxFileSize` | `number` | unlimited | Stop automatically after N bytes |
| `captureSystemAudio` | `boolean` | `true` | Include app/system audio (browser + iOS; Android records microphone only) |
| `captureMicrophone` | `boolean` | `false` | Include microphone audio in recording |
## Building from source
```bash
bun run --cwd plugins/plugin-native-screencapture build
```
This runs `tsc` then `rollup` and outputs `dist/esm/`, `dist/plugin.js` (IIFE), and `dist/plugin.cjs.js`.