shorts-maker 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,166 @@
1
+ # shorts-maker
2
+
3
+ Split a long video into **consecutive parts** — the whole thing, in order, cut on natural
4
+ pauses — each titled `Main Title part-N #hashtags`, ready to post as a series to YouTube /
5
+ Instagram / TikTok.
6
+
7
+ TypeScript on [Bun](https://bun.sh) with a **React + Tailwind v4** frontend that Bun
8
+ bundles and hot-reloads itself — no Vite, no webpack, no PostCSS. No AI, no accounts. The
9
+ only runtime binary it shells out to is **ffmpeg**; a 90-minute video processes in seconds.
10
+
11
+ ## How it works
12
+
13
+ ```
14
+ video ──► find pauses (ffmpeg silencedetect) ──► split into parts ──► cut (stream-copy) ──► parts/ + captions
15
+ ```
16
+
17
+ - **Every second is covered** — parts are contiguous from 0:00 to the end. No highlight-picking.
18
+ - **Cuts land on a pause**, so parts don't end mid-sentence. (Stream-copy snaps to the
19
+ nearest keyframe, so a cut may shift a second or two.)
20
+ - **Part length is a cap, not a quota** — a 15-min target splits a 96-min video into 7
21
+ parts of ~14 min each (evenly), not 6 full 15-min parts plus a 6-min stub. If even parts
22
+ would come out under ~12 min, one part is dropped and the rest stretch a little to
23
+ absorb it.
24
+ - **Titles** = the video name (auto-derived from the file, editable in the form) + `part-N`
25
+ + a random set of hashtags from [`hashtags.txt`](hashtags.txt) (edit to taste).
26
+ - Your source is already **1080×1920 (9:16 vertical)**, so no cropping is needed.
27
+
28
+ ## Quick start
29
+
30
+ You need two things on your machine: [**Bun**](https://bun.sh) and **ffmpeg**.
31
+
32
+ ```bash
33
+ curl -fsSL https://bun.sh/install | bash # Bun (skip if installed)
34
+ brew install ffmpeg # ffmpeg — macOS; use your package manager elsewhere
35
+ brew install yt-dlp # optional — only to import from a video link
36
+ ```
37
+
38
+ `yt-dlp` is only needed if you paste a **link** (YouTube, Dailymotion, or a direct video
39
+ URL) instead of uploading a file.
40
+
41
+ > **YouTube “Sign in to confirm you’re not a bot”?** YouTube blocks some anonymous
42
+ > downloads. Point the app at your browser’s login:
43
+ > `bunx shorts-maker --serve --cookies-from-browser chrome` (or `safari` / `firefox` /
44
+ > `edge` / `brave`), or set `SHORTS_MAKER_COOKIES_FROM_BROWSER=chrome`. Failed link jobs
45
+ > also retry automatically through alternate players before giving up.
46
+
47
+ Then run it straight from npm — no clone, no install step:
48
+
49
+ ```bash
50
+ cd ~/videos # any folder — this is where output/ and config/ will be written
51
+ bunx shorts-maker --serve # → http://localhost:4321 (bare `bunx shorts-maker` prints help)
52
+ ```
53
+
54
+ `--serve` starts the app from your **current folder**: generated clips land in `./output/`,
55
+ staged uploads in `./uploads/`, and your saved credentials in `./config/`. Run it wherever
56
+ you want that data to live.
57
+
58
+ ```
59
+ shorts-maker --serve [options]
60
+
61
+ -s, --serve Start the web app (required — nothing runs without it)
62
+ -p, --port <n> Port to listen on (default 4321, or $PORT)
63
+ -d, --dir <path> Folder to read/write data in (default: current folder,
64
+ or $SHORTS_MAKER_DIR)
65
+ -v, --version Print the version and exit
66
+ -h, --help Show this help and exit
67
+ ```
68
+
69
+ ## From source
70
+
71
+ ```bash
72
+ git clone https://github.com/subasshrestha/ShortsMaker && cd ShortsMaker
73
+ bun install
74
+ bun dev # development → http://localhost:4321 (hot reload / React Fast Refresh)
75
+ bun start # production → builds dist/ then serves the optimized bundle
76
+ ```
77
+
78
+ At runtime it needs Bun + ffmpeg; everything else is bundled.
79
+
80
+ ## Using the app
81
+
82
+ The same server process serves both the React app and the API — one port, no second dev
83
+ server.
84
+
85
+ - **Pick a source three ways**: upload a video (click or drag-and-drop, with a live
86
+ progress bar), paste a **link**, or choose one you already have under **From uploads**.
87
+ - **Sources are kept**, not thrown away. Everything you upload — and every video fetched
88
+ from a link — lands in `uploads/` and stays there, so you can re-split it without
89
+ re-uploading or re-downloading. Manage them right in the **From uploads** tab: each
90
+ entry shows its size and date, with a trash icon to delete it and a **Clear all** to
91
+ empty the folder. Deleting a *job* never deletes its source video.
92
+ - The **title** auto-fills from the filename; adjust it, plus **part length**,
93
+ **hashtags-per-part**, and the **hashtag pool** (pre-filled from `hashtags.txt`) — all
94
+ from the form.
95
+ - Hit **Split** and watch the logs stream live.
96
+ - Every run is saved in the **History** sidebar — it survives refreshes and restarts.
97
+ Click a job to replay its logs, preview each part inline, copy captions, download
98
+ clips, **reveal a clip in Finder** (when running locally), or delete the whole run
99
+ (files included).
100
+
101
+ ## Output
102
+
103
+ Each run lands in its own folder under `output/`:
104
+
105
+ ```
106
+ output/<name>__<timestamp>/
107
+ parts/
108
+ 01_hacker-vs-coder.mp4
109
+ 01_hacker-vs-coder.txt # "Hacker VS Coder part-1 #tags" — paste-ready caption
110
+ 02_...
111
+ manifest.json # every part with timestamps + caption
112
+ ```
113
+
114
+ Hashtags are drawn from [`hashtags.txt`](hashtags.txt) — one per line, `#` lines are
115
+ comments. Edit that file to fit your niche.
116
+
117
+ ## Publish to social media
118
+
119
+ Each finished part card has a **one-click Publish** button. Facebook Pages are supported
120
+ today (more platforms are planned — the code is structured to drop them in). Uploads use
121
+ Facebook's [chunked video upload](https://developers.facebook.com/docs/graph-api/reference/page/videos/)
122
+ (`upload_phase` start → transfer → finish), with resume + retry and a live progress bar
123
+ on the card.
124
+
125
+ 1. Open **Settings** (gear in the sidebar) → **Facebook Page**, and follow the built-in
126
+ **Setup guide** to get a **Page ID** and a long-lived **Page Access Token**.
127
+ 2. Paste them in and **Save** — it verifies with Facebook first and only stores if it works.
128
+ (**Test connection** also checks that the token has the `pages_manage_posts` permission.)
129
+ 3. On any part card, hit **Publish to Facebook**. The clip is uploaded to your Page with
130
+ its caption; the card then shows **Posted ✓** with a link, and remembers it.
131
+
132
+ Credentials are stored **locally** in `config/social.json` (gitignored) and are never
133
+ returned to the browser or sent anywhere except Facebook's Graph API.
134
+
135
+ ## Project layout
136
+
137
+ ```
138
+ src/
139
+ cli.ts # `shorts-maker` command: --help/--version/--port/--dir, then serves
140
+ server.ts # Bun.serve: React app (dev bundler / prod dist) + REST/SSE API
141
+ build.ts # pre-builds frontend → dist/ (Bun.build + Tailwind plugin)
142
+ paths.ts # package-asset dirs vs. the user's data dir (cwd)
143
+ files.ts # shared fs helpers (safeJoin, uniqueName, video extensions)
144
+ jobs/
145
+ store.ts # job registry — SQLite (bun:sqlite, output/jobs.db) + SSE subscribers
146
+ pipeline/
147
+ pipeline.ts # orchestration (probe → pauses → split → cut → titles)
148
+ media.ts # ffprobe/ffmpeg wrappers (probe, silence detect, cut)
149
+ parts.ts # part model + splitter
150
+ social/
151
+ config.ts # credential store (config/social.json)
152
+ facebook.ts # Graph API verify + video upload
153
+ frontend/
154
+ index.html # entry — Bun bundles main.tsx from here
155
+ main.tsx # React mount + BrowserRouter
156
+ App.tsx # routes + app-shell layout
157
+ styles.css # Tailwind v4 entry: @import + @theme design tokens
158
+ pages/ # routes: NewSplitForm, JobDetail, Settings, Guide
159
+ components/ # shared: Sidebar, Brand, Dot, Icons, ConfirmDialog
160
+ lib/
161
+ api.ts # typed fetch helpers (+ streaming upload)
162
+ util.ts # formatting helpers
163
+ types.ts # shared Job/Part types
164
+ bunfig.toml # registers bun-plugin-tailwind for the dev bundler
165
+ hashtags.txt # default hashtag pool (a hashtags.txt in your run folder overrides it)
166
+ ```
package/bunfig.toml ADDED
@@ -0,0 +1,3 @@
1
+ # Run CSS imported by the HTML bundler (frontend/styles.css) through Tailwind v4.
2
+ [serve.static]
3
+ plugins = ["bun-plugin-tailwind"]