npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@x12i/youtube-video-uploader-cli

v1.1.0

Published

CLI tool to batch upload MP4 videos to YouTube via YouTube Data API v3 with OAuth2, metadata.json config, playlist assignment, and smart upload-state resume.

Readme

@x12i/youtube-video-uploader-cli 📺

Automated batch video uploader for YouTube Data API v3 with OAuth2 authentication, playlist assignment, quota estimation, and smart upload-state resume.


🚀 Features

  • 🔐 Interactive OAuth2 Authentication: Authenticates with YouTube using Google OAuth2. Features a local loopback server to automatically capture the callback redirect, with a terminal prompt fallback.
  • 💾 Token Persistence: Caches tokens locally in token.json so you only need to authorize once. Automatically handles token refresh.
  • 📄 Metadata-Driven Batch Uploads: Configure titles, descriptions, tags, category, privacy, and playlist via a simple metadata.json file.
  • ⚡ Smart Skip & Resume: Saves upload status to .upload-history.json and skips previously uploaded files on rerun to protect your API quota.
  • 📑 Playlist Integration: Automatically adds uploaded videos to a specified YouTube Playlist (playlistId).
  • 📊 Quota Estimation: Calculates estimated YouTube Data API units (1,600 units/video, 50 units/playlist addition) and warns if approaching the standard 10,000 units/day limit.
  • 🔍 Dry Run Mode: Validate your metadata.json, inspect files, and check estimated quota before uploading.

🔑 Google Cloud Setup (Prerequisite)

Before using the uploader, you need OAuth2 credentials from Google Cloud:

  1. Go to the Google Cloud Console.
  2. Create a new project and enable the YouTube Data API v3.
  3. Under OAuth consent screen:
    • Set user type to External.
    • Add your Google account email under Test Users.
  4. Under APIs & Services > Credentials:
    • Click Create Credentials > OAuth client ID.
    • Application type: Desktop App (or Web Application with redirect URI http://localhost:3000/oauth2callback).
    • Download the client_secret.json or copy your Client ID and Client Secret.

📦 Installation & Quick Start

Run immediately via npx

# In the folder containing your .mp4 files and metadata.json:
npx @x12i/youtube-video-uploader-cli

Install globally

npm install -g @x12i/youtube-video-uploader-cli

# Now you can use any of these commands anywhere:
youtube-video-uploader [folder]
yt-uploader [folder]
yvu-cli [folder]

📂 Folder Structure & metadata.json

Place your videos and a metadata.json file in your target folder:

my-videos/
├── metadata.json
├── track1.mp4
├── track2.mp4
└── track3.mp4

metadata.json Schema

{
  "playlistId": "PLxXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "privacyStatus": "private",
  "categoryId": "10",
  "videos": [
    {
      "filename": "track1.mp4",
      "title": "Ambient Track 01 - Chill Beats",
      "description": "Full track audio with custom artwork.\n\nSubscribe for more!",
      "tags": ["ambient", "lofi", "chill"]
    },
    {
      "filename": "track2.mp4",
      "title": "Ambient Track 02 - Night Drives",
      "description": "Relaxing night vibes.",
      "tags": ["night", "vibes"]
    }
  ]
}

Category IDs:

  • "10" = Music (default)
  • "22" = People & Blogs
  • "27" = Education
  • "28" = Science & Technology

⚙️ CLI Options Reference

Usage: youtube-video-uploader [directory] [options]

Arguments:
  directory                     Target folder containing MP4 videos and metadata.json (default: ".")

Options:
  -v, --version                 Output current version
  -d, --dir <path>              Explicit target directory path
  -m, --metadata <file>         Custom path to metadata.json file
  -f, --force                   Force re-upload of already uploaded videos (default: false)
  -n, --dry-run                 Preview video uploads and estimate quota without uploading (default: false)
  --client-id <id>              Google OAuth Client ID
  --client-secret <secret>      Google OAuth Client Secret
  --client-secrets-file <file>  Path to client_secret.json downloaded from Google Cloud
  --token-file <file>           Path to store or read OAuth token (default: token.json in target dir)
  -q, --quiet                   Minimal output mode (default: false)
  -h, --help                    Display help

💡 Examples

1. Dry run (verify metadata and estimate API quota)

npx @x12i/youtube-video-uploader-cli ./my-videos --dry-run

2. Upload with credentials from environment variables

export YOUTUBE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export YOUTUBE_CLIENT_SECRET="your-client-secret"

npx @x12i/youtube-video-uploader-cli ./my-videos

3. Upload with downloaded client_secret.json

npx @x12i/youtube-video-uploader-cli ./my-videos --client-secrets-file ./client_secret.json

🛠️ Programmatic Node.js API

import { batchUpload, uploadVideo, loadMetadata } from '@x12i/youtube-video-uploader-cli';

const result = await batchUpload('./my-videos', {
  clientId: process.env.YOUTUBE_CLIENT_ID,
  clientSecret: process.env.YOUTUBE_CLIENT_SECRET,
  onEvent: (event) => {
    if (event.type === 'upload_success') {
      console.log(`Uploaded ${event.item.filename} -> ${event.record.url}`);
    }
  },
});

console.log(`Uploaded: ${result.uploaded.length}, Skipped: ${result.skipped.length}`);

📜 License

MIT License.