pup-recorder 0.1.16 → 0.1.17

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.
package/build_rust.ts CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { $ } from "bun";
4
4
  import { zipSync } from "fflate";
5
- import { mkdir, readFile, writeFile } from "fs/promises";
5
+ import { mkdir, readFile, stat, writeFile } from "fs/promises";
6
6
  import { join } from "path";
7
7
 
8
8
  function getTriple(platform: string, arch: string) {
@@ -31,6 +31,22 @@ function getArtifactName(platform: string) {
31
31
  const PLATFORMS = ["darwin", "linux", "win32"];
32
32
  const ARCHS = ["x64", "arm64"];
33
33
  const RUST_DIR = "rust";
34
+ const ZIP_PATH = join(RUST_DIR, "native.zip");
35
+ const RUST_SOURCES = ["src/rust/lib.rs", "build.rs", "Cargo.toml", "Cargo.lock"];
36
+
37
+ async function needsRebuild(): Promise<boolean> {
38
+ const zipMtime = await stat(ZIP_PATH)
39
+ .then((s) => s.mtimeMs)
40
+ .catch(() => 0);
41
+ const mtimes = await Promise.all(
42
+ RUST_SOURCES.map((f) =>
43
+ stat(f)
44
+ .then((s) => s.mtimeMs)
45
+ .catch(() => Infinity),
46
+ ),
47
+ );
48
+ return mtimes.some((m) => m > zipMtime);
49
+ }
34
50
 
35
51
  async function cargoBuild(platform: string, arch: string): Promise<[string, Uint8Array] | undefined> {
36
52
  const triple = getTriple(platform, arch);
@@ -48,6 +64,10 @@ async function cargoBuild(platform: string, arch: string): Promise<[string, Uint
48
64
  }
49
65
 
50
66
  export async function buildRust() {
67
+ if (!(await needsRebuild())) {
68
+ return;
69
+ }
70
+
51
71
  await $`cargo install --quiet cargo-zigbuild cargo-xwin`;
52
72
 
53
73
  const entries: [string, Uint8Array][] = [];
@@ -61,6 +81,6 @@ export async function buildRust() {
61
81
  await mkdir(RUST_DIR, { recursive: true });
62
82
 
63
83
  const zip = zipSync(Object.fromEntries(entries));
64
- await writeFile(join(RUST_DIR, "native.zip"), zip);
84
+ await writeFile(ZIP_PATH, zip);
65
85
  await writeFile(join(RUST_DIR, "native.zip.d.ts"), `declare const data: Uint8Array;\nexport default data;\n`);
66
86
  }
@@ -1,3 +1,4 @@
1
+ import { AudioCodec } from 'mediabunny';
1
2
  import { BrowserWindow } from 'electron';
2
3
  import { ChildProcess } from 'child_process';
3
4
  import type { Debugger } from 'electron';
@@ -8,9 +9,12 @@ import type { EncodedVideoChunk as EncodedVideoChunk_2 } from '@napi-rs/webcodec
8
9
  import type { EncodedVideoChunkMetadataJs } from '@napi-rs/webcodecs';
9
10
  import { IsobmffOutputFormat } from 'mediabunny';
10
11
  import type { NativeImage } from 'electron';
12
+ import { OutputFormat } from 'mediabunny';
11
13
  import { Size } from 'electron';
12
14
  import { SpawnOptions } from 'child_process';
13
15
  import { StreamTarget } from 'mediabunny';
16
+ import { VideoCodec } from 'mediabunny';
17
+ import { WebMOutputFormat } from 'mediabunny';
14
18
  import z from 'zod';
15
19
 
16
20
  declare class AbortLink {
@@ -47,13 +51,12 @@ export declare interface AudioCapture {
47
51
  teardown(): Promise<void>;
48
52
  }
49
53
 
50
- declare interface AudioInit {
51
- sampleRate: number;
52
- numberOfChannels: number;
53
- description?: Uint8Array;
54
+ declare interface AudioChunk {
55
+ data: Uint8Array;
56
+ type: EncodedAudioChunk_2["type"];
57
+ timestampS: number;
58
+ durationS: number;
54
59
  }
55
- export { AudioInit }
56
- export { AudioInit as AudioInit_alias_1 }
57
60
 
58
61
  export declare const basedir: string;
59
62
 
@@ -64,25 +67,6 @@ export declare interface BgraConverter {
64
67
 
65
68
  export declare const BgraConverter: BgraConverter;
66
69
 
67
- declare interface BufferedAudio {
68
- data: Uint8Array;
69
- type: EncodedAudioChunk_2["type"];
70
- timestampS: number;
71
- durationS: number;
72
- }
73
- export { BufferedAudio }
74
- export { BufferedAudio as BufferedAudio_alias_1 }
75
-
76
- declare interface BufferedVideo {
77
- data: Uint8Array;
78
- alphaSideData?: Uint8Array;
79
- type: EncodedVideoChunk_2["type"];
80
- timestampS: number;
81
- durationS: number;
82
- }
83
- export { BufferedVideo }
84
- export { BufferedVideo as BufferedVideo_alias_1 }
85
-
86
70
  export declare function buildRust(): Promise<void>;
87
71
 
88
72
  export declare function buildWrapperHTML(targetURL: string, size: Size): string;
@@ -142,16 +126,18 @@ export { DEFAULT_WIDTH as DEFAULT_WIDTH_alias_1 }
142
126
  export declare function electronOpts(): Promise<string[]>;
143
127
 
144
128
  export declare class EncoderPipeline {
129
+ private readonly _entries;
130
+ private readonly _encoders;
131
+ private readonly _converter;
145
132
  private readonly _width;
146
133
  private readonly _height;
147
134
  private readonly _fps;
148
- private readonly _entries;
149
- private readonly _converter;
150
135
  private _frameIndex;
151
- constructor({ width, height, fps, formats, outDir }: EncoderPipelineOptions);
136
+ private _sampleRate;
137
+ constructor({ width, height, fps, formats, outDir, withAudio }: EncoderPipelineOptions);
152
138
  setupAudio(sampleRate: number): void;
153
- encodeFrame(bgraBuffer: Buffer, timestampUs: number): Promise<void>;
154
- encodeAudio(interleavedFloat32Buffer: Buffer, sampleRate: number): void;
139
+ encodeFrame(bgra: Buffer, timestampUs: number): Promise<void>;
140
+ encodeAudio(pcm: Buffer): void;
155
141
  flush(): Promise<void>;
156
142
  finalize(): Promise<Partial<Record<VideoFormat, string>>>;
157
143
  }
@@ -162,6 +148,7 @@ export declare interface EncoderPipelineOptions {
162
148
  fps: number;
163
149
  formats: VideoFormat[];
164
150
  outDir: string;
151
+ withAudio?: boolean;
165
152
  }
166
153
 
167
154
  declare type EnvParser<T> = (value: unknown) => T;
@@ -177,9 +164,14 @@ export declare const FRAME_SYNC_MARKER_HEIGHT = 1;
177
164
  export declare const FRAME_SYNC_MARKER_WIDTH = 32;
178
165
 
179
166
  declare class HEVCIsobmffMuxer extends MediaMuxer {
180
- private readonly format;
181
- constructor(opts: MuxerOptions, format: IsobmffOutputFormat);
182
- finalize(): Promise<string>;
167
+ private readonly _format;
168
+ constructor(opts: MuxerOptions, _format: IsobmffOutputFormat);
169
+ protected get format(): IsobmffOutputFormat;
170
+ protected get videoCodec(): VideoCodec;
171
+ protected get audioCodec(): AudioCodec;
172
+ protected get audioDecoderCodec(): string;
173
+ protected get videoConfig(): EncodedVideoChunkMetadata["decoderConfig"];
174
+ protected makeVideoPacket({ data, type, timestampS, durationS }: VideoChunk, isFirst: boolean): EncodedPacket;
183
175
  }
184
176
 
185
177
  export declare function isEmpty(image: NativeImage): boolean;
@@ -237,14 +229,24 @@ export declare function makeCLI(name: string, callback: CLICallback): Promise<vo
237
229
 
238
230
  declare abstract class MediaMuxer {
239
231
  protected readonly opts: MuxerOptions;
240
- protected videoChunks: BufferedVideo[];
241
- protected audioChunks: BufferedAudio[];
242
232
  protected videoDesc?: Uint8Array;
243
- protected audioInit?: AudioInit;
233
+ private _chain;
234
+ private _videoSrc;
235
+ private _audioSrc?;
236
+ private _output;
237
+ private _firstVideo;
238
+ private _firstAudio;
239
+ protected abstract get format(): OutputFormat;
240
+ protected abstract get videoCodec(): VideoCodec;
241
+ protected abstract get audioCodec(): AudioCodec;
242
+ protected abstract get audioDecoderCodec(): string;
243
+ protected abstract get videoConfig(): EncodedVideoChunkMetadata["decoderConfig"];
244
+ protected abstract makeVideoPacket(chunk: VideoChunk, isFirst: boolean): EncodedPacket;
244
245
  constructor(opts: MuxerOptions);
245
- addVideoChunk(chunk: EncodedVideoChunk_2, meta?: EncodedVideoChunkMetadataJs): void;
246
- addAudioChunk(chunk: EncodedAudioChunk_2, meta?: EncodedAudioChunkMetadataJs): void;
247
- abstract finalize(): Promise<string>;
246
+ private init;
247
+ addVideoChunk(raw: EncodedVideoChunk_2, meta?: EncodedVideoChunkMetadataJs): void;
248
+ addAudioChunk(raw: EncodedAudioChunk_2, meta?: EncodedAudioChunkMetadataJs): void;
249
+ finalize(): Promise<string>;
248
250
  }
249
251
  export { MediaMuxer }
250
252
  export { MediaMuxer as MediaMuxer_alias_1 }
@@ -254,6 +256,7 @@ declare interface MuxerOptions {
254
256
  height: number;
255
257
  fps: number;
256
258
  outPath: string;
259
+ withAudio?: boolean;
257
260
  }
258
261
  export { MuxerOptions }
259
262
  export { MuxerOptions as MuxerOptions_alias_1 }
@@ -395,7 +398,7 @@ export declare function startSync(cdp: Debugger): Promise<any>;
395
398
 
396
399
  export declare function stopSync(cdp: Debugger): Promise<any>;
397
400
 
398
- declare const toPacket: ({ data, type, timestampS, durationS }: BufferedVideo | BufferedAudio) => EncodedPacket;
401
+ declare const toPacket: ({ data, type, timestampS, durationS }: VideoChunk | AudioChunk) => EncodedPacket;
399
402
  export { toPacket }
400
403
  export { toPacket as toPacket_alias_1 }
401
404
 
@@ -409,6 +412,16 @@ declare const VIDEO_FORMATS: readonly ["mp4", "mov", "webm"];
409
412
  export { VIDEO_FORMATS }
410
413
  export { VIDEO_FORMATS as VIDEO_FORMATS_alias_1 }
411
414
 
415
+ declare interface VideoChunk {
416
+ data: Uint8Array;
417
+ alphaSideData?: Uint8Array;
418
+ type: EncodedVideoChunk_2["type"];
419
+ timestampS: number;
420
+ durationS: number;
421
+ }
422
+ export { VideoChunk }
423
+ export { VideoChunk as VideoChunk_alias_1 }
424
+
412
425
  declare interface VideoFiles {
413
426
  cover: string;
414
427
  mp4?: string;
@@ -422,12 +435,6 @@ declare type VideoFormat = (typeof VIDEO_FORMATS)[number];
422
435
  export { VideoFormat }
423
436
  export { VideoFormat as VideoFormat_alias_1 }
424
437
 
425
- declare class Vp9WebMMuxer extends MediaMuxer {
426
- finalize(): Promise<string>;
427
- }
428
- export { Vp9WebMMuxer }
429
- export { Vp9WebMMuxer as Vp9WebMMuxer_alias_1 }
430
-
431
438
  export declare class WaitableEvent {
432
439
  private _promise?;
433
440
  private _resolve?;
@@ -441,4 +448,15 @@ export declare interface WaitOptions {
441
448
  onTimeout?: () => void;
442
449
  }
443
450
 
451
+ declare class WebMMuxer extends MediaMuxer {
452
+ protected get format(): WebMOutputFormat;
453
+ protected get videoCodec(): VideoCodec;
454
+ protected get audioCodec(): AudioCodec;
455
+ protected get audioDecoderCodec(): string;
456
+ protected get videoConfig(): EncodedVideoChunkMetadata["decoderConfig"];
457
+ protected makeVideoPacket(chunk: VideoChunk): EncodedPacket;
458
+ }
459
+ export { WebMMuxer }
460
+ export { WebMMuxer as WebMMuxer_alias_1 }
461
+
444
462
  export { }