my-space / index.html
ALAAZIADI's picture
ADD A BOTTEN TO GENERATE AND AND FIX YOUTUBE LIK NOT WORKING - Follow Up Deployment
51f0e45 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ShortsAI - Create Viral Shorts from Videos</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 src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="https://unpkg.com/@supabase/supabase-js@2"></script>
<style>
.video-preview {
aspect-ratio: 9/16;
}
.waveform {
height: 60px;
background: linear-gradient(90deg, #3b82f6 0%, #8b5cf6 50%, #ec4899 100%);
mask-image: url('data:image/svg+xml;utf8,<svg viewBox="0 0 100 20" xmlns="http://www.w3.org/2000/svg"><path d="M0 10 Q 5 5, 10 10 T 20 10 T 30 10 T 40 10 T 50 10 T 60 10 T 70 10 T 80 10 T 90 10 T 100 10" stroke="black" fill="none"/></svg>');
mask-size: 100% 100%;
mask-repeat: no-repeat;
}
.progress-ring {
transition: stroke-dashoffset 0.1s;
}
.short-clip {
scroll-snap-align: start;
}
.shorts-container {
scroll-snap-type: y mandatory;
}
.text-tracking {
animation: textTrack 5s infinite alternate;
}
@keyframes textTrack {
0% { transform: translateY(0) scale(1); opacity: 1; }
100% { transform: translateY(-10px) scale(1.05); opacity: 0.9; }
}
.fade-in {
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
</style>
</head>
<body class="bg-gray-900 text-white min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<header class="flex justify-between items-center mb-8">
<div class="flex items-center space-x-2">
<i class="fas fa-bolt text-yellow-400 text-2xl"></i>
<h1 class="text-2xl font-bold bg-gradient-to-r from-blue-400 via-purple-500 to-pink-500 bg-clip-text text-transparent">ShortsAI</h1>
</div>
<div class="flex space-x-4">
<button class="px-4 py-2 rounded-full bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700 transition-all">
<i class="fas fa-user mr-2"></i>Login
</button>
<button class="px-4 py-2 rounded-full bg-gradient-to-r from-purple-500 to-pink-600 hover:from-purple-600 hover:to-pink-700 transition-all">
<i class="fas fa-crown mr-2"></i>Go Pro
</button>
</div>
</header>
<!-- Main Content -->
<main class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Upload Section -->
<div class="lg:col-span-2 bg-gray-800 rounded-xl p-6 shadow-lg">
<h2 class="text-xl font-semibold mb-4">Create Viral Shorts</h2>
<!-- Upload Options -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<div class="bg-gray-700 rounded-lg p-4 border-2 border-dashed border-gray-600 hover:border-blue-400 transition-colors">
<label for="file-upload" class="cursor-pointer flex flex-col items-center justify-center h-full">
<i class="fas fa-upload text-4xl mb-3 text-blue-400"></i>
<p class="text-center font-medium">Upload Video</p>
<p class="text-sm text-gray-400 text-center">MP4, MOV, AVI up to 500MB</p>
<input id="file-upload" type="file" accept="video/*" class="hidden">
</label>
</div>
<div class="bg-gray-700 rounded-lg p-4">
<div class="flex flex-col h-full">
<div class="flex items-center mb-3">
<i class="fas fa-link text-4xl mr-3 text-purple-400"></i>
<p class="font-medium">YouTube/TikTok URL</p>
</div>
<div class="flex-grow flex items-center">
<input type="text" id="video-url" placeholder="Paste video link here" class="w-full bg-gray-600 rounded-l-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500">
<button id="submit-url" class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded-r-lg transition-colors">
<i class="fas fa-arrow-right"></i>
</button>
</div>
</div>
</div>
</div>
<!-- Video Preview -->
<div class="mb-6">
<div id="video-preview-container" class="relative bg-black rounded-xl overflow-hidden video-preview mx-auto max-w-md flex items-center justify-center hidden">
<video id="video-preview" controls class="w-full h-full object-cover"></video>
<div id="processing-overlay" class="absolute inset-0 bg-black bg-opacity-70 flex items-center justify-center hidden">
<div class="text-center">
<div class="w-16 h-16 mx-auto mb-4">
<svg class="w-full h-full" viewBox="0 0 100 100">
<circle class="text-gray-400" stroke-width="8" stroke="currentColor" fill="transparent" r="40" cx="50" cy="50" />
<circle class="progress-ring text-blue-500" stroke-width="8" stroke-linecap="round" stroke="currentColor" fill="transparent" r="40" cx="50" cy="50" />
</svg>
</div>
<p class="text-lg font-medium">Analyzing video...</p>
<p class="text-sm text-gray-300" id="processing-status">Extracting highlights</p>
</div>
</div>
</div>
<div id="upload-prompt" class="text-center py-12 border-2 border-dashed border-gray-700 rounded-xl">
<i class="fas fa-video text-4xl mb-4 text-gray-500"></i>
<h3 class="text-xl font-medium text-gray-300">Upload a video to get started</h3>
<p class="text-gray-500 mt-2">Or paste a YouTube/TikTok link above</p>
</div>
</div>
<!-- Analysis Options -->
<div class="bg-gray-700 rounded-xl p-4 mb-6">
<h3 class="font-medium mb-3">AI Analysis Options</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-3">
<div class="flex items-center">
<input type="checkbox" id="auto-highlights" checked class="mr-2 h-4 w-4 rounded bg-gray-800 border-gray-600 text-blue-500 focus:ring-blue-500">
<label for="auto-highlights">Auto Highlights</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="trend-analysis" checked class="mr-2 h-4 w-4 rounded bg-gray-800 border-gray-600 text-purple-500 focus:ring-purple-500">
<label for="trend-analysis">Trend Analysis</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="speech-tracking" checked class="mr-2 h-4 w-4 rounded bg-gray-800 border-gray-600 text-pink-500 focus:ring-pink-500">
<label for="speech-tracking">Speech Tracking</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="auto-effects" checked class="mr-2 h-4 w-4 rounded bg-gray-800 border-gray-600 text-green-500 focus:ring-green-500">
<label for="auto-effects">Auto Effects</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="auto-music" class="mr-2 h-4 w-4 rounded bg-gray-800 border-gray-600 text-yellow-500 focus:ring-yellow-500">
<label for="auto-music">Auto Music</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="auto-captions" class="mr-2 h-4 w-4 rounded bg-gray-800 border-gray-600 text-red-500 focus:ring-red-500">
<label for="auto-captions">Auto Captions</label>
</div>
</div>
</div>
<!-- Generate Button -->
<button id="generate-btn" class="w-full py-3 rounded-xl bg-gradient-to-r from-blue-500 to-purple-600 hover:from-blue-600 hover:to-purple-700 font-bold text-lg transition-all flex items-center justify-center hidden">
<i class="fas fa-magic mr-2"></i> Generate Shorts
</button>
</div>
<!-- Results Section -->
<div class="bg-gray-800 rounded-xl p-6 shadow-lg">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-semibold">Generated Shorts</h2>
<div class="flex space-x-2">
<button id="batch-download" class="p-2 rounded-lg bg-gray-700 hover:bg-gray-600 transition-colors hidden">
<i class="fas fa-download"></i>
</button>
<button id="batch-settings" class="p-2 rounded-lg bg-gray-700 hover:bg-gray-600 transition-colors hidden">
<i class="fas fa-sliders-h"></i>
</button>
</div>
</div>
<div id="results-container" class="space-y-4">
<div class="text-center py-12 border-2 border-dashed border-gray-700 rounded-xl">
<i class="fas fa-film text-4xl mb-4 text-gray-500"></i>
<h3 class="text-xl font-medium text-gray-300">No shorts generated yet</h3>
<p class="text-gray-500 mt-2">Upload a video and click "Generate Shorts"</p>
</div>
</div>
</div>
</main>
<!-- Generated Shorts Preview Modal -->
<div id="preview-modal" class="fixed inset-0 bg-black bg-opacity-80 z-50 flex items-center justify-center hidden">
<div class="bg-gray-800 rounded-xl overflow-hidden w-full max-w-md mx-4">
<div class="relative video-preview bg-black">
<video id="modal-preview" class="w-full h-full object-cover" controls></video>
<div id="modal-processing" class="absolute inset-0 bg-black bg-opacity-70 flex items-center justify-center hidden">
<div class="text-center">
<div class="w-16 h-16 mx-auto mb-4">
<svg class="w-full h-full" viewBox="0 0 100 100">
<circle class="text-gray-400" stroke-width="8" stroke="currentColor" fill="transparent" r="40" cx="50" cy="50" />
<circle class="progress-ring text-pink-500" stroke-width="8" stroke-linecap="round" stroke="currentColor" fill="transparent" r="40" cx="50" cy="50" />
</svg>
</div>
<p class="text-lg font-medium">Applying effects...</p>
</div>
</div>
</div>
<div class="p-4">
<div class="flex justify-between items-center mb-4">
<h3 class="font-bold text-lg">Short #<span id="short-number">1</span></h3>
<div class="flex space-x-2">
<button class="p-2 rounded-full bg-gray-700 hover:bg-gray-600">
<i class="fas fa-random"></i>
</button>
<button class="p-2 rounded-full bg-gray-700 hover:bg-gray-600">
<i class="fas fa-music"></i>
</button>
<button class="p-2 rounded-full bg-gray-700 hover:bg-gray-600">
<i class="fas fa-text-height"></i>
</button>
</div>
</div>
<div class="mb-4">
<div class="waveform mb-2"></div>
<div class="flex justify-between text-sm text-gray-400">
<span>0:00</span>
<span>0:15</span>
</div>
</div>
<div class="grid grid-cols-2 gap-3 mb-4">
<div>
<label class="block text-sm font-medium mb-1">Effect</label>
<select class="w-full bg-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500">
<option>Auto (Recommended)</option>
<option>Zoom In</option>
<option>Slow Mo</option>
<option>Glitch</option>
<option>VHS</option>
</select>
</div>
<div>
<label class="block text-sm font-medium mb-1">Music</label>
<select class="w-full bg-gray-700 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-purple-500">
<option>Auto (Recommended)</option>
<option>Upbeat</option>
<option>Chill</option>
<option>Epic</option>
<option>None</option>
</select>
</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium mb-1">Captions</label>
<textarea class="w-full bg-gray-700 rounded-lg px-3 py-2 h-20 focus:outline-none focus:ring-2 focus:ring-purple-500" placeholder="Auto-generated captions will appear here"></textarea>
</div>
<div class="flex space-x-3">
<button class="flex-1 py-2 rounded-lg bg-gray-700 hover:bg-gray-600 transition-colors">
<i class="fas fa-redo mr-2"></i> Regenerate
</button>
<button id="download-short" class="flex-1 py-2 rounded-lg bg-gradient-to-r from-purple-500 to-pink-600 hover:from-purple-600 hover:to-pink-700 transition-colors">
<i class="fas fa-download mr-2"></i> Download
</button>
</div>
</div>
</div>
</div>
</div>
<script>
// Initialize Supabase
const supabase = createClient(
'https://fzorlrrqglliagqluklw.supabase.co',
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZ6b3JscnJxZ2xsaWFncWx1a2x3Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDk4MjY2MTYsImV4cCI6MjA2NTQwMjYxNn0.PeCHU18GmnlaXUd_dxRO_LFZzPlxNRagMxvRh1I-Cg4'
);
// DOM Elements
const fileUpload = document.getElementById('file-upload');
const videoPreviewContainer = document.getElementById('video-preview-container');
const videoPreview = document.getElementById('video-preview');
const uploadPrompt = document.getElementById('upload-prompt');
const generateBtn = document.getElementById('generate-btn');
const resultsContainer = document.getElementById('results-container');
const previewModal = document.getElementById('preview-modal');
const modalPreview = document.getElementById('modal-preview');
const modalProcessing = document.getElementById('modal-processing');
const processingOverlay = document.getElementById('processing-overlay');
const processingStatus = document.getElementById('processing-status');
const downloadShort = document.getElementById('download-short');
const batchDownload = document.getElementById('batch-download');
const batchSettings = document.getElementById('batch-settings');
// Video processing state
let videoFile = null;
let generatedShorts = [];
let currentShortIndex = 0;
// Event Listeners
fileUpload.addEventListener('change', handleFileUpload);
generateBtn.addEventListener('click', generateShorts);
downloadShort.addEventListener('click', downloadCurrentShort);
batchDownload.addEventListener('click', batchDownloadShorts);
document.getElementById('submit-url').addEventListener('click', handleUrlSubmit);
document.getElementById('video-url').addEventListener('keypress', (e) => {
if (e.key === 'Enter') handleUrlSubmit();
});
// Handle URL submission
function handleUrlSubmit() {
const url = document.getElementById('video-url').value.trim();
if (!url) return;
// Enhanced URL validation
const youtubeRegex = /(youtube\.com|youtu\.be)\/(watch\?v=|embed\/|v\/|.+\?v=)?([^&]+)/i;
const tiktokRegex = /tiktok\.com\/(@[\w.-]+\/video\/\d+|v\/\d+)/i;
if (!youtubeRegex.test(url) && !tiktokRegex.test(url)) {
alert('Please enter a valid YouTube or TikTok URL\nExample YouTube: https://youtube.com/watch?v=dQw4w9WgXcQ\nExample TikTok: https://tiktok.com/@user/video/123456789');
return;
}
// Extract video ID
let videoId;
if (url.includes('youtube') || url.includes('youtu.be')) {
videoId = url.match(/(?:v=|\/)([0-9A-Za-z_-]{11}).*/)[1];
} else {
videoId = url.split('/').pop();
}
// Show processing state
uploadPrompt.classList.add('hidden');
videoPreviewContainer.classList.remove('hidden');
processingOverlay.classList.remove('hidden');
generateBtn.classList.remove('hidden');
processingStatus.textContent = "Processing video link...";
// Simulate processing (in a real app, you'd fetch the video here)
setTimeout(() => {
processingOverlay.classList.add('hidden');
videoPreview.src = ''; // In a real app, this would be the processed video
videoPreview.poster = 'https://img.youtube.com/vi/' + (url.match(/[?&]v=([^&]+)/)?.[1] || '') + '/0.jpg';
startVideoAnalysis();
}, 1500);
}
// Handle file upload
function handleFileUpload(e) {
const file = e.target.files[0];
if (!file) return;
videoFile = file;
// Show video preview
uploadPrompt.classList.add('hidden');
videoPreviewContainer.classList.remove('hidden');
generateBtn.classList.remove('hidden');
const videoURL = URL.createObjectURL(file);
videoPreview.src = videoURL;
// Start analysis
startVideoAnalysis();
}
// Simulate video analysis
function startVideoAnalysis() {
processingOverlay.classList.remove('hidden');
const statusMessages = [
"Analyzing video content...",
"Detecting key moments...",
"Identifying trending elements...",
"Extracting speech patterns...",
"Finalizing analysis..."
];
let progress = 0;
const interval = setInterval(() => {
progress += 10;
if (progress > 100) {
clearInterval(interval);
processingOverlay.classList.add('hidden');
return;
}
// Update progress ring
const circle = document.querySelector('.progress-ring');
const radius = circle.r.baseVal.value;
const circumference = 2 * Math.PI * radius;
const offset = circumference - (progress / 100) * circumference;
circle.style.strokeDashoffset = offset;
// Update status message
const messageIndex = Math.min(Math.floor(progress / 20), statusMessages.length - 1);
processingStatus.textContent = statusMessages[messageIndex];
}, 300);
}
// Generate shorts from video
function generateShorts() {
processingOverlay.classList.remove('hidden');
processingStatus.textContent = "Generating shorts...";
// Simulate AI processing
setTimeout(() => {
processingOverlay.classList.add('hidden');
// Generate mock shorts data
generatedShorts = [
{ id: 1, start: 12, end: 27, caption: "This is the most exciting part!", effect: "zoom-in", music: "upbeat" },
{ id: 2, start: 45, end: 60, caption: "You won't believe what happens next", effect: "slow-mo", music: "epic" },
{ id: 3, start: 78, end: 93, caption: "The perfect ending to this story", effect: "glitch", music: "chill" },
{ id: 4, start: 112, end: 127, caption: "Trending moment detected!", effect: "auto", music: "auto" },
{ id: 5, start: 150, end: 165, caption: "Speech analysis highlights", effect: "auto", music: "auto" }
];
// Display results
displayGeneratedShorts();
// Show batch controls
batchDownload.classList.remove('hidden');
batchSettings.classList.remove('hidden');
}, 2000);
}
// Display generated shorts in results
function displayGeneratedShorts() {
resultsContainer.innerHTML = '';
if (generatedShorts.length === 0) {
resultsContainer.innerHTML = `
<div class="text-center py-12 border-2 border-dashed border-gray-700 rounded-xl">
<i class="fas fa-exclamation-triangle text-4xl mb-4 text-yellow-400"></i>
<h3 class="text-xl font-medium text-gray-300">No shorts generated</h3>
<p class="text-gray-500 mt-2">Try adjusting your analysis settings</p>
</div>
`;
return;
}
// Create a container with vertical scrolling
const container = document.createElement('div');
container.className = 'shorts-container h-[500px] overflow-y-auto space-y-4';
// Add each short as a preview
generatedShorts.forEach((short, index) => {
const shortElement = document.createElement('div');
shortElement.className = 'short-clip bg-gray-700 rounded-xl p-4 cursor-pointer hover:bg-gray-600 transition-colors fade-in';
shortElement.innerHTML = `
<div class="flex">
<div class="w-24 h-24 bg-black rounded-lg overflow-hidden mr-4">
<div class="w-full h-full flex items-center justify-center">
<i class="fas fa-play text-gray-400 text-xl"></i>
</div>
</div>
<div class="flex-1">
<h4 class="font-medium">Short #${short.id}</h4>
<p class="text-sm text-gray-400 mb-2">${short.start}s - ${short.end}s</p>
<div class="flex flex-wrap gap-2">
<span class="text-xs bg-blue-900 text-blue-200 px-2 py-1 rounded">${short.effect}</span>
<span class="text-xs bg-purple-900 text-purple-200 px-2 py-1 rounded">${short.music}</span>
<span class="text-xs bg-pink-900 text-pink-200 px-2 py-1 rounded">AI Generated</span>
</div>
</div>
<div class="flex items-center">
<button class="p-2 rounded-full hover:bg-gray-500 transition-colors download-short" data-index="${index}">
<i class="fas fa-download"></i>
</button>
</div>
</div>
`;
shortElement.addEventListener('click', () => previewShort(index));
container.appendChild(shortElement);
});
resultsContainer.appendChild(container);
// Add event listeners to download buttons
document.querySelectorAll('.download-short').forEach(btn => {
btn.addEventListener('click', (e) => {
e.stopPropagation();
downloadShortAtIndex(parseInt(btn.dataset.index));
});
});
}
// Preview a short in modal
function previewShort(index) {
currentShortIndex = index;
const short = generatedShorts[index];
// Update modal info
document.getElementById('short-number').textContent = short.id;
// Show modal with processing state
previewModal.classList.remove('hidden');
modalProcessing.classList.remove('hidden');
// Simulate loading the short
setTimeout(() => {
modalProcessing.classList.add('hidden');
modalPreview.src = videoPreview.src;
modalPreview.currentTime = short.start;
modalPreview.play();
}, 800);
}
// Download current short
function downloadCurrentShort() {
const short = generatedShorts[currentShortIndex];
alert(`Downloading short #${short.id} (${short.start}s-${short.end}s)`);
// In a real app, this would generate and download the actual short video
}
// Download short at specific index
function downloadShortAtIndex(index) {
const short = generatedShorts[index];
alert(`Downloading short #${short.id} (${short.start}s-${short.end}s)`);
// In a real app, this would generate and download the actual short video
}
// Batch download all shorts
function batchDownloadShorts() {
alert(`Preparing to download ${generatedShorts.length} shorts...`);
// In a real app, this would generate a ZIP file with all shorts
}
// Close modal when clicking outside
previewModal.addEventListener('click', (e) => {
if (e.target === previewModal) {
previewModal.classList.add('hidden');
modalPreview.pause();
}
});
// Initialize progress rings
document.addEventListener('DOMContentLoaded', () => {
const circles = document.querySelectorAll('.progress-ring');
circles.forEach(circle => {
const radius = circle.r.baseVal.value;
const circumference = 2 * Math.PI * radius;
circle.style.strokeDasharray = circumference;
circle.style.strokeDashoffset = circumference;
});
});
</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://deepsite.hf.co/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://deepsite.hf.co" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://deepsite.hf.co?remix=ALAAZIADI/my-space" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>