Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>YTDownloader - Free YouTube Video Downloader</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<script> | |
tailwind.config = { | |
darkMode: 'class', | |
theme: { | |
extend: { | |
animation: { | |
'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite', | |
'bounce-slow': 'bounce 2s infinite' | |
}, | |
colors: { | |
primary: { | |
light: '#FF0000', | |
dark: '#FF3333' | |
} | |
} | |
} | |
} | |
} | |
</script> | |
<style> | |
.gradient-bg { | |
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
} | |
.dark .gradient-bg { | |
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); | |
} | |
.video-card { | |
transition: all 0.3s ease; | |
} | |
.video-card:hover { | |
transform: translateY(-5px); | |
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); | |
} | |
.dark .video-card:hover { | |
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3); | |
} | |
.loader { | |
border-top-color: #FF0000; | |
-webkit-animation: spinner 1.5s linear infinite; | |
animation: spinner 1.5s linear infinite; | |
} | |
@-webkit-keyframes spinner { | |
0% { -webkit-transform: rotate(0deg); } | |
100% { -webkit-transform: rotate(360deg); } | |
} | |
@keyframes spinner { | |
0% { transform: rotate(0deg); } | |
100% { transform: rotate(360deg); } | |
} | |
</style> | |
</head> | |
<body class="gradient-bg min-h-screen transition-colors duration-300"> | |
<div class="container mx-auto px-4 py-8"> | |
<!-- Header --> | |
<header class="flex justify-between items-center mb-10"> | |
<div class="flex items-center"> | |
<i class="fab fa-youtube text-4xl mr-3 text-primary-light dark:text-primary-dark"></i> | |
<h1 class="text-3xl font-bold text-gray-800 dark:text-white"> | |
<span class="text-primary-light dark:text-primary-dark">YT</span>Downloader | |
</h1> | |
</div> | |
<button id="themeToggle" class="p-2 rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200"> | |
<i class="fas fa-moon dark:hidden"></i> | |
<i class="fas fa-sun hidden dark:block"></i> | |
</button> | |
</header> | |
<!-- Main Content --> | |
<main> | |
<div class="max-w-3xl mx-auto"> | |
<!-- Search Box --> | |
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 mb-8 transition-all duration-300 hover:shadow-xl"> | |
<h2 class="text-xl font-semibold mb-4 text-gray-800 dark:text-white">Download YouTube Videos</h2> | |
<div class="flex flex-col md:flex-row gap-4"> | |
<input | |
type="text" | |
id="videoUrl" | |
placeholder="Paste YouTube or YouTube Music URL here..." | |
class="flex-grow px-4 py-3 rounded-lg border border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-2 focus:ring-primary-light dark:focus:ring-primary-dark bg-white dark:bg-gray-700 text-gray-800 dark:text-white" | |
> | |
<button | |
id="downloadBtn" | |
class="px-6 py-3 bg-primary-light dark:bg-primary-dark text-white rounded-lg font-medium hover:opacity-90 transition-opacity flex items-center justify-center" | |
> | |
<i class="fas fa-download mr-2"></i> Download | |
</button> | |
</div> | |
<p class="text-sm text-gray-500 dark:text-gray-400 mt-3">Supports YouTube & YouTube Music - All formats: MP4, WEBM, 3GP, MP3 and more</p> | |
</div> | |
<!-- How It Works --> | |
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 mb-8"> | |
<h2 class="text-xl font-semibold mb-4 text-gray-800 dark:text-white">How to Download</h2> | |
<div class="grid grid-cols-1 md:grid-cols-3 gap-6"> | |
<div class="flex flex-col items-center text-center"> | |
<div class="w-16 h-16 bg-blue-100 dark:bg-blue-900 rounded-full flex items-center justify-center mb-3"> | |
<i class="fas fa-link text-blue-600 dark:text-blue-300 text-2xl"></i> | |
</div> | |
<h3 class="font-medium text-gray-800 dark:text-white mb-1">1. Paste URL</h3> | |
<p class="text-gray-600 dark:text-gray-400 text-sm">Copy and paste the YouTube video URL</p> | |
</div> | |
<div class="flex flex-col items-center text-center"> | |
<div class="w-16 h-16 bg-purple-100 dark:bg-purple-900 rounded-full flex items-center justify-center mb-3"> | |
<i class="fas fa-cog text-purple-600 dark:text-purple-300 text-2xl"></i> | |
</div> | |
<h3 class="font-medium text-gray-800 dark:text-white mb-1">2. Process</h3> | |
<p class="text-gray-600 dark:text-gray-400 text-sm">Our system will analyze the video</p> | |
</div> | |
<div class="flex flex-col items-center text-center"> | |
<div class="w-16 h-16 bg-green-100 dark:bg-green-900 rounded-full flex items-center justify-center mb-3"> | |
<i class="fas fa-download text-green-600 dark:text-green-300 text-2xl"></i> | |
</div> | |
<h3 class="font-medium text-gray-800 dark:text-white mb-1">3. Download</h3> | |
<p class="text-gray-600 dark:text-gray-400 text-sm">Choose format and download</p> | |
</div> | |
</div> | |
</div> | |
<!-- Results Section (Initially Hidden) --> | |
<div id="resultsSection" class="hidden bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6 mb-8"> | |
<div class="flex justify-between items-center mb-4"> | |
<h2 class="text-xl font-semibold text-gray-800 dark:text-white">Download Options</h2> | |
<button id="newDownloadBtn" class="text-sm text-primary-light dark:text-primary-dark hover:underline"> | |
<i class="fas fa-redo mr-1"></i> New Download | |
</button> | |
</div> | |
<!-- Video Info --> | |
<div id="videoInfo" class="flex flex-col md:flex-row gap-4 mb-6"> | |
<div class="w-full md:w-1/3"> | |
<div class="relative pb-[56.25%] bg-gray-200 dark:bg-gray-700 rounded-lg overflow-hidden"> | |
<img id="videoThumbnail" src="" alt="Video thumbnail" class="absolute h-full w-full object-cover"> | |
<div class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-30"> | |
<i class="fab fa-youtube text-5xl text-white opacity-80"></i> | |
</div> | |
</div> | |
</div> | |
<div class="w-full md:w-2/3"> | |
<h3 id="videoTitle" class="text-lg font-medium text-gray-800 dark:text-white mb-2"></h3> | |
<p id="videoDuration" class="text-sm text-gray-600 dark:text-gray-400 mb-3"></p> | |
<div class="flex flex-wrap gap-2"> | |
<span id="videoViews" class="px-3 py-1 bg-gray-100 dark:bg-gray-700 rounded-full text-xs text-gray-800 dark:text-gray-300"></span> | |
<span id="videoUploadDate" class="px-3 py-1 bg-gray-100 dark:bg-gray-700 rounded-full text-xs text-gray-800 dark:text-gray-300"></span> | |
</div> | |
</div> | |
</div> | |
<!-- Loading State --> | |
<div id="loadingState" class="flex flex-col items-center justify-center py-8"> | |
<div class="loader ease-linear rounded-full border-4 border-t-4 border-gray-200 h-12 w-12 mb-4"></div> | |
<p class="text-gray-600 dark:text-gray-400">Processing video, please wait...</p> | |
</div> | |
<!-- Download Options --> | |
<div id="downloadOptions" class="hidden"> | |
<div class="mb-4"> | |
<div class="flex items-center mb-2"> | |
<h3 class="font-medium text-gray-800 dark:text-white">Video Formats</h3> | |
<span class="ml-2 px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded-full text-xs text-gray-800 dark:text-gray-300">MP4</span> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 mb-4" id="videoFormats"> | |
<!-- Dynamically populated --> | |
</div> | |
</div> | |
<div> | |
<div class="flex items-center mb-2"> | |
<h3 class="font-medium text-gray-800 dark:text-white">Audio Only</h3> | |
<span class="ml-2 px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded-full text-xs text-gray-800 dark:text-gray-300">MP3</span> | |
</div> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-3" id="audioFormats"> | |
<!-- Dynamically populated --> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Features --> | |
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6"> | |
<h2 class="text-xl font-semibold mb-4 text-gray-800 dark:text-white">Why Choose Us?</h2> | |
<div class="space-y-4"> | |
<div class="flex items-start"> | |
<div class="flex-shrink-0 mt-1"> | |
<div class="w-8 h-8 bg-primary-light dark:bg-primary-dark rounded-full flex items-center justify-center"> | |
<i class="fas fa-bolt text-white text-sm"></i> | |
</div> | |
</div> | |
<div class="ml-3"> | |
<h3 class="font-medium text-gray-800 dark:text-white">Fast Downloads</h3> | |
<p class="text-gray-600 dark:text-gray-400 text-sm">Our servers provide high-speed downloads for all your videos.</p> | |
</div> | |
</div> | |
<div class="flex items-start"> | |
<div class="flex-shrink-0 mt-1"> | |
<div class="w-8 h-8 bg-primary-light dark:bg-primary-dark rounded-full flex items-center justify-center"> | |
<i class="fas fa-lock text-white text-sm"></i> | |
</div> | |
</div> | |
<div class="ml-3"> | |
<h3 class="font-medium text-gray-800 dark:text-white">Secure & Private</h3> | |
<p class="text-gray-600 dark:text-gray-400 text-sm">We don't store your videos or track your downloads.</p> | |
</div> | |
</div> | |
<div class="flex items-start"> | |
<div class="flex-shrink-0 mt-1"> | |
<div class="w-8 h-8 bg-primary-light dark:bg-primary-dark rounded-full flex items-center justify-center"> | |
<i class="fas fa-mobile-alt text-white text-sm"></i> | |
</div> | |
</div> | |
<div class="ml-3"> | |
<h3 class="font-medium text-gray-800 dark:text-white">All Devices Supported</h3> | |
<p class="text-gray-600 dark:text-gray-400 text-sm">Download videos compatible with any device or platform.</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</main> | |
<!-- Footer --> | |
<footer class="mt-16 text-center text-gray-600 dark:text-gray-400 text-sm"> | |
<p>© 2023 YTDownloader. All rights reserved.</p> | |
<p class="mt-1">This service is for educational purposes only.</p> | |
</footer> | |
</div> | |
<script> | |
// Theme toggle | |
const themeToggle = document.getElementById('themeToggle'); | |
themeToggle.addEventListener('click', () => { | |
document.documentElement.classList.toggle('dark'); | |
localStorage.setItem('darkMode', document.documentElement.classList.contains('dark')); | |
}); | |
// Check for saved theme preference | |
if (localStorage.getItem('darkMode') === 'true') { | |
document.documentElement.classList.add('dark'); | |
} | |
// Mock download functionality (in a real app, this would connect to a backend service) | |
const downloadBtn = document.getElementById('downloadBtn'); | |
const videoUrl = document.getElementById('videoUrl'); | |
const resultsSection = document.getElementById('resultsSection'); | |
const loadingState = document.getElementById('loadingState'); | |
const downloadOptions = document.getElementById('downloadOptions'); | |
const newDownloadBtn = document.getElementById('newDownloadBtn'); | |
const videoInfo = document.getElementById('videoInfo'); | |
const videoTitle = document.getElementById('videoTitle'); | |
const videoThumbnail = document.getElementById('videoThumbnail'); | |
const videoDuration = document.getElementById('videoDuration'); | |
const videoViews = document.getElementById('videoViews'); | |
const videoUploadDate = document.getElementById('videoUploadDate'); | |
const videoFormats = document.getElementById('videoFormats'); | |
const audioFormats = document.getElementById('audioFormats'); | |
downloadBtn.addEventListener('click', () => { | |
const url = videoUrl.value.trim(); | |
// Basic URL validation | |
if (!url || (!url.includes('youtube.com') && !url.includes('youtu.be') && !url.includes('music.youtube.com'))) { | |
alert('Please enter a valid YouTube URL'); | |
return; | |
} | |
// Show loading state | |
resultsSection.classList.remove('hidden'); | |
loadingState.classList.remove('hidden'); | |
downloadOptions.classList.add('hidden'); | |
videoInfo.classList.add('hidden'); | |
// Simulate API call delay | |
setTimeout(() => { | |
// Mock data - in a real app, this would come from your backend | |
const videoData = { | |
title: "How to Build a YouTube Downloader", | |
thumbnail: "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", | |
duration: "12:34", | |
views: "1.2M views", | |
uploadDate: "Uploaded 2 weeks ago", | |
formats: [ | |
{ quality: "1080p", type: "MP4", size: "45.2 MB", url: "#" }, | |
{ quality: "720p", type: "MP4", size: "28.7 MB", url: "#" }, | |
{ quality: "480p", type: "MP4", size: "15.3 MB", url: "#" }, | |
{ quality: "360p", type: "MP4", size: "9.8 MB", url: "#" }, | |
{ quality: "144p", type: "MP4", size: "3.2 MB", url: "#" }, | |
{ quality: "High", type: "MP3", size: "5.6 MB", url: "#" }, | |
{ quality: "Medium", type: "MP3", size: "3.8 MB", url: "#" }, | |
{ quality: "Low", type: "MP3", size: "2.1 MB", url: "#" } | |
] | |
}; | |
// Populate video info | |
videoTitle.textContent = videoData.title; | |
videoThumbnail.src = videoData.thumbnail; | |
videoDuration.textContent = videoData.duration; | |
videoViews.textContent = videoData.views; | |
videoUploadDate.textContent = videoData.uploadDate; | |
// Populate video formats | |
videoFormats.innerHTML = ''; | |
audioFormats.innerHTML = ''; | |
videoData.formats.forEach(format => { | |
const formatElement = document.createElement('div'); | |
formatElement.className = 'video-card bg-gray-50 dark:bg-gray-700 p-4 rounded-lg'; | |
const isAudio = format.type === 'MP3'; | |
const icon = isAudio ? 'fas fa-music' : 'fas fa-video'; | |
const bgColor = isAudio ? 'bg-purple-100 dark:bg-purple-900' : 'bg-blue-100 dark:bg-blue-900'; | |
const textColor = isAudio ? 'text-purple-600 dark:text-purple-300' : 'text-blue-600 dark:text-blue-300'; | |
formatElement.innerHTML = ` | |
<div class="flex items-center justify-between"> | |
<div class="flex items-center"> | |
<div class="w-10 h-10 ${bgColor} rounded-full flex items-center justify-center mr-3"> | |
<i class="${icon} ${textColor}"></i> | |
</div> | |
<div> | |
<h4 class="font-medium text-gray-800 dark:text-white">${format.quality}</h4> | |
<p class="text-xs text-gray-600 dark:text-gray-400">${format.type} • ${format.size}</p> | |
</div> | |
</div> | |
<a href="${format.url}" class="px-3 py-1 bg-primary-light dark:bg-primary-dark text-white text-sm rounded hover:opacity-90 transition-opacity"> | |
Download | |
</a> | |
</div> | |
`; | |
if (isAudio) { | |
audioFormats.appendChild(formatElement); | |
} else { | |
videoFormats.appendChild(formatElement); | |
} | |
}); | |
// Hide loading, show results | |
loadingState.classList.add('hidden'); | |
videoInfo.classList.remove('hidden'); | |
downloadOptions.classList.remove('hidden'); | |
}, 2000); | |
}); | |
// New download button | |
newDownloadBtn.addEventListener('click', () => { | |
resultsSection.classList.add('hidden'); | |
videoUrl.value = ''; | |
}); | |
// Example URLs for demo purposes | |
videoUrl.addEventListener('focus', () => { | |
if (!videoUrl.value) { | |
videoUrl.value = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'; | |
} | |
}); | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=AgentP23/yt-downloader" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |