UNPKG

@ytb-dw/sdk

Version:

Official JavaScript SDK for ytb-dw YouTube download service - Download YouTube videos and audio with ease

205 lines (173 loc) 6.75 kB
class YtbDwClient { constructor(apiKey, baseUrl = 'https://ytb-dw-api.onrender.com') { if (!apiKey) { throw new Error('API key is required'); } this.apiKey = apiKey; this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash } /** * Get video information without downloading * @param {string} url - YouTube video URL * @returns {Promise<Object>} Video information */ async getVideoInfo(url) { if (!url) { throw new Error('YouTube URL is required'); } try { const response = await fetch(`${this.baseUrl}/video_info.php?url=${encodeURIComponent(url)}`); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${this._getErrorMessage(response.status)}`); } const data = await response.json(); if (!data.success) { throw new Error(data.error || 'Unknown error occurred'); } return data; } catch (error) { throw new Error(`Failed to get video info: ${error.message}`); } } /** * Download a YouTube video * @param {string} url - YouTube video URL * @param {Object} options - Download options * @param {string} options.format - 'audio' or 'video' (default: 'video') * @param {string} options.quality - '480', '720', '1080', 'best' (default: 'best') * @returns {Promise<Response>} Download response */ async downloadVideo(url, options = {}) { if (!url) { throw new Error('YouTube URL is required'); } const { format = 'video', quality = 'best' } = options; const params = new URLSearchParams({ api_key: this.apiKey, url: url, format: format, quality: quality }); try { const response = await fetch(`${this.baseUrl}/download.php?${params.toString()}`); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${this._getErrorMessage(response.status)}`); } return response; } catch (error) { throw new Error(`Failed to download video: ${error.message}`); } } /** * Download video as audio (MP3) * @param {string} url - YouTube video URL * @returns {Promise<Response>} Download response */ async downloadAudio(url) { return this.downloadVideo(url, { format: 'audio' }); } /** * Download video in specific quality * @param {string} url - YouTube video URL * @param {string} quality - Video quality ('480', '720', '1080', 'best') * @returns {Promise<Response>} Download response */ async downloadVideoQuality(url, quality) { return this.downloadVideo(url, { format: 'video', quality }); } /** * Get download URL (for browser usage) * @param {string} url - YouTube video URL * @param {Object} options - Download options * @returns {string} Download URL */ getDownloadUrl(url, options = {}) { if (!url) { throw new Error('YouTube URL is required'); } const { format = 'video', quality = 'best' } = options; const params = new URLSearchParams({ api_key: this.apiKey, url: url, format: format, quality: quality }); return `${this.baseUrl}/download.php?${params.toString()}`; } /** * Download and save file (Node.js only) * @param {string} url - YouTube video URL * @param {string} filename - Output filename * @param {Object} options - Download options * @returns {Promise<void>} */ async downloadToFile(url, filename, options = {}) { // Check if we're in Node.js environment if (typeof window !== 'undefined') { throw new Error('downloadToFile is only available in Node.js environment'); } const fs = require('fs'); const path = require('path'); try { const response = await this.downloadVideo(url, options); // Ensure directory exists const dir = path.dirname(filename); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } const fileStream = fs.createWriteStream(filename); // For Node.js, we need to handle the stream if (response.body) { const reader = response.body.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; fileStream.write(Buffer.from(value)); } } fileStream.end(); console.log(`Download completed: ${filename}`); } catch (error) { throw new Error(`Failed to download to file: ${error.message}`); } } /** * Open download in browser (browser only) * @param {string} url - YouTube video URL * @param {Object} options - Download options */ openDownload(url, options = {}) { if (typeof window === 'undefined') { throw new Error('openDownload is only available in browser environment'); } const downloadUrl = this.getDownloadUrl(url, options); window.open(downloadUrl, '_blank'); } /** * Get error message from HTTP status code * @private */ _getErrorMessage(statusCode) { const errorMessages = { 400: 'Bad Request - Missing or invalid parameters', 401: 'Unauthorized - Invalid or inactive API key', 403: 'Forbidden - Format not authorized for your account', 404: 'Not Found - Video not found or private', 429: 'Too Many Requests - Daily quota exceeded', 500: 'Internal Server Error - Temporary server error' }; return errorMessages[statusCode] || 'Unknown error'; } } // Export for different environments if (typeof module !== 'undefined' && module.exports) { // Node.js module.exports = YtbDwClient; } else if (typeof window !== 'undefined') { // Browser window.YtbDwClient = YtbDwClient; } // Default export for ES6 modules if (typeof exports !== 'undefined') { exports.default = YtbDwClient; }