pup-recorder 0.2.8 → 0.3.0

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)
@@ -10,16 +10,20 @@ import { FFAudioEncoder } from 'node-av/constants';
10
10
  import { FFVideoEncoder } from 'node-av/constants';
11
11
  import { FormatContext } from 'node-av';
12
12
  import { Frame } from 'node-av';
13
+ import { HardwareContext } from 'node-av/api';
13
14
  import type { NativeImage } from 'electron';
14
15
  import { Packet } from 'node-av';
15
16
  import { Size } from 'electron';
16
17
  import { Socket } from 'net';
17
18
  import { SoftwareScaleContext } from 'node-av';
18
19
  import { SpawnOptions } from 'child_process';
20
+ import { Stream } from 'node-av';
19
21
  import z from 'zod';
20
22
 
21
23
  export declare function advanceVirtualTime(cdp: Debugger, budget: number): Promise<void>;
22
24
 
25
+ export declare const ANNEX_B_START_CODE: Buffer<ArrayBuffer>;
26
+
23
27
  export declare interface AudioCapture {
24
28
  teardown(): Promise<void>;
25
29
  }
@@ -63,6 +67,12 @@ export declare interface AudioEncoderOptions {
63
67
  muxer: FormatMuxer;
64
68
  }
65
69
 
70
+ /**
71
+ * Build alpha_channel_info SEI message (payloadType=165).
72
+ * Layout from x265 SEIAlphaChannelInfo::writeSEI.
73
+ */
74
+ export declare function buildAlphaChannelInfoSEI(): Buffer;
75
+
66
76
  export declare function buildRust(): Promise<void>;
67
77
 
68
78
  export declare function buildStegoHTML(targetURL: string, size: Size): string;
@@ -76,11 +86,18 @@ export declare function buildStegoHTML(targetURL: string, size: Size): string;
76
86
  */
77
87
  export declare function buildTickInjector(opts?: TickInjectorOptions): string;
78
88
 
89
+ /**
90
+ * Build unified extradata: base VPS (patched for alpha) + interleaved SPS/PPS.
91
+ * Alpha SPS/PPS follow their base counterparts so the HVCC serializer
92
+ * groups them into the same NAL array (required for multi-layer).
93
+ */
94
+ export declare function buildUnifiedExtradata(baseExtradata: Buffer, alphaExtradata: Buffer): Buffer;
95
+
79
96
  export declare const canIUseGPU: Promise<boolean>;
80
97
 
81
98
  export declare function checkHTML(source: string): void;
82
99
 
83
- export declare function chromiumOptions(): Promise<string[]>;
100
+ export declare function chromiumOptions(disableGpu: boolean): Promise<string[]>;
84
101
 
85
102
  export declare interface CLIOptions {
86
103
  name: string;
@@ -102,6 +119,7 @@ declare class CodecState_2 implements Disposable {
102
119
  * across frames, so a shared instance corrupts output when decoding standalone PNGs.
103
120
  */
104
121
  png(): Promise<CodecContext>;
122
+ decodePNG(pngData: Buffer): Promise<Frame>;
105
123
  get sws(): SoftwareScaleContext;
106
124
  [Symbol.dispose](): void;
107
125
  }
@@ -111,13 +129,15 @@ declare class ConcurrencyLimiter {
111
129
  readonly maxConcurrency: number;
112
130
  private _active;
113
131
  private _queue;
114
- private _ended;
132
+ private _signals;
133
+ private _resolve?;
115
134
  constructor(maxConcurrency: number);
116
135
  get active(): number;
117
136
  get pending(): number;
118
137
  get stats(): string;
119
- schedule<T>(fn: () => Promise<T>): Promise<T>;
120
- end(): Promise<void>;
138
+ schedule<T>(fn: () => Promise<T>, signal?: AbortSignal): Promise<T>;
139
+ drain(): Promise<void>;
140
+ private flush;
121
141
  private next;
122
142
  }
123
143
  export { ConcurrencyLimiter }
@@ -129,6 +149,10 @@ export declare function createIpcServer(socketPath: string): Promise<IpcServer>;
129
149
 
130
150
  export declare function createStegoURL(src: string, size: Size): string;
131
151
 
152
+ export declare function createVideoEncoder(opts: VideoFactoryOptions, muxer: FormatMuxer): Promise<VideoSetup>;
153
+
154
+ export declare function debounce<T extends (...args: unknown[]) => void>(fn: T, delay?: number): T;
155
+
132
156
  export declare function decodeStego(bitmap: Buffer, size: Size): number | undefined;
133
157
 
134
158
  declare const DEFAULT_DURATION = 5;
@@ -161,15 +185,14 @@ export declare function doProcess(timestampMs: number): string;
161
185
 
162
186
  export declare function doPuppeteer(source: string, options: RenderOptions, onProgress?: (p: number) => void): Promise<IpcDonePayload>;
163
187
 
164
- export declare function electronOpts(): Promise<string[]>;
188
+ export declare function drainPackets(ctx: CodecContext, pkt: Packet, stream: Stream, muxer: FormatMuxer): Promise<void>;
189
+
190
+ export declare function electronOpts(disableGpu: boolean): Promise<string[]>;
191
+
192
+ export declare function encodeNalHeader(type: number, layerId: number, temporalId: number): [number, number];
165
193
 
166
194
  declare class EncoderPipeline {
167
- private _video;
168
- private _audio;
169
- private _muxer;
170
- private _limiter;
171
- private _outFile;
172
- private _codec;
195
+ private _s;
173
196
  private _disposed;
174
197
  private constructor();
175
198
  static create(opts: EncoderPipelineOptions): Promise<EncoderPipeline>;
@@ -180,6 +203,7 @@ declare class EncoderPipeline {
180
203
  finish(): Promise<string>;
181
204
  [Symbol.asyncDispose](): Promise<void>;
182
205
  private free;
206
+ private bgraFrame;
183
207
  }
184
208
  export { EncoderPipeline }
185
209
  export { EncoderPipeline as EncoderPipeline_alias_1 }
@@ -190,6 +214,7 @@ declare interface EncoderPipelineOptions {
190
214
  fps: number;
191
215
  outFile: string;
192
216
  withAudio?: boolean;
217
+ disableGpu?: boolean;
193
218
  }
194
219
  export { EncoderPipelineOptions }
195
220
  export { EncoderPipelineOptions as EncoderPipelineOptions_alias_1 }
@@ -258,6 +283,20 @@ export declare class FrameDropStats {
258
283
  finalize(): FrameDropScore;
259
284
  }
260
285
 
286
+ export declare type HwEncoder = VideoToolboxEncoder | NvencDualLayerEncoder;
287
+
288
+ export declare interface HwVideoEncoderOptions {
289
+ width: number;
290
+ height: number;
291
+ fps: number;
292
+ hw: HardwareContext;
293
+ bitrate: number;
294
+ muxer: FormatMuxer;
295
+ }
296
+
297
+ /** Interleave base and alpha NALs for a single frame. */
298
+ export declare function interleaveAccessUnits(baseNals: NalUnit[], alphaNals: NalUnit[]): Buffer;
299
+
261
300
  export declare interface IpcDonePayload {
262
301
  written: number;
263
302
  jank: number;
@@ -350,6 +389,18 @@ export { LoggerLike as LoggerLike_alias_1 }
350
389
 
351
390
  export declare function makeCLI(options: CLIOptions): Promise<void>;
352
391
 
392
+ export declare function makeFrame(width: number, height: number, pixFmt: AVPixelFormat): Frame;
393
+
394
+ export declare function makePacket(): Packet;
395
+
396
+ export declare const NAL_HEADER_SIZE = 2;
397
+
398
+ export declare interface NalUnit {
399
+ type: number;
400
+ layerId: number;
401
+ data: Buffer;
402
+ }
403
+
353
404
  export declare interface NetworkOptions {
354
405
  source: string;
355
406
  window: BrowserWindow;
@@ -360,6 +411,23 @@ declare function noerr<Fn extends (...args: any[]) => any, D>(fn: Fn, defaultVal
360
411
  export { noerr }
361
412
  export { noerr as noerr_alias_1 }
362
413
 
414
+ export declare class NvencDualLayerEncoder implements Disposable {
415
+ private _s;
416
+ private _seiBuffer;
417
+ private _pts;
418
+ private _seiInjected;
419
+ private _alphaBuf?;
420
+ private _alphaFrame?;
421
+ private constructor();
422
+ static create(opts: HwVideoEncoderOptions): Promise<NvencDualLayerEncoder>;
423
+ encode(bgraFrame: Frame, muxer: FormatMuxer): Promise<void>;
424
+ flush(muxer: FormatMuxer): Promise<void>;
425
+ [Symbol.dispose](): void;
426
+ private drainInterleaved;
427
+ }
428
+
429
+ export declare function packBits(bits: number[]): Buffer;
430
+
363
431
  declare function pargs(): string[];
364
432
  export { pargs }
365
433
  export { pargs as pargs_alias_1 }
@@ -473,6 +541,7 @@ declare const RenderSchema: z.ZodObject<{
473
541
  outFile: z.ZodString;
474
542
  useInnerProxy: z.ZodBoolean;
475
543
  deterministic: z.ZodBoolean;
544
+ disableGpu: z.ZodBoolean;
476
545
  }, z.core.$strip>;
477
546
  export { RenderSchema }
478
547
  export { RenderSchema as RenderSchema_alias_1 }
@@ -485,6 +554,9 @@ declare interface RetryOptions<Args extends any[], Ret> {
485
554
  export { RetryOptions }
486
555
  export { RetryOptions as RetryOptions_alias_1 }
487
556
 
557
+ /** Rewrite nuh_layer_id in a NAL unit (returns copy). */
558
+ export declare function rewriteNalLayerId(nal: Buffer, layerId: number): Buffer;
559
+
488
560
  export declare function runElectronApp(size: Size, args: unknown[], ipcSocketPath: string): Promise<ProcessHandle>;
489
561
 
490
562
  export declare function setInterceptor({ source, window, useInnerProxy }: NetworkOptions): void;
@@ -499,6 +571,9 @@ declare function sleep(ms: number): Promise<void>;
499
571
  export { sleep }
500
572
  export { sleep as sleep_alias_1 }
501
573
 
574
+ /** Split Annex B bitstream into NAL units. */
575
+ export declare function splitNalUnits(bitstream: Buffer): NalUnit[];
576
+
502
577
  export declare function startStego(cdp: Debugger): Promise<any>;
503
578
 
504
579
  export declare function stopStego(cdp: Debugger): Promise<any>;
@@ -547,6 +622,34 @@ export declare interface VideoEncoderOptions {
547
622
  muxer: FormatMuxer;
548
623
  }
549
624
 
625
+ export declare interface VideoFactoryOptions {
626
+ width: number;
627
+ height: number;
628
+ fps: number;
629
+ bitrate?: number;
630
+ disableGpu?: boolean;
631
+ }
632
+
633
+ export declare interface VideoSetup {
634
+ video?: VideoEncoder_2;
635
+ hwVideo?: HwEncoder;
636
+ codec?: CodecState_2;
637
+ hw?: HardwareContext;
638
+ }
639
+
640
+ export declare class VideoToolboxEncoder implements Disposable {
641
+ private _ctx;
642
+ private _pkt;
643
+ private _stream;
644
+ private _pts;
645
+ private constructor();
646
+ static create(opts: HwVideoEncoderOptions): Promise<VideoToolboxEncoder>;
647
+ encode(bgraFrame: Frame, muxer: FormatMuxer): Promise<void>;
648
+ flush(muxer: FormatMuxer): Promise<void>;
649
+ [Symbol.dispose](): void;
650
+ private drain;
651
+ }
652
+
550
653
  export declare class WaitableEvent {
551
654
  private _promise?;
552
655
  private _resolve?;