Uploading 10 Videos to YouTube With a Single Command
You just finished a batch render session. Ten Shorts sitting in an output directory, each with its own title, description, tags, and thumbnail file. Uploading them one by one through YouTube Studio means clicking through the same multi-step upload wizard ten separate times, dragging files, copying metadata, setting thumbnails, configuring privacy settings. Here is how to send all ten videos to YouTube with a single command and per-video metadata.
The Batch Upload Script
A batch upload script iterates over a directory of video files, reads metadata from companion JSON files, and calls the YouTube API sequentially for each video with individual settings:
const fs = require('fs');
const path = require('path');
const { google } = require('googleapis');
async function batchUpload(videoDir) {
const youtube = google.youtube({ version: 'v3', auth: oauth2Client });
const files = fs.readdirSync(videoDir)
.filter(f => f.endsWith('.mp4'))
.sort();
for (const file of files) {
const slug = path.basename(file, '.mp4');
const metaPath = path.join(videoDir, slug + '.json');
const meta = JSON.parse(fs.readFileSync(metaPath));
const res = await youtube.videos.insert({
part: ['snippet', 'status'],
requestBody: {
snippet: {
title: meta.title,
description: meta.description,
tags: meta.tags,
categoryId: '28',
},
status: {
privacyStatus: meta.scheduledAt ? 'private' : 'public',
publishAt: meta.scheduledAt || undefined,
},
},
media: { body: fs.createReadStream(path.join(videoDir, file)) },
});
// Set thumbnail if companion image exists
const thumbPath = path.join(videoDir, slug + '.jpg');
if (fs.existsSync(thumbPath)) {
await youtube.thumbnails.set({
videoId: res.data.id,
media: { body: fs.createReadStream(thumbPath) },
});
}
}
}
Directory Structure
Organize your batch output directory so the script can discover everything automatically through naming conventions:
output/
video-01.mp4
video-01.json # metadata: title, description, tags, scheduledAt
video-01.jpg # thumbnail (1280x720)
video-02.mp4
video-02.json
video-02.jpg
...
Each JSON file contains the metadata for its corresponding video. The naming convention (shared base name with different extensions) keeps metadata tightly coupled with its video file and makes the batch self-documenting.
Quota Math
Each video upload costs 1,600 quota units. Each thumbnail set costs 50 units. Ten videos with thumbnails costs 16,500 units. The default daily quota is 10,000 units. So uploading 10 videos with thumbnails in a single batch exceeds the default quota limit.
Solutions to the quota constraint:
- Apply for higher quota. Google grants quota increases for legitimate content channels. A channel that uploads 10+ videos per day is a reasonable use case that typically gets approved within 1-2 weeks.
- Spread uploads across multiple days. Upload 6 videos today, 4 tomorrow. The script can track remaining quota and automatically pause when approaching the limit, resuming the next day.
- Upload as unlisted first. Unlisted uploads still cost quota, but you can spread the upload activity across off-peak hours and schedule the videos for public release on your preferred publishing dates.
Error Recovery
In a batch of 10 uploads, at least one will probably fail at some point. Network timeouts, transient API errors, rate limiting, and token expiration all happen in practice. The script needs robust error handling:
- Log which videos succeeded with their YouTube video IDs for tracking
- Catch errors per video and continue processing the remaining batch
- Write a failure log that records which videos failed and why
- Support re-running with a flag that skips already-uploaded videos
Never retry immediately on a 403 quota exceeded or 429 rate limited response. Back off for at least 60 seconds before retrying, and implement exponential backoff for repeated failures.
VidNo's Batch Upload
VidNo's pipeline produces batch output in exactly the directory structure described above. When you process multiple source recordings through the pipeline, it renders all of them with captions, generates thumbnails, creates metadata, and then uploads them sequentially with proper error handling and quota awareness. One pipeline command takes a folder of raw recordings and produces uploaded, scheduled, thumbnail-set YouTube videos ready for their publish dates.