CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ytdl-core

YouTube video downloader in pure JavaScript with streaming interface and comprehensive metadata extraction.

Overview
Eval results
Files

url-processing.mddocs/

URL Processing

URL validation and video ID extraction supporting all YouTube URL formats including shortened URLs, embed links, and mobile URLs. Provides robust parsing with comprehensive error handling.

Capabilities

Video ID Validation

Validates whether a string matches YouTube's video ID format.

/**
 * Validates if string matches YouTube video ID format
 * @param {string} id - String to validate as video ID
 * @returns {boolean} - Whether string is valid video ID format
 */
function validateID(id);

YouTube video IDs are exactly 11 characters long and contain only alphanumeric characters, hyphens, and underscores.

Usage Examples:

// Valid video IDs
console.log(ytdl.validateID('aqz-KE-bpKQ')); // true
console.log(ytdl.validateID('dQw4w9WgXcQ')); // true

// Invalid video IDs
console.log(ytdl.validateID('too-short'));   // false
console.log(ytdl.validateID('too-long-id')); // false
console.log(ytdl.validateID('invalid@chars')); // false
console.log(ytdl.validateID(''));            // false

URL Validation

Validates whether a URL can be parsed to extract a YouTube video ID.

/**
 * Validates if URL can be parsed to extract video ID
 * @param {string} url - URL to validate
 * @returns {boolean} - Whether URL is valid YouTube URL
 */
function validateURL(url);

Usage Examples:

// Valid YouTube URLs
console.log(ytdl.validateURL('https://www.youtube.com/watch?v=aqz-KE-bpKQ')); // true
console.log(ytdl.validateURL('https://youtu.be/aqz-KE-bpKQ'));                // true
console.log(ytdl.validateURL('https://m.youtube.com/watch?v=aqz-KE-bpKQ'));   // true

// Invalid URLs
console.log(ytdl.validateURL('https://example.com/video'));     // false
console.log(ytdl.validateURL('https://youtube.com/invalid'));   // false
console.log(ytdl.validateURL('not-a-url'));                     // false

Extract Video ID from URL

Extracts the video ID from various YouTube URL formats.

/**
 * Extracts video ID from YouTube URL
 * @param {string} url - YouTube URL
 * @returns {string} - 11-character video ID
 * @throws {Error} - If URL is invalid or no video ID found
 * @throws {TypeError} - If extracted ID doesn't match expected format
 */
function getURLVideoID(url);

Supported URL Formats:

  • https://www.youtube.com/watch?v=VIDEO_ID
  • https://m.youtube.com/watch?v=VIDEO_ID
  • https://youtu.be/VIDEO_ID
  • https://www.youtube.com/v/VIDEO_ID
  • https://www.youtube.com/embed/VIDEO_ID
  • https://www.youtube.com/shorts/VIDEO_ID
  • https://music.youtube.com/watch?v=VIDEO_ID
  • https://gaming.youtube.com/watch?v=VIDEO_ID

Usage Examples:

// Standard watch URLs
const id1 = ytdl.getURLVideoID('https://www.youtube.com/watch?v=aqz-KE-bpKQ');
console.log(id1); // 'aqz-KE-bpKQ'

// Shortened URLs
const id2 = ytdl.getURLVideoID('https://youtu.be/dQw4w9WgXcQ');
console.log(id2); // 'dQw4w9WgXcQ'

// Embed URLs
const id3 = ytdl.getURLVideoID('https://www.youtube.com/embed/aqz-KE-bpKQ');
console.log(id3); // 'aqz-KE-bpKQ'

// Mobile URLs
const id4 = ytdl.getURLVideoID('https://m.youtube.com/watch?v=aqz-KE-bpKQ&t=30s');
console.log(id4); // 'aqz-KE-bpKQ'

// Music URLs
const id5 = ytdl.getURLVideoID('https://music.youtube.com/watch?v=aqz-KE-bpKQ&list=PLrAXtmRdnEQy4Qg8SU5U6QP0X3bL5T8lN');
console.log(id5); // 'aqz-KE-bpKQ'

// URLs with extra parameters are handled
const id6 = ytdl.getURLVideoID('https://www.youtube.com/watch?v=aqz-KE-bpKQ&list=PLxxx&index=1&t=120s');
console.log(id6); // 'aqz-KE-bpKQ'

Get Video ID (Flexible)

Gets video ID from either a URL or validates if the input is already a video ID.

/**
 * Gets video ID from URL or validates if already an ID
 * @param {string} str - URL or video ID string
 * @returns {string} - 11-character video ID
 * @throws {Error} - If unable to extract valid video ID
 * @throws {TypeError} - If extracted ID doesn't match expected format
 */
function getVideoID(str);

This is the most flexible function - it handles both URLs and direct video IDs.

Usage Examples:

// Works with URLs
const id1 = ytdl.getVideoID('https://www.youtube.com/watch?v=aqz-KE-bpKQ');
console.log(id1); // 'aqz-KE-bpKQ'

// Works with direct video IDs
const id2 = ytdl.getVideoID('aqz-KE-bpKQ');
console.log(id2); // 'aqz-KE-bpKQ'

// Automatically detects format
function processVideo(input) {
  try {
    const videoId = ytdl.getVideoID(input);
    console.log(`Processing video: ${videoId}`);
    return ytdl.getInfo(videoId);
  } catch (error) {
    console.error('Invalid video input:', error.message);
  }
}

processVideo('https://youtu.be/dQw4w9WgXcQ');  // Works
processVideo('dQw4w9WgXcQ');                   // Also works
processVideo('invalid-input');                 // Throws error

URL Format Details

Standard YouTube Domains

Valid domains for query-based URLs:

  • youtube.com
  • www.youtube.com
  • m.youtube.com (mobile)
  • music.youtube.com
  • gaming.youtube.com

Path-based URL Patterns

URLs where the video ID is in the path:

  • youtu.be/VIDEO_ID (shortened)
  • youtube.com/embed/VIDEO_ID (embed)
  • youtube.com/v/VIDEO_ID (old format)
  • youtube.com/shorts/VIDEO_ID (shorts)

Query Parameter Handling

For query-based URLs, the video ID is extracted from the v parameter:

// All of these extract the same video ID
ytdl.getVideoID('https://www.youtube.com/watch?v=aqz-KE-bpKQ');
ytdl.getVideoID('https://www.youtube.com/watch?v=aqz-KE-bpKQ&t=30s');
ytdl.getVideoID('https://www.youtube.com/watch?list=PLxxx&v=aqz-KE-bpKQ&index=2');
ytdl.getVideoID('https://www.youtube.com/watch?feature=youtu.be&v=aqz-KE-bpKQ');

Error Handling

Common Errors and Solutions

try {
  const videoId = ytdl.getVideoID(userInput);
} catch (error) {
  if (error.message.includes('Not a YouTube domain')) {
    console.error('URL is not from YouTube');
  } else if (error.message.includes('No video id found')) {
    console.error('URL does not contain a video ID'); 
  } else if (error.message.includes('does not match expected format')) {
    console.error('Video ID format is invalid');
  } else {
    console.error('Unknown URL parsing error:', error.message);
  }
}

Input Validation Pattern

Robust input validation for user-provided URLs or IDs:

function sanitizeVideoInput(input) {
  if (!input || typeof input !== 'string') {
    throw new Error('Input must be a non-empty string');
  }
  
  // Trim whitespace
  input = input.trim();
  
  // Check if it looks like a URL
  if (input.includes('youtube.com') || input.includes('youtu.be')) {
    // Validate URL format
    if (!ytdl.validateURL(input)) {
      throw new Error('Invalid YouTube URL format');
    }
    return ytdl.getURLVideoID(input);
  } else {
    // Assume it's a video ID
    if (!ytdl.validateID(input)) {
      throw new Error('Invalid video ID format');
    }
    return input;
  }
}

// Usage
try {
  const videoId = sanitizeVideoInput(userInput);
  const info = await ytdl.getInfo(videoId);
} catch (error) {
  console.error('Invalid input:', error.message);
}

Batch URL Processing

Processing multiple URLs with error handling:

async function processVideoURLs(urls) {
  const results = [];
  
  for (const url of urls) {
    try {
      const videoId = ytdl.getVideoID(url);
      const info = await ytdl.getBasicInfo(videoId);
      
      results.push({
        url,
        videoId,
        title: info.videoDetails.title,
        success: true
      });
    } catch (error) {
      results.push({
        url,
        error: error.message,
        success: false
      });
    }
  }
  
  return results;
}

// Process mixed input
const urls = [
  'https://www.youtube.com/watch?v=aqz-KE-bpKQ',
  'https://youtu.be/dQw4w9WgXcQ',
  'invalid-url',
  'aqz-KE-bpKQ'
];

const results = await processVideoURLs(urls);
results.forEach(result => {
  if (result.success) {
    console.log(`✓ ${result.title} (${result.videoId})`);
  } else {
    console.log(`✗ ${result.url}: ${result.error}`);
  }
});

Integration Patterns

URL Normalization

Normalize different URL formats to a standard format:

function normalizeYouTubeURL(input) {
  const videoId = ytdl.getVideoID(input);
  return `https://www.youtube.com/watch?v=${videoId}`;
}

// All of these become the same normalized URL
console.log(normalizeYouTubeURL('https://youtu.be/aqz-KE-bpKQ'));
console.log(normalizeYouTubeURL('https://m.youtube.com/watch?v=aqz-KE-bpKQ'));
console.log(normalizeYouTubeURL('aqz-KE-bpKQ'));
// All output: https://www.youtube.com/watch?v=aqz-KE-bpKQ

User Input Handling

Create user-friendly interfaces that accept flexible input:

class YouTubeProcessor {
  async process(input) {
    try {
      // Flexible input handling
      const videoId = ytdl.getVideoID(input);
      
      console.log(`Processing video ID: ${videoId}`);
      
      // Check if video exists and is accessible
      const basicInfo = await ytdl.getBasicInfo(videoId);
      
      if (basicInfo.videoDetails.isPrivate) {
        throw new Error('Video is private');
      }
      
      return basicInfo;
      
    } catch (error) {
      throw new Error(`Failed to process input "${input}": ${error.message}`);
    }
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-ytdl-core

docs

format-selection.md

index.md

url-processing.md

video-downloading.md

video-information.md

tile.json