yt-dlp-bridge 0.3.0 → 0.6.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 +72 -8
- package/dist/audio-conversion.d.ts +13 -0
- package/dist/audio-conversion.d.ts.map +1 -0
- package/dist/audio-conversion.js +101 -0
- package/dist/audio-conversion.js.map +1 -0
- package/dist/config.d.ts +0 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -1
- package/dist/config.js.map +1 -1
- package/dist/environment.d.ts.map +1 -1
- package/dist/environment.js +2 -2
- package/dist/environment.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +3 -5
- package/dist/errors.js.map +1 -1
- package/dist/extractorArgs.d.ts +22 -0
- package/dist/extractorArgs.d.ts.map +1 -0
- package/dist/extractorArgs.js +115 -0
- package/dist/extractorArgs.js.map +1 -0
- package/dist/fields.d.ts +6 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +12 -0
- package/dist/fields.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/info.d.ts +166 -0
- package/dist/info.d.ts.map +1 -0
- package/dist/info.js +131 -0
- package/dist/info.js.map +1 -0
- package/dist/output-events.d.ts +7 -1
- package/dist/output-events.d.ts.map +1 -1
- package/dist/output-events.js +11 -10
- package/dist/output-events.js.map +1 -1
- package/dist/output-target.d.ts +26 -0
- package/dist/output-target.d.ts.map +1 -0
- package/dist/output-target.js +66 -0
- package/dist/output-target.js.map +1 -0
- package/dist/output-template.d.ts +15 -0
- package/dist/output-template.d.ts.map +1 -0
- package/dist/output-template.js +19 -0
- package/dist/output-template.js.map +1 -0
- package/dist/parsers.d.ts +2 -2
- package/dist/parsers.d.ts.map +1 -1
- package/dist/parsers.js +63 -100
- package/dist/parsers.js.map +1 -1
- package/dist/progress.d.ts +44 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +138 -0
- package/dist/progress.js.map +1 -0
- package/dist/runner.d.ts +27 -0
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +169 -20
- package/dist/runner.js.map +1 -1
- package/dist/schemas.d.ts +42 -41
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +4 -4
- package/dist/schemas.js.map +1 -1
- package/dist/types.d.ts +1 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/workflow.d.ts +31 -10
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +112 -58
- package/dist/workflow.js.map +1 -1
- package/package.json +52 -18
package/README.md
CHANGED
|
@@ -13,6 +13,8 @@ Source and contributions live in the Arroxy monorepo at [`packages/yt-dlp-bridge
|
|
|
13
13
|
|
|
14
14
|
- [Install](#install)
|
|
15
15
|
- [Features](#features)
|
|
16
|
+
- [What changed in 0.5.0](#what-changed-in-050)
|
|
17
|
+
- [What changed in 0.4.0](#what-changed-in-040)
|
|
16
18
|
- [What changed in 0.3.0](#what-changed-in-030)
|
|
17
19
|
- [What changed in 0.2.0](#what-changed-in-020)
|
|
18
20
|
- [Usage](#usage)
|
|
@@ -43,10 +45,52 @@ Requires Node.js >= 22.13 and ESM.
|
|
|
43
45
|
- Managed output policy for output roots, temp roots, archive files, overwrite behavior, and parent-directory traversal checks.
|
|
44
46
|
- Secret redaction for auth flags, cookies, PO tokens, visitor data, proxies, signed URLs, and command previews.
|
|
45
47
|
- Parsers for JSON lines, format lists, subtitle lists, thumbnail lists, progress output, final output paths, and live yt-dlp output events.
|
|
46
|
-
- Low-level process runner using `spawn` with `shell: false
|
|
48
|
+
- Low-level process runner using `spawn` with `shell: false`: streams whole output lines (yt-dlp's `\r` progress redraws included), keeps a bounded tail of output, and on timeout or cancel kills the whole process tree, never a reaped pid.
|
|
49
|
+
- A Zod schema for yt-dlp's `info_dict` (`--dump-json` / `--dump-single-json` output).
|
|
47
50
|
- Source-derived option catalog generated from `yt_dlp.options.create_parser`.
|
|
48
51
|
- ESM and TypeScript declarations.
|
|
49
52
|
|
|
53
|
+
## What changed in 0.6.0
|
|
54
|
+
|
|
55
|
+
0.6.0 contains breaking changes and requires `ytdlp-errors` 1.4.0.
|
|
56
|
+
|
|
57
|
+
- **Breaking:** a plan that writes files now carries `cwd`, and every path in its `args` is relative to it. Run it there (`runCommand(…, {cwd: plan.cwd})`): run elsewhere, the files land in the wrong folder. Create the folder first if it may not exist (`mkdir(plan.cwd, {recursive: true})`): yt-dlp used to make it through `--paths home`, and a spawn in a missing folder fails with `ENOENT`. Caller plans run in `output.directory`; `--paths home:` is gone, and `output.tempDirectory`, `-o infojson:`, the subtitle subfolder and a `resume.loadInfoJsonPath` inside the folder become relative. Managed plans run in the output root; the temp root and the download archive are relative when they are inside it. yt-dlp expands `$NAME`, `%NAME%` and `~` in every path it is given, with no escape on POSIX for `--paths`, and strips trailing spaces from `--paths` values. So a folder such as `$HOME`, `%USERPROFILE%` or `Downloads ` (trailing space) wrote somewhere else; now its name never reaches argv.
|
|
58
|
+
- **Breaking:** `output.tempDirectory` must be inside `output.directory`; a plan with one outside it throws.
|
|
59
|
+
- Caller subtitles take planned tracks: `subtitles: {tracks: [{key, auto}], format}`. Each key goes to `--sub-langs` as an exact, case-sensitive, escaped match, and the plan sets `--write-subs` only for a manual track and `--write-auto-subs` only for an automatic caption. The flags cover the whole run and yt-dlp takes a key from the manual tracks first, so a plan with both kinds should ask for an automatic caption only under a key the manual tracks lack (on YouTube, its `<lang>-orig` key). The languages form (`languages`, `writeAuto`, `autoOnly`) stays, sent as given, for a caller that cannot plan the tracks; on YouTube a bare code there also matches machine translations.
|
|
60
|
+
- Caller subtitles take `loadInfoJsonPath`: yt-dlp fetches the subtitle URLs stored in that info-json instead of extracting the video again (and extracts it again only if one of them fails). The URL is not passed.
|
|
61
|
+
- New `subtitle-listing` workflow: `-J` with `--write-subs --write-auto-subs --sub-langs all`, which fills `subtitles` and `automatic_captions` for extractors that list them only when asked (Vimeo, TikTok, Bilibili and others) and writes no files. Its JSON on stdout is what a caller plans tracks from, and what `loadInfoJsonPath` then loads. Exhaustive `switch` statements over `WorkflowPlan['kind']` need the new case.
|
|
62
|
+
- New `output.report`: `finalPath` has yt-dlp append the media's absolute path once every postprocessor and the move are done (`--print-to-file after_move:filepath`); `subtitles` has it append `requested_subtitles` as JSON, with each track's `filepath`, also under `--skip-download` (`after_video`). Both files must be inside `output.directory`.
|
|
63
|
+
- New `templateLiteral(text)`, also from the new `yt-dlp-bridge/output-template` subpath: literal text for an output template. Each `%`, `$` and `~` becomes an absent field whose default is that sign (`%(_absent|$)s`), which yt-dlp's expansion cannot see through. `%%` is not used: on Windows, ntpath pairs `%` signs, and a field before a `%%` lets a literal `%NAME%` expand.
|
|
64
|
+
- **Breaking:** progress is read from yt-dlp's numbers, not its human-readable `[download] 42.0% of …` line. The `progress` event no longer carries `percent`, `total`, `speed` or `eta`; it is now only the fallback for other lines (`raw`).
|
|
65
|
+
- Caller media, caller subtitles and managed download plans pass `--progress-template` with `YT_DLP_PROGRESS_TEMPLATE`, a prefixed JSON line per update. Caller media plans and every managed download plan (media, audio, subtitles, thumbnail and playlist) also pass `--print before_dl:` with `YT_DLP_REQUESTED_FORMATS_TEMPLATE`, one prefixed stdout line per video; caller media plans pass `--no-quiet` so that print does not silence yt-dlp's other output.
|
|
66
|
+
- `parseYtDlpOutputLine` emits two new event kinds: `download-progress` (`status`, `formatId`, `downloadedBytes`, `totalBytes`, `totalBytesEstimate`, `speedBps`, `etaSeconds`, `elapsedSeconds`, `fragmentIndex`, `fragmentCount`) and `requested-formats` (the streams yt-dlp is about to download, in order, with `filesize` / `filesizeApprox`). Exhaustive `switch` statements over `YtDlpOutputEvent` need the two new cases.
|
|
67
|
+
- New `YtDlpDownloadProgressTracker` turns those events into one percent over every stream of a video, so the audio download after the video counts instead of restarting at 0%. It also estimates the time left over all remaining streams.
|
|
68
|
+
- An audio conversion now converts a stream already in the target codec when the source has one (AAC 140 for m4a on YouTube, Opus 251 for opus). yt-dlp copies such a stream instead of re-encoding it, so there is no second lossy pass; `--audio-quality` does not apply to it. A stream below 96 kbps (`AUDIO_CONVERSION_COPY_MIN_KBPS`) is not worth copying: the best stream is re-encoded instead. Each tier of the source chain (the source's track, then any) tries non-DRC before DRC, and every stereo stream before Dolby surround, which libopus cannot take. The "original" track filter no longer matches a stream with no `format_note`.
|
|
69
|
+
- With `audio.convert`, a caller's `selection.formatSelector` (and `formatSort`) now picks the stream to convert, in place of the bridge's source chain. `--audio-format best` (`target: 'best'`) extracts the audio and keeps its codec where yt-dlp can.
|
|
70
|
+
- New `yt-dlp-bridge/audio-conversion` subpath: `audioConversionCopies(target, acodec)` says whether converting a stream to `target` copies it, `audioConversionCopyFilter(target)` is the `-f` filter for such a stream, `audioConversionOutcome(target, {ext, acodec})` gives the file's extension and whether the audio is kept as is, `audioCodecPreference(acodec)` ranks a codec as yt-dlp's format sorter does, and `audioConversionSourceSelector(target)` is the `-f` the planner gives a conversion that names no stream.
|
|
71
|
+
- An MP3 conversion also copies an MP3 stream inside an MP4 (`acodec` `mp4a.40.34`), where it used to pass it over and re-encode another one.
|
|
72
|
+
- A `[VideoRemuxer] Remuxing video from … to …; Destination: <path>` or `[VideoConvertor] Converting video …` line now gives its destination in the `postprocess` event; it came out without a path before, so a consumer following the file kept the pre-remux path, which yt-dlp deletes.
|
|
73
|
+
- A caller's directory that reaches `-o` no longer loses or expands `%` signs: a folder named `100%% done` or containing `%(id)s` keeps its name. Since every path is now relative to the plan's `cwd`, the folder text no longer reaches argv at all.
|
|
74
|
+
|
|
75
|
+
## What changed in 0.5.0
|
|
76
|
+
|
|
77
|
+
0.5.0 contains breaking changes and requires `ytdlp-errors` 1.3.0. 0.4.0 was never published; its change is listed under 0.4.0 below and ships in 0.5.0.
|
|
78
|
+
|
|
79
|
+
- **Breaking:** `CONFIG` is gone from `yt-dlp-bridge/config`. The package no longer reads `YTDLP_MCP_*` or the home directory at import: `planWorkflow` and `checkEnvironment` call `loadConfig()` when no `config` is passed, so they see the environment as it is at call time.
|
|
80
|
+
- **Breaking:** `parseProgress`, `ProgressEvent`, `ProgressEventPhaseSchema`/`ProgressEventPhase` and `PROGRESS_EVENT_PHASES` are removed. `parseYtDlpOutputLine` is the one progress parser: its `progress` event now also carries `total`, `speed` and `eta` from a `[download]` line.
|
|
81
|
+
- **Breaking:** `sanitizeMetadataItem` reads its input through the new `infoDictSchema`. A dict the schema rejects (a field of the wrong type, say) now sanitizes to `{}` instead of keeping the fields that happened to be valid. A playlist dict keeps only `id`, `title`, `webpageUrl`, `extractor`, `extractorKey` and `thumbnailCount`.
|
|
82
|
+
- **Breaking:** `SUBTITLE_MODES` is now ordered `sidecar`, `embed`, `subfolder`.
|
|
83
|
+
- New `yt-dlp-bridge/info` subpath: `infoDictSchema`, `ytDlpFormatSchema`, `ytDlpSubtitleTrackSchema`, the `InfoDict` / `VideoInfo` / `PlaylistInfo` / `MultiVideoInfo` / `UrlRedirectInfo` / `YtDlpFormat` / `YtDlpSubtitleTrack` types, and `isPlaylistLike` / `isUrlRedirect`.
|
|
84
|
+
- `runCommand` spawns the child as its own process group on Unix and kills the whole tree on timeout or cancel (`taskkill /T /F` on Windows), so an ffmpeg that yt-dlp forked no longer survives. It never signals a child that has already exited. New options: `onStdoutLine` / `onStderrLine` stream each whole, trimmed line as it arrives (if one throws, the child is killed and the run rejects with that error), and `logger` receives the warnings the runner absorbs. Output capture no longer copies the whole buffer on every chunk.
|
|
85
|
+
- New runner exports: `killProcessTree`, `splitOutputLines`, `createStreamTextReader`, `SPAWN_AS_PROCESS_GROUP`, and the `RunnerLogger`, `KillableProcess`, `StreamTextReader`, `StreamTextChunk` types.
|
|
86
|
+
- `toStructuredError` takes `unsupportedUrl` from the `ytdlp-errors` classifier instead of a regex of its own. A line such as `... is not a valid URL` still classifies; text that merely mentions an unsupported URL no longer does.
|
|
87
|
+
- `CallerMediaWorkflowInput` gains `downloadSections` (yt-dlp `--download-sections` values such as `*220-435`) and `forceKeyframesAtCuts`. A plan with sections lists ffmpeg as required and reports the cut as a side effect; an exact cut also reports the re-encode as a risk.
|
|
88
|
+
- `embed.chapters: false` now passes `--no-embed-chapters` (unless SponsorBlock marks segments as chapters). yt-dlp otherwise embeds chapters whenever `--add-metadata` is on.
|
|
89
|
+
|
|
90
|
+
## What changed in 0.4.0
|
|
91
|
+
|
|
92
|
+
- Requires `ytdlp-errors` 1.2.0. `toStructuredError` can now return `kind: 'outputNotWritable'` when the output folder refuses writes (permission denied, read-only drive, or a privacy-protected folder), with a suggested fix to grant write access or choose another output root.
|
|
93
|
+
|
|
50
94
|
## What changed in 0.3.0
|
|
51
95
|
|
|
52
96
|
- `parseYtDlpOutputLine` emits two new event kinds: `artifact` (a written description, info JSON, or thumbnail sidecar, with its `path`) and `transfer-retry` (yt-dlp's in-process `Got error: ... Retrying (n/m)` line, with `attempt` and `total`). `postprocess` events now carry the output `path` when yt-dlp prints one. Exhaustive `switch` statements over `YtDlpOutputEvent` need the two new cases.
|
|
@@ -153,7 +197,7 @@ const plan = planWorkflow(input, { config });
|
|
|
153
197
|
|
|
154
198
|
```ts
|
|
155
199
|
{
|
|
156
|
-
kind: "probe" | "inspect" | "media" | "audio" | "subtitles" | "thumbnail" | "playlist" | "postprocess" | "expert",
|
|
200
|
+
kind: "probe" | "subtitle-listing" | "inspect" | "media" | "audio" | "subtitles" | "thumbnail" | "playlist" | "postprocess" | "expert",
|
|
157
201
|
args: string[],
|
|
158
202
|
redactedArgs: string[],
|
|
159
203
|
facts: {
|
|
@@ -214,12 +258,27 @@ if (event?.kind === "merge") {
|
|
|
214
258
|
}
|
|
215
259
|
```
|
|
216
260
|
|
|
261
|
+
Plans for media downloads ask yt-dlp for structured progress. Feed it to a tracker for one percent across every stream of a merged download:
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
import { parseYtDlpOutputLine, YtDlpDownloadProgressTracker } from "yt-dlp-bridge/parsers";
|
|
265
|
+
|
|
266
|
+
const tracker = new YtDlpDownloadProgressTracker();
|
|
267
|
+
|
|
268
|
+
function onLine(line: string) {
|
|
269
|
+
const event = parseYtDlpOutputLine(line);
|
|
270
|
+
if (event?.kind === "requested-formats") tracker.setRequestedFormats(event.formats);
|
|
271
|
+
if (event?.kind === "download-progress") console.log(tracker.update(event.progress).percent);
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
217
275
|
### Run a planned command
|
|
218
276
|
|
|
219
|
-
The bridge runner is low-level. It executes a command path plus argv; it does not resolve binaries or decide retries.
|
|
277
|
+
The bridge runner is low-level. It executes a command path plus argv; it does not resolve binaries or decide retries. Pass the plan's `cwd`, which must exist: the paths in its argv are relative to it. The child runs as its own process group on Unix, so it does not receive the terminal's Ctrl+C: stop it with `signal`.
|
|
220
278
|
|
|
221
279
|
```ts
|
|
222
280
|
import { planWorkflow } from "yt-dlp-bridge";
|
|
281
|
+
import { parseYtDlpOutputLine } from "yt-dlp-bridge/parsers";
|
|
223
282
|
import { runCommand } from "yt-dlp-bridge/runner";
|
|
224
283
|
import { toStructuredError } from "yt-dlp-bridge/errors";
|
|
225
284
|
|
|
@@ -230,8 +289,10 @@ const plan = planWorkflow({
|
|
|
230
289
|
|
|
231
290
|
try {
|
|
232
291
|
const result = await runCommand("yt-dlp", plan.args, {
|
|
292
|
+
cwd: plan.cwd,
|
|
233
293
|
timeoutMs: 900_000,
|
|
234
|
-
maxOutputBytes: 4 * 1024 * 1024
|
|
294
|
+
maxOutputBytes: 4 * 1024 * 1024,
|
|
295
|
+
onStderrLine: line => console.log(parseYtDlpOutputLine(line))
|
|
235
296
|
});
|
|
236
297
|
console.log(result.stdout);
|
|
237
298
|
} catch (error) {
|
|
@@ -258,14 +319,17 @@ Prefer the root export for workflow planning and subpaths for lower-level utilit
|
|
|
258
319
|
|
|
259
320
|
| Area | Exports |
|
|
260
321
|
| --- | --- |
|
|
261
|
-
| Workflow planning | `planWorkflow`, workflow input/plan/fact types |
|
|
322
|
+
| Workflow planning | `planWorkflow`, `templateLiteral`, workflow input/plan/fact types |
|
|
262
323
|
| Schemas | `WorkflowInspectInputSchema`, `WorkflowDownloadInputSchema`, `WorkflowExecutionInputSchema`, `WorkflowPostprocessInputSchema`, `WorkflowExpertInputSchema`, `WorkflowInputSchema`, `ValidateWorkflowInputSchema` |
|
|
263
|
-
|
|
|
324
|
+
| Audio conversion | `audioConversionCopies`, `audioConversionOutcome`, `audioConversionCopyFilter`, `audioCodecPreference`, `audioConversionSourceSelector`, `AUDIO_CONVERSION_COPY_MIN_KBPS` from `yt-dlp-bridge/audio-conversion` |
|
|
325
|
+
| Config | `loadConfig` from `yt-dlp-bridge/config` |
|
|
264
326
|
| Environment | `checkEnvironment` from `yt-dlp-bridge/environment` |
|
|
265
327
|
| Filesystem policy | `resolveOutputPolicy`, `resolveManagedPath`, `ensureWithinRoot`, `isPathInside`, `isPathInsideWith`, `hasParentTraversal`, `ensureDirectory`, `readArchive` from `yt-dlp-bridge/filesystem` |
|
|
328
|
+
| Output templates | `templateLiteral` from `yt-dlp-bridge/output-template` (also from the root) |
|
|
266
329
|
| Option catalog | `UPSTREAM_OPTION_CATALOG`, `listLongFlags`, `findOptionByFlag`, `optionMetadata` from `yt-dlp-bridge/option-catalog` |
|
|
267
|
-
|
|
|
268
|
-
|
|
|
330
|
+
| info_dict | `infoDictSchema`, `ytDlpFormatSchema`, `ytDlpSubtitleTrackSchema`, `isPlaylistLike`, `isUrlRedirect` and the `InfoDict` family of types from `yt-dlp-bridge/info` |
|
|
331
|
+
| Parsers | `parseYtDlpOutputLine`, `parseJsonLines`, `sanitizeMetadataItem`, `sanitizeMetadataItems`, `paginate`, `parseFormats`, `parseSubtitles`, `parseThumbnails`, `parseFinalPaths` from `yt-dlp-bridge/parsers` |
|
|
332
|
+
| Runner | `runCommand`, `CommandExecutionError`, `killProcessTree`, `splitOutputLines`, `createStreamTextReader`, `SPAWN_AS_PROCESS_GROUP` from `yt-dlp-bridge/runner` |
|
|
269
333
|
| Redaction | `redactArgs`, `redactText`, `excerpt` from `yt-dlp-bridge/redaction` |
|
|
270
334
|
| Structured errors | `toStructuredError` from `yt-dlp-bridge/errors` |
|
|
271
335
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const AUDIO_CONVERSION_COPY_MIN_KBPS = 96;
|
|
2
|
+
export declare function audioConversionCopies(target: string, acodec: string | undefined): boolean;
|
|
3
|
+
export declare function audioConversionOutcome(target: string, source: {
|
|
4
|
+
ext: string | undefined;
|
|
5
|
+
acodec: string | undefined;
|
|
6
|
+
}): {
|
|
7
|
+
ext: string;
|
|
8
|
+
copies: boolean;
|
|
9
|
+
} | undefined;
|
|
10
|
+
export declare function audioConversionCopyFilter(target: string): string | undefined;
|
|
11
|
+
export declare function audioCodecPreference(acodec: string | undefined): number;
|
|
12
|
+
export declare function audioConversionSourceSelector(target: string): string;
|
|
13
|
+
//# sourceMappingURL=audio-conversion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-conversion.d.ts","sourceRoot":"","sources":["../src/audio-conversion.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,8BAA8B,KAAK,CAAA;AAwBhD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKzF;AAMD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE;IAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;CAAC,GAAG;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAAG,SAAS,CAShK;AAID,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG5E;AAQD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMvE;AAiBD,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMpE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Port of the copy-or-encode choice in yt-dlp's FFmpegExtractAudioPP.run
|
|
2
|
+
// (postprocessor/ffmpeg.py): a source whose codec already is the target (AAC
|
|
3
|
+
// into m4a too) is copied with `-acodec copy` and --audio-quality does not
|
|
4
|
+
// apply; any other source is re-encoded. WAV has no codec of its own to match.
|
|
5
|
+
// `best` keeps the source's codec wherever yt-dlp can.
|
|
6
|
+
// yt-dlp's `acodec` names each codec as ffprobe does, except AAC: `mp4a.40.<n>`
|
|
7
|
+
// for its object types (LC, HE, HEv2, LD, ELD, USAC), never `mp4a.40.34` (MP3)
|
|
8
|
+
// or `mp4a.6B` (MPEG audio).
|
|
9
|
+
const AAC_PATTERN = '^(?:aac|mp4a(?:\\.40\\.(?:[1-6]|23|29|39|42))?)$';
|
|
10
|
+
const TARGET_CODEC_PATTERNS = { aac: AAC_PATTERN, m4a: AAC_PATTERN, opus: '^opus$', mp3: '^(?:mp3|mp4a\\.40\\.34)$', vorbis: '^vorbis$', flac: '^flac$', alac: '^alac$' };
|
|
11
|
+
// A copied stream keeps its bitrate: below this a stream is no better for
|
|
12
|
+
// being copied, and the best stream is re-encoded instead (YouTube's 48 kbps
|
|
13
|
+
// HE-AAC 139 where no 140 is offered, against a 130 kbps Opus 251).
|
|
14
|
+
export const AUDIO_CONVERSION_COPY_MIN_KBPS = 96;
|
|
15
|
+
function targetCodecPattern(target) {
|
|
16
|
+
return Object.hasOwn(TARGET_CODEC_PATTERNS, target) ? TARGET_CODEC_PATTERNS[target] : undefined;
|
|
17
|
+
}
|
|
18
|
+
// ffprobe's name for the codecs yt-dlp's ACODECS table can copy, from
|
|
19
|
+
// yt-dlp's `acodec` (which names AAC by its object type, MP3 in an MP4
|
|
20
|
+
// `mp4a.40.34`).
|
|
21
|
+
const COPYABLE_CODECS = ['opus', 'vorbis', 'mp3', 'flac', 'alac'];
|
|
22
|
+
function ffprobeCodec(acodec) {
|
|
23
|
+
if (acodec === undefined)
|
|
24
|
+
return undefined;
|
|
25
|
+
if (new RegExp(AAC_PATTERN, 'i').test(acodec))
|
|
26
|
+
return 'aac';
|
|
27
|
+
if (/^mp4a\.40\.34$/i.test(acodec))
|
|
28
|
+
return 'mp3';
|
|
29
|
+
return COPYABLE_CODECS.find(codec => codec === acodec.toLowerCase());
|
|
30
|
+
}
|
|
31
|
+
// Each target's container (ACODECS in postprocessor/ffmpeg.py).
|
|
32
|
+
const TARGET_EXTENSIONS = { mp3: 'mp3', aac: 'm4a', m4a: 'm4a', opus: 'opus', vorbis: 'ogg', flac: 'flac', alac: 'm4a', wav: 'wav' };
|
|
33
|
+
// FFmpegExtractAudioPP.COMMON_AUDIO_EXTS: `best` leaves these files alone.
|
|
34
|
+
const COMMON_AUDIO_EXTENSIONS = new Set(['aiff', 'alac', 'flac', 'm4a', 'mka', 'mp3', 'ogg', 'opus', 'wav', 'wma']);
|
|
35
|
+
// Whether converting a stream with this `acodec` to `target` copies it.
|
|
36
|
+
// `best` copies any codec yt-dlp has a container for.
|
|
37
|
+
export function audioConversionCopies(target, acodec) {
|
|
38
|
+
const codec = ffprobeCodec(acodec);
|
|
39
|
+
if (codec === undefined)
|
|
40
|
+
return false;
|
|
41
|
+
if (target === 'best')
|
|
42
|
+
return true;
|
|
43
|
+
return (codec === 'aac' && target === 'm4a') || codec === target;
|
|
44
|
+
}
|
|
45
|
+
// What converting a stream to `target` gives: the file's extension, and
|
|
46
|
+
// whether the audio is kept as it is (copied, or left alone) rather than
|
|
47
|
+
// re-encoded. Undefined when yt-dlp's choice can't be told from the stream:
|
|
48
|
+
// an unknown target, or `best` for a stream whose codec isn't named.
|
|
49
|
+
export function audioConversionOutcome(target, source) {
|
|
50
|
+
if (target === 'best') {
|
|
51
|
+
if (source.ext !== undefined && COMMON_AUDIO_EXTENSIONS.has(source.ext))
|
|
52
|
+
return { ext: source.ext, copies: true };
|
|
53
|
+
if (source.acodec === undefined)
|
|
54
|
+
return undefined;
|
|
55
|
+
const codec = ffprobeCodec(source.acodec);
|
|
56
|
+
return codec === undefined ? { ext: 'mp3', copies: false } : { ext: TARGET_EXTENSIONS[codec] ?? codec, copies: true };
|
|
57
|
+
}
|
|
58
|
+
const ext = Object.hasOwn(TARGET_EXTENSIONS, target) ? TARGET_EXTENSIONS[target] : undefined;
|
|
59
|
+
return ext === undefined ? undefined : { ext, copies: audioConversionCopies(target, source.acodec) };
|
|
60
|
+
}
|
|
61
|
+
// The `-f` filter for a stream worth copying when converting to `target`:
|
|
62
|
+
// in its codec, and not below the copy floor (a stream naming no bitrate passes).
|
|
63
|
+
export function audioConversionCopyFilter(target) {
|
|
64
|
+
const pattern = targetCodecPattern(target);
|
|
65
|
+
return pattern === undefined ? undefined : `[acodec~='(?i)${pattern}'][abr>=?${AUDIO_CONVERSION_COPY_MIN_KBPS}]`;
|
|
66
|
+
}
|
|
67
|
+
// Port of FormatSorter's `acodec` order (utils/_utils.py): each pattern is
|
|
68
|
+
// matched at the start of the codec, first match wins; a codec matching none
|
|
69
|
+
// ranks at the empty entry, and an unknown one (no acodec) below it. Higher is
|
|
70
|
+
// preferred. On YouTube it is what puts Opus 251 ahead of AAC 140.
|
|
71
|
+
const ACODEC_ORDER = ['[af]lac', 'wav|aiff', 'opus', 'vorbis|ogg', 'aac', 'mp?4a?', 'mp3', 'ac-?4', 'e-?a?c-?3', 'ac-?3', 'dts', '', null, 'none'];
|
|
72
|
+
export function audioCodecPreference(acodec) {
|
|
73
|
+
const length = ACODEC_ORDER.length;
|
|
74
|
+
if (acodec === undefined)
|
|
75
|
+
return length - ACODEC_ORDER.indexOf(null);
|
|
76
|
+
const codec = acodec.toLowerCase();
|
|
77
|
+
const index = ACODEC_ORDER.findIndex(pattern => pattern !== null && pattern !== '' && new RegExp(`^(?:${pattern})`).test(codec));
|
|
78
|
+
return length - (index === -1 ? ACODEC_ORDER.indexOf('') : index);
|
|
79
|
+
}
|
|
80
|
+
const NON_DRC_AUDIO_FILTERS = "[format_id!~=?'(?i)(?:^|[-_\\s])drc(?:$|[-_\\s])'][format_note!~=?'(?i)\\bdrc\\b']";
|
|
81
|
+
// Dolby surround makes a poor conversion source: libopus refuses its 5.1(side)
|
|
82
|
+
// layout outright, and the other lossy targets downmix it. A stream with no
|
|
83
|
+
// codec named passes.
|
|
84
|
+
const NON_DOLBY_AUDIO_FILTER = "[acodec!~=?'^(?:e-?ac-?3|ec-3|ac-?3)$']";
|
|
85
|
+
// Strict: `~=?` would also take a stream with no note at all as the original.
|
|
86
|
+
const SOURCE_TRACK_AUDIO_FILTERS = ['[language_preference>0]', "[format_note~='(?i)\\boriginal\\b']", ''];
|
|
87
|
+
// The stream to convert, most wanted first: the source's own track before any
|
|
88
|
+
// other; within it the non-DRC master before the DRC one, a stream that is
|
|
89
|
+
// copied as-is before one that is re-encoded, and every stereo stream (DRC
|
|
90
|
+
// ones too) before Dolby surround.
|
|
91
|
+
// The `-f` the planner gives a conversion that names no stream (a caller's
|
|
92
|
+
// stream goes ahead of it). Exported so a caller can run it through its own
|
|
93
|
+
// copy of yt-dlp's selection and know which stream converts.
|
|
94
|
+
export function audioConversionSourceSelector(target) {
|
|
95
|
+
// A stream already in the target codec is copied, not re-encoded a second time.
|
|
96
|
+
const codecFilter = audioConversionCopyFilter(target);
|
|
97
|
+
const stereoFilters = [...(codecFilter ? [codecFilter] : []), NON_DOLBY_AUDIO_FILTER];
|
|
98
|
+
const streamFilters = [...[NON_DRC_AUDIO_FILTERS, ''].flatMap(drcFilter => stereoFilters.map(filter => `${filter}${drcFilter}`)), NON_DRC_AUDIO_FILTERS, ''];
|
|
99
|
+
return [...SOURCE_TRACK_AUDIO_FILTERS.flatMap(trackFilter => streamFilters.map(filters => `bestaudio${trackFilter}${filters}`)), 'best'].join('/');
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=audio-conversion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audio-conversion.js","sourceRoot":"","sources":["../src/audio-conversion.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,yBAAyB,EAAE,OAAO,CAAA;IAClC,gBAAgB,EAAE,OAAO,CAAA;IACzB,eAAe,EAAE,OAAO,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,UAAU,EAAE,MAAM,EAAE,CAAA;CACpB;AA2BD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,YAAY,CAoB7E
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,yBAAyB,EAAE,OAAO,CAAA;IAClC,gBAAgB,EAAE,OAAO,CAAA;IACzB,eAAe,EAAE,OAAO,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAChC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,UAAU,EAAE,MAAM,EAAE,CAAA;CACpB;AA2BD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,YAAY,CAoB7E"}
|
package/dist/config.js
CHANGED
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,YAAY,EAAC,MAAM,aAAa,CAAA;AAEzD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,YAAY,CAAA;AAElD,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAA;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,CAAA;IACzC,YAAY,EAAE,kBAAkB,EAAE,CAAA;IAClC,OAAO,EAAE;QAAC,cAAc,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,iBAAiB,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAC,CAAA;IACtG,MAAM,EAAE;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,yBAAyB,EAAE,OAAO,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAC;QAAC,eAAe,EAAE,OAAO,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAA;KAAC,CAAA;CAClK;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,YAA2B,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAuBtG"}
|
package/dist/environment.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import os from 'node:os';
|
|
3
|
-
import {
|
|
3
|
+
import { loadConfig } from './config.js';
|
|
4
4
|
import { runCommand } from './runner.js';
|
|
5
|
-
export async function checkEnvironment(config =
|
|
5
|
+
export async function checkEnvironment(config = loadConfig()) {
|
|
6
6
|
const dependencies = await Promise.all([
|
|
7
7
|
detectBinary('yt-dlp', config.ytdlpPath, ['--version'], ['all yt-dlp operations'], true, config),
|
|
8
8
|
detectBinary('ffmpeg', config.ffmpegPath ?? 'ffmpeg', ['-version'], ['merge', 'remux', 'recode', 'extract audio', 'embed assets'], false, config),
|
package/dist/environment.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,YAAY,CAAA;AAE/C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,YAAY,CAAA;AAE/C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,CAgBjE"}
|
package/dist/errors.js
CHANGED
|
@@ -4,8 +4,7 @@ import { CommandExecutionError } from './runner.js';
|
|
|
4
4
|
export function toStructuredError(error) {
|
|
5
5
|
if (error instanceof CommandExecutionError) {
|
|
6
6
|
const stderr = [error.result.stderr, error.result.stdout, error.message].find(value => value.length > 0) ?? error.message;
|
|
7
|
-
const
|
|
8
|
-
const kind = inferUnsupportedUrl(stderr) ? 'unsupportedUrl' : classified.kind;
|
|
7
|
+
const { kind } = classifyYtDlpStderr(stderr);
|
|
9
8
|
const metadata = errorKindMetadata(kind);
|
|
10
9
|
const structured = { kind, message: extractLastError(stderr) ?? error.message, retryable: metadata.recoverable, exitCode: error.result.exitCode, stderrExcerpt: excerpt(stderr), suggestedFixes: suggestedFixes(kind, metadata.suggestedFlags) };
|
|
11
10
|
const dependency = inferDependency(stderr);
|
|
@@ -33,9 +32,6 @@ function inferDependency(text) {
|
|
|
33
32
|
return 'js-runtime';
|
|
34
33
|
return undefined;
|
|
35
34
|
}
|
|
36
|
-
function inferUnsupportedUrl(text) {
|
|
37
|
-
return /unsupported url|no suitable extractor|not a valid URL/i.test(text);
|
|
38
|
-
}
|
|
39
35
|
function suggestedFixes(kind, flags) {
|
|
40
36
|
const fixes = new Set();
|
|
41
37
|
for (const flag of flags ?? [])
|
|
@@ -50,6 +46,8 @@ function suggestedFixes(kind, flags) {
|
|
|
50
46
|
fixes.add('Use an allowed region, proxy, or yt-dlp geo-bypass option where legal.');
|
|
51
47
|
if (kind === 'outOfDiskSpace')
|
|
52
48
|
fixes.add('Free disk space or choose a different output root.');
|
|
49
|
+
if (kind === 'outputNotWritable')
|
|
50
|
+
fixes.add('Grant write access to the output root or choose a different one.');
|
|
53
51
|
return [...fixes];
|
|
54
52
|
}
|
|
55
53
|
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAC,MAAM,cAAc,CAAA;AACrF,OAAO,EAAC,OAAO,EAAC,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAC,qBAAqB,EAAC,MAAM,aAAa,CAAA;AAGjD,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC/C,IAAI,KAAK,YAAY,qBAAqB,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAA;QACzH,MAAM,
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** One extractor's arguments: each key's values, as `_configuration_arg` reads them. */
|
|
2
|
+
export type ExtractorArgValues = Readonly<Record<string, readonly string[]>>;
|
|
3
|
+
/** Extractor arguments by lower-cased extractor name (`youtube`, `youtubetab`, …). */
|
|
4
|
+
export type ExtractorArgs = Readonly<Record<string, ExtractorArgValues>>;
|
|
5
|
+
/** Parses one `--extractor-args` value (`IE:key=v1,v2;key2=v`) with yt-dlp's rules. */
|
|
6
|
+
export declare function parseExtractorArgsBlock(value: string): ExtractorArgs;
|
|
7
|
+
/** Renders one extractor's arguments as a single `--extractor-args` value. */
|
|
8
|
+
export declare function renderExtractorArgsBlock(extractor: string, values: ExtractorArgValues): string;
|
|
9
|
+
/** Merges extractor arguments key by key; a later layer's key replaces an earlier one's. */
|
|
10
|
+
export declare function mergeExtractorArgs(...layers: readonly ExtractorArgs[]): ExtractorArgs;
|
|
11
|
+
/** The extractor arguments yt-dlp would act on for this argv: the last block per extractor wins whole. */
|
|
12
|
+
export declare function effectiveExtractorArgs(argv: readonly string[]): ExtractorArgs;
|
|
13
|
+
/** Extractors that this argv names in more than one block, where all but the last are silently lost. */
|
|
14
|
+
export declare function duplicateExtractorArgsBlocks(argv: readonly string[]): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Folds every extractor-args block in `argv`, then `overrides`, into one block
|
|
17
|
+
* per extractor, merged key by key, so everything a caller meant to pass
|
|
18
|
+
* reaches yt-dlp. The blocks take the place of the first one in the argv, or
|
|
19
|
+
* lead it when it had none.
|
|
20
|
+
*/
|
|
21
|
+
export declare function withExtractorArgs(argv: readonly string[], overrides: ExtractorArgs): string[];
|
|
22
|
+
//# sourceMappingURL=extractorArgs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractorArgs.d.ts","sourceRoot":"","sources":["../src/extractorArgs.ts"],"names":[],"mappings":"AAMA,wFAAwF;AACxF,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAA;AAE5E,sFAAsF;AACtF,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAA;AAUxE,uFAAuF;AACvF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAcpE;AAED,8EAA8E;AAC9E,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAa9F;AAED,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,GAAG,MAAM,EAAE,SAAS,aAAa,EAAE,GAAG,aAAa,CAQrF;AA4BD,0GAA0G;AAC1G,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,aAAa,CAI7E;AAED,wGAAwG;AACxG,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAU9E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,aAAa,GAAG,MAAM,EAAE,CAS7F"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// yt-dlp keeps one argument dict per extractor and *replaces* it when the same
|
|
2
|
+
// extractor is given again: `--extractor-args youtube:a=1 --extractor-args
|
|
3
|
+
// youtube:b=2` leaves only `b` (options.py `_dict_from_options_callback`,
|
|
4
|
+
// append=False). Callers that add their own options to a planned argv must
|
|
5
|
+
// therefore merge into the extractor's single block, never append another.
|
|
6
|
+
const EXTRACTOR_ARGS_FLAG = '--extractor-args';
|
|
7
|
+
const EXTRACTOR_NAME = /^([\w-]+):(.*)$/s;
|
|
8
|
+
const KEY = /^[\w-]+$/;
|
|
9
|
+
function normalizeKey(key) {
|
|
10
|
+
return key.trim().toLowerCase().replace(/-/g, '_');
|
|
11
|
+
}
|
|
12
|
+
/** Parses one `--extractor-args` value (`IE:key=v1,v2;key2=v`) with yt-dlp's rules. */
|
|
13
|
+
export function parseExtractorArgsBlock(value) {
|
|
14
|
+
const match = EXTRACTOR_NAME.exec(value);
|
|
15
|
+
const extractor = match?.[1];
|
|
16
|
+
const body = match?.[2];
|
|
17
|
+
if (extractor === undefined || body === undefined)
|
|
18
|
+
throw new Error(`--extractor-args value must start with an extractor name: ${value}`);
|
|
19
|
+
const values = {};
|
|
20
|
+
for (const part of body.split(';')) {
|
|
21
|
+
const separator = part.indexOf('=');
|
|
22
|
+
const key = normalizeKey(separator === -1 ? part : part.slice(0, separator));
|
|
23
|
+
if (key === '')
|
|
24
|
+
continue;
|
|
25
|
+
const raw = separator === -1 ? '' : part.slice(separator + 1);
|
|
26
|
+
values[key] = raw.split(/(?<!\\),/).map(item => item.replace(/\\,/g, ',').trim());
|
|
27
|
+
}
|
|
28
|
+
return { [extractor.toLowerCase()]: values };
|
|
29
|
+
}
|
|
30
|
+
/** Renders one extractor's arguments as a single `--extractor-args` value. */
|
|
31
|
+
export function renderExtractorArgsBlock(extractor, values) {
|
|
32
|
+
if (!KEY.test(extractor))
|
|
33
|
+
throw new Error(`Invalid extractor name for --extractor-args: ${extractor}`);
|
|
34
|
+
const parts = [];
|
|
35
|
+
for (const [key, list] of Object.entries(values)) {
|
|
36
|
+
if (!KEY.test(key))
|
|
37
|
+
throw new Error(`Invalid --extractor-args key: ${key}`);
|
|
38
|
+
if (list.length === 0)
|
|
39
|
+
continue;
|
|
40
|
+
for (const item of list) {
|
|
41
|
+
// yt-dlp splits keys on ';' with no escape, so such a value cannot be passed at all.
|
|
42
|
+
if (item.includes(';'))
|
|
43
|
+
throw new Error(`--extractor-args value for ${extractor}:${key} cannot contain ';'`);
|
|
44
|
+
}
|
|
45
|
+
parts.push(`${key}=${list.map(item => item.replace(/,/g, '\\,')).join(',')}`);
|
|
46
|
+
}
|
|
47
|
+
return `${extractor.toLowerCase()}:${parts.join(';')}`;
|
|
48
|
+
}
|
|
49
|
+
/** Merges extractor arguments key by key; a later layer's key replaces an earlier one's. */
|
|
50
|
+
export function mergeExtractorArgs(...layers) {
|
|
51
|
+
const merged = {};
|
|
52
|
+
for (const layer of layers) {
|
|
53
|
+
for (const [extractor, values] of Object.entries(layer)) {
|
|
54
|
+
merged[extractor] = { ...merged[extractor], ...values };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return merged;
|
|
58
|
+
}
|
|
59
|
+
function occurrences(argv) {
|
|
60
|
+
const found = [];
|
|
61
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
62
|
+
const arg = argv[index] ?? '';
|
|
63
|
+
const next = argv[index + 1];
|
|
64
|
+
if (arg === EXTRACTOR_ARGS_FLAG && next !== undefined) {
|
|
65
|
+
found.push({ index, width: 2, value: next });
|
|
66
|
+
index += 1;
|
|
67
|
+
}
|
|
68
|
+
else if (arg.startsWith(`${EXTRACTOR_ARGS_FLAG}=`)) {
|
|
69
|
+
found.push({ index, width: 1, value: arg.slice(EXTRACTOR_ARGS_FLAG.length + 1) });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return found;
|
|
73
|
+
}
|
|
74
|
+
// The blocks yt-dlp would accept; one it rejects (no extractor name) carries nothing.
|
|
75
|
+
function acceptedBlocks(argv) {
|
|
76
|
+
return occurrences(argv).flatMap(({ value }) => (EXTRACTOR_NAME.test(value) ? [parseExtractorArgsBlock(value)] : []));
|
|
77
|
+
}
|
|
78
|
+
/** The extractor arguments yt-dlp would act on for this argv: the last block per extractor wins whole. */
|
|
79
|
+
export function effectiveExtractorArgs(argv) {
|
|
80
|
+
const effective = {};
|
|
81
|
+
for (const block of acceptedBlocks(argv))
|
|
82
|
+
Object.assign(effective, block);
|
|
83
|
+
return effective;
|
|
84
|
+
}
|
|
85
|
+
/** Extractors that this argv names in more than one block, where all but the last are silently lost. */
|
|
86
|
+
export function duplicateExtractorArgsBlocks(argv) {
|
|
87
|
+
const seen = new Set();
|
|
88
|
+
const duplicates = new Set();
|
|
89
|
+
for (const block of acceptedBlocks(argv)) {
|
|
90
|
+
for (const extractor of Object.keys(block)) {
|
|
91
|
+
if (seen.has(extractor))
|
|
92
|
+
duplicates.add(extractor);
|
|
93
|
+
seen.add(extractor);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return [...duplicates];
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Folds every extractor-args block in `argv`, then `overrides`, into one block
|
|
100
|
+
* per extractor, merged key by key, so everything a caller meant to pass
|
|
101
|
+
* reaches yt-dlp. The blocks take the place of the first one in the argv, or
|
|
102
|
+
* lead it when it had none.
|
|
103
|
+
*/
|
|
104
|
+
export function withExtractorArgs(argv, overrides) {
|
|
105
|
+
const found = occurrences(argv);
|
|
106
|
+
if (found.length === 0 && Object.keys(overrides).length === 0)
|
|
107
|
+
return [...argv];
|
|
108
|
+
const merged = mergeExtractorArgs(...found.map(({ value }) => parseExtractorArgsBlock(value)), overrides);
|
|
109
|
+
const rendered = Object.entries(merged).flatMap(([extractor, values]) => [EXTRACTOR_ARGS_FLAG, renderExtractorArgsBlock(extractor, values)]);
|
|
110
|
+
const skipped = new Set(found.flatMap(({ index, width }) => (width === 2 ? [index, index + 1] : [index])));
|
|
111
|
+
const rest = argv.filter((_, index) => !skipped.has(index));
|
|
112
|
+
const at = found[0]?.index ?? 0;
|
|
113
|
+
return [...rest.slice(0, at), ...rendered, ...rest.slice(at)];
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=extractorArgs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractorArgs.js","sourceRoot":"","sources":["../src/extractorArgs.ts"],"names":[],"mappings":"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"}
|
package/dist/fields.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,CAAC,CAAC,IAAI;KAAE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC;CAAC,CAAA;AAInE,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAO5F"}
|
package/dist/fields.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Drops undefined values so optional fields are absent rather than present-
|
|
2
|
+
// but-undefined (exactOptionalPropertyTypes).
|
|
3
|
+
export function definedFields(fields) {
|
|
4
|
+
const result = {};
|
|
5
|
+
for (const key of Object.keys(fields)) {
|
|
6
|
+
const value = fields[key];
|
|
7
|
+
if (value !== undefined)
|
|
8
|
+
result[key] = value;
|
|
9
|
+
}
|
|
10
|
+
return result;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,8CAA8C;AAC9C,MAAM,UAAU,aAAa,CAAoC,MAAS;IACzE,MAAM,MAAM,GAAqB,EAAE,CAAA;IACnC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAgB,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;QACzB,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAuC,CAAA;IAC/E,CAAC;IACD,OAAO,MAAM,CAAA;AACd,CAAC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA"}
|