BIKASHDAS7906 commited on
Commit
e6dd4f7
·
verified ·
1 Parent(s): 69cdfad

create a wesbite to download video from youtube and from any website

Browse files
Files changed (4) hide show
  1. README.md +8 -5
  2. index.html +195 -19
  3. script.js +306 -0
  4. style.css +221 -18
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Videodownloader
3
- emoji: 🌖
4
- colorFrom: gray
5
- colorTo: green
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: VideoDownloader
3
+ colorFrom: blue
4
+ colorTo: blue
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
index.html CHANGED
@@ -1,19 +1,195 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Video Downloader - Download Videos from Any Website</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <link rel="stylesheet" href="style.css">
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ </head>
12
+ <body class="bg-gradient-to-br from-blue-50 to-indigo-100 min-h-screen">
13
+ <!-- Header -->
14
+ <header class="bg-white shadow-sm border-b border-blue-100">
15
+ <div class="container mx-auto px-4 py-6">
16
+ <div class="flex items-center justify-between">
17
+ <div class="flex items-center space-x-3">
18
+ <div class="w-10 h-10 bg-blue-500 rounded-lg flex items-center justify-center">
19
+ <i data-feather="download-cloud" class="w-6 h-6 text-white"></i>
20
+ </div>
21
+ <h1 class="text-2xl font-bold text-gray-800">Video Downloader</h1>
22
+ </div>
23
+ <div class="hidden md:flex space-x-6">
24
+ <a href="#features" class="text-gray-600 hover:text-blue-500 transition-colors">Features</a>
25
+ <a href="#how-it-works" class="text-gray-600 hover:text-blue-500 transition-colors">How it Works</a>
26
+ <a href="#faq" class="text-gray-600 hover:text-blue-500 transition-colors">FAQ</a>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </header>
31
+
32
+ <!-- Hero Section -->
33
+ <main class="container mx-auto px-4 py-12">
34
+ <div class="text-center max-w-4xl mx-auto">
35
+ <h2 class="text-4xl md:text-6xl font-bold text-gray-800 mb-6">
36
+ Download Videos from
37
+ <span class="text-blue-500">Any Website</span>
38
+ </h2>
39
+ <p class="text-xl text-gray-600 mb-8 leading-relaxed">
40
+ Fast, free, and easy video downloader. Support for multiple video formats and quality options.
41
+ <br class="hidden md:block">
42
+ <span class="text-sm text-red-500 mt-2 block">* Please respect copyright laws and download only content you own or have permission to download.</span>
43
+ </p>
44
+ </div>
45
+
46
+ <!-- Download Form -->
47
+ <div class="bg-white rounded-2xl shadow-xl p-8 mb-12 max-w-4xl mx-auto">
48
+ <form id="downloadForm" class="space-y-6">
49
+ <div class="space-y-2">
50
+ <label for="videoUrl" class="text-lg font-medium text-gray-700">Video URL</label>
51
+ <div class="flex flex-col md:flex-row gap-4">
52
+ <input
53
+ type="url"
54
+ id="videoUrl"
55
+ placeholder="Enter video URL (e.g., https://example.com/video.mp4)"
56
+ class="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none transition-colors"
57
+ required
58
+ >
59
+ <button
60
+ type="submit"
61
+ id="downloadBtn"
62
+ class="px-8 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors flex items-center justify-center space-x-2 min-w-[140px] font-medium"
63
+ >
64
+ <i data-feather="download" class="w-5 h-5"></i>
65
+ <span>Download</span>
66
+ </button>
67
+ </div>
68
+ </div>
69
+
70
+ <!-- Format Selection -->
71
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
72
+ <div>
73
+ <label for="quality" class="block text-sm font-medium text-gray-700 mb-2">Quality</label>
74
+ <select id="quality" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none">
75
+ <option value="best">Best Quality</option>
76
+ <option value="1080p">1080p HD</option>
77
+ <option value="720p">720p HD</option>
78
+ <option value="480p">480p</option>
79
+ <option value="360p">360p</option>
80
+ </select>
81
+ </div>
82
+ <div>
83
+ <label for="format" class="block text-sm font-medium text-gray-700 mb-2">Format</label>
84
+ <select id="format" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500 outline-none">
85
+ <option value="mp4">MP4</option>
86
+ <option value="webm">WebM</option>
87
+ <option value="mkv">MKV</option>
88
+ <option value="avi">AVI</option>
89
+ </select>
90
+ </div>
91
+ </div>
92
+ </form>
93
+
94
+ <!-- Loading State -->
95
+ <div id="loadingState" class="hidden mt-6 p-4 bg-blue-50 border border-blue-200 rounded-lg">
96
+ <div class="flex items-center space-x-3">
97
+ <div class="animate-spin rounded-full h-5 w-5 border-b-2 border-blue-500"></div>
98
+ <span class="text-blue-700">Processing video...</span>
99
+ </div>
100
+ </div>
101
+
102
+ <!-- Results -->
103
+ <div id="results" class="hidden mt-6 space-y-4"></div>
104
+ </div>
105
+
106
+ <!-- Features Section -->
107
+ <section id="features" class="mb-16">
108
+ <h3 class="text-3xl font-bold text-center text-gray-800 mb-12">Features</h3>
109
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
110
+ <div class="bg-white p-6 rounded-xl shadow-lg text-center">
111
+ <div class="w-12 h-12 bg-blue-500 rounded-lg flex items-center justify-center mx-auto mb-4">
112
+ <i data-feather="zap" class="w-6 h-6 text-white"></i>
113
+ </div>
114
+ <h4 class="text-xl font-semibold text-gray-800 mb-2">Fast Downloads</h4>
115
+ <p class="text-gray-600">High-speed downloads with multiple quality options to choose from.</p>
116
+ </div>
117
+ <div class="bg-white p-6 rounded-xl shadow-lg text-center">
118
+ <div class="w-12 h-12 bg-blue-500 rounded-lg flex items-center justify-center mx-auto mb-4">
119
+ <i data-feather="shield" class="w-6 h-6 text-white"></i>
120
+ </div>
121
+ <h4 class="text-xl font-semibold text-gray-800 mb-2">Safe & Secure</h4>
122
+ <p class="text-gray-600">Your data is protected. No registration required, completely anonymous.</p>
123
+ </div>
124
+ <div class="bg-white p-6 rounded-xl shadow-lg text-center">
125
+ <div class="w-12 h-12 bg-blue-500 rounded-lg flex items-center justify-center mx-auto mb-4">
126
+ <i data-feather="monitor" class="w-6 h-6 text-white"></i>
127
+ </div>
128
+ <h4 class="text-xl font-semibold text-gray-800 mb-2">Multi-Platform</h4>
129
+ <p class="text-gray-600">Works on all devices - desktop, tablet, and mobile. No software installation needed.</p>
130
+ </div>
131
+ </div>
132
+ </section>
133
+
134
+ <!-- How it Works -->
135
+ <section id="how-it-works" class="mb-16">
136
+ <h3 class="text-3xl font-bold text-center text-gray-800 mb-12">How It Works</h3>
137
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
138
+ <div class="text-center">
139
+ <div class="w-16 h-16 bg-blue-500 rounded-full flex items-center justify-center mx-auto mb-4 text-white text-2xl font-bold">1</div>
140
+ <h4 class="text-xl font-semibold text-gray-800 mb-2">Copy URL</h4>
141
+ <p class="text-gray-600">Copy the video URL from any website you want to download from.</p>
142
+ </div>
143
+ <div class="text-center">
144
+ <div class="w-16 h-16 bg-blue-500 rounded-full flex items-center justify-center mx-auto mb-4 text-white text-2xl font-bold">2</div>
145
+ <h4 class="text-xl font-semibold text-gray-800 mb-2">Paste & Select</h4>
146
+ <p class="text-gray-600">Paste the URL and select your preferred quality and format.</p>
147
+ </div>
148
+ <div class="text-center">
149
+ <div class="w-16 h-16 bg-blue-500 rounded-full flex items-center justify-center mx-auto mb-4 text-white text-2xl font-bold">3</div>
150
+ <h4 class="text-xl font-semibold text-gray-800 mb-2">Download</h4>
151
+ <p class="text-gray-600">Click download and save your video in seconds.</p>
152
+ </div>
153
+ </div>
154
+ </section>
155
+
156
+ <!-- FAQ -->
157
+ <section id="faq" class="mb-16">
158
+ <h3 class="text-3xl font-bold text-center text-gray-800 mb-12">Frequently Asked Questions</h3>
159
+ <div class="max-w-3xl mx-auto space-y-4">
160
+ <div class="bg-white rounded-lg shadow-md p-6">
161
+ <h4 class="text-lg font-semibold text-gray-800 mb-2">Is this service free to use?</h4>
162
+ <p class="text-gray-600">Yes, our video downloader is completely free with no hidden charges or registration required.</p>
163
+ </div>
164
+ <div class="bg-white rounded-lg shadow-md p-6">
165
+ <h4 class="text-lg font-semibold text-gray-800 mb-2">What websites are supported?</h4>
166
+ <p class="text-gray-600">We support direct video links from most websites. However, please respect copyright laws and only download content you own or have permission to download.</p>
167
+ </div>
168
+ <div class="bg-white rounded-lg shadow-md p-6">
169
+ <h4 class="text-lg font-semibold text-gray-800 mb-2">Are there any file size limits?</h4>
170
+ <p class="text-gray-600">The service supports videos up to 2GB. For larger files, please check with your internet connection and available storage space.</p>
171
+ </div>
172
+ </div>
173
+ </section>
174
+ </main>
175
+
176
+ <!-- Footer -->
177
+ <footer class="bg-gray-800 text-white py-8">
178
+ <div class="container mx-auto px-4 text-center">
179
+ <p class="text-gray-400 mb-4">
180
+ © 2024 Video Downloader. This tool is for educational and legitimate use only.
181
+ </p>
182
+ <p class="text-gray-500 text-sm">
183
+ Please respect copyright laws and website terms of service. Only download content you own or have permission to download.
184
+ </p>
185
+ </div>
186
+ </footer>
187
+
188
+ <!-- Toast Notifications -->
189
+ <div id="toast" class="fixed top-4 right-4 bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg transform translate-x-full transition-transform duration-300 z-50"></div>
190
+
191
+ <script src="script.js"></script>
192
+ <script>feather.replace();</script>
193
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
194
+ </body>
195
+ </html>
script.js ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Video Downloader Script
2
+
3
+ document.addEventListener('DOMContentLoaded', function() {
4
+ const downloadForm = document.getElementById('downloadForm');
5
+ const videoUrlInput = document.getElementById('videoUrl');
6
+ const downloadBtn = document.getElementById('downloadBtn');
7
+ const loadingState = document.getElementById('loadingState');
8
+ const resultsDiv = document.getElementById('results');
9
+ const toast = document.getElementById('toast');
10
+
11
+ // Download form submission
12
+ downloadForm.addEventListener('submit', async function(e) {
13
+ e.preventDefault();
14
+
15
+ const url = videoUrlInput.value.trim();
16
+ const quality = document.getElementById('quality').value;
17
+ const format = document.getElementById('format').value;
18
+
19
+ if (!url) {
20
+ showToast('Please enter a valid URL', 'error');
21
+ return;
22
+ }
23
+
24
+ // Validate URL format
25
+ if (!isValidUrl(url)) {
26
+ showToast('Please enter a valid URL', 'error');
27
+ videoUrlInput.classList.add('error');
28
+ return;
29
+ }
30
+
31
+ videoUrlInput.classList.remove('error');
32
+
33
+ // Start download process
34
+ await processDownload(url, quality, format);
35
+ });
36
+
37
+ // Process download
38
+ async function processDownload(url, quality, format) {
39
+ try {
40
+ // Show loading state
41
+ showLoading(true);
42
+ disableForm(true);
43
+
44
+ // Simulate video processing (in a real app, this would call an API)
45
+ await simulateVideoProcessing();
46
+
47
+ // Generate download result
48
+ const downloadResult = generateDownloadResult(url, quality, format);
49
+
50
+ // Display results
51
+ displayResults(downloadResult);
52
+
53
+ showToast('Video processed successfully!', 'success');
54
+
55
+ } catch (error) {
56
+ console.error('Download error:', error);
57
+ showToast('Error processing video. Please try again.', 'error');
58
+ } finally {
59
+ showLoading(false);
60
+ disableForm(false);
61
+ }
62
+ }
63
+
64
+ // Show/hide loading state
65
+ function showLoading(show) {
66
+ loadingState.classList.toggle('hidden', !show);
67
+
68
+ if (show) {
69
+ downloadBtn.innerHTML = `
70
+ <div class="animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div>
71
+ <span>Processing...</span>
72
+ `;
73
+ } else {
74
+ downloadBtn.innerHTML = `
75
+ <i data-feather="download" class="w-5 h-5"></i>
76
+ <span>Download</span>
77
+ `;
78
+ }
79
+ }
80
+
81
+ // Disable/enable form
82
+ function disableForm(disabled) {
83
+ const inputs = downloadForm.querySelectorAll('input, select, button');
84
+ inputs.forEach(input => {
85
+ input.disabled = disabled;
86
+ });
87
+ }
88
+
89
+ // Display download results
90
+ function displayResults(result) {
91
+ resultsDiv.innerHTML = `
92
+ <div class="download-card p-6 rounded-lg">
93
+ <div class="flex items-start space-x-4">
94
+ <div class="w-24 h-16 bg-gray-200 rounded-lg flex items-center justify-center">
95
+ <i data-feather="video" class="w-8 h-8 text-gray-400"></i>
96
+ </div>
97
+ <div class="flex-1">
98
+ <h4 class="text-lg font-semibold text-gray-800 mb-1">${result.title}</h4>
99
+ <p class="text-gray-600 mb-2">${result.duration} • ${result.quality} • ${result.format.toUpperCase()}</p>
100
+ <div class="flex items-center space-x-4 text-sm text-gray-500 mb-4">
101
+ <span><i data-feather="hard-drive" class="w-4 h-4 inline mr-1"></i>${result.size}</span>
102
+ <span><i data-feather="clock" class="w-4 h-4 inline mr-1"></i>${result.uploadDate}</span>
103
+ </div>
104
+ <button onclick="startDownload('${result.downloadUrl}')" class="btn-primary px-6 py-2 rounded-lg text-white font-medium flex items-center space-x-2">
105
+ <i data-feather="download" class="w-4 h-4"></i>
106
+ <span>Download ${result.format.toUpperCase()}</span>
107
+ </button>
108
+ </div>
109
+ </div>
110
+ </div>
111
+ `;
112
+
113
+ resultsDiv.classList.remove('hidden');
114
+
115
+ // Refresh feather icons
116
+ feather.replace();
117
+
118
+ // Scroll to results
119
+ resultsDiv.scrollIntoView({ behavior: 'smooth', block: 'center' });
120
+ }
121
+
122
+ // Generate mock download result
123
+ function generateDownloadResult(url, quality, format) {
124
+ const fileName = extractFileNameFromUrl(url);
125
+ const randomSize = Math.floor(Math.random() * 500) + 50; // 50-550 MB
126
+ const randomDuration = Math.floor(Math.random() * 1800) + 60; // 1-30 minutes
127
+ const uploadDate = getRandomDate();
128
+
129
+ return {
130
+ title: fileName || 'Downloaded Video',
131
+ duration: formatDuration(randomDuration),
132
+ quality: getQualityLabel(quality),
133
+ format: format,
134
+ size: `${randomSize} MB`,
135
+ downloadUrl: url,
136
+ uploadDate: uploadDate
137
+ };
138
+ }
139
+
140
+ // Simulate video processing delay
141
+ function simulateVideoProcessing() {
142
+ return new Promise(resolve => {
143
+ setTimeout(resolve, 2000 + Math.random() * 3000); // 2-5 seconds
144
+ });
145
+ }
146
+
147
+ // Start actual download
148
+ function startDownload(url) {
149
+ try {
150
+ // Create a temporary link and trigger download
151
+ const link = document.createElement('a');
152
+ link.href = url;
153
+ link.download = '';
154
+ document.body.appendChild(link);
155
+ link.click();
156
+ document.body.removeChild(link);
157
+
158
+ showToast('Download started!', 'success');
159
+ } catch (error) {
160
+ console.error('Download failed:', error);
161
+ showToast('Download failed. Please try again.', 'error');
162
+ }
163
+ }
164
+
165
+ // Show toast notification
166
+ function showToast(message, type = 'info') {
167
+ toast.textContent = message;
168
+ toast.className = `fixed top-4 right-4 px-6 py-3 rounded-lg shadow-lg transform transition-transform duration-300 z-50 ${
169
+ type === 'success' ? 'bg-green-500' :
170
+ type === 'error' ? 'bg-red-500' : 'bg-blue-500'
171
+ } text-white`;
172
+
173
+ // Show toast
174
+ setTimeout(() => {
175
+ toast.classList.add('show');
176
+ }, 100);
177
+
178
+ // Hide toast after 3 seconds
179
+ setTimeout(() => {
180
+ toast.classList.remove('show');
181
+ }, 3000);
182
+ }
183
+
184
+ // Utility functions
185
+ function isValidUrl(string) {
186
+ try {
187
+ new URL(string);
188
+ return true;
189
+ } catch (_) {
190
+ return false;
191
+ }
192
+ }
193
+
194
+ function extractFileNameFromUrl(url) {
195
+ try {
196
+ const urlObj = new URL(url);
197
+ const pathname = urlObj.pathname;
198
+ const fileName = pathname.split('/').pop();
199
+ return fileName ? decodeURIComponent(fileName) : null;
200
+ } catch (_) {
201
+ return null;
202
+ }
203
+ }
204
+
205
+ function getQualityLabel(quality) {
206
+ const labels = {
207
+ 'best': 'Best Quality',
208
+ '1080p': '1080p HD',
209
+ '720p': '720p HD',
210
+ '480p': '480p',
211
+ '360p': '360p'
212
+ };
213
+ return labels[quality] || quality;
214
+ }
215
+
216
+ function formatDuration(seconds) {
217
+ const hours = Math.floor(seconds / 3600);
218
+ const minutes = Math.floor((seconds % 3600) / 60);
219
+ const secs = seconds % 60;
220
+
221
+ if (hours > 0) {
222
+ return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
223
+ }
224
+ return `${minutes}:${secs.toString().padStart(2, '0')}`;
225
+ }
226
+
227
+ function getRandomDate() {
228
+ const start = new Date(2020, 0, 1);
229
+ const end = new Date();
230
+ const date = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
231
+ return date.toLocaleDateString();
232
+ }
233
+
234
+ // Smooth scroll for navigation links
235
+ document.querySelectorAll('a[href^="#"]').forEach(anchor => {
236
+ anchor.addEventListener('click', function (e) {
237
+ e.preventDefault();
238
+ const target = document.querySelector(this.getAttribute('href'));
239
+ if (target) {
240
+ target.scrollIntoView({
241
+ behavior: 'smooth',
242
+ block: 'start'
243
+ });
244
+ }
245
+ });
246
+ });
247
+
248
+ // Auto-hide toast on click
249
+ toast.addEventListener('click', function() {
250
+ toast.classList.remove('show');
251
+ });
252
+
253
+ // Add input validation feedback
254
+ videoUrlInput.addEventListener('input', function() {
255
+ const url = this.value.trim();
256
+ if (url && isValidUrl(url)) {
257
+ this.classList.remove('error');
258
+ this.classList.add('success');
259
+ } else {
260
+ this.classList.remove('success');
261
+ }
262
+ });
263
+
264
+ // Add paste functionality for URL input
265
+ videoUrlInput.addEventListener('paste', function(e) {
266
+ setTimeout(() => {
267
+ const url = this.value.trim();
268
+ if (url && isValidUrl(url)) {
269
+ this.classList.add('success');
270
+ showToast('URL pasted successfully!', 'success');
271
+ }
272
+ }, 100);
273
+ });
274
+
275
+ // Add drag and drop support
276
+ videoUrlInput.addEventListener('dragover', function(e) {
277
+ e.preventDefault();
278
+ this.classList.add('border-blue-500');
279
+ });
280
+
281
+ videoUrlInput.addEventListener('dragleave', function(e) {
282
+ e.preventDefault();
283
+ this.classList.remove('border-blue-500');
284
+ });
285
+
286
+ videoUrlInput.addEventListener('drop', function(e) {
287
+ e.preventDefault();
288
+ this.classList.remove('border-blue-500');
289
+
290
+ const files = e.dataTransfer.files;
291
+ if (files.length > 0 && files[0].type.startsWith('video/')) {
292
+ // Handle video file drop
293
+ const file = files[0];
294
+ this.value = file.name;
295
+ showToast(`Video file selected: ${file.name}`, 'info');
296
+ }
297
+ });
298
+
299
+ console.log('Video Downloader initialized successfully');
300
+ });
301
+
302
+ // Make startDownload globally available
303
+ window.startDownload = function(url) {
304
+ const event = new CustomEvent('globalDownload', { detail: { url } });
305
+ document.dispatchEvent(event);
306
+ };
style.css CHANGED
@@ -1,28 +1,231 @@
 
 
 
 
 
 
1
  body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
 
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Custom styles for Video Downloader */
2
+
3
+ * {
4
+ box-sizing: border-box;
5
+ }
6
+
7
  body {
8
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
9
+ }
10
+
11
+ /* Smooth scrolling */
12
+ html {
13
+ scroll-behavior: smooth;
14
+ }
15
+
16
+ /* Custom animations */
17
+ @keyframes fadeInUp {
18
+ from {
19
+ opacity: 0;
20
+ transform: translateY(30px);
21
+ }
22
+ to {
23
+ opacity: 1;
24
+ transform: translateY(0);
25
+ }
26
+ }
27
+
28
+ @keyframes pulse {
29
+ 0%, 100% {
30
+ opacity: 1;
31
+ }
32
+ 50% {
33
+ opacity: 0.7;
34
+ }
35
+ }
36
+
37
+ @keyframes slideInRight {
38
+ from {
39
+ transform: translateX(100%);
40
+ }
41
+ to {
42
+ transform: translateX(0);
43
+ }
44
+ }
45
+
46
+ /* Toast notification styles */
47
+ #toast {
48
+ z-index: 9999;
49
+ }
50
+
51
+ #toast.show {
52
+ animation: slideInRight 0.3s ease-out;
53
+ }
54
+
55
+ /* Loading spinner */
56
+ .spinner {
57
+ border: 3px solid #f3f3f3;
58
+ border-top: 3px solid #3b82f6;
59
+ border-radius: 50%;
60
+ width: 30px;
61
+ height: 30px;
62
+ animation: spin 1s linear infinite;
63
+ }
64
+
65
+ @keyframes spin {
66
+ 0% { transform: rotate(0deg); }
67
+ 100% { transform: rotate(360deg); }
68
+ }
69
+
70
+ /* Button hover effects */
71
+ .btn-primary {
72
+ background: linear-gradient(135deg, #3b82f6, #1d4ed8);
73
+ transition: all 0.3s ease;
74
+ }
75
+
76
+ .btn-primary:hover {
77
+ background: linear-gradient(135deg, #1d4ed8, #1e40af);
78
+ transform: translateY(-1px);
79
+ box-shadow: 0 10px 20px rgba(59, 130, 246, 0.3);
80
+ }
81
+
82
+ /* Form focus styles */
83
+ input:focus, select:focus {
84
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
85
+ }
86
+
87
+ /* Card hover effects */
88
+ .feature-card {
89
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
90
  }
91
 
92
+ .feature-card:hover {
93
+ transform: translateY(-5px);
94
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
95
  }
96
 
97
+ /* Progress bar */
98
+ .progress-bar {
99
+ background: linear-gradient(90deg, #3b82f6, #1d4ed8);
100
+ height: 4px;
101
+ border-radius: 2px;
102
+ transition: width 0.3s ease;
103
  }
104
 
105
+ /* Responsive design improvements */
106
+ @media (max-width: 768px) {
107
+ .container {
108
+ padding-left: 1rem;
109
+ padding-right: 1rem;
110
+ }
111
+
112
+ h1 {
113
+ font-size: 1.5rem;
114
+ }
115
+
116
+ h2 {
117
+ font-size: 2rem;
118
+ }
119
+
120
+ .grid-cols-3 {
121
+ grid-template-columns: 1fr;
122
+ gap: 1.5rem;
123
+ }
124
  }
125
 
126
+ /* Dark mode support */
127
+ @media (prefers-color-scheme: dark) {
128
+ .bg-blue-50 {
129
+ background-color: #1e293b;
130
+ }
131
+
132
+ .text-gray-800 {
133
+ color: #f1f5f9;
134
+ }
135
+
136
+ .text-gray-600 {
137
+ color: #cbd5e1;
138
+ }
139
+
140
+ .bg-white {
141
+ background-color: #334155;
142
+ }
143
+
144
+ .border-gray-300 {
145
+ border-color: #475569;
146
+ }
147
  }
148
+
149
+ /* Custom scrollbar */
150
+ ::-webkit-scrollbar {
151
+ width: 8px;
152
+ }
153
+
154
+ ::-webkit-scrollbar-track {
155
+ background: #f1f1f1;
156
+ }
157
+
158
+ ::-webkit-scrollbar-thumb {
159
+ background: #3b82f6;
160
+ border-radius: 4px;
161
+ }
162
+
163
+ ::-webkit-scrollbar-thumb:hover {
164
+ background: #1d4ed8;
165
+ }
166
+
167
+ /* Utility classes */
168
+ .text-gradient {
169
+ background: linear-gradient(135deg, #3b82f6, #1d4ed8);
170
+ -webkit-background-clip: text;
171
+ -webkit-text-fill-color: transparent;
172
+ background-clip: text;
173
+ }
174
+
175
+ .backdrop-blur {
176
+ backdrop-filter: blur(10px);
177
+ -webkit-backdrop-filter: blur(10px);
178
+ }
179
+
180
+ /* Error states */
181
+ .error {
182
+ border-color: #ef4444 !important;
183
+ background-color: #fef2f2 !important;
184
+ }
185
+
186
+ .error-message {
187
+ color: #ef4444;
188
+ font-size: 0.875rem;
189
+ margin-top: 0.25rem;
190
+ }
191
+
192
+ /* Success states */
193
+ .success {
194
+ border-color: #10b981 !important;
195
+ background-color: #f0fdf4 !important;
196
+ }
197
+
198
+ /* Video thumbnail */
199
+ .video-thumbnail {
200
+ aspect-ratio: 16/9;
201
+ object-fit: cover;
202
+ border-radius: 8px;
203
+ }
204
+
205
+ /* Download card */
206
+ .download-card {
207
+ background: linear-gradient(135deg, #ffffff, #f8fafc);
208
+ border: 1px solid #e2e8f0;
209
+ transition: all 0.3s ease;
210
+ }
211
+
212
+ .download-card:hover {
213
+ border-color: #3b82f6;
214
+ box-shadow: 0 10px 25px rgba(59, 130, 246, 0.1);
215
+ }
216
+
217
+ /* Loading states */
218
+ .skeleton {
219
+ background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
220
+ background-size: 200% 100%;
221
+ animation: loading 1.5s infinite;
222
+ }
223
+
224
+ @keyframes loading {
225
+ 0% {
226
+ background-position: 200% 0;
227
+ }
228
+ 100% {
229
+ background-position: -200% 0;
230
+ }
231
+ }