batchedits 1.5.0 → 1.7.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 +21 -3
- package/dist/cli.js +92 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,14 +19,15 @@ Needs Node.js 18.17+ and a [BatchEdits](https://batchedits.com) account (7-day f
|
|
|
19
19
|
| `login` / `logout` / `whoami` | Sign in through your browser; check the connection |
|
|
20
20
|
| `styles` | List your styles |
|
|
21
21
|
| `actions` | List editing actions and their settings |
|
|
22
|
-
| `style create <name> [--captions] [--emojis] [--silence] [--repeats] [--crop 9:16] [--zoom] [--clips [n]] [--hook] [--hook-clip <id or words>] [--broll] [--cta [text]] [--set action.setting=value…]` | Create a style from flags |
|
|
22
|
+
| `style create <name> [--captions] [--emojis] [--silence] [--repeats] [--fillers] [--crop 9:16] [--zoom] [--clips [n]] [--hook] [--hook-clip <id or words>] [--broll] [--cta [text]] [--sfx] [--set action.setting=value…]` | Create a style from flags |
|
|
23
23
|
| `hooks [words]` | Find intro clips for a video hook |
|
|
24
24
|
| `style edit <name> [same flags] [--set …] [--remove <action>…] [--name <new>]` | Change a saved style's edits and settings |
|
|
25
|
-
| `
|
|
25
|
+
| `style copy <link\|file\|video id> [--name <name>]` | Create a style copying a reference video's captions, zooms and crop |
|
|
26
|
+
| `upload <files, folders or links…>` | Upload up to 50 videos (YouTube or video-file links are downloaded by BatchEdits), print their ids |
|
|
26
27
|
| `process <ids…> --style <name> [--yes]` | Edit videos (1 credit each, 1 per AI clip) |
|
|
27
28
|
| `status [ids…] [--watch]` | Show status, or wait until done |
|
|
28
29
|
| `download <ids…> [--out dir]` | Save finished videos (and their AI clips) |
|
|
29
|
-
| `run <files or
|
|
30
|
+
| `run <files, folders or links…> --style <name> [--out dir] [--hooks file] [--ctas file] [--yes]` | All of the above in one go |
|
|
30
31
|
|
|
31
32
|
Every command has `--help` with an example, and `--json` for machine-readable output.
|
|
32
33
|
|
|
@@ -57,6 +58,12 @@ batchedits run ./raw --style "Hooks" --hooks hooks.txt --out ./edited --yes
|
|
|
57
58
|
batchedits style create "Talking head" --silence --broll --captions
|
|
58
59
|
```
|
|
59
60
|
|
|
61
|
+
`--sfx` adds sound effects to the other edits' moments: a whoosh as B-roll cuts in and on each zoom, a pop for each caption emoji, a riser into the text hook and a ding on the call to action. They sit under your voice; change it with `--set sfx.volume=low|medium|high`, or `--set sfx.zoom=impact` for a hit instead of a whoosh on zooms.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
batchedits style create "Punchy" --silence --broll --captions --emojis --zoom --sfx
|
|
65
|
+
```
|
|
66
|
+
|
|
60
67
|
`--cta` adds a call to action over the last 3 seconds of every video ("Follow for more" unless you give your own line). For a different line per video, pass a file with `--ctas`, one per line in upload order. An outro clip played after each video is uploaded once in the dashboard's Call to action settings:
|
|
61
68
|
|
|
62
69
|
```bash
|
|
@@ -106,3 +113,14 @@ openModal({ videoUrl: "https://example.com/video.mp4", mode: "popup", onComplete
|
|
|
106
113
|
```
|
|
107
114
|
|
|
108
115
|
MIT licensed.
|
|
116
|
+
|
|
117
|
+
## Copy a style, or edit videos from links
|
|
118
|
+
|
|
119
|
+
`style copy` reads a reference video (a TikTok, Reel, Short or YouTube link, a direct video link, a local file or one of your video ids) and saves its look as a style: caption font, colours, word-by-word or letter-by-letter highlight, position, zooms and crop. Only the first 90 seconds are read; colours and font are a close match.
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
batchedits style copy https://www.tiktok.com/@creator/video/123 --name "Like this"
|
|
123
|
+
batchedits run https://youtu.be/dQw4w9WgXcQ ./raw --style "Like this" --out ./edited --yes
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`upload` and `run` take links next to files and folders: YouTube links, or public links to a video file (direct .mp4, Dropbox, Google Drive). BatchEdits downloads them, which can take a minute for long YouTube videos.
|
package/dist/cli.js
CHANGED
|
@@ -298,6 +298,17 @@ var BatchEdits = class {
|
|
|
298
298
|
}
|
|
299
299
|
return body.videos[0];
|
|
300
300
|
}
|
|
301
|
+
/** Uploads a video from a link (YouTube, or a public link to a video file); BatchEdits downloads it. */
|
|
302
|
+
async uploadLink(url) {
|
|
303
|
+
const res = await this.call("upload_videos", { video_url: url });
|
|
304
|
+
const video = res.videos?.[0];
|
|
305
|
+
if (!video) throw new CliError("The server didn't upload the link.", EXIT.ERROR, "It may not support links yet. Download the video and upload the file instead.");
|
|
306
|
+
return video;
|
|
307
|
+
}
|
|
308
|
+
/** Saves a new style copying a reference video's look; returns its id, name and what was copied. */
|
|
309
|
+
async copyStyle(ref, name) {
|
|
310
|
+
return this.call("copy_style", { ...ref, ...name ? { name } : {} });
|
|
311
|
+
}
|
|
301
312
|
/** Streams a download link to `dir`, never overwriting an existing file. */
|
|
302
313
|
async download(url, name, dir) {
|
|
303
314
|
import_node_fs2.default.mkdirSync(dir, { recursive: true });
|
|
@@ -340,6 +351,22 @@ function expandFiles(inputs) {
|
|
|
340
351
|
if (files.length > MAX_BATCH) throw new CliError(`${files.length} files: upload up to ${MAX_BATCH} at a time.`, EXIT.USAGE, "Split the folder and run once per part.");
|
|
341
352
|
return files;
|
|
342
353
|
}
|
|
354
|
+
var isLink = (input) => /^https?:\/\//i.test(input);
|
|
355
|
+
function expandInputs(inputs) {
|
|
356
|
+
const result = [];
|
|
357
|
+
for (const input of inputs) {
|
|
358
|
+
if (isLink(input)) result.push({ kind: "link", url: input });
|
|
359
|
+
else result.push(...expandFiles([input]).map((p) => ({ kind: "file", path: p })));
|
|
360
|
+
}
|
|
361
|
+
if (result.length === 0) throw new CliError("Give files, folders or video links.", EXIT.USAGE, "Example: batchedits upload ./raw https://youtu.be/\u2026");
|
|
362
|
+
if (result.length > MAX_BATCH) throw new CliError(`${result.length} videos: upload up to ${MAX_BATCH} at a time.`, EXIT.USAGE, "Split them and run once per part.");
|
|
363
|
+
return result;
|
|
364
|
+
}
|
|
365
|
+
var inputLabel = (input) => input.kind === "link" ? input.url : import_node_path3.default.basename(input.path);
|
|
366
|
+
async function uploadInput(api, input, i, total) {
|
|
367
|
+
info(`${input.kind === "link" ? "Importing" : "Uploading"} ${i + 1}/${total}: ${inputLabel(input)}${input.kind === "link" ? " (links can take a minute)" : ""}`);
|
|
368
|
+
return input.kind === "link" ? api.uploadLink(input.url) : api.upload(input.path);
|
|
369
|
+
}
|
|
343
370
|
async function resolveStyle(api, ref) {
|
|
344
371
|
if (typeof ref !== "string" || !ref) throw new CliError("--style is required.", EXIT.USAGE, "List them with: batchedits styles");
|
|
345
372
|
const styles = await api.styles();
|
|
@@ -355,7 +382,7 @@ async function confirm(flags, question) {
|
|
|
355
382
|
rl.close();
|
|
356
383
|
if (answer !== "y" && answer !== "yes") throw new CliError("Cancelled. Nothing was processed.", EXIT.ERROR);
|
|
357
384
|
}
|
|
358
|
-
var ACTION_ORDER = ["crop_video", "remove_silence", "remove_repeated_sentences", "broll", "add_captions", "punch_zoom", "ai_clips", "hook", "cta"];
|
|
385
|
+
var ACTION_ORDER = ["crop_video", "remove_silence", "remove_repeated_sentences", "broll", "add_captions", "punch_zoom", "ai_clips", "hook", "cta", "sound_effects"];
|
|
359
386
|
var ACTION_ALIASES = {
|
|
360
387
|
crop: "crop_video",
|
|
361
388
|
silence: "remove_silence",
|
|
@@ -365,15 +392,17 @@ var ACTION_ALIASES = {
|
|
|
365
392
|
clips: "ai_clips",
|
|
366
393
|
hook: "hook",
|
|
367
394
|
cta: "cta",
|
|
368
|
-
broll: "broll"
|
|
395
|
+
broll: "broll",
|
|
396
|
+
sfx: "sound_effects"
|
|
369
397
|
};
|
|
370
398
|
var SET_HELP = [
|
|
371
399
|
" --set <action.setting=value> Any setting from `batchedits actions` (repeatable). Adds the edit if missing.",
|
|
372
400
|
" captions.position=top|center|bottom captions.fontColor=#FFFFFF captions.highlightColor=#FF6B00",
|
|
373
|
-
" captions.fontSize=64 silence.silentThreshold=0.06 zoom.zoomPercent=125 clips.maxSeconds=60",
|
|
401
|
+
" captions.fontSize=64 silence.silentThreshold=0.06 silence.fillerWords=true zoom.zoomPercent=125 clips.maxSeconds=60",
|
|
374
402
|
" hook.position=top|center|bottom hook.y=0.3 hook.duration=auto|3 hook.source=ai|manual hook.animation=fade|pop|none hook.backgroundColor=#FF6B00",
|
|
375
403
|
' cta.text="Link in bio" cta.duration=auto|5 cta.position=center|top|bottom cta.animation=pop|fade|none',
|
|
376
|
-
" broll.seconds=auto|3 broll.source=mine_first|mine|stock"
|
|
404
|
+
" broll.seconds=auto|3 broll.source=mine_first|mine|stock",
|
|
405
|
+
" sfx.volume=low|medium|high sfx.zoom=whoosh|impact|off sfx.emojis=false sfx.hook=false sfx.cta=false sfx.broll=false"
|
|
377
406
|
].join("\n");
|
|
378
407
|
var actionName = (raw) => ACTION_ALIASES[raw.trim().toLowerCase()] ?? raw.trim().toLowerCase();
|
|
379
408
|
var list = (v) => Array.isArray(v) ? v : typeof v === "string" ? [v] : [];
|
|
@@ -386,7 +415,7 @@ function upsert(actions, name, params) {
|
|
|
386
415
|
function applyFlagActions(actions, flags) {
|
|
387
416
|
let out = actions;
|
|
388
417
|
if (typeof flags.crop === "string") out = upsert(out, "crop_video", { aspectRatio: flags.crop });
|
|
389
|
-
if (flags.silence) out = upsert(out, "remove_silence");
|
|
418
|
+
if (flags.silence || flags.fillers) out = upsert(out, "remove_silence", flags.fillers ? { fillerWords: true } : void 0);
|
|
390
419
|
if (flags.repeats) out = upsert(out, "remove_repeated_sentences");
|
|
391
420
|
if (flags.captions || flags.emojis) out = upsert(out, "add_captions", flags.emojis ? { emojis: true } : void 0);
|
|
392
421
|
if (flags.zoom) out = upsert(out, "punch_zoom");
|
|
@@ -399,6 +428,7 @@ function applyFlagActions(actions, flags) {
|
|
|
399
428
|
out = upsert(out, "hook");
|
|
400
429
|
}
|
|
401
430
|
if (flags.broll) out = upsert(out, "broll");
|
|
431
|
+
if (flags.sfx) out = upsert(out, "sound_effects");
|
|
402
432
|
if (flags.cta) out = upsert(out, "cta", typeof flags.cta === "string" && flags.cta.trim() ? { text: flags.cta.trim() } : void 0);
|
|
403
433
|
return out;
|
|
404
434
|
}
|
|
@@ -566,13 +596,14 @@ var commands = {
|
|
|
566
596
|
},
|
|
567
597
|
"style create": {
|
|
568
598
|
summary: "Create a style from simple flags",
|
|
569
|
-
usage: "batchedits style create <name> [--captions] [--emojis] [--silence] [--crop 9:16] [--zoom] [--clips [n]] [--repeats] [--hook] [--broll] [--cta [text]] [--set action.setting=value\u2026]",
|
|
599
|
+
usage: "batchedits style create <name> [--captions] [--emojis] [--silence] [--crop 9:16] [--zoom] [--clips [n]] [--repeats] [--fillers] [--hook] [--broll] [--cta [text]] [--sfx] [--set action.setting=value\u2026]",
|
|
570
600
|
help: [
|
|
571
601
|
"Creates a reusable style. Order of edits: crop, silence, repeats, captions, zoom, AI clips.",
|
|
572
602
|
" --captions Auto captions (word-by-word highlight)",
|
|
573
603
|
" --emojis Add AI-picked emojis to the captions",
|
|
574
604
|
" --silence Remove silences and dead air",
|
|
575
605
|
" --repeats Remove repeated takes of the same sentence",
|
|
606
|
+
' --fillers Also cut filler words (um, uh, filler "like" / "you know"); turns on --silence',
|
|
576
607
|
" --crop <ratio> Crop every video, e.g. 9:16, 1:1, 4:5",
|
|
577
608
|
" --zoom Zoom in on key moments",
|
|
578
609
|
" --clips [n] Cut long videos into n short clips (default 10; 1 credit per clip)",
|
|
@@ -582,6 +613,7 @@ var commands = {
|
|
|
582
613
|
" With --hook too, the text hook is drawn on the clip.",
|
|
583
614
|
" --broll Cut away to your B-roll while you talk about what it shows (name clips in the dashboard's Library)",
|
|
584
615
|
` --cta [text] A call to action in each video's last seconds (default "Follow for more"; pass --ctas to run/process for one per video)`,
|
|
616
|
+
" --sfx Sound effects on the other edits: whoosh on B-roll and zooms, pop on emojis, riser into the hook, ding on the CTA",
|
|
585
617
|
SET_HELP,
|
|
586
618
|
'Example: batchedits style create "Shorts" --crop 9:16 --silence --captions --zoom --set captions.position=center',
|
|
587
619
|
'Example: batchedits style create "Hooks" --captions --hook --set hook.position=top --set hook.duration=3',
|
|
@@ -639,16 +671,51 @@ Use it with: --style "${name}"`);
|
|
|
639
671
|
return EXIT.OK;
|
|
640
672
|
}
|
|
641
673
|
},
|
|
674
|
+
"style copy": {
|
|
675
|
+
summary: "Create a style that copies a video's look",
|
|
676
|
+
usage: "batchedits style copy <link|file|video id> [--name <name>]",
|
|
677
|
+
help: [
|
|
678
|
+
"Reads a reference video's captions (font, colours, word or letter highlight, position), zooms and crop, and saves them as a new style.",
|
|
679
|
+
"The reference is a YouTube, TikTok, Instagram, X or Vimeo link, a direct link to a video file, a local file (uploaded first), or the id of one of your videos.",
|
|
680
|
+
"Only the first 90 seconds are read. Colours and font are a close match. Uses no credits; up to 10 copies a day.",
|
|
681
|
+
" --name <name> Name for the new style (default: one based on the look)",
|
|
682
|
+
'Example: batchedits style copy https://www.tiktok.com/@creator/video/123 --name "Like this"',
|
|
683
|
+
'Example: batchedits style copy ./reference.mp4 && batchedits run ./raw --style "Like this" --yes'
|
|
684
|
+
].join("\n"),
|
|
685
|
+
async run({ api, positionals, flags }) {
|
|
686
|
+
const ref = positionals.join(" ").trim();
|
|
687
|
+
if (!ref) throw new CliError("Give a reference video: a link, a file or a video id.", EXIT.USAGE, "Example: batchedits style copy https://youtu.be/\u2026");
|
|
688
|
+
const name = typeof flags.name === "string" && flags.name.trim() ? flags.name.trim() : void 0;
|
|
689
|
+
let source;
|
|
690
|
+
if (isLink(ref)) source = { video_url: ref };
|
|
691
|
+
else if (import_node_fs3.default.existsSync(ref) && import_node_fs3.default.statSync(ref).isFile()) {
|
|
692
|
+
info(`Uploading ${import_node_path3.default.basename(ref)}\u2026`);
|
|
693
|
+
source = { video_id: (await api.upload(ref)).id };
|
|
694
|
+
} else if (/^[0-9a-f-]{8,64}$/i.test(ref)) source = { video_id: ref };
|
|
695
|
+
else throw new CliError(`No such file, link or video id: ${ref}`, EXIT.USAGE, "Give a link (https://\u2026), a local video file, or an id from: batchedits status");
|
|
696
|
+
info("Reading the reference video's style (about 20-60 seconds)\u2026");
|
|
697
|
+
const res = await api.copyStyle(source, name);
|
|
698
|
+
if (!res.styleId) throw new CliError("The server didn't create the style.", EXIT.ERROR, "It may not support copying styles yet. Use: batchedits style create");
|
|
699
|
+
if (isJson()) printJson({ styleId: res.styleId, name: res.name, summary: res.summary ?? [] });
|
|
700
|
+
else {
|
|
701
|
+
say(`Created style "${res.name}" (${res.styleId}).`);
|
|
702
|
+
for (const line of res.summary ?? []) say(` \u2022 ${line}`);
|
|
703
|
+
say(`Colours and font are a close match.
|
|
704
|
+
Use it with: --style "${res.name}"`);
|
|
705
|
+
}
|
|
706
|
+
return EXIT.OK;
|
|
707
|
+
}
|
|
708
|
+
},
|
|
642
709
|
upload: {
|
|
643
|
-
summary: "Upload
|
|
644
|
-
usage: "batchedits upload <files or
|
|
645
|
-
help: "Uploads videos or audio and prints their ids. A folder uploads the media files inside it.\nExample: batchedits upload ./raw",
|
|
710
|
+
summary: "Upload videos from files, folders or links (up to 50)",
|
|
711
|
+
usage: "batchedits upload <files, folders or links\u2026>",
|
|
712
|
+
help: "Uploads videos or audio and prints their ids. A folder uploads the media files inside it. A link (YouTube, or a public link to a video file such as Dropbox or Google Drive) is downloaded by BatchEdits.\nExample: batchedits upload ./raw https://youtu.be/dQw4w9WgXcQ",
|
|
646
713
|
async run({ api, positionals }) {
|
|
647
|
-
const
|
|
714
|
+
const inputs = expandInputs(positionals);
|
|
648
715
|
const uploaded = [];
|
|
649
|
-
for (let i = 0; i <
|
|
650
|
-
|
|
651
|
-
uploaded.push({ ...await api.
|
|
716
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
717
|
+
const input = inputs[i];
|
|
718
|
+
uploaded.push({ ...await uploadInput(api, input, i, inputs.length), file: input.kind === "link" ? input.url : input.path });
|
|
652
719
|
}
|
|
653
720
|
if (isJson()) printJson({ videos: uploaded });
|
|
654
721
|
else {
|
|
@@ -723,21 +790,18 @@ Next: batchedits status ${positionals.join(" ")} --watch`);
|
|
|
723
790
|
},
|
|
724
791
|
run: {
|
|
725
792
|
summary: "Upload, edit, wait and download in one go",
|
|
726
|
-
usage: "batchedits run <files or
|
|
727
|
-
help: 'Uploads up to 50 videos, edits them with the style, waits, and downloads the results.\n --hooks <file> One hook per line, in upload order (a folder uploads its files A-Z), for styles with a hook\n --ctas <file> One call to action per line, same order, for styles with a cta\nExample: batchedits run ./raw --style "Shorts" --out ./edited --yes',
|
|
793
|
+
usage: "batchedits run <files, folders or links\u2026> --style <name|id> [--out ./edited] [--hooks <file>] [--ctas <file>] [--yes]",
|
|
794
|
+
help: 'Uploads up to 50 videos (files, folders, or YouTube and video-file links), edits them with the style, waits, and downloads the results.\n --hooks <file> One hook per line, in upload order (a folder uploads its files A-Z), for styles with a hook\n --ctas <file> One call to action per line, same order, for styles with a cta\nExample: batchedits run ./raw --style "Shorts" --out ./edited --yes',
|
|
728
795
|
async run(ctx) {
|
|
729
796
|
const { api, positionals, flags } = ctx;
|
|
730
|
-
const
|
|
797
|
+
const inputs = expandInputs(positionals);
|
|
731
798
|
const style = await resolveStyle(api, flags.style);
|
|
732
|
-
const hooks = readLinesFile(flags.hooks, style,
|
|
733
|
-
const ctas = readLinesFile(flags.ctas, style,
|
|
799
|
+
const hooks = readLinesFile(flags.hooks, style, inputs.length, "hook");
|
|
800
|
+
const ctas = readLinesFile(flags.ctas, style, inputs.length, "cta");
|
|
734
801
|
const clips = (style.actions ?? []).some((a) => a.name === "ai_clips");
|
|
735
|
-
await confirm(flags, `Edit ${
|
|
802
|
+
await confirm(flags, `Edit ${inputs.length} video${inputs.length === 1 ? "" : "s"} with "${style.name}"? This uses ${inputs.length} credit${inputs.length === 1 ? "" : "s"}${clips ? ", plus 1 per AI clip" : ""}.`);
|
|
736
803
|
const ids = [];
|
|
737
|
-
for (let i = 0; i <
|
|
738
|
-
info(`Uploading ${i + 1}/${files.length}: ${import_node_path3.default.basename(files[i])}`);
|
|
739
|
-
ids.push((await api.upload(files[i])).id);
|
|
740
|
-
}
|
|
804
|
+
for (let i = 0; i < inputs.length; i++) ids.push((await uploadInput(api, inputs[i], i, inputs.length)).id);
|
|
741
805
|
for (const [i, videoId] of ids.entries()) await api.call("process_video", { videoId, styleId: style.id, ...perVideoText(hooks, ctas, i) });
|
|
742
806
|
info(`Editing ${ids.length} video${ids.length === 1 ? "" : "s"} with "${style.name}"\u2026`);
|
|
743
807
|
const group = await watch(api, ids, Number(flags.interval) || 10);
|
|
@@ -754,7 +818,7 @@ Next: batchedits status ${positionals.join(" ")} --watch`);
|
|
|
754
818
|
};
|
|
755
819
|
|
|
756
820
|
// src/cli.ts
|
|
757
|
-
var VERSION = true ? "1.
|
|
821
|
+
var VERSION = true ? "1.7.0" : "dev";
|
|
758
822
|
var FLAG_OPTIONS = {
|
|
759
823
|
help: { type: "boolean", short: "h" },
|
|
760
824
|
version: { type: "boolean", short: "v" },
|
|
@@ -769,6 +833,7 @@ var FLAG_OPTIONS = {
|
|
|
769
833
|
emojis: { type: "boolean" },
|
|
770
834
|
silence: { type: "boolean" },
|
|
771
835
|
repeats: { type: "boolean" },
|
|
836
|
+
fillers: { type: "boolean" },
|
|
772
837
|
crop: { type: "string" },
|
|
773
838
|
zoom: { type: "boolean" },
|
|
774
839
|
clips: { type: "string" },
|
|
@@ -777,6 +842,7 @@ var FLAG_OPTIONS = {
|
|
|
777
842
|
hooks: { type: "string" },
|
|
778
843
|
cta: { type: "string" },
|
|
779
844
|
broll: { type: "boolean" },
|
|
845
|
+
sfx: { type: "boolean" },
|
|
780
846
|
ctas: { type: "string" },
|
|
781
847
|
set: { type: "string", multiple: true },
|
|
782
848
|
remove: { type: "string", multiple: true },
|
|
@@ -800,7 +866,9 @@ function mainHelp() {
|
|
|
800
866
|
" batchedits login",
|
|
801
867
|
' batchedits style create "Shorts" --crop 9:16 --silence --captions --zoom',
|
|
802
868
|
' batchedits style edit "Shorts" --set captions.position=center',
|
|
869
|
+
' batchedits style copy https://www.tiktok.com/@creator/video/123 --name "Like this"',
|
|
803
870
|
' batchedits run ./raw --style "Shorts" --out ./edited',
|
|
871
|
+
' batchedits run https://youtu.be/dQw4w9WgXcQ ./raw --style "Shorts" --yes',
|
|
804
872
|
"",
|
|
805
873
|
"Exit codes: 0 ok \xB7 1 error \xB7 2 usage \xB7 3 sign in needed \xB7 4 some videos failed \xB7 5 needs --yes"
|
|
806
874
|
].join("\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "batchedits",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "BatchEdits CLI, SDK and React widgets: edit up to 50 videos at once from your terminal or AI agent (Claude Code, OpenClaw, Hermes)",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|