Overview
The downloader types define data structures for video downloading, format selection, search results, and download task management.
Location: /workspace/source/src/types/downloader.ts
Represents a single video or audio format available for download.
interface VideoFormat {
format_id: string;
ext: string;
quality: string;
resolution?: string;
filesize?: number;
filesize_approx?: string;
vcodec?: string;
acodec?: string;
abr?: number;
vbr?: number;
fps?: number;
asr?: number;
audio_channels?: number;
format_note: string;
}
Fields
Unique identifier for this format (used for selecting specific formats).
File extension (e.g., "mp4", "webm", "m4a").
Quality label (e.g., "1080p", "720p", "audio only").
Video resolution (e.g., "1920x1080", "1280x720").
Exact file size in bytes (may be undefined if unknown).
Approximate file size as a human-readable string (e.g., "150 MB").
Video codec (e.g., "avc1.64001f", "vp9", "none" for audio-only).
Audio codec (e.g., "opus", "mp4a.40.2", "none" for video-only).
Audio bitrate in kbps (e.g., 128, 192, 256).
Frames per second (e.g., 30, 60).
Audio sample rate in Hz (e.g., 44100, 48000).
Number of audio channels (e.g., 1 for mono, 2 for stereo).
Human-readable format description (e.g., "1080p (mp4)", "medium, m4a").
Example
const formats: VideoFormat[] = [
{
format_id: '137',
ext: 'mp4',
quality: '1080p',
resolution: '1920x1080',
filesize: 157286400,
vcodec: 'avc1.640028',
acodec: 'none',
vbr: 4000,
fps: 30,
format_note: '1080p (mp4)',
},
{
format_id: '251',
ext: 'webm',
quality: 'audio only',
filesize: 4194304,
vcodec: 'none',
acodec: 'opus',
abr: 160,
asr: 48000,
audio_channels: 2,
format_note: 'medium, webm',
},
];
VideoInfo
Complete information about a YouTube video, including all available formats.
interface VideoInfo {
id: string;
title: string;
description: string;
thumbnail: string;
duration: number;
uploader: string;
uploader_url: string;
view_count: number;
like_count: number;
upload_date: string;
formats: VideoFormat[];
subtitles: Record<string, Array<{url: string; name: string}>>;
is_playlist: boolean;
playlist_count?: number;
webpage_url: string;
}
Fields
YouTube video ID (e.g., "dQw4w9WgXcQ").
URL to video thumbnail image.
Video duration in seconds.
Channel name / uploader name.
URL to uploader’s channel page.
Upload date in YYYYMMDD format (e.g., "20240115").
Array of all available download formats.
subtitles
Record<string, Array<{url: string; name: string}>>
required
Available subtitles indexed by language code.
Whether the URL is a playlist.
Number of videos in the playlist (only if is_playlist is true).
Example
const videoInfo: VideoInfo = {
id: 'dQw4w9WgXcQ',
title: 'Rick Astley - Never Gonna Give You Up',
description: 'The official video for "Never Gonna Give You Up" by Rick Astley...',
thumbnail: 'https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg',
duration: 212,
uploader: 'Rick Astley',
uploader_url: 'https://www.youtube.com/@RickAstley',
view_count: 1400000000,
like_count: 15000000,
upload_date: '20091025',
formats: [
// ... array of VideoFormat objects
],
subtitles: {
en: [{ url: 'https://...', name: 'English' }],
es: [{ url: 'https://...', name: 'Spanish' }],
},
is_playlist: false,
webpage_url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
};
SearchResult
Represents a single video in search results or trending list.
interface SearchResult {
id: string;
title: string;
duration: number;
uploader: string;
thumbnail: string;
url: string;
view_count: number;
}
Fields
Example
const searchResults: SearchResult[] = [
{
id: 'abc123',
title: 'How to Learn TypeScript',
duration: 1230,
uploader: 'Code Academy',
thumbnail: 'https://i.ytimg.com/vi/abc123/hqdefault.jpg',
url: 'https://www.youtube.com/watch?v=abc123',
view_count: 500000,
},
];
DownloadTask
Represents an active or completed download task with progress tracking.
interface DownloadTask {
id: string;
url: string;
title: string;
status: 'pending' | 'downloading' | 'processing' | 'completed' | 'error' | 'cancelled';
progress: number;
speed: string;
eta: string;
thumbnail: string;
format_note: string;
filesize: number;
downloaded_bytes: number;
is_playlist: boolean;
playlist_index: number;
playlist_total: number;
quality: string;
download_type: string;
created_at: string;
completed_at?: string;
error_message?: string;
filename?: string;
}
Fields
status
'pending' | 'downloading' | 'processing' | 'completed' | 'error' | 'cancelled'
required
Current download status.
Download progress as a percentage (0-100).
Current download speed (e.g., "3.2 MB/s", "0 B/s").
Estimated time remaining (e.g., "2m 15s", "Unknown").
Format description (e.g., "1080p (mp4)").
Total file size in bytes.
Whether this is part of a playlist download.
Current video index in playlist (0 if not a playlist).
Total videos in playlist (0 if not a playlist).
Selected quality (e.g., "1080p", "720p").
Type of download (e.g., "video", "audio").
ISO 8601 timestamp when download was created.
ISO 8601 timestamp when download completed (only for completed downloads).
Error message (only for failed downloads).
Downloaded filename (only for completed downloads).
Example
const downloadTask: DownloadTask = {
id: 'dl_001',
url: 'https://www.youtube.com/watch?v=abc123',
title: 'Amazing Tutorial Video',
status: 'downloading',
progress: 45.5,
speed: '3.2 MB/s',
eta: '2m 15s',
thumbnail: 'https://i.ytimg.com/vi/abc123/hqdefault.jpg',
format_note: '1080p (mp4)',
filesize: 157286400,
downloaded_bytes: 71557939,
is_playlist: false,
playlist_index: 0,
playlist_total: 0,
quality: '1080p',
download_type: 'video',
created_at: '2024-01-15T10:30:00Z',
};
DownloadOptions
Options for initiating a new download.
interface DownloadOptions {
url: string;
format_id?: string;
quality: string;
download_type: 'video' | 'audio';
subtitle_langs: string[];
download_thumbnail: boolean;
}
Fields
YouTube video or playlist URL.
Specific format ID to download (optional, uses quality if not specified).
Desired quality (e.g., "1080p", "720p", "best").
download_type
'video' | 'audio'
required
Whether to download video or audio-only.
Array of language codes for subtitles to download (e.g., ["en", "es"]).
Whether to download the video thumbnail.
Example
const downloadOptions: DownloadOptions = {
url: 'https://www.youtube.com/watch?v=abc123',
format_id: '137+251', // Video format + audio format
quality: '1080p',
download_type: 'video',
subtitle_langs: ['en', 'es'],
download_thumbnail: true,
};
// Send to backend
fetch('/api/download', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(downloadOptions),
});
ViewMode
Defines the current view mode in the downloader interface.
type ViewMode = 'player' | 'explorer' | 'downloads';
Values
'player': Video player view
'explorer': YouTube search/browse view
'downloads': Download manager view
Example
import { useState } from 'react';
import type { ViewMode } from '@/types/downloader';
function DownloaderApp() {
const [viewMode, setViewMode] = useState<ViewMode>('explorer');
return (
<div>
<nav>
<button onClick={() => setViewMode('explorer')}>Explorer</button>
<button onClick={() => setViewMode('downloads')}>Downloads</button>
<button onClick={() => setViewMode('player')}>Player</button>
</nav>
{viewMode === 'explorer' && <YouTubeExplorer />}
{viewMode === 'downloads' && <DownloadManager />}
{viewMode === 'player' && <VideoPlayer />}
</div>
);
}
Type Utilities
function getVideoFormats(formats: VideoFormat[]): VideoFormat[] {
return formats.filter(f => f.vcodec !== 'none');
}
function getAudioFormats(formats: VideoFormat[]): VideoFormat[] {
return formats.filter(f => f.acodec !== 'none' && f.vcodec === 'none');
}
function getBestFormat(formats: VideoFormat[], quality: string): VideoFormat | undefined {
return formats
.filter(f => f.quality === quality && f.vcodec !== 'none')
.sort((a, b) => (b.filesize || 0) - (a.filesize || 0))[0];
}
Status Helpers
function isActiveDownload(task: DownloadTask): boolean {
return ['pending', 'downloading', 'processing'].includes(task.status);
}
function isCompletedDownload(task: DownloadTask): boolean {
return task.status === 'completed';
}
function hasError(task: DownloadTask): boolean {
return task.status === 'error';
}
function formatBytes(bytes: number): string {
if (bytes === 0) return '0 B';
const sizes = ['B', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(1024));
return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${sizes[i]}`;
}
function formatDuration(seconds: number): string {
const hrs = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
if (hrs > 0) return `${hrs}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
return `${mins}:${secs.toString().padStart(2, '0')}`;
}