YT Short Clipper v2
A Windows desktop app that turns a long-form YouTube video into ready-to-post 9:16 short-form clips — picking the highlights with an LLM, reframing to portrait, and burning in word-by-word captions.
Stack: React 19 + TypeScript + Vite · Tauri v2 (Rust shell) · Python sidecar (yt-dlp, FFmpeg, MediaPipe)
Windows only. The build scripts are PowerShell, the app ships as a portable zip with a WebView2 bootstrapper, and caption/hook rendering reads fonts from
C:\Windows\Fonts. Nothing is macOS/Linux-ready today.
Status: beta. Expect rough edges and breaking changes between releases.
What it does
- You paste a YouTube URL and upload your own
cookies.txt(see YouTube cookies). - yt-dlp fetches the video and its original subtitle track.
- An LLM reads the transcript and proposes highlight segments (58–120s by default).
- Each segment is cut, reframed to 9:16, captioned, and written out as an MP4.
- Optionally, clips are uploaded and scheduled through Repliz.
Features
- AI highlight detection from the video's subtitle transcript, via any OpenAI-compatible endpoint
- AI direction per video — free-text steering: name a time range, chase a recurring topic, or rule material out
- Output language for titles and hook text, defaulting to the video's own language
- Portrait reframe in three modes: face tracking (MediaPipe), centered on black bars, or centered on a blurred fill — the centered modes are dramatically faster since they skip per-frame face detection
- Word-by-word captions burned from YouTube's original subtitle track — no transcription API and no local Whisper model required
- Optional hook text overlays and logo/credit watermarks
- Direct upload to the Repliz social media platform
AI providers
One provider serves the whole app — highlight detection and title generation both — and is chosen once in AI Models. There are two ways to power it.
In-app AI. The app provisions its own wallet for this installation on first launch: no registration, no email, no API key to paste. Top up with QRIS from inside the app and the balance shows in the sidebar. The wallet is held by a key kept in the OS credential store (Windows Credential Manager, Keychain, libsecret) — never in a config file. There is no server-side recovery, so export that key and keep it somewhere safe: it is the only way to reach the balance from another machine, and nobody can restore it for you. Top-ups are not refundable.
Your own API key. Anything OpenAI-compatible works; the app ships presets for OpenAI, Google Gemini, Groq, ApiSmart, the web wallet at ai.ytclip.org, and a Custom/Local option for vLLM, Ollama, or similar. Your key is stored in the app's local data directory and is never sent anywhere except the provider you configured.
The two are separate wallets. A balance topped up at ai.ytclip.org is reached through the "YTClip AI (Web)" preset under your own API key, not through the in-app balance.
AI direction
Left empty, the model picks clips on its own. Filled in, the direction outranks the built-in selection principles:
- An explicit clock range (
2:00 - 2:50) is used exactly — that clip is exempt from the usual 58–120s duration filter, and the run samples at a lower temperature so the instruction is actually followed. - Array order is clip order, so "clip pertama dari …" lands first in the list.
- Anything the direction rules out is left out.
Custom system messages (in AI Models) can place the direction with a
{user_direction} placeholder; without it the direction is appended at the end.
YouTube cookies
The app needs cookies from a logged-in YouTube session for yt-dlp to fetch subtitles and video. You supply your own — nothing is bundled.
- Open YouTube in your browser and make sure you are logged in.
- Install the Get cookies.txt LOCALLY extension.
- Run it while on
youtube.comand exportcookies.txt. - In the app, click Upload YouTube cookies to continue and pick that file.
Notes:
- Don't log out of YouTube after exporting — that invalidates the cookies.
- Frequent 403s mean the cookies went stale; export a fresh file.
- A valid export contains
SID,HSID,SSID,APISID,SAPISID, andLOGIN_INFO. cookies.txtgrants access to your Google account. It is gitignored here, stored only in the app's local data directory, and passed to yt-dlp on your machine — but treat the file itself like a password and never share it.
Prerequisites
Setup
# 1. Install Node dependencies
npm install
# 2. Install Python dependencies
py -m pip install -r requirements.txt
# 3. Download runtime binaries (FFmpeg, Deno)
# Existing files are skipped — add -Force to actually re-download them.
powershell -ExecutionPolicy Bypass -File scripts/fetch-deps.ps1
# 4. Build the Python sidecar executable
npm run build:sidecar
FFmpeg must be a GnuTLS build (the fetch script pulls one from gyan.dev). Schannel builds hang forever on the byte-range requests used for section downloads.
Development
npm run dev # Start Vite dev server
npm run tauri dev # Start Tauri dev window
Python changes need a sidecar rebuild.
src-tauri/binaries/ytclip-sidecar-*.exetakes precedence over the dev Python module, so edits underyt_short_clipper_core/do nothing until you runnpm run build:sidecar— the app keeps running the frozen copy without complaining. Delete that binary to fall back topy -m yt_short_clipper_core.sidecarfor fast iteration. Frontend and Rust changes hot-reload as usual.
Updating yt-dlp
py -m pip install --upgrade yt-dlp # 1. upgrade the package
# 2. bump the floor in requirements.txt
npm run build:sidecar # 3. re-freeze it into the sidecar
Check the yt-dlp changelog for a raised Deno floor while you are there (2026.06.09
raised it to v2.3.0). Deno drives remote_components for YouTube's JS challenges, so an
under-floor binary breaks extraction quietly — and fetch-deps.ps1 will not replace an
existing deno.exe without -Force.
Release Build
# One command: sidecar → frontend → Tauri build → assemble portable zips
npm run release
This produces two zips in src-tauri/target/release/bundle/:
YTShortClipperV2__x64_portable.zip— full bundle for new usersYTShortClipperV2__x64_update.zip— app + sidecar only, for existing users
See BUILD_GUIDE.md for the full release flow, version bumping (4 files), and the build-only-what-changed shortcuts.
Network calls & telemetry
Being transparent about every host the app talks to, since some of it is the maintainer's own backend rather than a third party:
| Endpoint | When | What is sent |
|---|---|---|
YouTube / googlevideo (via yt-dlp) |
Fetching video + subtitles | Your YouTube cookies |
| Your configured AI provider | Highlight + title generation | Subtitle transcript, your prompt, your API key |
api-v2.ytclip.org/api/public/v1 |
Only if you use in-app AI | Platform and app version at activation; afterwards your device token, to read the balance and create QRIS invoices |
ai-api.ytclip.org/v1 |
Only if you use in-app AI | Subtitle transcript and your prompt, with the key the app issued itself |
api-v2.ytclip.org/api/public/v1/app |
On launch | Nothing — the request carries no parameters |
api-v2.ytclip.org/api/public/v1/notification |
On launch | Nothing |
api-v2.ytclip.org/api/public/v1/menu |
On launch | Nothing |
google-analytics.com/mp/collect |
After a clip renders | Random installation ID, app version, clip duration, reframe mode |
api.ytclip.org/webhook/yt-clipper/presigned-url + api.repliz.com |
Only if you use Repliz upload | Filename, the video file, your Repliz keys |
No video content or transcript is sent to any ytclip.org host except the AI endpoint you
pick — and that one only receives what you would send any AI provider. The installation ID
is a random UUID generated locally on first run, not tied to any account.
Google Analytics is the one third party here. It receives the installation ID, the app
version, and each finished clip's duration and reframe mode — plus, as with any HTTP
request, your IP address, which Google uses for coarse geolocation. No video, transcript,
title, or URL is sent. Builds without GA_API_SECRET set at compile time send nothing at
all.
If you fork this, point these at your own backend or strip them out — see
src/hooks/ and src-tauri/src/commands/analytics.rs.
Sidebar links
The external links at the bottom of the sidebar are served by
api-v2.ytclip.org/api/public/v1/menu, so they can change without an app release.
The four page routes above them stay hardcoded.
Icons are named by the API as kebab-case strings and resolved through the allowlist in
src/config/menuIcons.ts — an icon must exist there before
the server can use it. Responses are validated (https-only URLs, capped count and label
length, bad entries dropped individually), cached, and fall back to
DEFAULT_MENU_ITEMS in src/hooks/menu.ts when offline.
Sponsors
AI Provider Sponsor
Become a sponsor
Interested in sponsoring this project? Reach out at sponsorship@ytclip.org.
Legal
This tool automates downloading and re-cutting YouTube videos. Only use it on content you own or are otherwise licensed to reuse; downloading or republishing third-party videos may violate YouTube's Terms of Service and copyright law in your jurisdiction. You are responsible for what you process and post. The maintainer provides no warranty and accepts no liability — see LICENSE.
Not affiliated with, endorsed by, or sponsored by YouTube, Google, OpenAI, or Repliz.
License
MIT © Aji Prakoso
