🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Sign inDemoInstall
Socket

aperture

Package Overview
Dependencies
Maintainers
3
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

aperture - npm Package Compare versions

Comparing version

to
7.0.0

240

index.d.ts

@@ -1,156 +0,152 @@

declare namespace aperture {
type Screen = {
id: number;
name: string;
};
export type Screen = {
id: number;
name: string;
};
type AudioDevice = {
id: string;
name: string;
};
export type AudioDevice = {
id: string;
name: string;
};
type VideoCodec = 'h264' | 'hevc' | 'proRes422' | 'proRes4444';
export type VideoCodec = 'h264' | 'hevc' | 'proRes422' | 'proRes4444';
type RecordingOptions = {
/**
Number of frames per seconds.
*/
readonly fps?: number;
export 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;
};
/**
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;
/**
Show the cursor in the screen recording.
*/
readonly showCursor?: boolean;
/**
Highlight cursor clicks in the screen recording.
/**
Highlight cursor clicks in the screen recording.
Enabling this will also enable the `showCursor` option.
*/
readonly highlightClicks?: boolean;
Enabling this will also enable the `showCursor` option.
*/
readonly highlightClicks?: boolean;
/**
Screen to record.
/**
Screen to record.
Defaults to primary screen.
*/
readonly screenId?: number;
Defaults to primary screen.
*/
readonly screenId?: number;
/**
Audio device to include in the screen recording.
/**
Audio device to include in the screen recording.
Should be one of the `id`'s from `aperture.audioDevices()`.
*/
readonly audioDeviceId?: string;
Should be one of the `id`'s from `audioDevices()`.
*/
readonly audioDeviceId?: string;
/**
Video codec to use.
/**
Video codec to use.
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.
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.
The `proRes422` and `proRes4444` codecs are uncompressed data. They will create huge files.
*/
readonly videoCodec?: VideoCodec;
};
The `proRes422` and `proRes4444` codecs are uncompressed data. They will create huge files.
*/
readonly videoCodec?: VideoCodec;
};
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>;
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>;
/**
`Promise` that fullfills with the path to the screen recording file when it's ready. This will never reject.
/**
`Promise` that fullfills with the path to the screen recording file when it's ready. This will never reject.
Only available while a recording is happening, `undefined` otherwise.
Only available while a recording is happening, `undefined` otherwise.
Usually, this resolves around 1 second before the recording starts, but that's not guaranteed.
*/
isFileReady: Promise<string> | undefined;
Usually, this resolves around 1 second before the recording starts, but that's not guaranteed.
*/
isFileReady: Promise<string> | undefined;
/**
Pauses the recording. To resume, call `recorder.resume()`.
/**
Pauses the recording. To resume, call `recorder.resume()`.
Returns a `Promise` that fullfills when the recording has been paused.
*/
pause: () => Promise<void>;
Returns a `Promise` that fullfills when the recording has been paused.
*/
pause: () => Promise<void>;
/**
Resumes the recording if it's been paused.
/**
Resumes the recording if it's been paused.
Returns a `Promise` that fullfills when the recording has been resumed.
*/
resume: () => Promise<void>;
Returns a `Promise` that fullfills when the recording has been resumed.
*/
resume: () => Promise<void>;
/**
Returns a `Promise` that resolves with a boolean indicating whether or not the recording is currently paused.
*/
isPaused: () => Promise<boolean>;
/**
Returns a `Promise` that resolves with a boolean indicating whether or not the recording is currently paused.
*/
isPaused: () => Promise<boolean>;
/**
Returns a `Promise` for the path to the screen recording file.
*/
stopRecording: () => Promise<string>;
}
}
declare const aperture: (() => aperture.Recorder) & {
/**
Get a list of available video codecs.
Returns a `Promise` for the path to the screen recording file.
*/
stopRecording: () => Promise<string>;
};
The key is the `videoCodec` option name and the value is the codec name.
/**
Get a list of available video codecs.
It only returns `hevc` if your computer supports HEVC hardware encoding.
The key is the `videoCodec` option name and the value is the codec name.
@example
```
Map {
'h264' => 'H264',
'hevc' => 'HEVC',
'proRes422' => 'Apple ProRes 422',
'proRes4444' => 'Apple ProRes 4444'
}
```
*/
videoCodecs: Map<aperture.VideoCodec, string>;
It only returns `hevc` if your computer supports HEVC hardware encoding.
/**
Get a list of screens.
@example
```
Map {
'h264' => 'H264',
'hevc' => 'HEVC',
'proRes422' => 'Apple ProRes 422',
'proRes4444' => 'Apple ProRes 4444'
}
```
*/
export function videoCodecs(): Map<VideoCodec, string>;
The first screen is the primary screen.
/**
Get a list of screens.
@example
```
[{
id: 69732482,
name: 'Color LCD'
}]
```
*/
screens: () => Promise<aperture.Screen[]>;
The first screen is the primary screen.
/**
Get a list of audio devices.
@example
```
[{
id: 69732482,
name: 'Color LCD'
}]
```
*/
export function screens(): Promise<Screen[]>;
@example
```
[{
id: 'AppleHDAEngineInput:1B,0,1,0:1',
name: 'Built-in Microphone'
}]
```
*/
audioDevices: () => Promise<aperture.AudioDevice[]>;
};
/**
Get a list of audio devices.
export = aperture;
@example
```
[{
id: 'AppleHDAEngineInput:1B,0,1,0:1',
name: 'Built-in Microphone'
}]
```
*/
export function audioDevices(): Promise<AudioDevice[]>;
export const recorder: Recorder;

@@ -1,11 +0,11 @@

'use strict';
const os = require('os');
const {debuglog} = require('util');
const path = require('path');
const execa = require('execa');
const tempy = require('tempy');
const macosVersion = require('macos-version');
const fileUrl = require('file-url');
const electronUtil = require('electron-util/node');
const delay = require('delay');
import os from 'node:os';
import {debuglog} from 'node:util';
import path from 'node:path';
import url from 'node:url';
import {execa} from 'execa';
import {temporaryFile} from 'tempy';
import {assertMacOSVersionGreaterThanOrEqualTo} from 'macos-version';
import fileUrl from 'file-url';
import {fixPathForAsarUnpack} from 'electron-util/node';
import delay from 'delay';

@@ -15,4 +15,5 @@ const log = debuglog('aperture');

const dirname_ = path.dirname(url.fileURLToPath(import.meta.url));
// Workaround for https://github.com/electron/electron/issues/9459
const BIN = path.join(electronUtil.fixPathForAsarUnpack(__dirname), 'aperture');
const BINARY = path.join(fixPathForAsarUnpack(dirname_), 'aperture');

@@ -23,3 +24,4 @@ const supportsHevcHardwareEncoding = (() => {

// All Apple silicon Macs support HEVC hardware encoding.
if (cpuModel.startsWith('Apple ')) { // Source string example: `'Apple M1'`
if (cpuModel.startsWith('Apple ')) {
// Source string example: `'Apple M1'`
return true;

@@ -39,5 +41,5 @@ }

class Aperture {
class Recorder {
constructor() {
macosVersion.assertGreaterThanOrEqualTo('10.13');
assertMacOSVersionGreaterThanOrEqualTo('10.13');
}

@@ -52,3 +54,3 @@

audioDeviceId = undefined,
videoCodec = 'h264'
videoCodec = 'h264',
} = {}) {

@@ -63,3 +65,3 @@ this.processId = getRandomId();

this.tmpPath = tempy.file({extension: 'mp4'});
this.tmpPath = temporaryFile({extension: 'mp4'});

@@ -70,9 +72,8 @@ if (highlightClicks === true) {

if (typeof cropArea === 'object' &&
(
typeof cropArea.x !== 'number' ||
typeof cropArea.y !== 'number' ||
typeof cropArea.width !== 'number' ||
typeof cropArea.height !== 'number'
)
if (
typeof cropArea === 'object'
&& (typeof cropArea.x !== 'number'
|| typeof cropArea.y !== 'number'
|| typeof cropArea.width !== 'number'
|| typeof cropArea.height !== 'number')
) {

@@ -89,3 +90,3 @@ reject(new Error('Invalid `cropArea` option object'));

screenId,
audioDeviceId
audioDeviceId,
};

@@ -96,3 +97,3 @@

[cropArea.x, cropArea.y],
[cropArea.width, cropArea.height]
[cropArea.width, cropArea.height],
];

@@ -106,3 +107,3 @@ }

['proRes422', 'apcn'],
['proRes4444', 'ap4h']
['proRes4444', 'ap4h'],
]);

@@ -149,10 +150,8 @@

this.recorder = execa(
BIN, [
'record',
'--process-id',
this.processId,
JSON.stringify(recorderOptions)
]
);
this.recorder = execa(BINARY, [
'record',
'--process-id',
this.processId,
JSON.stringify(recorderOptions),
]);

@@ -171,12 +170,10 @@ this.recorder.catch(error => {

async waitForEvent(name, parse) {
const {stdout} = await execa(
BIN, [
'events',
'listen',
'--process-id',
this.processId,
'--exit',
name
]
);
const {stdout} = await execa(BINARY, [
'events',
'listen',
'--process-id',
this.processId,
'--exit',
name,
]);

@@ -189,11 +186,9 @@ if (parse) {

async sendEvent(name, parse) {
const {stdout} = await execa(
BIN, [
'events',
'send',
'--process-id',
this.processId,
name
]
);
const {stdout} = await execa(BINARY, [
'events',
'send',
'--process-id',
this.processId,
name,
]);

@@ -243,39 +238,35 @@ if (parse) {

module.exports = () => new Aperture();
export const recorder = new Recorder();
module.exports.screens = async () => {
const {stderr} = await execa(BIN, ['list', 'screens']);
const removeWarnings = string => string.split('\n').filter(line => !line.includes('] WARNING:')).join('\n');
export const screens = async () => {
const {stderr} = await execa(BINARY, ['list', 'screens']);
try {
return JSON.parse(stderr);
} catch {
return stderr;
return JSON.parse(removeWarnings(stderr));
} catch (error) {
throw new Error(stderr, {cause: error});
}
};
module.exports.audioDevices = async () => {
const {stderr} = await execa(BIN, ['list', 'audio-devices']);
export const audioDevices = async () => {
const {stderr} = await execa(BINARY, ['list', 'audio-devices']);
try {
return JSON.parse(stderr);
} catch {
return stderr;
return JSON.parse(removeWarnings(stderr));
} catch (error) {
throw new Error(stderr, {cause: error});
}
};
Object.defineProperty(module.exports, 'videoCodecs', {
get() {
const codecs = new Map([
['h264', 'H264'],
['hevc', 'HEVC'],
['proRes422', 'Apple ProRes 422'],
['proRes4444', 'Apple ProRes 4444']
]);
export const videoCodecs = new Map([
['h264', 'H264'],
['hevc', 'HEVC'],
['proRes422', 'Apple ProRes 422'],
['proRes4444', 'Apple ProRes 4444'],
]);
if (!supportsHevcHardwareEncoding) {
codecs.delete('hevc');
}
return codecs;
}
});
if (!supportsHevcHardwareEncoding) {
videoCodecs.delete('hevc');
}
{
"name": "aperture",
"version": "6.1.3",
"version": "7.0.0",
"description": "Record the screen on macOS",
"license": "MIT",
"repository": "wulkano/aperture-node",
"type": "module",
"exports": {
"types": "./index.d.ts",
"default": "./index.js"
},
"sideEffects": false,
"engines": {
"node": ">=10"
"node": ">=18"
},

@@ -21,16 +27,16 @@ "scripts": {

"dependencies": {
"delay": "^5.0.0",
"electron-util": "^0.14.2",
"execa": "^5.0.0",
"file-url": "^3.0.0",
"macos-version": "^5.2.1",
"tempy": "^1.0.0"
"delay": "^6.0.0",
"electron-util": "^0.18.1",
"execa": "^8.0.1",
"file-url": "^4.0.0",
"macos-version": "^6.0.0",
"tempy": "^3.1.0"
},
"devDependencies": {
"ava": "^2.4.0",
"file-type": "^12.0.0",
"read-chunk": "^3.2.0",
"tsd": "^0.14.0",
"xo": "^0.38.2"
"ava": "^6.1.2",
"file-type": "^19.0.0",
"read-chunk": "^4.0.3",
"tsd": "^0.30.7",
"xo": "^0.58.0"
}
}

@@ -16,4 +16,4 @@ # aperture-node

```js
const delay = require('delay');
const aperture = require('aperture')();
import {setTimeout} from 'node:timers/promises';
import {recorder} from 'aperture';

@@ -26,19 +26,19 @@ const options = {

width: 500,
height: 500
}
height: 500,
},
};
(async () => {
await aperture.startRecording(options);
await delay(3000);
console.log(await aperture.stopRecording());
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/cdf4f7df426c97880f8c10a1600879f7.mp4'
})();
await recorder.startRecording(options);
await setTimeout(3000);
console.log(await recorder.stopRecording());
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/cdf4f7df426c97880f8c10a1600879f7.mp4'
```
See [`example.js`](example.js) if you want to quickly try it out. *(The example requires Node.js 8+)*
See [`example.js`](example.js) if you want to quickly try it out. _(The example requires Node.js 18+)_
## API
#### aperture.screens() -> `Promise<Object[]>`
#### screens() -> `Promise<Object[]>`

@@ -50,9 +50,11 @@ Get a list of screens. The first screen is the primary screen.

```js
[{
id: 69732482,
name: 'Color LCD'
}]
[
{
id: 69732482,
name: 'Color LCD',
},
];
```
#### aperture.audioDevices() -> `Promise<Object[]>`
#### audioDevices() -> `Promise<Object[]>`

@@ -64,9 +66,11 @@ Get a list of audio devices.

```js
[{
id: 'AppleHDAEngineInput:1B,0,1,0:1',
name: 'Built-in Microphone'
}]
[
{
id: 'AppleHDAEngineInput:1B,0,1,0:1',
name: 'Built-in Microphone',
},
];
```
#### aperture.videoCodecs -> `Map`
#### videoCodecs -> `Map`

@@ -86,3 +90,3 @@ 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.

#### recorder = `aperture()`
#### recorder

@@ -158,3 +162,3 @@ #### recorder.startRecording([options?](#options))

Type: `number`\
Default: `aperture.screens()[0]` *(Primary screen)*
Default: `aperture.screens()[0]` _(Primary screen)_

@@ -161,0 +165,0 @@ Screen to record.

Sorry, the diff of this file is not supported yet