veodl 1.9.0 → 1.10.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/CHANGELOG.md +28 -0
- package/README.md +57 -37
- package/docs/AGENT_GUIDE.md +8 -5
- package/package.json +1 -1
- package/src/backend.js +64 -36
- package/src/cli.js +120 -56
- package/src/config-diagnostics.js +19 -9
- package/src/config-editor.js +181 -66
- package/src/config-template.js +63 -73
- package/src/config.js +110 -27
- package/src/downloader.js +28 -21
- package/src/interactive.js +19 -19
- package/src/jobs.js +13 -4
- package/src/option-suggestions.js +43 -0
- package/src/progress.js +68 -12
- package/src/runs.js +8 -5
- package/src/source-discovery.js +82 -30
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to veo. This project follows [Semantic Versioning](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## 1.10.0
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Persistent Profile Management**: Added `veo profile [NAME|list|reset]` commands to view the active configuration profile, inspect available profiles, switch defaults, or reset back to default without manual configuration edits.
|
|
10
|
+
- **On-demand Config Guide**: Added `veo config guide` to display full configuration guidance, supported options, and templates in the terminal without opening the interactive editor.
|
|
11
|
+
- **Interactive Config Editor enhancements**:
|
|
12
|
+
- Full Undo (`Ctrl+Z`) and Redo (`Ctrl+Y`) history support when modifying settings.
|
|
13
|
+
- Select All (`Ctrl+A`) shortcut to easily highlight and overwrite lines or entire sections.
|
|
14
|
+
- Interactive F3 guide management prompt (`A` to add/refresh, `R` to strip documentation lines).
|
|
15
|
+
- Mouse edge drag auto-scrolling when dragging selections past viewport bounds.
|
|
16
|
+
- **Automatic Browser Source Discovery**: Enabled automatic source discovery fallback by default when direct extraction fails, automatically selecting and proceeding if a single verified media stream is found.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Streamlined source discovery observation polling to immediately proceed once candidate streams are detected.
|
|
21
|
+
- Enhanced progress output styling and ANSI handling across terminal status reporting.
|
|
22
|
+
|
|
23
|
+
## 1.9.1
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- Added typo and spelling suggestions for misspelled CLI options and subcommands (e.g. `--deepscan` suggests `--deep-scan`, `veo histroy` suggests `veo history`).
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Improved browser-based player source discovery to continuously detect delayed play controls and overlays inside frames.
|
|
32
|
+
|
|
5
33
|
## 1.9.0
|
|
6
34
|
|
|
7
35
|
### Added
|
package/README.md
CHANGED
|
@@ -193,9 +193,11 @@ example through `veo config edit`. Enable it with `veo URL --profile kompatibel`
|
|
|
193
193
|
reserved by concurrent downloads in the same process. Unknown sizes are reported as
|
|
194
194
|
unknown; conversion sizes and other processes' disk usage cannot be predicted exactly.
|
|
195
195
|
Use `--no-check-space` to disable this conservative check.
|
|
196
|
-
- `--timings` shows
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
- `--timings` shows phase times at the end of the run. Single downloads show
|
|
197
|
+
timing without a summary; multiple downloads show timing below the summary.
|
|
198
|
+
The phases cover setup, metadata, download/backend, processing, saving and retry waits.
|
|
199
|
+
Download/backend includes the backend's own startup and extraction overhead;
|
|
200
|
+
these are summed per-download times, not a diagnosis of network speed.
|
|
199
201
|
JSON results include `timings` in milliseconds, or `entryTimings` for playlists.
|
|
200
202
|
Use `--no-timings` to hide/omit them.
|
|
201
203
|
- Terminal details are gray, titles bold, saves green and errors red. The same styling
|
|
@@ -230,7 +232,7 @@ veo config show --profile fast
|
|
|
230
232
|
Config checks validate every effective profile (or the selected one), including unknown
|
|
231
233
|
settings, ranges and conflicting options. Show prints merged built-in, global and profile
|
|
232
234
|
settings as JSON, with credential paths/browser profiles redacted. Neither command contacts
|
|
233
|
-
video sites. All new options are also documented
|
|
235
|
+
video sites. All new options are also documented in `veo config guide`.
|
|
234
236
|
|
|
235
237
|
### Files, names and resume
|
|
236
238
|
|
|
@@ -307,9 +309,10 @@ download fails because a login is required, the error message points at these fl
|
|
|
307
309
|
|
|
308
310
|
### Inspection and scripting
|
|
309
311
|
|
|
310
|
-
- `veo <page-url> --list-sources` opens the page in a temporary headless Chrome,
|
|
311
|
-
Edge or Chromium profile,
|
|
312
|
-
|
|
312
|
+
- `veo <page-url> --list-sources` opens the page in a temporary headless Chrome,
|
|
313
|
+
Edge or Chromium profile, repeatedly checks for visible Play controls (including
|
|
314
|
+
controls added later or inside frames), and watches media requests after interaction.
|
|
315
|
+
Use `--json` for numbered source
|
|
313
316
|
metadata. Each result includes its title, host, HLS/DASH/direct type, known
|
|
314
317
|
resolutions, estimated MiB size and Mbit/s bitrate when the source provides them. Signed media
|
|
315
318
|
URLs are not printed. Set `VEO_BROWSER_PATH` if the browser is not found.
|
|
@@ -321,14 +324,17 @@ download fails because a login is required, the error message points at these fl
|
|
|
321
324
|
is reached, verified sources found so far are shown with a timeout notice.
|
|
322
325
|
A deep scan covers observed requests; it cannot discover sources that the
|
|
323
326
|
page never loads. The timeout does not stop a subsequent download.
|
|
324
|
-
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
- For an unsupported single page URL, veo searches for media automatically and
|
|
328
|
+
uses the only verified source when there is one. If several sources are found,
|
|
329
|
+
the terminal asks which one to use; scripts receive a numbered source list and
|
|
330
|
+
a nonzero exit. `veo <page-url> --source 2 --dry-run --json` previews a chosen
|
|
331
|
+
source, and `veo <page-url> --source 2 --json` downloads it. Scripts never
|
|
332
|
+
receive an interactive prompt.
|
|
329
333
|
Retry jobs retain the page URL and selected number and discover a fresh media
|
|
330
334
|
URL, because player links may expire. Browser discovery uses a temporary
|
|
331
|
-
profile without copying browser cookies, and cannot unlock DRM content.
|
|
335
|
+
profile without copying browser cookies, and cannot unlock DRM content.
|
|
336
|
+
Misspelled flags and commands show a nearby valid spelling, for example
|
|
337
|
+
`--deepscan` suggests `--deep-scan`.
|
|
332
338
|
- `--list-formats` prints the backend's own format table for one URL and exits.
|
|
333
339
|
- `--dry-run` prints the title, the resolved quality and the destination path that would be
|
|
334
340
|
used — without creating the output directory or downloading anything.
|
|
@@ -388,10 +394,11 @@ silently ignoring a typo would be worse.
|
|
|
388
394
|
Source discovery defaults are `deepScan` (boolean), `timeout` (string such as
|
|
389
395
|
`"30s"` or `"2m"`), `listSources` (boolean) and `autoListSources` (boolean).
|
|
390
396
|
`listSources: true` makes a single URL list sources and exit; use
|
|
391
|
-
`--no-list-sources` to download for one invocation. `autoListSources
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
397
|
+
`--no-list-sources` to download for one invocation. `autoListSources` defaults
|
|
398
|
+
to `true` and searches when ordinary extraction finds no downloadable video.
|
|
399
|
+
Set it to `false` or pass `--no-auto-list-sources` to disable that fallback.
|
|
400
|
+
A single verified source is selected automatically; multiple sources require
|
|
401
|
+
a choice. `deepScan` and
|
|
395
402
|
`timeout` apply to either kind of source search.
|
|
396
403
|
|
|
397
404
|
Additional defaults are `skipExisting` and `playlistItems`. Boolean defaults can be disabled
|
|
@@ -400,11 +407,16 @@ disables stored subtitle languages and subtitle embedding for that invocation.
|
|
|
400
407
|
|
|
401
408
|
### Named profiles
|
|
402
409
|
|
|
403
|
-
If no profile is selected, `profiles.default` is applied automatically.
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
`veo
|
|
407
|
-
|
|
410
|
+
If no profile is selected, `profiles.default` is applied automatically. `veo profile music`
|
|
411
|
+
selects another named profile for future commands and stores it as `activeProfile` in the
|
|
412
|
+
config; `veo profile` shows the current choice, and `veo profile list` marks it in
|
|
413
|
+
the list. `veo profile reset` removes the stored choice and returns to `default`.
|
|
414
|
+
You can also use `veo profile default` to select it explicitly.
|
|
415
|
+
The names `list` and `reset` are reserved for these commands and cannot be used as profile names.
|
|
416
|
+
`--profile NAME` overrides this choice for one command. Named profiles use global defaults
|
|
417
|
+
rather than inheriting `default`. The wizard preselects the active profile.
|
|
418
|
+
New configurations include an empty `default` profile and the example profiles. Existing configurations are
|
|
419
|
+
left unchanged when opened. An empty profile does not change download behavior.
|
|
408
420
|
|
|
409
421
|
```json
|
|
410
422
|
{
|
|
@@ -417,13 +429,15 @@ preserving existing settings. An empty profile does not change download behavior
|
|
|
417
429
|
}
|
|
418
430
|
```
|
|
419
431
|
|
|
420
|
-
`veo <url> --profile music` merges global defaults, then the selected profile, then explicit
|
|
421
|
-
CLI flags. `veo config profiles` lists profile names; `veo config path` prints the file path.
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
432
|
+
`veo <url> --profile music` merges global defaults, then the selected profile, then explicit
|
|
433
|
+
CLI flags. `veo config profiles` lists profile names; `veo config path` prints the file path.
|
|
434
|
+
The download status shows `Profile: NAME` (or `global (no profile)` when none is configured).
|
|
435
|
+
`veo config edit` creates a small, valid configuration for new or empty files. Opening an
|
|
436
|
+
existing configuration does not add or update comments. The current option guide is kept in
|
|
437
|
+
the program; `veo config guide` prints it without changing the file. In the built-in editor,
|
|
438
|
+
F3 offers **A** to add or update the guide at the top and **R** to remove a previously
|
|
439
|
+
generated guide. Ctrl+S saves that choice. This can also clean up the long duplicate block
|
|
440
|
+
inserted by older versions. Personal settings and notes below a generated block are preserved.
|
|
427
441
|
In an interactive terminal, it opens the built-in editor
|
|
428
442
|
unless `VISUAL` or `EDITOR` is configured (an executable path, without shell arguments).
|
|
429
443
|
The editor provides syntax colors, line numbers and live validation. Syntax errors mark
|
|
@@ -432,11 +446,13 @@ spelling suggestions, expected types and allowed values in the status area. Vali
|
|
|
432
446
|
the same rules as the CLI, including profile overrides and audio/video formats.
|
|
433
447
|
Press F2 on a property or value to open suggestions, use Up/Down to choose, Enter to apply
|
|
434
448
|
or Esc to cancel. Suggestions require valid JSON syntax; free-text values and custom numeric
|
|
435
|
-
resolutions such as `900p` remain supported. Ctrl+S validates and saves;
|
|
436
|
-
|
|
449
|
+
resolutions such as `900p` remain supported. Ctrl+S validates and saves;
|
|
450
|
+
Ctrl+Z undoes edits, Ctrl+Y redoes them, and Ctrl+A selects the whole file.
|
|
451
|
+
Esc or Ctrl+Q exits, asking before discarding changes. Use arrows, Home/End and PageUp/PageDown
|
|
437
452
|
to navigate. Invalid configurations cannot be saved. `--no-color` disables syntax colors.
|
|
438
453
|
In terminals supporting SGR mouse reporting, left-click positions the cursor and dragging
|
|
439
|
-
selects text, including across lines.
|
|
454
|
+
selects text, including across lines. Holding the pointer at the top or bottom while dragging
|
|
455
|
+
scrolls the file and extends the selection. Backspace/Delete removes the selection; typing replaces
|
|
440
456
|
it. The mouse wheel scrolls without changing the editing position; Ctrl+Up/Down also scrolls.
|
|
441
457
|
Ctrl+C copies selected text to the system clipboard, and Ctrl+V pastes clipboard text at the
|
|
442
458
|
cursor or replaces the selection. Ctrl+Q or Esc exits the editor. The editor disables mouse
|
|
@@ -461,9 +477,8 @@ $env:VEO_CONFIG_EDITOR = 'external'
|
|
|
461
477
|
|
|
462
478
|
Non-interactive sessions use the external editor unless `--terminal` is explicitly selected,
|
|
463
479
|
in which case an interactive-terminal error is reported. The wizard also offers configured profiles.
|
|
464
|
-
Generated
|
|
465
|
-
|
|
466
|
-
paths and custom comments are preserved.
|
|
480
|
+
Generated guides and app messages are in English. Existing comments, profile names and
|
|
481
|
+
settings are preserved when opening the editor.
|
|
467
482
|
|
|
468
483
|
### Terminal output
|
|
469
484
|
|
|
@@ -499,9 +514,14 @@ paths and custom comments are preserved.
|
|
|
499
514
|
```bash
|
|
500
515
|
veo version # installed version (also: veo --version or veo -v)
|
|
501
516
|
veo # interactive download wizard (terminal only)
|
|
502
|
-
veo config edit # create/open config
|
|
517
|
+
veo config edit # create/open config; F3 offers the optional guide
|
|
518
|
+
veo config guide # print the current option guide
|
|
503
519
|
veo config reset # confirm with y; back up config and restore the current template
|
|
504
|
-
veo config profiles # list available profiles
|
|
520
|
+
veo config profiles # list available profiles
|
|
521
|
+
veo profile # show the currently selected profile
|
|
522
|
+
veo profile list # list all profiles and mark the active one
|
|
523
|
+
veo profile music # use music as the default for future commands
|
|
524
|
+
veo profile reset # return to default (or global settings if absent)
|
|
505
525
|
veo config path # show the config file location
|
|
506
526
|
veo doctor # diagnose the local setup; exit 1 if a check fails
|
|
507
527
|
veo doctor fix # restore missing or damaged managed tools
|
package/docs/AGENT_GUIDE.md
CHANGED
|
@@ -10,11 +10,14 @@ veo "https://example.com/video" --json --output ./downloads
|
|
|
10
10
|
veo inspect "./downloads/video.mp4" --check-audio --json
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
For a page with an embedded player that the normal extractor cannot identify,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
For a page with an embedded player that the normal extractor cannot identify,
|
|
14
|
+
`veo "<page-url>" --dry-run --json` searches for playable media automatically.
|
|
15
|
+
It uses a single verified source without a second command. If several sources
|
|
16
|
+
are found, run `veo "<page-url>" --list-sources --json` and choose an `index`,
|
|
17
|
+
then use `veo "<page-url>" --source <index> --dry-run --json` before downloading.
|
|
18
|
+
Source discovery opens a temporary headless Chromium-based
|
|
19
|
+
browser, repeatedly checks for Play controls, and observes media requests after
|
|
20
|
+
interaction. It needs Chrome, Edge or Chromium,
|
|
18
21
|
or `VEO_BROWSER_PATH`. A found source is verified by the backend; size may be
|
|
19
22
|
unknown, and DRM-protected media is excluded. Source numbers are tied to the
|
|
20
23
|
page's current discovery run and may change later.
|
package/package.json
CHANGED
package/src/backend.js
CHANGED
|
@@ -291,11 +291,19 @@ async function downloadBackend({ asset, release, expected, directory, signal, st
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
async function acquire(asset, directory, signal, status) {
|
|
294
|
+
async function acquire(asset, directory, signal, status, statusDone = () => {}) {
|
|
295
295
|
const destination = path.join(directory, `yt-dlp${exeSuffix()}`);
|
|
296
296
|
const expected = HASHES[asset];
|
|
297
297
|
status('Checking yt-dlp…');
|
|
298
|
-
|
|
298
|
+
let cached;
|
|
299
|
+
try {
|
|
300
|
+
cached = await matches(destination, expected, signal);
|
|
301
|
+
statusDone('Checking yt-dlp…', 'done');
|
|
302
|
+
} catch (error) {
|
|
303
|
+
if (!signal?.aborted && error?.name !== 'AbortError') statusDone('Checking yt-dlp…', 'failed');
|
|
304
|
+
throw error;
|
|
305
|
+
}
|
|
306
|
+
if (cached) {
|
|
299
307
|
if (process.platform !== 'win32') await chmod(destination, 0o755);
|
|
300
308
|
return destination;
|
|
301
309
|
}
|
|
@@ -330,7 +338,6 @@ async function managedMediaTools({ signal, status, directory }) {
|
|
|
330
338
|
} catch (cause) {
|
|
331
339
|
return `the bundled static media tools are unusable (${cause.message})`;
|
|
332
340
|
}
|
|
333
|
-
status('Preparing ffmpeg and ffprobe…');
|
|
334
341
|
const suffix = exeSuffix();
|
|
335
342
|
await stage(ffmpeg, path.join(directory, `ffmpeg${suffix}`), signal);
|
|
336
343
|
await stage(ffprobe, path.join(directory, `ffprobe${suffix}`), signal);
|
|
@@ -343,38 +350,58 @@ async function managedMediaTools({ signal, status, directory }) {
|
|
|
343
350
|
* then a system installation (which is what Windows on ARM needs, because
|
|
344
351
|
* ffmpeg-static and ffprobe-static ship no arm64 Windows binaries).
|
|
345
352
|
*/
|
|
346
|
-
export async function resolveMediaTools({ signal, status = () => {}, directory, offline = false,
|
|
353
|
+
export async function resolveMediaTools({ signal, status = () => {}, statusDone = () => {}, directory, offline = false,
|
|
347
354
|
find = findOnPath, managed = managedMediaTools, install = installMediaTools } = {}) {
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
355
|
+
const preparing = 'Preparing ffmpeg and ffprobe…';
|
|
356
|
+
let currentStatus;
|
|
357
|
+
const report = message => { currentStatus = message; status(message); };
|
|
358
|
+
const finish = outcome => {
|
|
359
|
+
if (currentStatus !== preparing) report(preparing);
|
|
360
|
+
statusDone(preparing, outcome);
|
|
361
|
+
};
|
|
362
|
+
report(preparing);
|
|
363
|
+
try {
|
|
364
|
+
const suffix = exeSuffix();
|
|
365
|
+
const override = envPath('VEO_FFMPEG_PATH');
|
|
366
|
+
if (override) {
|
|
367
|
+
await executable(path.join(override, `ffmpeg${suffix}`), 'VEO_FFMPEG_PATH ffmpeg');
|
|
368
|
+
await executable(path.join(override, `ffprobe${suffix}`), 'VEO_FFMPEG_PATH ffprobe');
|
|
369
|
+
finish('done');
|
|
370
|
+
report('Using VEO_FFMPEG_PATH override.');
|
|
371
|
+
return override;
|
|
372
|
+
}
|
|
373
|
+
const problem = await managed({ signal, status: report, directory });
|
|
374
|
+
if (!problem) { finish('done'); return directory; }
|
|
375
|
+
// A previous run may already have staged a working pair into the cache.
|
|
376
|
+
if (await isExecutable(path.join(directory, `ffmpeg${suffix}`))
|
|
377
|
+
&& await isExecutable(path.join(directory, `ffprobe${suffix}`))) { finish('done'); return directory; }
|
|
378
|
+
const ffmpeg = await find(['ffmpeg']);
|
|
379
|
+
const ffprobe = await find(['ffprobe']);
|
|
380
|
+
if (!ffmpeg || !ffprobe) {
|
|
381
|
+
if (!offline) {
|
|
382
|
+
const location = await install({ signal, status: report, directory, find, stage });
|
|
383
|
+
finish('done');
|
|
384
|
+
return location;
|
|
385
|
+
}
|
|
386
|
+
const missing = [!ffmpeg && 'ffmpeg', !ffprobe && 'ffprobe'].filter(Boolean).join(' and ');
|
|
387
|
+
throw new Error(`Cannot load media tools: ${problem}, and no ${missing} was found on PATH. `
|
|
388
|
+
+ 'Run veo doctor fix without --offline to install them automatically, or set VEO_FFMPEG_PATH to a directory containing both binaries.');
|
|
389
|
+
}
|
|
390
|
+
// Same directory: yt-dlp can use it in place instead of duplicating ~150 MB.
|
|
391
|
+
if (path.dirname(ffmpeg) === path.dirname(ffprobe)) {
|
|
392
|
+
finish('done');
|
|
393
|
+
report(`Using the system ffmpeg in ${path.dirname(ffmpeg)}.`);
|
|
394
|
+
return path.dirname(ffmpeg);
|
|
395
|
+
}
|
|
396
|
+
report('Copying system ffmpeg and ffprobe into the backend cache…');
|
|
397
|
+
await stage(ffmpeg, path.join(directory, `ffmpeg${suffix}`), signal);
|
|
398
|
+
await stage(ffprobe, path.join(directory, `ffprobe${suffix}`), signal);
|
|
399
|
+
finish('done');
|
|
400
|
+
return directory;
|
|
401
|
+
} catch (error) {
|
|
402
|
+
if (!signal?.aborted && error?.name !== 'AbortError') finish('failed');
|
|
403
|
+
throw error;
|
|
373
404
|
}
|
|
374
|
-
status('Copying system ffmpeg and ffprobe into the backend cache…');
|
|
375
|
-
await stage(ffmpeg, path.join(directory, `ffmpeg${suffix}`), signal);
|
|
376
|
-
await stage(ffprobe, path.join(directory, `ffprobe${suffix}`), signal);
|
|
377
|
-
return directory;
|
|
378
405
|
}
|
|
379
406
|
|
|
380
407
|
/**
|
|
@@ -457,12 +484,13 @@ export async function inspectBackend({ signal, platform = process.platform, arch
|
|
|
457
484
|
* cannot serve the current platform (notably Windows on ARM).
|
|
458
485
|
* onStatus receives plain strings. Throws on cancellation or acquisition failure.
|
|
459
486
|
*/
|
|
460
|
-
export async function resolveBackend({ signal, onStatus, offline = false, platform = process.platform, find = findOnPath,
|
|
487
|
+
export async function resolveBackend({ signal, onStatus, onStatusDone, offline = false, platform = process.platform, find = findOnPath,
|
|
461
488
|
setupTermux = installTermuxTools, hasEjs = hasTermuxEjs, run = runSetup } = {}) {
|
|
462
489
|
if (signal !== undefined && !(signal instanceof AbortSignal)) throw new TypeError('signal must be an AbortSignal.');
|
|
463
490
|
if (onStatus !== undefined && typeof onStatus !== 'function') throw new TypeError('onStatus must be a function.');
|
|
464
491
|
signal?.throwIfAborted();
|
|
465
492
|
const status = onStatus || (() => {});
|
|
493
|
+
const statusDone = onStatusDone || (() => {});
|
|
466
494
|
const ytOverride = envPath('VEO_YT_DLP_PATH');
|
|
467
495
|
if (platform === 'android') {
|
|
468
496
|
const mediaOverride = envPath('VEO_FFMPEG_PATH');
|
|
@@ -508,13 +536,13 @@ export async function resolveBackend({ signal, onStatus, offline = false, platfo
|
|
|
508
536
|
const installed = ytDlp ? null : await activeOverride(asset, { signal });
|
|
509
537
|
const directory = cacheDirectory();
|
|
510
538
|
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
511
|
-
const ffmpegLocation = await resolveMediaTools({ signal, status, directory, offline });
|
|
539
|
+
const ffmpegLocation = await resolveMediaTools({ signal, status, statusDone, directory, offline });
|
|
512
540
|
if (ytDlp) status('Using VEO_YT_DLP_PATH override.');
|
|
513
541
|
else if (installed) status(`Using the installed yt-dlp ${installed.release}.`);
|
|
514
542
|
if (offline && !ytDlp && !installed && !await matches(path.join(directory, `yt-dlp${exeSuffix()}`), HASHES[asset], signal)) {
|
|
515
543
|
throw new Error('yt-dlp is missing or damaged. Run veo doctor fix without --offline to download it.');
|
|
516
544
|
}
|
|
517
|
-
const backend = ytDlp || installed?.path || await acquire(asset, directory, signal, status);
|
|
545
|
+
const backend = ytDlp || installed?.path || await acquire(asset, directory, signal, status, statusDone);
|
|
518
546
|
signal?.throwIfAborted();
|
|
519
547
|
return { ytDlp: backend, ffmpegLocation };
|
|
520
548
|
}
|