Skip to content

Commit

Permalink
Require Node.js 18 and move to ESM and named exports (#31)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <[email protected]>
  • Loading branch information
yannbertrand and sindresorhus authored Mar 27, 2024
1 parent add1de1 commit 558b1b3
Show file tree
Hide file tree
Showing 8 changed files with 269 additions and 262 deletions.
12 changes: 5 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@ on:
jobs:
test:
name: Node.js ${{ matrix.node-version }}
runs-on: macos-11
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
node-version:
- 16
- 14
- 12
- 10
- 20
- 18
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
22 changes: 12 additions & 10 deletions example.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
'use strict';
const fs = require('fs');
const delay = require('delay');
const aperture = require('.');
import fs from 'node:fs';
import timers from 'node:timers/promises';
import {recorder, screens, audioDevices, videoCodecs} from './index.js';

async function main() {
const recorder = aperture();
console.log('Screens:', await aperture.screens());
console.log('Audio devices:', await aperture.audioDevices());
console.log('Video codecs:', aperture.videoCodecs);
console.log('Screens:', await screens());
console.log('Audio devices:', await audioDevices());
console.log('Video codecs:', videoCodecs);

console.log('Preparing to record for 5 seconds');
await recorder.startRecording();
console.log('Recording started');
await recorder.isFileReady;
console.log('File is ready');
await delay(5000);
await timers.setTimeout(5000);
const fp = await recorder.stopRecording();
fs.renameSync(fp, 'recording.mp4');
console.log('Video saved in the current directory');
}

main().catch(console.error);
try {
await main();
} catch (error) {
console.error(error);
}

// Run: $ node example.js
244 changes: 120 additions & 124 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,156 +1,152 @@
declare namespace aperture {
type Screen = {
id: number;
name: string;
};

type AudioDevice = {
id: string;
name: string;
};

type VideoCodec = 'h264' | 'hevc' | 'proRes422' | 'proRes4444';

type RecordingOptions = {
/**
Number of frames per seconds.
*/
readonly fps?: number;

/**
Record only an area of the screen.
*/
readonly cropArea?: {
x: number;
y: number;
width: number;
height: number;
};

/**
Show the cursor in the screen recording.
*/
readonly showCursor?: boolean;

/**
Highlight cursor clicks in the screen recording.
export type Screen = {
id: number;
name: string;
};

Enabling this will also enable the `showCursor` option.
*/
readonly highlightClicks?: boolean;
export type AudioDevice = {
id: string;
name: string;
};

/**
Screen to record.
export type VideoCodec = 'h264' | 'hevc' | 'proRes422' | 'proRes4444';

Defaults to primary screen.
*/
readonly screenId?: number;
export type RecordingOptions = {
/**
Number of frames per seconds.
*/
readonly fps?: number;

/**
Audio device to include in the screen recording.
/**
Record only an area of the screen.
*/
readonly cropArea?: {
x: number;
y: number;
width: number;
height: number;
};

Should be one of the `id`'s from `aperture.audioDevices()`.
*/
readonly audioDeviceId?: string;
/**
Show the cursor in the screen recording.
*/
readonly showCursor?: boolean;

/**
Video codec to use.
/**
Highlight cursor clicks in the screen recording.
A computer with Intel 6th generation processor or newer is strongly recommended for the `hevc` codec, as otherwise it will use software encoding, which only produces 3 FPS fullscreen recording.
Enabling this will also enable the `showCursor` option.
*/
readonly highlightClicks?: boolean;

The `proRes422` and `proRes4444` codecs are uncompressed data. They will create huge files.
*/
readonly videoCodec?: VideoCodec;
};
/**
Screen to record.
interface Recorder {
/**
Returns a `Promise` that fullfills when the recording starts or rejects if the recording didn't start after 5 seconds.
*/
startRecording: (options?: RecordingOptions) => Promise<void>;
Defaults to primary screen.
*/
readonly screenId?: number;

/**
`Promise` that fullfills with the path to the screen recording file when it's ready. This will never reject.
/**
Audio device to include in the screen recording.
Only available while a recording is happening, `undefined` otherwise.
Should be one of the `id`'s from `audioDevices()`.
*/
readonly audioDeviceId?: string;

Usually, this resolves around 1 second before the recording starts, but that's not guaranteed.
*/
isFileReady: Promise<string> | undefined;
/**
Video codec to use.
/**
Pauses the recording. To resume, call `recorder.resume()`.
A computer with Intel 6th generation processor or newer is strongly recommended for the `hevc` codec, as otherwise it will use software encoding, which only produces 3 FPS fullscreen recording.
Returns a `Promise` that fullfills when the recording has been paused.
*/
pause: () => Promise<void>;
The `proRes422` and `proRes4444` codecs are uncompressed data. They will create huge files.
*/
readonly videoCodec?: VideoCodec;
};

/**
Resumes the recording if it's been paused.
export type Recorder = {
/**
Returns a `Promise` that fullfills when the recording starts or rejects if the recording didn't start after 5 seconds.
*/
startRecording: (options?: RecordingOptions) => Promise<void>;

Returns a `Promise` that fullfills when the recording has been resumed.
*/
resume: () => Promise<void>;
/**
`Promise` that fullfills with the path to the screen recording file when it's ready. This will never reject.
/**
Returns a `Promise` that resolves with a boolean indicating whether or not the recording is currently paused.
*/
isPaused: () => Promise<boolean>;
Only available while a recording is happening, `undefined` otherwise.
/**
Returns a `Promise` for the path to the screen recording file.
*/
stopRecording: () => Promise<string>;
}
}
Usually, this resolves around 1 second before the recording starts, but that's not guaranteed.
*/
isFileReady: Promise<string> | undefined;

declare const aperture: (() => aperture.Recorder) & {
/**
Get a list of available video codecs.
The key is the `videoCodec` option name and the value is the codec name.
Pauses the recording. To resume, call `recorder.resume()`.
It only returns `hevc` if your computer supports HEVC hardware encoding.
@example
```
Map {
'h264' => 'H264',
'hevc' => 'HEVC',
'proRes422' => 'Apple ProRes 422',
'proRes4444' => 'Apple ProRes 4444'
}
```
Returns a `Promise` that fullfills when the recording has been paused.
*/
videoCodecs: Map<aperture.VideoCodec, string>;
pause: () => Promise<void>;

/**
Get a list of screens.
Resumes the recording if it's been paused.
The first screen is the primary screen.
Returns a `Promise` that fullfills when the recording has been resumed.
*/
resume: () => Promise<void>;

@example
```
[{
id: 69732482,
name: 'Color LCD'
}]
```
/**
Returns a `Promise` that resolves with a boolean indicating whether or not the recording is currently paused.
*/
screens: () => Promise<aperture.Screen[]>;
isPaused: () => Promise<boolean>;

/**
Get a list of audio devices.
@example
```
[{
id: 'AppleHDAEngineInput:1B,0,1,0:1',
name: 'Built-in Microphone'
}]
```
Returns a `Promise` for the path to the screen recording file.
*/
audioDevices: () => Promise<aperture.AudioDevice[]>;
stopRecording: () => Promise<string>;
};

export = aperture;
/**
Get a list of available video codecs.
The key is the `videoCodec` option name and the value is the codec name.
It only returns `hevc` if your computer supports HEVC hardware encoding.
@example
```
Map {
'h264' => 'H264',
'hevc' => 'HEVC',
'proRes422' => 'Apple ProRes 422',
'proRes4444' => 'Apple ProRes 4444'
}
```
*/
export function videoCodecs(): Map<VideoCodec, string>;

/**
Get a list of screens.
The first screen is the primary screen.
@example
```
[{
id: 69732482,
name: 'Color LCD'
}]
```
*/
export function screens(): Promise<Screen[]>;

/**
Get a list of audio devices.
@example
```
[{
id: 'AppleHDAEngineInput:1B,0,1,0:1',
name: 'Built-in Microphone'
}]
```
*/
export function audioDevices(): Promise<AudioDevice[]>;

export const recorder: Recorder;
Loading

0 comments on commit 558b1b3

Please sign in to comment.