Modify to receive pasted url in another window. When one is being used, disable the other input windo - Initial Deployment
7447431 verified | <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Video Transcript Generator</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 = { | |
| theme: { | |
| extend: { | |
| colors: { | |
| primary: '#4F46E5', | |
| secondary: '#818CF8', | |
| accent: '#F97316', | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
| min-height: 100vh; | |
| } | |
| .dropzone { | |
| border: 2px dashed #c3cfe2; | |
| border-radius: 10px; | |
| transition: all 0.3s ease; | |
| } | |
| .dropzone.dragover { | |
| border-color: #4F46E5; | |
| background-color: rgba(79, 70, 229, 0.05); | |
| } | |
| .progress-bar { | |
| transition: width 0.5s ease; | |
| } | |
| .transcript-container { | |
| max-height: 300px; | |
| overflow-y: auto; | |
| scrollbar-width: thin; | |
| } | |
| .transcript-container::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| .transcript-container::-webkit-scrollbar-thumb { | |
| background-color: #c3cfe2; | |
| border-radius: 4px; | |
| } | |
| .transcript-container::-webkit-scrollbar-thumb:hover { | |
| background-color: #a5b4fc; | |
| } | |
| .pulse-animation { | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { opacity: 1; } | |
| 50% { opacity: 0.5; } | |
| 100% { opacity: 1; } | |
| } | |
| .fade-in { | |
| animation: fadeIn 0.5s ease-in; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; } | |
| to { opacity: 1; } | |
| } | |
| </style> | |
| </head> | |
| <body class="py-8 px-4"> | |
| <div class="max-w-4xl mx-auto"> | |
| <!-- Header --> | |
| <header class="text-center mb-12"> | |
| <h1 class="text-3xl md:text-4xl font-bold text-gray-800 mb-2">Video Transcript Generator</h1> | |
| <p class="text-gray-600">Upload a video and get instant transcriptions with multiple export options</p> | |
| </header> | |
| <div class="bg-white rounded-xl shadow-lg p-6 md:p-8"> | |
| <!-- Input Method Tabs --> | |
| <div class="flex border-b border-gray-200 mb-6"> | |
| <button id="fileTab" class="px-4 py-2 font-medium text-primary border-b-2 border-primary transition-colors"> | |
| <i class="fas fa-upload mr-2"></i>File Upload | |
| </button> | |
| <button id="urlTab" class="px-4 py-2 font-medium text-gray-500 border-b-2 border-transparent hover:text-gray-700 transition-colors"> | |
| <i class="fas fa-link mr-2"></i>Video URL | |
| </button> | |
| </div> | |
| <!-- File Upload Section --> | |
| <div id="fileSection"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4">Upload Video</h2> | |
| <div class="dropzone p-8 text-center cursor-pointer" id="dropzone"> | |
| <input type="file" id="fileInput" class="hidden" accept="video/*"> | |
| <div class="flex flex-col items-center justify-center"> | |
| <i class="fas fa-cloud-upload-alt text-4xl text-primary mb-4"></i> | |
| <p class="text-gray-600 mb-2">Drag & drop your video file here</p> | |
| <p class="text-sm text-gray-500 mb-4">or</p> | |
| <label for="fileInput" class="bg-primary text-white px-6 py-2 rounded-lg cursor-pointer hover:bg-secondary transition-colors"> | |
| Browse Files | |
| </label> | |
| <p class="text-xs text-gray-500 mt-4">Supported formats: MP4, MOV, AVI, WebM</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- URL Input Section --> | |
| <div id="urlSection" class="hidden"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4">Enter Video URL</h2> | |
| <div class="space-y-4"> | |
| <input type="url" id="urlInput" placeholder="https://example.com/video.mp4" | |
| class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"> | |
| <button id="processUrlBtn" class="bg-primary text-white px-6 py-2 rounded-lg hover:bg-secondary transition-colors"> | |
| Process URL | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Progress Bar --> | |
| <div id="progressSection" class="mb-8 hidden"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4">Processing Video</h2> | |
| <div class="w-full bg-gray-200 rounded-full h-2.5"> | |
| <div class="progress-bar bg-primary h-2.5 rounded-full" style="width: 0%"></div> | |
| </div> | |
| <p class="text-sm text-gray-600 mt-2 text-center" id="progressText">0%</p> | |
| </div> | |
| <!-- Results Section --> | |
| <div id="resultsSection" class="hidden"> | |
| <h2 class="text-xl font-semibold text-gray-800 mb-4">Transcript Results</h2> | |
| <!-- Action Buttons --> | |
| <div class="flex flex-wrap gap-3 mb-6"> | |
| <button id="copyBtn" class="flex items-center gap-2 bg-gray-100 hover:bg-gray-200 text-gray-800 px-4 py-2 rounded-lg transition-colors"> | |
| <i class="fas fa-copy"></i> Copy | |
| </button> | |
| <button id="saveBtn" class="flex items-center gap-2 bg-gray-100 hover:bg-gray-200 text-gray-800 px-4 py-2 rounded-lg transition-colors"> | |
| <i class="fas fa-save"></i> Save as TXT | |
| </button> | |
| <button id="emailBtn" class="flex items-center gap-2 bg-gray-100 hover:bg-gray-200 text-gray-800 px-4 py-2 rounded-lg transition-colors"> | |
| <i class="fas fa-envelope"></i> Email | |
| </button> | |
| </div> | |
| <!-- Transcript Display --> | |
| <div class="transcript-container bg-gray-50 p-4 rounded-lg border border-gray-200 mb-6"> | |
| <p id="transcriptText" class="text-gray-700 leading-relaxed"></p> | |
| </div> | |
| <!-- Email Modal --> | |
| <div id="emailModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50"> | |
| <div class="bg-white rounded-xl p-6 w-full max-w-md"> | |
| <h3 class="text-xl font-semibold text-gray-800 mb-4">Email Transcript</h3> | |
| <div class="mb-4"> | |
| <label class="block text-gray-700 mb-2">Email Address</label> | |
| <input type="email" id="emailInput" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"> | |
| </div> | |
| <div class="flex justify-end gap-3"> | |
| <button id="cancelEmail" class="px-4 py-2 text-gray-600 hover:text-gray-800">Cancel</button> | |
| <button id="sendEmail" class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-secondary transition-colors">Send</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Footer --> | |
| <footer class="text-center mt-12 text-gray-600 text-sm"> | |
| <p>© 2023 Video Transcript Generator. All rights reserved.</p> | |
| </footer> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const dropzone = document.getElementById('dropzone'); | |
| const fileInput = document.getElementById('fileInput'); | |
| const fileSection = document.getElementById('fileSection'); | |
| const urlSection = document.getElementById('urlSection'); | |
| const fileTab = document.getElementById('fileTab'); | |
| const urlTab = document.getElementById('urlTab'); | |
| const urlInput = document.getElementById('urlInput'); | |
| const processUrlBtn = document.getElementById('processUrlBtn'); | |
| const progressSection = document.getElementById('progressSection'); | |
| const progressBar = document.querySelector('.progress-bar'); | |
| const progressText = document.getElementById('progressText'); | |
| const resultsSection = document.getElementById('resultsSection'); | |
| const transcriptText = document.getElementById('transcriptText'); | |
| const copyBtn = document.getElementById('copyBtn'); | |
| const saveBtn = document.getElementById('saveBtn'); | |
| const emailBtn = document.getElementById('emailBtn'); | |
| const emailModal = document.getElementById('emailModal'); | |
| const cancelEmail = document.getElementById('cancelEmail'); | |
| const sendEmail = document.getElementById('sendEmail'); | |
| const emailInput = document.getElementById('emailInput'); | |
| let currentTranscript = ""; | |
| let currentMethod = 'file'; | |
| // Tab switching functionality | |
| fileTab.addEventListener('click', function() { | |
| if (currentMethod !== 'file') { | |
| currentMethod = 'file'; | |
| fileTab.classList.add('text-primary', 'border-primary'); | |
| fileTab.classList.remove('text-gray-500', 'border-transparent'); | |
| urlTab.classList.add('text-gray-500', 'border-transparent'); | |
| urlTab.classList.remove('text-primary', 'border-primary'); | |
| fileSection.classList.remove('hidden'); | |
| urlSection.classList.add('hidden'); | |
| } | |
| }); | |
| urlTab.addEventListener('click', function() { | |
| if (currentMethod !== 'url') { | |
| currentMethod = 'url'; | |
| urlTab.classList.add('text-primary', 'border-primary'); | |
| urlTab.classList.remove('text-gray-500', 'border-transparent'); | |
| fileTab.classList.add('text-gray-500', 'border-transparent'); | |
| fileTab.classList.remove('text-primary', 'border-primary'); | |
| urlSection.classList.remove('hidden'); | |
| fileSection.classList.add('hidden'); | |
| } | |
| }); | |
| // URL processing | |
| processUrlBtn.addEventListener('click', function() { | |
| const url = urlInput.value.trim(); | |
| if (url) { | |
| if (isValidUrl(url)) { | |
| processVideoUrl(url); | |
| } else { | |
| alert('Please enter a valid URL'); | |
| } | |
| } else { | |
| alert('Please enter a video URL'); | |
| } | |
| }); | |
| function isValidUrl(string) { | |
| try { | |
| new URL(string); | |
| return true; | |
| } catch (_) { | |
| return false; | |
| } | |
| } | |
| // Drag and drop functionality | |
| ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { | |
| dropzone.addEventListener(eventName, preventDefaults, false); | |
| }); | |
| function preventDefaults(e) { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| } | |
| ['dragenter', 'dragover'].forEach(eventName => { | |
| dropzone.addEventListener(eventName, highlight, false); | |
| }); | |
| ['dragleave', 'drop'].forEach(eventName => { | |
| dropzone.addEventListener(eventName, unhighlight, false); | |
| }); | |
| function highlight() { | |
| dropzone.classList.add('dragover'); | |
| } | |
| function unhighlight() { | |
| dropzone.classList.remove('dragover'); | |
| } | |
| dropzone.addEventListener('drop', handleDrop, false); | |
| function handleDrop(e) { | |
| const dt = e.dataTransfer; | |
| const files = dt.files; | |
| handleFiles(files); | |
| } | |
| fileInput.addEventListener('change', function() { | |
| handleFiles(this.files); | |
| }); | |
| function handleFiles(files) { | |
| if (files.length > 0) { | |
| const file = files[0]; | |
| if (file.type.startsWith('video/')) { | |
| processVideoFile(file); | |
| } else { | |
| alert('Please upload a valid video file.'); | |
| } | |
| } | |
| } | |
| function processVideoFile(file) { | |
| // Show processing UI | |
| progressSection.classList.remove('hidden'); | |
| resultsSection.classList.add('hidden'); | |
| // Simulate processing progress | |
| let progress = 0; | |
| const interval = setInterval(() => { | |
| progress += Math.random() * 10; | |
| if (progress >= 100) { | |
| progress = 100; | |
| clearInterval(interval); | |
| showResults(file.name); | |
| } | |
| progressBar.style.width = `${progress}%`; | |
| progressText.textContent = `${Math.round(progress)}%`; | |
| }, 300); | |
| } | |
| function processVideoUrl(url) { | |
| // Show processing UI | |
| progressSection.classList.remove('hidden'); | |
| resultsSection.classList.add('hidden'); | |
| // Extract filename from URL for display | |
| const filename = url.split('/').pop() || 'video_from_url'; | |
| // Simulate processing progress | |
| let progress = 0; | |
| const interval = setInterval(() => { | |
| progress += Math.random() * 10; | |
| if (progress >= 100) { | |
| progress = 100; | |
| clearInterval(interval); | |
| showResults(filename); | |
| } | |
| progressBar.style.width = `${progress}%`; | |
| progressText.textContent = `${Math.round(progress)}%`; | |
| }, 300); | |
| } | |
| function showResults(filename) { | |
| // Hide progress and show results | |
| progressSection.classList.add('hidden'); | |
| resultsSection.classList.remove('hidden'); | |
| // Generate example transcript | |
| currentTranscript = `Transcript for: ${filename}\n\n`; | |
| currentTranscript += "[00:00:01] Hello and welcome to this video presentation.\n"; | |
| currentTranscript += "[00:00:05] Today we're going to discuss the importance of transcript generation.\n"; | |
| currentTranscript += "[00:00:12] Transcripts make video content accessible to everyone.\n"; | |
| currentTranscript += "[00:00:18] They help with SEO and allow users to quickly find information.\n"; | |
| currentTranscript += "[00:00:25] This is just a sample transcript generated by our tool.\n"; | |
| currentTranscript += "[00:00:32] In a real application, this would be the actual content from your video.\n"; | |
| currentTranscript += "[00:00:40] Thank you for using our Video Transcript Generator!"; | |
| transcriptText.textContent = currentTranscript; | |
| } | |
| // Copy functionality | |
| copyBtn.addEventListener('click', function() { | |
| navigator.clipboard.writeText(currentTranscript).then(() => { | |
| const originalHtml = copyBtn.innerHTML; | |
| copyBtn.innerHTML = '<i class="fas fa-check"></i> Copied!'; | |
| setTimeout(() => { | |
| copyBtn.innerHTML = originalHtml; | |
| }, 2000); | |
| }); | |
| }); | |
| // Save functionality | |
| saveBtn.addEventListener('click', function() { | |
| const blob = new Blob([currentTranscript], { type: 'text/plain' }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = 'transcript.txt'; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| }); | |
| // Email functionality | |
| emailBtn.addEventListener('click', function() { | |
| emailModal.classList.remove('hidden'); | |
| }); | |
| cancelEmail.addEventListener('click', function() { | |
| emailModal.classList.add('hidden'); | |
| emailInput.value = ''; | |
| }); | |
| sendEmail.addEventListener('click', function() { | |
| const email = emailInput.value; | |
| if (validateEmail(email)) { | |
| // Simulate sending email | |
| emailModal.classList.add('hidden'); | |
| alert(`Transcript sent to ${email}`); | |
| emailInput.value = ''; | |
| } else { | |
| alert('Please enter a valid email address.'); | |
| } | |
| }); | |
| function validateEmail(email) { | |
| const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; | |
| return re.test(email); | |
| } | |
| }); | |
| </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=Professorjoe/prof-joebell-projects-space" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |