YouTube Video Downloader

Disclaimer: Downloading copyrighted material without permission is illegal in many countries and violates YouTube's Terms of Service. This tool is provided for educational purposes only. Use it responsibly and only for videos you have the right to download (e.g., your own content, public domain, or Creative Commons licensed videos where downloading is permitted). The creator of this page is not responsible for any misuse of this tool. External services used by this tool may contain ads or have their own terms of service.

async function getVideoInfo() { const youtubeUrlInput = document.getElementById('youtubeUrl'); const resultsDiv = document.getElementById('results'); const loadingDiv = document.getElementById('loading'); const errorDiv = document.getElementById('error'); const videoUrl = youtubeUrlInput.value.trim(); resultsDiv.innerHTML = ''; // Clear previous results errorDiv.innerHTML = ''; // Clear previous errors loadingDiv.style.display = 'block'; // Show loading indicator if (!videoUrl) { errorDiv.innerHTML = 'Please enter a YouTube URL.'; loadingDiv.style.display = 'none'; return; } // A simple check for YouTube URL pattern (can be improved) if (!videoUrl.match(/^(https|http):\/\/(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)[\w-]+/)) { errorDiv.innerHTML = 'Invalid YouTube URL format.'; loadingDiv.style.display = 'none'; return; } // Using Cobalt API (https://github.com/wukko/cobalt) // It's open source and generally more reliable than shady ad-filled ones. // It requires a POST request. const COBALT_API_ENDPOINT = 'https://api.cobalt.tools/api/json'; try { const response = await fetch(COBALT_API_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' // We want JSON response }, body: JSON.stringify({ url: videoUrl, // You can add more options here if Cobalt supports them, e.g., quality // isAudioOnly: false, // for video + audio // aFormat: "mp3", // if you want specific audio format // vQuality: "720" // if you want specific video quality }) }); loadingDiv.style.display = 'none'; if (!response.ok) { const errorData = await response.json().catch(() => ({ text: 'API request failed with status: ' + response.status })); throw new Error(errorData.text || `API error: ${response.status}`); } const data = await response.json(); if (data.status === 'error') { errorDiv.innerHTML = `Error from service: ${data.text}`; } else if (data.status === 'redirect' || data.status === 'stream') { // Cobalt gives a direct download link in `data.url` for 'stream' or 'redirect' let downloadUrl = data.url; let filename = 'video.mp4'; // Default filename // Try to get a better filename from Content-Disposition header if available // This part is tricky with client-side JS due to CORS for HEAD requests // So we'll rely on the API or a generic name. // If the API provided a filename or title, you could use it here. // For Cobalt, the URL often contains a good hint or is direct. const link = document.createElement('a'); link.href = downloadUrl; link.textContent = `Download Video (Quality: ${data.quality || 'Best Available'})`; link.className = 'download-link'; link.setAttribute('download', filename); // Suggests a filename to the browser link.setAttribute('target', '_blank'); // Open in new tab to start download resultsDiv.appendChild(link); // Cobalt might also return a 'picker' if multiple options are available. // For simplicity, this example handles only the direct 'stream' or 'redirect' status. // You would need to parse data.picker if it exists. // For example: // if (data.status === 'picker' && data.picker && data.picker.length > 0) { // data.picker.forEach(item => { // if (item.type === 'video' && item.url) { // Or audio, etc. // const pickerLink = document.createElement('a'); // pickerLink.href = item.url; // pickerLink.textContent = `Download ${item.quality || item.format || 'Option'}`; // pickerLink.className = 'download-link'; // pickerLink.setAttribute('download', `video_${item.quality || item.format}.mp4`); // pickerLink.setAttribute('target', '_blank'); // resultsDiv.appendChild(pickerLink); // } // }); // } } else if (data.status === 'picker' && data.picker && Array.isArray(data.picker)) { resultsDiv.innerHTML += 'Available options:
'; data.picker.forEach(item => { if (item.url) { // Ensure there's a URL const pickerLink = document.createElement('a'); pickerLink.href = item.url; let label = `Download ${item.type || 'File'}`; if(item.quality) label += ` (${item.quality})`; if(item.format) label += ` - ${item.format}`; if(item.audio) label += ` (Audio: ${item.audio})`; pickerLink.textContent = label; pickerLink.className = 'download-link'; let suggestedFilename = "download"; if(item.type) suggestedFilename = item.type; if(item.quality) suggestedFilename += `_${item.quality}`; if(item.format) suggestedFilename += `.${item.format}`; else if (item.type === 'video') suggestedFilename += ".mp4"; else if (item.type === 'audio') suggestedFilename += ".mp3"; pickerLink.setAttribute('download', suggestedFilename); pickerLink.setAttribute('target', '_blank'); resultsDiv.appendChild(pickerLink); } }); if (resultsDiv.innerHTML === 'Available options:
') { errorDiv.innerHTML = 'No downloadable links found in picker options.'; } } else { errorDiv.innerHTML = 'Unexpected response from service. Status: ' + data.status; console.log('Full API response:', data); } } catch (err) { console.error('Fetch error:', err); loadingDiv.style.display = 'none'; errorDiv.innerHTML = 'Failed to fetch download links. The service might be down or the URL is invalid. Details: ' + err.message; } }

Post a Comment

أحدث أقدم