Uploading videos to YouTube does not always require a web interface. Developers and content creators who prefer automation and efficiency can leverage open-source command-line tools for YouTube uploads. This guide explores how to streamline your video export workflow, including bulk uploads and video metadata management, using CLI tools.

Available CLI tools for YouTube uploads

Several open-source tools can help you upload videos to YouTube from the command line:

  • youtube-upload: A Python-based tool with broad functionality.
  • youtubeuploader: A Go-based uploader with good performance.
  • upload-to-youtube: A Node.js CLI utility.

We will focus on youtube-upload as it is widely used and feature-rich.

Setting up youtube-upload

First, install the tool using pip:

pip install youtube-upload

Oauth 2.0 authentication setup

To authenticate the youtube-upload tool, follow these steps:

  1. Visit the Google Cloud Console.
  2. Create a new project or select an existing one.
  3. In the APIs & Services dashboard, click on Enable APIs and Services.
  4. Search for and enable the YouTube Data API v3.
  5. In the Credentials section, click Create Credentials and select OAuth client ID.
  6. Choose Desktop app as the application type, and provide a name if desired.
  7. Click Create to generate the OAuth 2.0 credentials.
  8. Download the client secrets JSON file.

Save the client secrets file as client_secrets.json in your working directory.

Basic upload command

To upload a single video, use the following command:

youtube-upload \
  --title="My Video Title" \
  --description="Video description" \
  --category="Science & Technology" \
  --privacy="private" \
  --client-secrets="client_secrets.json" \
  video.mp4
  • --title: The title of your video.
  • --description: A description for your video.
  • --category: The YouTube category for your video.
  • --privacy: The privacy setting (public, unlisted, or private).
  • --client-secrets: Path to your OAuth 2.0 client secrets file.
  • video.mp4: The path to your video file.

Managing video metadata

For more comprehensive video information, you can create a metadata file in JSON format. This allows you to include additional details such as tags, category ID, and language settings.

Create a metadata.json file with the following content:

{
  "title": "My Video Title",
  "description": "Detailed video description\nWith multiple lines",
  "tags": ["programming", "tutorial", "tech"],
  "privacyStatus": "private",
  "categoryId": "28",
  "language": "en"
}
  • title: The title of your video.
  • description: A detailed description.
  • tags: An array of tags associated with your video.
  • privacyStatus: The privacy setting.
  • categoryId: The numerical ID of the YouTube category.
  • language: The language code (e.g., en for English).

Note: You can find category IDs in the YouTube API documentation. For example, 28 corresponds to "Science & Technology".

To upload using the metadata file, run:

youtube-upload --metadata-json=metadata.json video.mp4

Batch upload script

If you have multiple videos to upload, you can automate the process by creating a shell script. This script will iterate over all video files in a directory and upload them, optionally using corresponding metadata files.

Create a shell script named batch-upload.sh:

#!/bin/bash

VIDEO_DIR="./videos"
METADATA_DIR="./metadata"

for video in "$VIDEO_DIR"/*.mp4; do
  filename=$(basename "$video")
  name="${filename%.*}"

  if [ -f "$METADATA_DIR/$name.json" ]; then
    echo "Uploading $filename with metadata"
    youtube-upload \
      --metadata-json="$METADATA_DIR/$name.json" \
      --client-secrets="client_secrets.json" \
      "$video"
  else
    echo "Uploading $filename with default settings"
    youtube-upload \
      --title="$name" \
      --privacy="private" \
      --client-secrets="client_secrets.json" \
      "$video"
  fi

  # Avoid API rate limits
  sleep 5
done

Make the script executable:

chmod +x batch-upload.sh

Before running the script, ensure you have:

  • A directory ./videos containing your video files (e.g., video1.mp4, video2.mp4).
  • Optionally, a directory ./metadata containing metadata files named after your videos (e.g., video1.json, video2.json).

Run the script:

./batch-upload.sh

This script processes each video file, checks for a corresponding metadata file, and uploads accordingly. It includes a delay (sleep 5) between uploads to avoid hitting API rate limits.

Automated workflow integration

You can integrate YouTube uploads into your applications by creating scripts that automatically process and upload videos. The following Node.js example demonstrates how to watch a directory for new video files, generate metadata, and upload them using youtube-upload.

Create a script named auto-upload.js:

const { exec } = require('child_process')
const fs = require('fs')
const path = require('path')
const util = require('util')

const execAsync = util.promisify(exec)

const processAndUpload = async (videoPath) => {
  try {
    // Generate metadata based on video properties
    const metadata = {
      title: path.basename(videoPath, path.extname(videoPath)),
      description: `Uploaded on ${new Date().toISOString()}`,
      tags: ['auto-upload'],
      privacyStatus: 'private',
    }

    // Write metadata to temporary file
    const metadataPath = `${videoPath}.json`
    fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2))

    // Execute upload command
    const command = `youtube-upload --metadata-json="${metadataPath}" --client-secrets="client_secrets.json" "${videoPath}"`

    const { stdout, stderr } = await execAsync(command)
    if (stderr) {
      console.error(`Upload stderr: ${stderr}`)
    }
    console.log(`Upload successful: ${stdout}`)

    // Clean up
    fs.unlinkSync(metadataPath)
  } catch (error) {
    console.error(`Upload failed: ${error.message}`)
  }
}

// Watch directory for new videos
const watchDir = './uploads'
fs.watch(watchDir, (eventType, filename) => {
  if (eventType === 'rename' && filename.match(/\.(mp4|mov)$/i)) {
    const videoPath = path.join(watchDir, filename)
    if (fs.existsSync(videoPath)) {
      processAndUpload(videoPath)
    }
  }
})

To run the script:

  1. Install the required Node.js modules:

    npm install fs path util child_process
    
  2. Start the script:

    node auto-upload.js
    

Place your video files in the ./uploads directory, and the script will automatically process and upload them to YouTube.

Troubleshooting common issues

Rate limiting

The YouTube API imposes quotas on the number of requests you can make in a given period. If you exceed these limits, you may receive errors or temporary bans.

To mitigate this, add delays between uploads in your scripts. For example, include a sleep command to wait a specified amount of time between uploads:

sleep 60  # Wait 60 seconds between uploads

Adjust the delay as needed based on your upload frequency and quota limits.

Authentication errors

If you encounter authentication issues, such as invalid credentials or expired tokens, follow these steps to resolve them:

  1. Delete the existing OAuth 2.0 token file, typically named youtube-upload-credentials.json or similar.
  2. Regenerate your client secrets by returning to the Google Cloud Console, and creating new OAuth 2.0 credentials.
  3. Save the new client_secrets.json file in your working directory.
  4. Run the upload command again. You will be prompted to authenticate your application.

Failed uploads

Network issues or temporary API errors may cause uploads to fail. Implement a retry mechanism in your scripts to handle transient failures. Here's an example function for a shell script:

upload_with_retry() {
  max_attempts=3
  attempt=1

  while [ $attempt -le $max_attempts ]; do
    youtube-upload "$@" && break
    echo "Attempt $attempt failed. Retrying in 30 seconds..."
    attempt=$((attempt + 1))
    sleep 30
  done

  if [ $attempt -gt $max_attempts ]; then
    echo "Upload failed after $max_attempts attempts."
  fi
}

Use this function in your script when calling youtube-upload:

upload_with_retry --title="Video" --client-secrets="client_secrets.json" video.mp4

Conclusion

Uploading videos to YouTube via the command line streamlines the publishing process and allows developers to automate workflows effectively. By leveraging open-source tools like youtube-upload, you can perform bulk uploads, manage video metadata, and integrate uploads into custom scripts or applications.

For more advanced video processing needs before uploading to YouTube, consider using Transloadit's Video Encoding Service. It offers powerful features to encode and process videos at scale.