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

video-downloading.mddocs/

Video Downloading

Core streaming download functionality for YouTube videos with extensive configuration options, progress tracking, and support for various video formats including live streams.

Capabilities

Main Download Function

Downloads a YouTube video and returns a readable stream with comprehensive options for customization.

/**
 * Downloads a YouTube video and returns a readable stream
 * @param {string} url - YouTube video URL or video ID
 * @param {downloadOptions} options - Download configuration options
 * @returns {stream.Readable} - Readable stream of video data
 */
function ytdl(url, options);

interface downloadOptions {
  // Range options
  range?: {
    start?: number;  // Start byte position
    end?: number;    // End byte position
  };
  
  // Timing options
  begin?: string | number | Date;  // Start time (e.g., '1:30', '05:10.123', '10m30s')
  liveBuffer?: number;             // Live stream buffer in milliseconds (default: 20000)
  
  // Stream options
  highWaterMark?: number;  // Buffer size in bytes (default: 512KB)
  dlChunkSize?: number;    // Chunk size for video-only/audio-only downloads (default: 10MB, 0 to disable)
  
  // Network options
  IPv6Block?: string;        // IPv6 block for request rotation
  requestOptions?: object;   // Options passed to miniget
  requestCallback?: function; // Callback for request streams
  
  // Format selection (inherited from chooseFormatOptions)
  quality?: string | number | string[] | number[];
  filter?: string | function;
  format?: object;
  
  // Info options (inherited from getInfoOptions)
  lang?: string;  // Language code (default: 'en')
}

Usage Examples:

const ytdl = require('ytdl-core');
const fs = require('fs');

// Basic download
ytdl('https://www.youtube.com/watch?v=aqz-KE-bpKQ')
  .pipe(fs.createWriteStream('video.mp4'));

// Download with range (bytes 1000-5000)
ytdl(videoUrl, {
  range: { start: 1000, end: 5000 }
}).pipe(outputStream);

// Download starting from specific time
ytdl(videoUrl, {
  begin: '1:30'  // Start at 1 minute 30 seconds
}).pipe(outputStream);

// Download with specific quality
ytdl(videoUrl, {
  quality: 'highestaudio'
}).pipe(outputStream);

// Download with IPv6 rotation
ytdl(videoUrl, {
  IPv6Block: '2001:2::/48'
}).pipe(outputStream);

Download from Pre-fetched Info

Downloads video using previously fetched video information, useful when you want to examine video details before downloading.

/**
 * Downloads video using pre-fetched info object
 * @param {videoInfo} info - Video info from getInfo() (must have full: true)
 * @param {downloadOptions} options - Download options
 * @returns {stream.Readable} - Readable stream of video data
 * @throws {Error} - If info is from getBasicInfo() (full: false)
 */
function downloadFromInfo(info, options);

Usage Examples:

// Get info first, then download
const info = await ytdl.getInfo(videoUrl);
console.log(`Downloading: ${info.videoDetails.title}`);

const stream = ytdl.downloadFromInfo(info, {
  quality: 'highest'
});
stream.pipe(fs.createWriteStream('video.mp4'));

Stream Events

The returned stream emits several events for monitoring download progress and handling responses.

Event: 'info'

Emitted when video information is fetched and format is chosen.

/**
 * Emitted when video info is fetched and format is selected
 * @param {videoInfo} info - Complete video information
 * @param {videoFormat} format - Selected format for download
 */
stream.on('info', (info, format) => {
  console.log(`Title: ${info.videoDetails.title}`);
  console.log(`Format: ${format.qualityLabel} ${format.container}`);
});

Event: 'progress'

Emitted during download to track progress.

/**
 * Emitted during download for progress tracking
 * @param {number} chunkLength - Length of current chunk or segment number
 * @param {number} downloaded - Total bytes downloaded or segments completed
 * @param {number} total - Total bytes or total segments
 */
stream.on('progress', (chunkLength, downloaded, total) => {
  const percent = downloaded / total * 100;
  console.log(`Downloaded ${percent.toFixed(1)}%`);
});

Miniget Events

All miniget request events are forwarded and can be listened to:

// Network events forwarded from miniget
stream.on('request', (req) => { /* HTTP request started */ });
stream.on('response', (res) => { /* HTTP response received */ });
stream.on('redirect', (url) => { /* Request redirected */ });
stream.on('retry', (retryCount) => { /* Request retried */ });
stream.on('reconnect', (reconnectCount) => { /* Connection reconnected */ });
stream.on('abort', () => { /* Request aborted */ });
stream.on('error', (err) => { /* Error occurred */ });

Stream Control

Destroy Stream

Aborts and stops downloading a video.

/**
 * Aborts the download and destroys the stream
 */
stream.destroy();

Usage Example:

const stream = ytdl(videoUrl);
stream.pipe(outputStream);

// Abort after 5 seconds
setTimeout(() => {
  stream.destroy();
  console.log('Download aborted');
}, 5000);

Download Options Details

Range Downloads

Specify byte ranges for partial content downloads (not supported for segmented formats).

// Download first 1MB
ytdl(url, { range: { start: 0, end: 1024 * 1024 } })

// Download from 1MB onwards
ytdl(url, { range: { start: 1024 * 1024 } })

Time-based Downloads

Start downloading from specific timestamps.

// Various time formats supported
ytdl(url, { begin: '1:30' })        // 1 minute 30 seconds
ytdl(url, { begin: '05:10.123' })   // 5 minutes 10.123 seconds
ytdl(url, { begin: '10m30s' })      // 10 minutes 30 seconds
ytdl(url, { begin: 90000 })         // 90 seconds (milliseconds)

// For live videos, use Unix timestamp or Date
ytdl(liveUrl, { begin: Date.now() }) // Start from now
ytdl(liveUrl, { begin: new Date('2023-01-01T10:00:00Z') })

IPv6 Block Rotation

Use IPv6 address rotation to avoid rate limiting.

ytdl(url, {
  IPv6Block: '2001:2::/48'  // Rotates through IPv6 addresses in this block
})

Chunked Downloads

Control download chunking for video-only or audio-only formats.

ytdl(url, {
  dlChunkSize: 1024 * 1024 * 5  // 5MB chunks (default: 10MB)
})

ytdl(url, {
  dlChunkSize: 0  // Disable chunking
})

Error Handling

Common errors and how to handle them:

const stream = ytdl(url);

stream.on('error', (err) => {
  if (err.message.includes('unavailable')) {
    console.error('Video is unavailable');
  } else if (err.message.includes('private')) {
    console.error('Video is private');
  } else if (err.statusCode === 429) {
    console.error('Rate limited - try using proxies or IPv6 rotation');
  } else {
    console.error('Download error:', err.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