Skip to content

About

Headless YouTube uploader for Windows. Authenticates via cookie export — no OAuth, no Google Cloud project, no quota approval. Drives the same Studio web upload pipeline a real browser would.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nemo-youtube

Headless YouTube uploader for Windows. Authenticates via cookie export — no OAuth, no Google Cloud project, no quota approval. Drives the same Studio web upload pipeline a real browser would.

nemo-youtube screenshot

What it does

Upload videos to your own YouTube channel from the command line, without going through Google's OAuth flow or applying for a Cloud project. Two small CLIs:

  • nemo-yt-upload.exe — headless upload (title, description, tags, privacy, made-for-kids). Runs hidden, prints progress to console.
  • nemo-yt-studio.exe — opens YouTube Studio in a real browser window. Used for first-time login (no cookie export needed) and for manual checks / metadata edits after automated uploads.

Both share a persistent WebView2 profile, so once you log in via nemo-yt-studio (or seed cookies via the Chrome extension), subsequent uploads run completely unattended.

Why

If you only need to push your own videos to your own channel, the official YouTube Data API forces you to:

  1. Create a Google Cloud project
  2. Configure an OAuth consent screen
  3. Apply for upload-quota approval (rejected for most personal use cases)
  4. Re-grant OAuth on every session

nemo-youtube skips all four by using your existing browser session — the same cookies your Chrome already sends. Drive Studio from Python, no API keys required.

Install

  1. Download the latest nemo-yt-portable_<version>.zip from Releases (see DOWNLOADS.md for version history + verification).

  2. Extract anywhere. You get two self-contained .exe files — no companion folders, drag-anywhere-and-run.

  3. Open a terminal in the extracted folder (or wherever you put the .exes).

  4. Verify both binaries work:

    nemo-yt-upload.exe --help
    nemo-yt-studio.exe --help
    

No Python install needed on the target machine. Windows 10/11 with WebView2 runtime (already shipped with modern Edge / Windows updates).

Quick start

First-time login (no extension required)

nemo-yt-studio.exe --profile-label default

A browser window opens at studio.youtube.com. Log in with your Google account. The WebView2 profile keeps the cookies after you close the window.

Upload a video (minimal)

nemo-yt-upload.exe ^
  --video       "C:\path\to\video.mp4" ^
  --title       "My headless upload" ^
  --description "First line\nSecond line" ^
  --tags        "music,cover,acoustic" ^
  --privacy     PRIVATE

--nmx is optional — by default the uploader uses the WebView2 profile seeded by nemo-yt-studio above.

Upload a video (full options)

nemo-yt-upload.exe ^
  --video       "C:\path\to\video.mp4" ^
  --title       "My title" ^
  --description "..." ^
  --tags        "tag1,tag2" ^
  --privacy     PRIVATE ^
  --thumbnail   "C:\path\to\cover.jpg" ^
  --captions    "C:\path\to\track.srt" --captions-lang vi ^
  --playlist    "Auto-dub batch"

--playlist accepts either a playlist ID (PL...) or a title — titles are looked up and reused if they exist, else a new playlist is created. Repeat --playlist for multiple. All optional flags can be mixed with the minimal example above.

Alternative login: .nmx cookie file

If you prefer not to log in via nemo-yt-studio, install Nemo Cookie Anywhere from the Chrome Web Store, sign in to YouTube in Chrome, click the extension icon, export. Pass the resulting file via --nmx:

→ https://chromewebstore.google.com/detail/nemo-cookie-anywhere/hnjephdikibgiajfdllmpjaahpjcgmei

Features

  • ✅ Headless upload (title, description, tags, privacy, made-for-kids)
  • ✅ Multi-line descriptions via --description-file
  • ✅ Custom thumbnail upload (.jpg/.png, ≤ 2 MB)
  • ✅ Caption track from .srt (UTF-8, any language code)
  • ✅ Playlist attach — by ID or by title (smart upsert: reuse if title exists, else create); repeatable for multiple playlists
  • ✅ Cookie auth: .nmx file OR persistent WebView2 profile (login once via nemo-yt-studio, all subsequent uploads run unattended)
  • ✅ Hidden 1×1 minimized window for unattended batch jobs
  • ✅ Visible Studio session for first-time login + manual edits
  • ✅ DevTools mode for debugging (nemo-yt-studio --debug)
  • ✅ Optional proxy support for wire inspection (Charles, mitmproxy)

Use with AI agents and automation

nemo-youtube is CLI-first by design, so it slots cleanly into any workflow that can shell out — Claude Code, Cursor / Aider, custom Python scripts, n8n, GitHub Actions, Make, Zapier with a shell node, etc. A few traits make it especially agent-friendly:

  • No OAuth round-trip per run. The WebView2 profile keeps cookies between invocations. An agent calls nemo-yt-upload.exe and gets a videoId back — no consent-screen popup to click through.
  • No Cloud project, no quota approval. The official YouTube Data API requires manual quota review (often rejected for personal use). This tool works on day one.
  • Headless by default. Uploads run in a 1×1 minimized window. No UI for the agent to interact with.
  • Predictable stdout. Progress is line-buffered; the final block prints videoId: …, studio URL: …, metadata updated: …. Trivial to parse with a regex or string .split().
  • Exit-code aware. 0 = success, 2 = stale NMX cookies (agent should prompt for re-export), other non-zero = generic failure.
  • Stateless invocations. Each call uploads one video and exits. No session to keep alive between calls.
  • Library API too. from nemo_youtube import StudioUploader if you prefer in-process integration over shelling out.

Integration patterns

1. Shell-exec from any agent or scripting tool

import subprocess, re

result = subprocess.run([
    "nemo-yt-upload.exe",
    "--nmx",     "C:/cookies.nmx",
    "--video",   "C:/out.mp4",
    "--title",   "AI-generated highlight #1",
    "--privacy", "PRIVATE",
], capture_output=True, text=True, check=True)

video_id = re.search(r"videoId:\s*(\S+)", result.stdout).group(1)

2. As a tool exposed to an LLM

Wrap the subprocess call in an upload_to_youtube(video_path, title, description, tags, privacy) function and register it as a tool / function-call in your agent framework. The model picks a clip + writes metadata; your wrapper handles auth, upload, and returns the videoId.

3. In-process Python library (batch jobs)

from nemo_youtube import StudioUploader

def workflow(up):
    return [up.upload(v, title=t) for v, t in queue]

results = StudioUploader(nmx_path="C:/cookies.nmx").run(workflow)

One WebView2 window opened, every video in queue uploaded inside that one session — saves the per-call window-spawn overhead when publishing 10+ clips at a time.

4. n8n / Make / Zapier — no-code workflow tools

Use the Execute Command node (n8n) or its equivalent. Example n8n node config:

Command:    nemo-yt-upload.exe
Arguments:  --nmx "C:/cookies.nmx" --video "{{ $json.video_path }}"
            --title "{{ $json.title }}" --privacy PRIVATE

Wire it after a "Watch Folder" / Webhook / Google Drive trigger to get "video lands in folder → uploaded to YouTube" with zero custom code. Parse videoId: from stdout in a follow-up "Set" node if you need to chain (Slack notify, DB log, etc.).

Common automation use cases

  • AI pipeline produces a video (text → script → TTS → render) → auto- upload as PRIVATE for human review before publishing
  • Scheduled batch from a writeup queue (overnight cron, GitHub Actions on a runner)
  • "Repurpose long-form into shorts" agent: input one long video, output N clipped shorts, all uploaded
  • Multilingual dub pipeline: same source video → N language tracks → upload one variant per language

What's NOT supported (yet)

  • Schedule publish (publishAt)
  • Localized title/description
  • macOS / Linux (Windows only — depends on WebView2)

See the project for roadmap details.

Limitations & disclaimer

  • Cookies expire. When the uploader fails preflight with sessionInfo.token unavailable, re-export your .nmx (or run nemo-yt-studio to refresh the profile).
  • Not affiliated with or endorsed by YouTube/Google. This tool operates outside the official API. Cookie-based automation may violate YouTube's Terms of Service in certain contexts; use on your own channels only, at your own risk.
  • Personal use intended. No bulk-upload spam, no operating other people's channels.

Origin

Built as the upload step of a Vietnamese video-dubbing pipeline. The helper machinery (in-page JS injector + WebSocket bridge) was developed through extensive reverse-engineering of YouTube Studio's bundle. See the DOWNLOADS page for version history.

Support

If this tool saved you time, please consider supporting development: DONATE.

Contact

For inquiries beyond what's documented above:

Common reasons people reach out:

  • Upload to Facebook / TikTok / Instagram — same headless-browser approach can be ported to other platforms (no official API, no OAuth hoops). Currently YouTube-only; ping if you'd commission/sponsor another platform.
  • Source-code access — the public repo only ships binaries; access to the underlying source is granted case-by-case
  • Custom features / contract work — additions tailored to your workflow (scheduled releases, multi-channel batch, localized metadata, ...)
  • Commercial-use license — if you intend to use this in a for-profit / company setting beyond personal use
  • Partnership / collaboration — integrations with other tools, co-development, etc.

Bug reports and small feature suggestions are best filed via GitHub Issues on the public repo (faster than email and visible to other users). Private/sensitive topics → Telegram or email.

License

MIT — free to use, modify, redistribute. The "use on your own channels only" guidance under Limitations & disclaimer is about YouTube's Terms of Service, not about this tool's license.

About

Headless YouTube uploader for Windows. Authenticates via cookie export — no OAuth, no Google Cloud project, no quota approval. Drives the same Studio web upload pipeline a real browser would.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors