dimchr commited on
Commit
0476b73
·
verified ·
1 Parent(s): 3734437

we need to be able to select the translated language. we would also like to be able to select the format when copying the selected (srt, tab seperatged) - Follow Up Deployment

Browse files
Files changed (1) hide show
  1. index.html +368 -240
index.html CHANGED
@@ -3,289 +3,417 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>YouTube Subtitle Downloader - Fast & Easy Captions</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
- .gradient-bg {
11
- background: linear-gradient(135deg, #FF0000 0%, #FF4500 100%);
 
 
 
12
  }
13
- .download-btn {
14
- transition: all 0.3s ease;
 
 
 
 
15
  }
16
- .download-btn:hover {
17
- transform: translateY(-2px);
18
- box-shadow: 0 10px 20px rgba(255, 69, 0, 0.3);
19
  }
20
- .feature-card:hover {
21
- transform: translateY(-5px);
22
- box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
23
  }
24
- .language-select {
25
- background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
26
- background-position: right 0.5rem center;
27
- background-repeat: no-repeat;
28
- background-size: 1.5em 1.5em;
 
 
 
 
 
29
  }
30
  </style>
31
  </head>
32
- <body class="font-sans bg-gray-50">
33
- <!-- Header -->
34
- <header class="gradient-bg text-white">
35
- <div class="container mx-auto px-4 py-6">
36
- <div class="flex flex-col md:flex-row justify-between items-center">
37
- <div class="flex items-center mb-4 md:mb-0">
38
- <i class="fab fa-youtube text-3xl mr-3"></i>
39
- <h1 class="text-2xl md:text-3xl font-bold">YouTube Subtitle Downloader</h1>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  </div>
41
- <nav class="flex space-x-6">
42
- <a href="#how-it-works" class="hover:text-gray-200 transition">How It Works</a>
43
- <a href="#features" class="hover:text-gray-200 transition">Features</a>
44
- <a href="#extension" class="hover:text-gray-200 transition">Extension</a>
45
- </nav>
46
  </div>
47
- </div>
48
- </header>
49
 
50
- <!-- Hero Section -->
51
- <section class="gradient-bg text-white py-12">
52
- <div class="container mx-auto px-4">
53
- <div class="max-w-4xl mx-auto text-center">
54
- <h2 class="text-3xl md:text-4xl font-bold mb-6">Download YouTube Subtitles in Seconds</h2>
55
- <p class="text-xl mb-8">Get accurate subtitles in SRT, VTT or TXT formats for any YouTube video. Fast, easy and free!</p>
56
-
57
- <div class="bg-white rounded-lg shadow-xl p-6 max-w-2xl mx-auto">
58
- <div class="flex flex-col md:flex-row gap-4">
59
- <input type="text" placeholder="Paste YouTube URL here..." class="flex-grow px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 text-gray-800">
60
- <button class="bg-red-600 hover:bg-red-700 text-white font-bold py-3 px-6 rounded-lg download-btn">
61
- <i class="fas fa-download mr-2"></i> Get Subtitles
62
- </button>
63
- </div>
64
- <div class="mt-4 flex items-center justify-center">
65
- <select class="language-select appearance-none bg-gray-100 border border-gray-300 rounded-lg px-4 py-2 pr-8 focus:outline-none focus:ring-2 focus:ring-red-500 text-gray-700">
66
- <option>Select Language</option>
67
- <option>English</option>
68
- <option>Spanish</option>
69
- <option>French</option>
70
- <option>German</option>
71
- <option>Japanese</option>
72
- </select>
73
  </div>
74
  </div>
75
- </div>
76
- </div>
77
- </section>
78
 
79
- <!-- How It Works Section -->
80
- <section id="how-it-works" class="py-16 bg-white">
81
- <div class="container mx-auto px-4">
82
- <h2 class="text-3xl font-bold text-center mb-12 text-gray-800">How To Download YouTube Subtitles</h2>
83
-
84
- <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
85
- <!-- Desktop Guide -->
86
- <div class="bg-gray-50 p-6 rounded-xl shadow-md feature-card transition">
87
- <div class="flex items-center mb-4">
88
- <div class="bg-red-100 text-red-600 p-3 rounded-full mr-4">
89
- <i class="fas fa-desktop text-xl"></i>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  </div>
91
- <h3 class="text-xl font-semibold text-gray-800">For Desktop Computers</h3>
92
- </div>
93
- <ol class="list-decimal pl-5 space-y-3 text-gray-600">
94
- <li>Go to YouTube and find your video</li>
95
- <li>Copy the URL from your browser</li>
96
- <li>Paste it above and click "Get Subtitles"</li>
97
- <li>Download in your preferred format</li>
98
- </ol>
99
- <div class="mt-6">
100
- <img src="https://www.downloadyoutubesubtitles.com/static/youtube-subtitles-how-to-desktop-pc.jpg" alt="Desktop guide" class="rounded-lg shadow-md w-full">
101
  </div>
102
- </div>
103
-
104
- <!-- Mobile Guide -->
105
- <div class="bg-gray-50 p-6 rounded-xl shadow-md feature-card transition">
106
- <div class="flex items-center mb-4">
107
- <div class="bg-blue-100 text-blue-600 p-3 rounded-full mr-4">
108
- <i class="fas fa-mobile-alt text-xl"></i>
109
- </div>
110
- <h3 class="text-xl font-semibold text-gray-800">For Mobile Devices</h3>
111
  </div>
112
- <ol class="list-decimal pl-5 space-y-3 text-gray-600">
113
- <li>In the YouTube app, tap "Share"</li>
114
- <li>Choose "Copy link"</li>
115
- <li>Paste the URL above</li>
116
- <li>Select language and download</li>
117
- </ol>
118
- <div class="mt-6">
119
- <img src="https://www.downloadyoutubesubtitles.com/static/youtube-subtitles-how-to-smartphone.jpg" alt="Mobile guide" class="rounded-lg shadow-md w-full">
 
 
120
  </div>
121
  </div>
122
  </div>
123
- </div>
124
- </section>
125
 
126
- <!-- Features Section -->
127
- <section id="features" class="py-16 bg-gray-50">
128
- <div class="container mx-auto px-4">
129
- <h2 class="text-3xl font-bold text-center mb-12 text-gray-800">Why Use Our YouTube Subtitle Downloader?</h2>
130
-
131
- <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
132
- <div class="bg-white p-6 rounded-xl shadow-md feature-card transition">
133
- <div class="text-red-500 text-4xl mb-4">
134
- <i class="fas fa-bolt"></i>
135
  </div>
136
- <h3 class="text-xl font-semibold mb-3 text-gray-800">Lightning Fast</h3>
137
- <p class="text-gray-600">Get subtitles in seconds with our optimized processing system. No waiting, no delays.</p>
138
  </div>
139
-
140
- <div class="bg-white p-6 rounded-xl shadow-md feature-card transition">
141
- <div class="text-red-500 text-4xl mb-4">
142
- <i class="fas fa-language"></i>
143
- </div>
144
- <h3 class="text-xl font-semibold mb-3 text-gray-800">100+ Languages</h3>
145
- <p class="text-gray-600">Support for subtitles in virtually any language available on YouTube.</p>
146
- </div>
147
-
148
- <div class="bg-white p-6 rounded-xl shadow-md feature-card transition">
149
- <div class="text-red-500 text-4xl mb-4">
150
- <i class="fas fa-file-alt"></i>
151
  </div>
152
- <h3 class="text-xl font-semibold mb-3 text-gray-800">Multiple Formats</h3>
153
- <p class="text-gray-600">Download in SRT, VTT or TXT formats for compatibility with any device or player.</p>
154
  </div>
155
- </div>
156
-
157
- <div class="mt-12 bg-white rounded-xl shadow-md overflow-hidden max-w-4xl mx-auto">
158
- <div class="md:flex">
159
- <div class="md:w-1/2 p-8">
160
- <h3 class="text-2xl font-bold mb-4 text-gray-800">Read Instead of Watch</h3>
161
- <p class="text-gray-600 mb-4">Save time by reading video transcripts instead of watching. Perfect for research or quick information gathering.</p>
162
- <p class="text-gray-600">Search through subtitles to find specific phrases or keywords in seconds.</p>
163
- </div>
164
- <div class="md:w-1/2">
165
- <img src="https://www.downloadyoutubesubtitles.com/static/youtube-subtitle-embedded.jpg" alt="Embedded subtitles" class="h-full w-full object-cover">
166
  </div>
 
 
167
  </div>
168
  </div>
169
- </div>
170
- </section>
171
 
172
- <!-- Extension Section -->
173
- <section id="extension" class="py-16 bg-white">
174
- <div class="container mx-auto px-4">
175
- <div class="max-w-4xl mx-auto bg-gradient-to-r from-red-500 to-orange-500 rounded-xl shadow-xl overflow-hidden">
176
- <div class="md:flex">
177
- <div class="md:w-1/2 p-8 text-white">
178
- <h2 class="text-2xl font-bold mb-4">One-Click Subtitle Download</h2>
179
- <p class="mb-6">Install our browser extension for instant access to subtitles with just one click!</p>
180
- <a href="https://www.downloadyoutubesubtitles.com/extensions" class="inline-block bg-white text-red-600 font-bold py-3 px-6 rounded-lg download-btn hover:text-red-700">
181
- <i class="fas fa-download mr-2"></i> Install Extension Now
182
- </a>
183
- </div>
184
- <div class="md:w-1/2">
185
- <img src="https://www.downloadyoutubesubtitles.com/static/youtube-extension.jpg" alt="Browser extension" class="h-full w-full object-cover">
186
- </div>
187
- </div>
188
- </div>
189
  </div>
190
- </section>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
 
192
- <!-- Benefits Section -->
193
- <section class="py-16 bg-gray-50">
194
- <div class="container mx-auto px-4">
195
- <h2 class="text-3xl font-bold text-center mb-12 text-gray-800">The Importance of YouTube Subtitles</h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
 
197
- <div class="grid grid-cols-1 md:grid-cols-2 gap-8 max-w-4xl mx-auto">
198
- <div class="bg-white p-6 rounded-xl shadow-md">
199
- <div class="flex items-start mb-4">
200
- <div class="bg-green-100 text-green-600 p-3 rounded-full mr-4">
201
- <i class="fas fa-universal-access"></i>
202
- </div>
203
- <div>
204
- <h3 class="text-xl font-semibold text-gray-800">Accessibility</h3>
205
- <p class="text-gray-600 mt-2">Make your content available to viewers with hearing impairments or language barriers.</p>
206
- </div>
207
- </div>
208
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
- <div class="bg-white p-6 rounded-xl shadow-md">
211
- <div class="flex items-start mb-4">
212
- <div class="bg-blue-100 text-blue-600 p-3 rounded-full mr-4">
213
- <i class="fas fa-globe"></i>
214
- </div>
215
- <div>
216
- <h3 class="text-xl font-semibold text-gray-800">Global Reach</h3>
217
- <p class="text-gray-600 mt-2">Attract international audiences by providing subtitles in multiple languages.</p>
218
- </div>
219
- </div>
220
- </div>
221
 
222
- <div class="bg-white p-6 rounded-xl shadow-md">
223
- <div class="flex items-start mb-4">
224
- <div class="bg-purple-100 text-purple-600 p-3 rounded-full mr-4">
225
- <i class="fas fa-chart-line"></i>
226
- </div>
227
- <div>
228
- <h3 class="text-xl font-semibold text-gray-800">Better Engagement</h3>
229
- <p class="text-gray-600 mt-2">Videos with captions have higher watch times and lower bounce rates.</p>
230
  </div>
231
- </div>
232
- </div>
233
 
234
- <div class="bg-white p-6 rounded-xl shadow-md">
235
- <div class="flex items-start mb-4">
236
- <div class="bg-yellow-100 text-yellow-600 p-3 rounded-full mr-4">
237
- <i class="fas fa-search"></i>
238
- </div>
239
- <div>
240
- <h3 class="text-xl font-semibold text-gray-800">Improved SEO</h3>
241
- <p class="text-gray-600 mt-2">Subtitles make your content more discoverable through search engines.</p>
242
- </div>
243
- </div>
244
- </div>
245
- </div>
246
- </div>
247
- </section>
 
 
 
 
 
 
248
 
249
- <!-- Footer -->
250
- <footer class="bg-gray-800 text-white py-8">
251
- <div class="container mx-auto px-4">
252
- <div class="flex flex-col md:flex-row justify-between items-center">
253
- <div class="mb-4 md:mb-0">
254
- <h3 class="text-xl font-bold">YouTube Subtitle Downloader</h3>
255
- <p class="text-gray-400 mt-1">Fast, easy and free subtitle downloads</p>
256
- </div>
257
- <div class="flex space-x-6">
258
- <a href="#" class="text-gray-400 hover:text-white transition">Privacy Policy</a>
259
- <a href="#" class="text-gray-400 hover:text-white transition">Terms of Service</a>
260
- <a href="#" class="text-gray-400 hover:text-white transition">Contact</a>
261
- </div>
262
- </div>
263
- <div class="border-t border-gray-700 mt-6 pt-6 text-center text-gray-400">
264
- <p>© 2023 YouTube Subtitle Downloader. All rights reserved.</p>
265
- <p class="mt-2">Not affiliated with YouTube or Google LLC.</p>
266
- </div>
267
- </div>
268
- </footer>
269
 
270
- <script>
271
- // Simple animation for the download button
272
- document.querySelector('.download-btn').addEventListener('click', function() {
273
- this.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Processing...';
274
- setTimeout(() => {
275
- this.innerHTML = '<i class="fas fa-check mr-2"></i> Subtitles Ready!';
276
- this.classList.remove('bg-red-600', 'hover:bg-red-700');
277
- this.classList.add('bg-green-500', 'hover:bg-green-600');
278
- }, 2000);
279
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
 
281
- // Smooth scrolling for anchor links
282
- document.querySelectorAll('a[href^="#"]').forEach(anchor => {
283
- anchor.addEventListener('click', function (e) {
284
- e.preventDefault();
285
- document.querySelector(this.getAttribute('href')).scrollIntoView({
286
- behavior: 'smooth'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  });
288
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  });
290
  </script>
291
  <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=dimchr/captions" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Free YouTube Caption Extractor</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
  <style>
10
+ .video-container {
11
+ position: relative;
12
+ padding-bottom: 56.25%;
13
+ height: 0;
14
+ overflow: hidden;
15
  }
16
+ .video-container iframe {
17
+ position: absolute;
18
+ top: 0;
19
+ left: 0;
20
+ width: 100%;
21
+ height: 100%;
22
  }
23
+ .caption-text {
24
+ max-height: 300px;
25
+ overflow-y: auto;
26
  }
27
+ .caption-line:hover {
28
+ background-color: #f0f0f0;
29
+ cursor: pointer;
30
  }
31
+ .caption-line.selected {
32
+ background-color: #e2e8f0;
33
+ font-weight: 500;
34
+ }
35
+ .fade-in {
36
+ animation: fadeIn 0.5s ease-in-out;
37
+ }
38
+ @keyframes fadeIn {
39
+ from { opacity: 0; transform: translateY(10px); }
40
+ to { opacity: 1; transform: translateY(0); }
41
  }
42
  </style>
43
  </head>
44
+ <body class="bg-gray-50 min-h-screen">
45
+ <div class="container mx-auto px-4 py-8 max-w-4xl">
46
+ <!-- Header -->
47
+ <header class="text-center mb-8">
48
+ <h1 class="text-3xl md:text-4xl font-bold text-indigo-700 mb-2">YouTube Caption Extractor</h1>
49
+ <p class="text-gray-600">Get captions/subtitles from any YouTube video for free</p>
50
+ </header>
51
+
52
+ <!-- Main Content -->
53
+ <main>
54
+ <!-- URL Input Section -->
55
+ <div class="bg-white rounded-lg shadow-md p-6 mb-8">
56
+ <div class="flex flex-col md:flex-row gap-4">
57
+ <input
58
+ type="text"
59
+ id="youtube-url"
60
+ placeholder="Paste YouTube video URL here (e.g. https://www.youtube.com/watch?v=...)"
61
+ class="flex-grow px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500"
62
+ >
63
+ <button
64
+ id="extract-btn"
65
+ class="bg-indigo-600 hover:bg-indigo-700 text-white font-medium px-6 py-3 rounded-lg transition-colors flex items-center justify-center gap-2"
66
+ >
67
+ <i class="fas fa-play"></i> Extract Captions
68
+ </button>
69
  </div>
70
+ <div id="error-message" class="text-red-500 mt-2 text-sm hidden"></div>
 
 
 
 
71
  </div>
 
 
72
 
73
+ <!-- Video Player Section -->
74
+ <div id="video-section" class="hidden fade-in">
75
+ <div class="bg-white rounded-lg shadow-md overflow-hidden mb-6">
76
+ <div class="video-container">
77
+ <iframe id="video-player" frameborder="0" allowfullscreen></iframe>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  </div>
79
  </div>
 
 
 
80
 
81
+ <!-- Captions Section -->
82
+ <div class="bg-white rounded-lg shadow-md p-6">
83
+ <div class="flex flex-col md:flex-row md:justify-between md:items-center mb-4 gap-4">
84
+ <h2 class="text-xl font-semibold text-gray-800">Video Captions</h2>
85
+ <div class="flex flex-col sm:flex-row gap-2">
86
+ <select id="language-select" class="px-3 py-2 border border-gray-300 rounded-lg text-sm">
87
+ <option value="es">Spanish</option>
88
+ <option value="fr">French</option>
89
+ <option value="de">German</option>
90
+ <option value="it">Italian</option>
91
+ <option value="pt">Portuguese</option>
92
+ <option value="ja">Japanese</option>
93
+ <option value="ko">Korean</option>
94
+ <option value="zh">Chinese</option>
95
+ </select>
96
+ <select id="format-select" class="px-3 py-2 border border-gray-300 rounded-lg text-sm">
97
+ <option value="plain">Plain Text</option>
98
+ <option value="srt">SRT Format</option>
99
+ <option value="tab">Tab Separated</option>
100
+ </select>
101
+ <button
102
+ id="copy-all-btn"
103
+ class="text-indigo-600 hover:text-indigo-800 flex items-center gap-1 text-sm whitespace-nowrap"
104
+ >
105
+ <i class="fas fa-copy"></i> Copy All
106
+ </button>
107
  </div>
 
 
 
 
 
 
 
 
 
 
108
  </div>
109
+
110
+ <div class="bg-gray-100 rounded-lg p-4 caption-text" id="captions-container">
111
+ <p class="text-gray-500 text-center py-8">Captions will appear here after extraction</p>
 
 
 
 
 
 
112
  </div>
113
+
114
+ <div class="mt-4 flex justify-between items-center text-sm text-gray-500">
115
+ <div id="selected-count">0 captions selected</div>
116
+ <button
117
+ id="copy-selected-btn"
118
+ class="text-indigo-600 hover:text-indigo-800 flex items-center gap-1 disabled:opacity-50"
119
+ disabled
120
+ >
121
+ <i class="fas fa-copy"></i> Copy Selected
122
+ </button>
123
  </div>
124
  </div>
125
  </div>
126
+ </main>
 
127
 
128
+ <!-- How It Works Section -->
129
+ <section class="mt-12 bg-white rounded-lg shadow-md p-6">
130
+ <h2 class="text-xl font-semibold text-gray-800 mb-4">How It Works</h2>
131
+ <div class="grid md:grid-cols-3 gap-6">
132
+ <div class="flex flex-col items-center text-center">
133
+ <div class="bg-indigo-100 w-12 h-12 rounded-full flex items-center justify-center mb-3">
134
+ <i class="fas fa-link text-indigo-600 text-xl"></i>
 
 
135
  </div>
136
+ <h3 class="font-medium mb-1">1. Paste URL</h3>
137
+ <p class="text-gray-600 text-sm">Enter any YouTube video URL in the box above</p>
138
  </div>
139
+ <div class="flex flex-col items-center text-center">
140
+ <div class="bg-indigo-100 w-12 h-12 rounded-full flex items-center justify-center mb-3">
141
+ <i class="fas fa-play-circle text-indigo-600 text-xl"></i>
 
 
 
 
 
 
 
 
 
142
  </div>
143
+ <h3 class="font-medium mb-1">2. Extract Captions</h3>
144
+ <p class="text-gray-600 text-sm">Click the button to process the video</p>
145
  </div>
146
+ <div class="flex flex-col items-center text-center">
147
+ <div class="bg-indigo-100 w-12 h-12 rounded-full flex items-center justify-center mb-3">
148
+ <i class="fas fa-copy text-indigo-600 text-xl"></i>
 
 
 
 
 
 
 
 
149
  </div>
150
+ <h3 class="font-medium mb-1">3. Copy & Study</h3>
151
+ <p class="text-gray-600 text-sm">Select and copy captions for your study needs</p>
152
  </div>
153
  </div>
154
+ </section>
 
155
 
156
+ <!-- Footer -->
157
+ <footer class="mt-12 text-center text-gray-500 text-sm">
158
+ <p>Free YouTube Caption Extractor - No registration required</p>
159
+ <p class="mt-1">© 2023 All Rights Reserved</p>
160
+ </footer>
161
+ </div>
162
+
163
+ <!-- Toast Notification -->
164
+ <div id="toast" class="fixed bottom-4 right-4 bg-gray-800 text-white px-4 py-2 rounded-lg shadow-lg hidden">
165
+ <div class="flex items-center gap-2">
166
+ <i class="fas fa-check-circle text-green-400"></i>
167
+ <span id="toast-message">Copied to clipboard!</span>
 
 
 
 
 
168
  </div>
169
+ </div>
170
+
171
+ <script>
172
+ document.addEventListener('DOMContentLoaded', function() {
173
+ const youtubeUrlInput = document.getElementById('youtube-url');
174
+ const extractBtn = document.getElementById('extract-btn');
175
+ const videoSection = document.getElementById('video-section');
176
+ const videoPlayer = document.getElementById('video-player');
177
+ const captionsContainer = document.getElementById('captions-container');
178
+ const errorMessage = document.getElementById('error-message');
179
+ const copyAllBtn = document.getElementById('copy-all-btn');
180
+ const copySelectedBtn = document.getElementById('copy-selected-btn');
181
+ const selectedCount = document.getElementById('selected-count');
182
+ const toast = document.getElementById('toast');
183
+ const toastMessage = document.getElementById('toast-message');
184
 
185
+ let captions = [];
186
+ let selectedCaptions = new Set();
187
+ let currentLanguage = 'es';
188
+ let currentFormat = 'plain';
189
+
190
+ // Extract video ID from URL
191
+ function getVideoId(url) {
192
+ const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/;
193
+ const match = url.match(regExp);
194
+ return (match && match[2].length === 11) ? match[2] : null;
195
+ }
196
+
197
+ // Validate YouTube URL
198
+ function isValidYouTubeUrl(url) {
199
+ return url.includes('youtube.com') || url.includes('youtu.be');
200
+ }
201
+
202
+ // Show error message
203
+ function showError(message) {
204
+ errorMessage.textContent = message;
205
+ errorMessage.classList.remove('hidden');
206
+ }
207
+
208
+ // Hide error message
209
+ function hideError() {
210
+ errorMessage.classList.add('hidden');
211
+ }
212
+
213
+ // Show toast notification
214
+ function showToast(message) {
215
+ toastMessage.textContent = message;
216
+ toast.classList.remove('hidden');
217
+ setTimeout(() => {
218
+ toast.classList.add('hidden');
219
+ }, 3000);
220
+ }
221
+
222
+ // Extract captions (mock function - in a real app, you'd call a backend service)
223
+ function extractCaptions(videoId) {
224
+ // This is a mock implementation
225
+ // In a real app, you would need to:
226
+ // 1. Call a backend service that uses the YouTube API to get captions
227
+ // 2. Or use a proxy service to fetch captions
228
 
229
+ return new Promise((resolve) => {
230
+ // Simulate API delay
231
+ setTimeout(() => {
232
+ // Mock captions data
233
+ const mockCaptions = [
234
+ {
235
+ start: 0,
236
+ duration: 5,
237
+ original: "Hello and welcome to this tutorial.",
238
+ translated: "Hola y bienvenidos a este tutorial."
239
+ },
240
+ {
241
+ start: 5,
242
+ duration: 4,
243
+ original: "Today we'll learn about YouTube captions.",
244
+ translated: "Hoy aprenderemos sobre los subtítulos de YouTube."
245
+ },
246
+ {
247
+ start: 9,
248
+ duration: 6,
249
+ original: "Captions are important for accessibility.",
250
+ translated: "Los subtítulos son importantes para la accesibilidad."
251
+ },
252
+ {
253
+ start: 15,
254
+ duration: 5,
255
+ original: "They help people understand the content.",
256
+ translated: "Ayudan a las personas a entender el contenido."
257
+ },
258
+ {
259
+ start: 20,
260
+ duration: 6,
261
+ original: "You can use them for language learning too.",
262
+ translated: "También puedes usarlos para aprender idiomas."
263
+ }
264
+ ];
265
+ resolve(mockCaptions);
266
+ }, 1000);
267
+ });
268
+ }
269
+
270
+ // Display captions in the UI
271
+ function displayCaptions(captionsData) {
272
+ captions = captionsData;
273
+ selectedCaptions.clear();
274
+ updateSelectedCount();
275
+ copySelectedBtn.disabled = true;
276
 
277
+ if (captionsData.length === 0) {
278
+ captionsContainer.innerHTML = '<p class="text-gray-500 text-center py-8">No captions available for this video</p>';
279
+ return;
280
+ }
 
 
 
 
 
 
 
281
 
282
+ let html = '';
283
+ captionsData.forEach((caption, index) => {
284
+ html += `
285
+ <div class="caption-line py-2 px-3 rounded mb-1" data-index="${index}">
286
+ <div class="font-medium mb-1">${caption.original}</div>
287
+ <div class="text-gray-600 text-sm">${caption.translated}</div>
 
 
288
  </div>
289
+ `;
290
+ });
291
 
292
+ captionsContainer.innerHTML = html;
293
+
294
+ // Add click event to caption lines
295
+ document.querySelectorAll('.caption-line').forEach(line => {
296
+ line.addEventListener('click', function() {
297
+ const index = parseInt(this.getAttribute('data-index'));
298
+
299
+ if (selectedCaptions.has(index)) {
300
+ selectedCaptions.delete(index);
301
+ this.classList.remove('selected');
302
+ } else {
303
+ selectedCaptions.add(index);
304
+ this.classList.add('selected');
305
+ }
306
+
307
+ updateSelectedCount();
308
+ copySelectedBtn.disabled = selectedCaptions.size === 0;
309
+ });
310
+ });
311
+ }
312
 
313
+ // Update selected count display
314
+ function updateSelectedCount() {
315
+ const count = selectedCaptions.size;
316
+ selectedCount.textContent = `${count} caption${count !== 1 ? 's' : ''} selected`;
317
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
 
319
+ // Handle language selection change
320
+ document.getElementById('language-select').addEventListener('change', function() {
321
+ currentLanguage = this.value;
322
+ // In a real app, you would fetch translations for the selected language
323
+ // For this demo, we're just using mock data
324
+ displayCaptions(captions);
325
+ });
326
+
327
+ // Handle format selection change
328
+ document.getElementById('format-select').addEventListener('change', function() {
329
+ currentFormat = this.value;
330
+ });
331
+
332
+ // Format captions based on selected format
333
+ function formatCaptionText(original, translated) {
334
+ switch(currentFormat) {
335
+ case 'srt':
336
+ return `${original}\n${translated}`;
337
+ case 'tab':
338
+ return `${original}\t${translated}`;
339
+ default: // plain
340
+ return `${original}\n${translated}`;
341
+ }
342
+ }
343
 
344
+ // Copy all captions to clipboard
345
+ copyAllBtn.addEventListener('click', function() {
346
+ if (captions.length === 0) return;
347
+
348
+ const allText = captions.map(c => formatCaptionText(c.original, c.translated)).join('\n\n');
349
+ navigator.clipboard.writeText(allText).then(() => {
350
+ showToast('All captions copied to clipboard!');
351
+ });
352
+ });
353
+
354
+ // Copy selected captions to clipboard
355
+ copySelectedBtn.addEventListener('click', function() {
356
+ if (selectedCaptions.size === 0) return;
357
+
358
+ const selectedText = Array.from(selectedCaptions)
359
+ .sort((a, b) => a - b)
360
+ .map(index => formatCaptionText(captions[index].original, captions[index].translated))
361
+ .join(currentFormat === 'tab' ? '\n' : '\n\n');
362
+
363
+ navigator.clipboard.writeText(selectedText).then(() => {
364
+ showToast('Selected captions copied to clipboard!');
365
  });
366
  });
367
+
368
+ // Extract captions when button is clicked
369
+ extractBtn.addEventListener('click', function() {
370
+ const url = youtubeUrlInput.value.trim();
371
+
372
+ if (!url) {
373
+ showError('Please enter a YouTube URL');
374
+ return;
375
+ }
376
+
377
+ if (!isValidYouTubeUrl(url)) {
378
+ showError('Please enter a valid YouTube URL');
379
+ return;
380
+ }
381
+
382
+ const videoId = getVideoId(url);
383
+ if (!videoId) {
384
+ showError('Could not extract video ID from URL');
385
+ return;
386
+ }
387
+
388
+ hideError();
389
+ extractBtn.disabled = true;
390
+ extractBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Extracting...';
391
+
392
+ // Set up video player
393
+ videoPlayer.src = `https://www.youtube.com/embed/${videoId}?cc_load_policy=1`;
394
+ videoSection.classList.remove('hidden');
395
+
396
+ // Extract captions
397
+ extractCaptions(videoId)
398
+ .then(captions => {
399
+ displayCaptions(captions);
400
+ extractBtn.disabled = false;
401
+ extractBtn.innerHTML = '<i class="fas fa-play"></i> Extract Captions';
402
+ })
403
+ .catch(error => {
404
+ console.error('Error extracting captions:', error);
405
+ captionsContainer.innerHTML = '<p class="text-red-500 text-center py-8">Error extracting captions. Please try another video.</p>';
406
+ extractBtn.disabled = false;
407
+ extractBtn.innerHTML = '<i class="fas fa-play"></i> Extract Captions';
408
+ });
409
+ });
410
+
411
+ // Allow pressing Enter in the input field
412
+ youtubeUrlInput.addEventListener('keypress', function(e) {
413
+ if (e.key === 'Enter') {
414
+ extractBtn.click();
415
+ }
416
+ });
417
  });
418
  </script>
419
  <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=dimchr/captions" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>