pup-recorder 0.2.8 → 0.3.1

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/README.md CHANGED
@@ -1,78 +1,45 @@
1
- # pup-recorder(1)
1
+ # PUP-RECORDER(1)
2
2
 
3
3
  ## NAME
4
4
 
5
- pup-recorder - record web pages as video
5
+ pup-recorder record web pages as video
6
6
 
7
7
  ## SYNOPSIS
8
8
 
9
- ```
10
- pup source [-W width] [-H height] [-f fps] [-t duration] [-o file] [-a] [-d] [--use-inner-proxy]
11
- ```
9
+ pup source [-W width] [-H height] [-f fps] [-t duration] [-o file] [-a] [-d]
12
10
 
13
11
  ## OPTIONS
14
12
 
15
- ```
16
- source file://, http(s)://, or data: URI
17
-
18
- -W, --width <number> default: 1920
19
- -H, --height <number> default: 1080
20
- -f, --fps <number> default: 30
21
- -t, --duration <number> default: 5
22
- -o, --out-file <path> default: output.mp4
23
- -a, --with-audio
24
- -d, --deterministic frame-by-frame rendering mode
25
- --use-inner-proxy use Bilibili inner proxy
26
- ```
13
+ source file://, http(s)://, or data: URI
14
+ -W, --width <number> default: 1920
15
+ -H, --height <number> default: 1080
16
+ -f, --fps <number> default: 30
17
+ -t, --duration <number> default: 5
18
+ -o, --out-file <path> default: output.mp4
19
+ -a, --with-audio
20
+ -d, --deterministic frame-by-frame rendering mode
21
+ --use-inner-proxy use Bilibili inner proxy
27
22
 
28
23
  ## ENVIRONMENT
29
24
 
30
- ```
31
- PUP_LOG_LEVEL 0=error 1=warn 2=info 3=debug. default: 2
32
- PUP_USE_INNER_PROXY 1=on
33
- PUP_DISABLE_GPU 1=on
34
- PUP_DETERMINISTIC 1=on
35
- ```
25
+ PUP_LOG_LEVEL 0=error 1=warn 2=info 3=debug (default: 2)
26
+ PUP_USE_INNER_PROXY 1=on
27
+ PUP_DISABLE_GPU 1=on
28
+ PUP_DETERMINISTIC 1=on
29
+ PUP_EXPERIMENTAL_PUPPETEER 1=on (Linux puppeteer mode)
36
30
 
37
31
  ## API
38
32
 
39
- ```typescript
33
+ ```ts
40
34
  import { pup } from "pup-recorder";
41
35
 
42
36
  const result = await pup(source, {
43
- width?: number,
44
- height?: number,
45
- fps?: number,
46
- duration?: number,
47
- outFile?: string,
48
- withAudio?: boolean,
49
- deterministic?: boolean,
50
- useInnerProxy?: boolean,
51
- signal?: AbortSignal,
52
- onProgress?: (progress: number) => void,
37
+ width, height, fps, duration, outFile,
38
+ withAudio, deterministic, useInnerProxy,
39
+ signal, onProgress,
53
40
  });
54
- // result: { options, written, jank, outFile, audio? }
55
- ```
56
-
57
- ## FILES
58
-
59
- ```
60
- dist/cli.cjs
61
- dist/index.js
62
- ```
63
-
64
- ## EXAMPLES
65
-
66
- ```sh
67
- pup https://example.com -t 5
68
- pup file:///path/to/page.html -d -t 10
69
- pup https://example.com -a -W 1280 -H 720 -f 60 -t 10
70
41
  ```
71
42
 
72
43
  ## SEE ALSO
73
44
 
74
- pup-recorder-mcp(1), pup-server(1), pup(7)
75
-
76
- ## AUTHOR
77
-
78
- qq1909698494@gmail.com
45
+ pup-server(1), pup-recorder-mcp(1), pup(7)
@@ -1,8 +1,10 @@
1
1
  import { AV_SAMPLE_FMT_FLT } from 'node-av/constants';
2
2
  import { AV_SAMPLE_FMT_FLTP } from 'node-av/constants';
3
+ import { AVColorRange } from 'node-av/constants';
3
4
  import { AVPixelFormat } from 'node-av/constants';
4
5
  import { BrowserWindow } from 'electron';
5
6
  import { ChildProcess } from 'child_process';
7
+ import { Codec } from 'node-av';
6
8
  import { CodecContext } from 'node-av';
7
9
  import type { Debugger } from 'electron';
8
10
  import { EventEmitter } from 'events';
@@ -10,16 +12,23 @@ import { FFAudioEncoder } from 'node-av/constants';
10
12
  import { FFVideoEncoder } from 'node-av/constants';
11
13
  import { FormatContext } from 'node-av';
12
14
  import { Frame } from 'node-av';
15
+ import { HardwareContext } from 'node-av/api';
13
16
  import type { NativeImage } from 'electron';
14
17
  import { Packet } from 'node-av';
15
18
  import { Size } from 'electron';
16
19
  import { Socket } from 'net';
17
20
  import { SoftwareScaleContext } from 'node-av';
18
21
  import { SpawnOptions } from 'child_process';
22
+ import { Stream } from 'node-av';
19
23
  import z from 'zod';
20
24
 
25
+ /** Insert emulation prevention bytes (00 00 03) for Annex B compliance. */
26
+ export declare function addEmulationPrevention(nal: Buffer): Buffer;
27
+
21
28
  export declare function advanceVirtualTime(cdp: Debugger, budget: number): Promise<void>;
22
29
 
30
+ export declare const ANNEX_B_START_CODE: Buffer<ArrayBuffer>;
31
+
23
32
  export declare interface AudioCapture {
24
33
  teardown(): Promise<void>;
25
34
  }
@@ -63,6 +72,33 @@ export declare interface AudioEncoderOptions {
63
72
  muxer: FormatMuxer;
64
73
  }
65
74
 
75
+ export declare class BitReader {
76
+ private _bits;
77
+ pos: number;
78
+ constructor(data: Buffer);
79
+ get bits(): number[];
80
+ read(n: number): number;
81
+ readUe(): number;
82
+ }
83
+
84
+ export declare class BitWriter {
85
+ bits: number[];
86
+ w(val: number, n: number): void;
87
+ flag(val: boolean | number): void;
88
+ ue(val: number): void;
89
+ align(pad: number): void;
90
+ copy(src: number[], start: number, len: number): void;
91
+ }
92
+
93
+ export declare function buildAlphaChannelInfoSEI(): Buffer;
94
+
95
+ /**
96
+ * Build a complete alpha VPS from scratch, using the original NVENC VPS
97
+ * only as a source for the PTL (profile/tier/level) bytes.
98
+ * Matches x265 4.1 ENABLE_ALPHA VPS structure.
99
+ */
100
+ export declare function buildAlphaVPS(vpsData: Buffer, width: number, height: number): Buffer;
101
+
66
102
  export declare function buildRust(): Promise<void>;
67
103
 
68
104
  export declare function buildStegoHTML(targetURL: string, size: Size): string;
@@ -76,11 +112,13 @@ export declare function buildStegoHTML(targetURL: string, size: Size): string;
76
112
  */
77
113
  export declare function buildTickInjector(opts?: TickInjectorOptions): string;
78
114
 
115
+ export declare function buildUnifiedExtradata(opts: UnifiedExtradataOptions): Buffer;
116
+
79
117
  export declare const canIUseGPU: Promise<boolean>;
80
118
 
81
119
  export declare function checkHTML(source: string): void;
82
120
 
83
- export declare function chromiumOptions(): Promise<string[]>;
121
+ export declare function chromiumOptions(disableGpu: boolean): Promise<string[]>;
84
122
 
85
123
  export declare interface CLIOptions {
86
124
  name: string;
@@ -102,6 +140,7 @@ declare class CodecState_2 implements Disposable {
102
140
  * across frames, so a shared instance corrupts output when decoding standalone PNGs.
103
141
  */
104
142
  png(): Promise<CodecContext>;
143
+ decodePNG(pngData: Buffer): Promise<Frame>;
105
144
  get sws(): SoftwareScaleContext;
106
145
  [Symbol.dispose](): void;
107
146
  }
@@ -111,13 +150,15 @@ declare class ConcurrencyLimiter {
111
150
  readonly maxConcurrency: number;
112
151
  private _active;
113
152
  private _queue;
114
- private _ended;
153
+ private _signals;
154
+ private _resolve?;
115
155
  constructor(maxConcurrency: number);
116
156
  get active(): number;
117
157
  get pending(): number;
118
158
  get stats(): string;
119
- schedule<T>(fn: () => Promise<T>): Promise<T>;
120
- end(): Promise<void>;
159
+ schedule<T>(fn: () => Promise<T>, signal?: AbortSignal): Promise<T>;
160
+ drain(): Promise<void>;
161
+ private flush;
121
162
  private next;
122
163
  }
123
164
  export { ConcurrencyLimiter }
@@ -129,6 +170,10 @@ export declare function createIpcServer(socketPath: string): Promise<IpcServer>;
129
170
 
130
171
  export declare function createStegoURL(src: string, size: Size): string;
131
172
 
173
+ export declare function createVideoEncoder(opts: VideoFactoryOptions, muxer: FormatMuxer): Promise<VideoSetup>;
174
+
175
+ export declare function debounce<T extends (...args: unknown[]) => void>(fn: T, delay?: number): T;
176
+
132
177
  export declare function decodeStego(bitmap: Buffer, size: Size): number | undefined;
133
178
 
134
179
  declare const DEFAULT_DURATION = 5;
@@ -161,15 +206,14 @@ export declare function doProcess(timestampMs: number): string;
161
206
 
162
207
  export declare function doPuppeteer(source: string, options: RenderOptions, onProgress?: (p: number) => void): Promise<IpcDonePayload>;
163
208
 
164
- export declare function electronOpts(): Promise<string[]>;
209
+ export declare function drainPackets(ctx: CodecContext, pkt: Packet, stream: Stream, muxer: FormatMuxer): Promise<void>;
210
+
211
+ export declare function electronOpts(disableGpu: boolean): Promise<string[]>;
212
+
213
+ export declare function encodeNalHeader(type: number, layerId: number, temporalId: number): [number, number];
165
214
 
166
215
  declare class EncoderPipeline {
167
- private _video;
168
- private _audio;
169
- private _muxer;
170
- private _limiter;
171
- private _outFile;
172
- private _codec;
216
+ private _s;
173
217
  private _disposed;
174
218
  private constructor();
175
219
  static create(opts: EncoderPipelineOptions): Promise<EncoderPipeline>;
@@ -180,6 +224,7 @@ declare class EncoderPipeline {
180
224
  finish(): Promise<string>;
181
225
  [Symbol.asyncDispose](): Promise<void>;
182
226
  private free;
227
+ private bgraFrame;
183
228
  }
184
229
  export { EncoderPipeline }
185
230
  export { EncoderPipeline as EncoderPipeline_alias_1 }
@@ -190,6 +235,7 @@ declare interface EncoderPipelineOptions {
190
235
  fps: number;
191
236
  outFile: string;
192
237
  withAudio?: boolean;
238
+ disableHwCodec?: boolean;
193
239
  }
194
240
  export { EncoderPipelineOptions }
195
241
  export { EncoderPipelineOptions as EncoderPipelineOptions_alias_1 }
@@ -258,6 +304,19 @@ export declare class FrameDropStats {
258
304
  finalize(): FrameDropScore;
259
305
  }
260
306
 
307
+ export declare type HwEncoder = VideoToolboxEncoder | NvencDualLayerEncoder;
308
+
309
+ export declare interface HwVideoEncoderOptions {
310
+ width: number;
311
+ height: number;
312
+ fps: number;
313
+ hw: HardwareContext;
314
+ bitrate: number;
315
+ muxer: FormatMuxer;
316
+ }
317
+
318
+ export declare function interleaveAccessUnits(baseNals: NalUnit[], alphaNals: NalUnit[]): Buffer;
319
+
261
320
  export declare interface IpcDonePayload {
262
321
  written: number;
263
322
  jank: number;
@@ -350,6 +409,18 @@ export { LoggerLike as LoggerLike_alias_1 }
350
409
 
351
410
  export declare function makeCLI(options: CLIOptions): Promise<void>;
352
411
 
412
+ export declare function makeFrame(width: number, height: number, pixFmt: AVPixelFormat): Frame;
413
+
414
+ export declare function makePacket(): Packet;
415
+
416
+ export declare const NAL_HEADER_SIZE = 2;
417
+
418
+ export declare interface NalUnit {
419
+ type: number;
420
+ layerId: number;
421
+ data: Buffer;
422
+ }
423
+
353
424
  export declare interface NetworkOptions {
354
425
  source: string;
355
426
  window: BrowserWindow;
@@ -360,6 +431,25 @@ declare function noerr<Fn extends (...args: any[]) => any, D>(fn: Fn, defaultVal
360
431
  export { noerr }
361
432
  export { noerr as noerr_alias_1 }
362
433
 
434
+ export declare class NvencDualLayerEncoder implements Disposable {
435
+ private _s;
436
+ private _seiBuffer;
437
+ private _pts;
438
+ private _seiInjected;
439
+ private _alphaBuf?;
440
+ private _alphaFrame?;
441
+ private constructor();
442
+ static create(opts: HwVideoEncoderOptions): Promise<NvencDualLayerEncoder>;
443
+ encode(bgraFrame: Frame, muxer: FormatMuxer): Promise<void>;
444
+ flush(muxer: FormatMuxer): Promise<void>;
445
+ [Symbol.dispose](): void;
446
+ private drainInterleaved;
447
+ }
448
+
449
+ export declare function openVideoCtx(opts: VideoCtxOptions, label: string): Promise<CodecContext>;
450
+
451
+ export declare function packBits(bits: number[]): Buffer;
452
+
363
453
  declare function pargs(): string[];
364
454
  export { pargs }
365
455
  export { pargs as pargs_alias_1 }
@@ -413,6 +503,10 @@ declare const pupDisableGPU: boolean;
413
503
  export { pupDisableGPU }
414
504
  export { pupDisableGPU as pupDisableGPU_alias_1 }
415
505
 
506
+ declare const pupDisableHwCodec: boolean;
507
+ export { pupDisableHwCodec }
508
+ export { pupDisableHwCodec as pupDisableHwCodec_alias_1 }
509
+
416
510
  declare const pupExperimentalPuppeteer: boolean;
417
511
  export { pupExperimentalPuppeteer }
418
512
  export { pupExperimentalPuppeteer as pupExperimentalPuppeteer_alias_1 }
@@ -449,6 +543,9 @@ declare const pupUseInnerProxy: boolean;
449
543
  export { pupUseInnerProxy }
450
544
  export { pupUseInnerProxy as pupUseInnerProxy_alias_1 }
451
545
 
546
+ /** Remove emulation prevention bytes (00 00 03 → 00 00) from RBSP. */
547
+ export declare function removeEmulationPrevention(data: Buffer): Buffer;
548
+
452
549
  export declare function render(writer: IpcWriter, source: string, options: RenderOptions): Promise<IpcDonePayload>;
453
550
 
454
551
  declare type RenderOptions = z.infer<typeof RenderSchema>;
@@ -473,6 +570,8 @@ declare const RenderSchema: z.ZodObject<{
473
570
  outFile: z.ZodString;
474
571
  useInnerProxy: z.ZodBoolean;
475
572
  deterministic: z.ZodBoolean;
573
+ disableGpu: z.ZodBoolean;
574
+ disableHwCodec: z.ZodBoolean;
476
575
  }, z.core.$strip>;
477
576
  export { RenderSchema }
478
577
  export { RenderSchema as RenderSchema_alias_1 }
@@ -485,6 +584,9 @@ declare interface RetryOptions<Args extends any[], Ret> {
485
584
  export { RetryOptions }
486
585
  export { RetryOptions as RetryOptions_alias_1 }
487
586
 
587
+ /** Rewrite nuh_layer_id in a NAL unit (returns copy). */
588
+ export declare function rewriteNalLayerId(nal: Buffer, layerId: number): Buffer;
589
+
488
590
  export declare function runElectronApp(size: Size, args: unknown[], ipcSocketPath: string): Promise<ProcessHandle>;
489
591
 
490
592
  export declare function setInterceptor({ source, window, useInnerProxy }: NetworkOptions): void;
@@ -499,6 +601,9 @@ declare function sleep(ms: number): Promise<void>;
499
601
  export { sleep }
500
602
  export { sleep as sleep_alias_1 }
501
603
 
604
+ /** Split Annex B bitstream into NAL units. */
605
+ export declare function splitNalUnits(bitstream: Buffer): NalUnit[];
606
+
502
607
  export declare function startStego(cdp: Debugger): Promise<any>;
503
608
 
504
609
  export declare function stopStego(cdp: Debugger): Promise<any>;
@@ -514,12 +619,31 @@ export declare interface TickInjectorOptions {
514
619
  skipFrameGuard?: boolean;
515
620
  }
516
621
 
622
+ export declare interface UnifiedExtradataOptions {
623
+ baseExtradata: Buffer;
624
+ alphaExtradata: Buffer;
625
+ width: number;
626
+ height: number;
627
+ }
628
+
517
629
  export declare function unsetInterceptor(window: BrowserWindow): void;
518
630
 
519
631
  declare function useRetry<Args extends any[], Ret>({ fn, maxAttempts, timeout }: RetryOptions<Args, Ret>): (...args: Args) => Promise<Ret>;
520
632
  export { useRetry }
521
633
  export { useRetry as useRetry_alias_1 }
522
634
 
635
+ export declare interface VideoCtxOptions {
636
+ codec: Codec;
637
+ width: number;
638
+ height: number;
639
+ fps: number;
640
+ bitrate: number;
641
+ pixelFormat: AVPixelFormat;
642
+ codecTag?: string;
643
+ colorRange?: AVColorRange;
644
+ options?: Record<string, string>;
645
+ }
646
+
523
647
  declare class VideoEncoder_2 implements Disposable {
524
648
  private readonly _ctx;
525
649
  private readonly _pkt;
@@ -540,13 +664,40 @@ export declare interface VideoEncoderOptions {
540
664
  fps: number;
541
665
  codecName: FFVideoEncoder;
542
666
  codecTag?: string;
543
- globalHeader: boolean;
544
667
  codecOpts: Record<string, string>;
545
668
  bitrate: number;
546
669
  pixelFormat: AVPixelFormat;
547
670
  muxer: FormatMuxer;
548
671
  }
549
672
 
673
+ export declare interface VideoFactoryOptions {
674
+ width: number;
675
+ height: number;
676
+ fps: number;
677
+ bitrate?: number;
678
+ disableHwCodec?: boolean;
679
+ }
680
+
681
+ export declare interface VideoSetup {
682
+ video?: VideoEncoder_2;
683
+ hwVideo?: HwEncoder;
684
+ codec?: CodecState_2;
685
+ hw?: HardwareContext;
686
+ }
687
+
688
+ export declare class VideoToolboxEncoder implements Disposable {
689
+ private _ctx;
690
+ private _pkt;
691
+ private _stream;
692
+ private _pts;
693
+ private constructor();
694
+ static create(opts: HwVideoEncoderOptions): Promise<VideoToolboxEncoder>;
695
+ encode(bgraFrame: Frame, muxer: FormatMuxer): Promise<void>;
696
+ flush(muxer: FormatMuxer): Promise<void>;
697
+ [Symbol.dispose](): void;
698
+ private drain;
699
+ }
700
+
550
701
  export declare class WaitableEvent {
551
702
  private _promise?;
552
703
  private _resolve?;