2nd / Index
Ayeeee45's picture
Create Index
b3b827b verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced Live Portrait WebUI</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--primary: #6366f1;
--primary-dark: #4f46e5;
--secondary: #8b5cf6;
--dark: #1f2937;
--light: #f9fafb;
--gray: #6b7280;
--success: #10b981;
--danger: #ef4444;
--shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
--transition: all 0.3s ease;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: var(--dark);
padding: 20px;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: white;
border-radius: 20px;
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
overflow: hidden;
}
/* Header */
.header {
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
color: white;
padding: 3rem 2rem;
text-align: center;
position: relative;
overflow: hidden;
}
.header::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.1) 1px, transparent 1px);
background-size: 50px 50px;
animation: float 20s linear infinite;
}
@keyframes float {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.logo {
font-size: 4rem;
margin-bottom: 1rem;
display: inline-block;
animation: bounce 2s infinite;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
.title {
font-size: 3rem;
font-weight: 700;
margin-bottom: 0.5rem;
position: relative;
z-index: 1;
}
.subtitle {
font-size: 1.2rem;
opacity: 0.9;
max-width: 800px;
margin: 0 auto;
line-height: 1.6;
position: relative;
z-index: 1;
}
/* Main Content */
.main-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
padding: 3rem;
}
@media (max-width: 992px) {
.main-content {
grid-template-columns: 1fr;
}
}
/* Card Styles */
.card {
background: white;
border-radius: 15px;
padding: 2rem;
box-shadow: var(--shadow);
border: 1px solid #e5e7eb;
transition: var(--transition);
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15);
}
.card h2 {
color: var(--primary);
margin-bottom: 1.5rem;
padding-bottom: 0.5rem;
border-bottom: 3px solid var(--primary);
display: inline-block;
}
/* Upload Area */
.upload-area {
border: 3px dashed var(--primary);
border-radius: 15px;
padding: 3rem 2rem;
text-align: center;
cursor: pointer;
transition: var(--transition);
margin-bottom: 2rem;
background: #f8fafc;
}
.upload-area:hover {
background: #f0f9ff;
border-color: var(--primary-dark);
}
.upload-icon {
font-size: 4rem;
color: var(--primary);
margin-bottom: 1rem;
}
.upload-area h3 {
color: var(--dark);
margin-bottom: 0.5rem;
}
/* Preview */
.preview-container {
position: relative;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
margin-bottom: 1.5rem;
}
.preview-container img {
width: 100%;
height: auto;
display: block;
transition: var(--transition);
}
/* Buttons */
.btn {
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
color: white;
border: none;
padding: 1rem 2.5rem;
font-size: 1.1rem;
font-weight: 600;
border-radius: 50px;
cursor: pointer;
transition: var(--transition);
display: inline-flex;
align-items: center;
justify-content: center;
gap: 10px;
box-shadow: 0 5px 15px rgba(99, 102, 241, 0.3);
margin: 0.5rem;
min-width: 200px;
}
.btn:hover {
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(99, 102, 241, 0.4);
}
.btn:active {
transform: translateY(-1px);
}
.btn-success {
background: linear-gradient(135deg, var(--success) 0%, #059669 100%);
}
.btn-secondary {
background: linear-gradient(135deg, var(--gray) 0%, #4b5563 100%);
}
.btn-danger {
background: linear-gradient(135deg, var(--danger) 0%, #dc2626 100%);
}
.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none !important;
box-shadow: none !important;
}
/* Output Area */
.output-area {
min-height: 300px;
background: #f8fafc;
border-radius: 15px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 2rem;
text-align: center;
transition: var(--transition);
}
.output-area.video-loaded {
background: white;
padding: 0;
overflow: hidden;
}
.output-placeholder {
font-size: 5rem;
color: var(--primary);
margin-bottom: 1rem;
}
/* Examples */
.examples-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
margin: 1.5rem 0;
}
@media (max-width: 768px) {
.examples-grid {
grid-template-columns: repeat(2, 1fr);
}
}
.example-img {
width: 100%;
height: 150px;
object-fit: cover;
border-radius: 10px;
cursor: pointer;
transition: var(--transition);
border: 3px solid transparent;
}
.example-img:hover {
transform: scale(1.05);
border-color: var(--primary);
}
/* Installation */
.code-block {
background: #1e293b;
color: #e2e8f0;
padding: 1.5rem;
border-radius: 10px;
font-family: 'Courier New', monospace;
overflow-x: auto;
margin: 1.5rem 0;
line-height: 1.8;
}
.code-block code {
color: #7dd3fc;
}
.comment {
color: #94a3b8;
}
/* Steps */
.steps {
display: flex;
flex-direction: column;
gap: 1.5rem;
margin: 2rem 0;
}
.step {
display: flex;
align-items: flex-start;
gap: 1rem;
}
.step-number {
background: var(--primary);
color: white;
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
flex-shrink: 0;
}
/* Footer */
.footer {
background: var(--dark);
color: white;
padding: 3rem 2rem;
text-align: center;
margin-top: 2rem;
}
.footer-links {
display: flex;
justify-content: center;
gap: 2rem;
margin: 2rem 0;
flex-wrap: wrap;
}
.footer-link {
color: #d1d5db;
text-decoration: none;
transition: var(--transition);
display: flex;
align-items: center;
gap: 8px;
}
.footer-link:hover {
color: white;
}
/* Loading Animation */
.loader {
border: 6px solid #f3f3f3;
border-top: 6px solid var(--primary);
border-radius: 50%;
width: 60px;
height: 60px;
animation: spin 1s linear infinite;
margin-bottom: 1rem;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Progress Bar */
.progress-container {
width: 100%;
background: #e5e7eb;
border-radius: 10px;
margin: 1.5rem 0;
overflow: hidden;
}
.progress-bar {
height: 10px;
background: linear-gradient(90deg, var(--primary) 0%, var(--secondary) 100%);
width: 0%;
border-radius: 10px;
transition: width 0.5s ease;
}
/* Stats */
.stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
margin: 2rem 0;
}
.stat {
text-align: center;
padding: 1rem;
background: #f8fafc;
border-radius: 10px;
}
.stat-number {
font-size: 2rem;
font-weight: bold;
color: var(--primary);
margin-bottom: 0.5rem;
}
/* Responsive */
@media (max-width: 768px) {
.title {
font-size: 2rem;
}
.subtitle {
font-size: 1rem;
}
.main-content {
padding: 1.5rem;
}
.card {
padding: 1.5rem;
}
}
</style>
</head>
<body>
<div class="container">
<!-- Header -->
<header class="header">
<div class="logo">🎬</div>
<h1 class="title">Advanced Live Portrait WebUI</h1>
<p class="subtitle">Transform static portraits into animated videos with AI-powered face animation technology</p>
<div class="stats">
<div class="stat">
<div class="stat-number">1,000+</div>
<div>Animations Created</div>
</div>
<div class="stat">
<div class="stat-number">99%</div>
<div>Accuracy Rate</div>
</div>
<div class="stat">
<div class="stat-number">24/7</div>
<div>Available</div>
</div>
</div>
</header>
<!-- Main Content -->
<div class="main-content">
<!-- Left Column - Upload & Controls -->
<div class="left-column">
<div class="card">
<h2><i class="fas fa-upload"></i> Upload Image</h2>
<div class="upload-area" id="uploadArea">
<div class="upload-icon">
<i class="fas fa-cloud-upload-alt"></i>
</div>
<h3>Click to Upload Face Image</h3>
<p>or drag and drop</p>
<p class="comment">JPG, PNG up to 5MB • Clear frontal face works best</p>
</div>
<input type="file" id="fileInput" accept="image/*" style="display: none;">
<div id="imagePreview" style="display: none;">
<div class="preview-container">
<img id="previewImage" src="" alt="Preview">
</div>
<div style="text-align: center;">
<button class="btn btn-danger" onclick="clearImage()">
<i class="fas fa-trash"></i> Remove Image
</button>
</div>
</div>
<div class="steps">
<div class="step">
<div class="step-number">1</div>
<div>
<h4>Upload Image</h4>
<p class="comment">Select a clear frontal face photo</p>
</div>
</div>
<div class="step">
<div class="step-number">2</div>
<div>
<h4>Generate Animation</h4>
<p class="comment">Click generate to create animation</p>
</div>
</div>
<div class="step">
<div class="step-number">3</div>
<div>
<h4>Download Result</h4>
<p class="comment">Save your animated portrait</p>
</div>
</div>
</div>
<div style="text-align: center; margin-top: 2rem;">
<button class="btn" id="generateBtn" onclick="generateAnimation()" disabled>
<i class="fas fa-bolt"></i> Generate Animation
</button>
</div>
</div>
<!-- Examples -->
<div class="card">
<h2><i class="fas fa-images"></i> Try Examples</h2>
<p class="comment">Click on any example image to try it instantly</p>
<div class="examples-grid">
<img src="https://images.unsplash.com/photo-1494790108755-2616b786d4b9?w=400&h=400&fit=crop&crop=face"
class="example-img"
onclick="useExample(this.src)"
alt="Example 1">
<img src="https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=400&h=400&fit=crop&crop=face"
class="example-img"
onclick="useExample(this.src)"
alt="Example 2">
<img src="https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=400&fit=crop&crop=face"
class="example-img"
onclick="useExample(this.src)"
alt="Example 3">
</div>
</div>
</div>
<!-- Right Column - Output & Info -->
<div class="right-column">
<!-- Output Area -->
<div class="card">
<h2><i class="fas fa-video"></i> Generated Animation</h2>
<div class="output-area" id="outputArea">
<div class="output-placeholder">
<i class="fas fa-film"></i>
</div>
<h3>Your animation will appear here</h3>
<p class="comment">Upload an image and click generate to start</p>
</div>
<div class="progress-container" id="progressContainer" style="display: none;">
<div class="progress-bar" id="progressBar"></div>
</div>
<div style="text-align: center; margin-top: 1.5rem;">
<button class="btn btn-success" id="downloadBtn" onclick="downloadResult()" disabled>
<i class="fas fa-download"></i> Download Video
</button>
<button class="btn btn-secondary" onclick="shareResult()">
<i class="fas fa-share"></i> Share
</button>
</div>
</div>
<!-- Installation Instructions -->
<div class="card">
<h2><i class="fas fa-download"></i> Full Installation</h2>
<p class="comment">This demo shows the interface. For full functionality with audio-driven animation:</p>
<div class="code-block">
<code>
<span class="comment"># 1. Clone the repository</span><br>
git clone https://github.com/Ayeeee45/AdvancedLivePortrait-WebUI.git<br>
cd AdvancedLivePortrait-WebUI<br><br>
<span class="comment"># 2. Install dependencies</span><br>
pip install -r requirements.txt<br><br>
<span class="comment"># 3. Download required models</span><br>
<span class="comment"># Check README.md for model download links</span><br><br>
<span class="comment"># 4. Run the application</span><br>
python webui.py<br><br>
<span class="comment"># 5. Open in browser</span><br>
<span class="comment"># Visit http://localhost:7860</span>
</code>
</div>
<div class="steps">
<div class="step">
<div class="step-number"><i class="fas fa-server"></i></div>
<div>
<h4>System Requirements</h4>
<p class="comment">• 8GB+ GPU VRAM (NVIDIA recommended)<br>• 20GB+ free disk space<br>• Python 3.10</p>
</div>
</div>
<div class="step">
<div class="step-number"><i class="fas fa-microphone"></i></div>
<div>
<h4>Audio Support</h4>
<p class="comment">Full version supports audio-driven lip sync animation</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Footer -->
<footer class="footer">
<h3>Advanced Live Portrait WebUI</h3>
<p>AI-powered portrait animation tool</p>
<div class="footer-links">
<a href="https://github.com/Ayeeee45/AdvancedLivePortrait-WebUI" target="_blank" class="footer-link">
<i class="fab fa-github"></i> GitHub Repository
</a>
<a href="https://github.com/Ayeeee45/AdvancedLivePortrait-WebUI/issues" target="_blank" class="footer-link">
<i class="fas fa-bug"></i> Report Issues
</a>
<a href="https://github.com/Ayeeee45/AdvancedLivePortrait-WebUI/wiki" target="_blank" class="footer-link">
<i class="fas fa-book"></i> Documentation
</a>
</div>
<p style="color: #9ca3af; margin-top: 2rem; font-size: 0.9rem;">
© 2024 Advanced Live Portrait WebUI Demo. This is a preview interface.<br>
For complete functionality with audio support and real AI animation, install locally.
</p>
</footer>
</div>
<script>
// Global variables
let currentImage = null;
let animationProgress = 0;
let progressInterval = null;
// DOM Elements
const uploadArea = document.getElementById('uploadArea');
const fileInput = document.getElementById('fileInput');
const imagePreview = document.getElementById('imagePreview');
const previewImage = document.getElementById('previewImage');
const generateBtn = document.getElementById('generateBtn');
const outputArea = document.getElementById('outputArea');
const downloadBtn = document.getElementById('downloadBtn');
const progressContainer = document.getElementById('progressContainer');
const progressBar = document.getElementById('progressBar');
// Event Listeners
uploadArea.addEventListener('click', () => fileInput.click());
uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
uploadArea.style.background = '#e0f2fe';
});
uploadArea.addEventListener('dragleave', () => {
uploadArea.style.background = '#f8fafc';
});
uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
uploadArea.style.background = '#f8fafc';
if (e.dataTransfer.files.length) {
handleFile(e.dataTransfer.files[0]);
}
});
fileInput.addEventListener('change', (e) => {
if (e.target.files.length) {
handleFile(e.target.files[0]);
}
});
// Handle file upload
function handleFile(file) {
if (!file.type.match('image.*')) {
alert('Please upload an image file (JPG, PNG)');
return;
}
if (file.size > 5 * 1024 * 1024) {
alert('File size must be less than 5MB');
return;
}
const reader = new FileReader();
reader.onload = function(e) {
currentImage = e.target.result;
previewImage.src = currentImage;
imagePreview.style.display = 'block';
generateBtn.disabled = false;
// Update upload area
uploadArea.innerHTML = `
<div class="upload-icon" style="color: #10b981;">
<i class="fas fa-check-circle"></i>
</div>
<h3>Image Uploaded Successfully!</h3>
<p>Ready to generate animation</p>
`;
};
reader.readAsDataURL(file);
}
// Use example image
function useExample(src) {
currentImage = src;
previewImage.src = src;
imagePreview.style.display = 'block';
generateBtn.disabled = false;
uploadArea.innerHTML = `
<div class="upload-icon" style="color: #10b981;">
<i class="fas fa-check-circle"></i>
</div>
<h3>Example Image Loaded!</h3>
<p>Ready to generate animation</p>
`;
}
// Clear image
function clearImage() {
currentImage = null;
imagePreview.style.display = 'none';
generateBtn.disabled = true;
fileInput.value = '';
uploadArea.innerHTML = `
<div class="upload-icon">
<i class="fas fa-cloud-upload-alt"></i>
</div>
<h3>Click to Upload Face Image</h3>
<p>or drag and drop</p>
<p class="comment">JPG, PNG up to 5MB • Clear frontal face works best</p>
`;
}
// Generate animation
function generateAnimation() {
if (!currentImage) return;
// Reset
outputArea.className = 'output-area';
downloadBtn.disabled = true;
progressContainer.style.display = 'block';
progressBar.style.width = '0%';
animationProgress = 0;
// Show loading
outputArea.innerHTML = `
<div class="loader"></div>
<h3>Creating Animation...</h3>
<p class="comment">Processing image and generating animation frames</p>
<div style="margin-top: 1rem; color: #6b7280; font-size: 0.9rem;">
<i class="fas fa-info-circle"></i> This is a demo. For actual animation, install locally.
</div>
`;
// Simulate progress
progressInterval = setInterval(() => {
animationProgress += Math.random() * 15;
if (animationProgress > 100) animationProgress = 100;
progressBar.style.width = animationProgress + '%';
if (animationProgress >= 100) {
clearInterval(progressInterval);
showResult();
}
}, 200);
}
// Show result
function showResult() {
progressContainer.style.display = 'none';
outputArea.className = 'output-area video-loaded';
// Create a demo video element
outputArea.innerHTML = `
<video width="100%" height="100%" controls autoplay style="border-radius: 10px;">
<source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
<div style="position: absolute; bottom: 20px; right: 20px; background: rgba(0,0,0,0.7); color: white; padding: 10px 20px; border-radius: 20px; font-size: 0.9rem;">
<i class="fas fa-info-circle"></i> Demo Video
</div>
`;
downloadBtn.disabled = false;
// Show success message
setTimeout(() => {
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
color: white;
padding: 15px 25px;
border-radius: 10px;
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
z-index: 1000;
animation: slideIn 0.5s ease;
`;
notification.innerHTML = `
<i class="fas fa-check-circle"></i>
<strong>Animation Complete!</strong>
<p style="margin: 5px 0 0 0; font-size: 0.9rem;">Ready to download</p>
`;
document.body.appendChild(notification);
setTimeout(() => {
notification.style.animation = 'slideOut 0.5s ease';
setTimeout(() => notification.remove(), 500);
}, 3000);
// Add animation keyframes
const style = document.createElement('style');
style.textContent = `
@keyframes slideIn {
from { transform: translateX(100%); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slideOut {
from { transform: translateX(0); opacity: 1; }
to { transform: translateX(100%); opacity: 0; }
}
`;
document.head.appendChild(style);
}, 500);
}
// Download result
function downloadResult() {
// Create a demo download experience
const downloadLink = document.createElement('a');
downloadLink.href = '#';
downloadLink.download = 'animated_portrait.mp4';
// Show modal with instructions
const modal = document.createElement('div');
modal.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.8);
display: flex;
align-items: center;
justify-content: center;
z-index: 2000;
`;
modal.innerHTML = `
<div style="background: white; padding: 2rem; border-radius: 15px; max-width: 500px; width: 90%; text-align: center;">
<div style="font-size: 3rem; color: #6366f1; margin-bottom: 1rem;">
<i class="fas fa-download"></i>
</div>
<h3 style="color: #1f2937; margin-bottom: 1rem;">Download Full Version</h3>
<p style="color: #6b7280; margin-bottom: 1.5rem; line-height: 1.6;">
This is a demo interface. To download actual animated portraits with audio support,
you need to install the full application locally.
</p>
<div style="background: #f8fafc; padding: 1.5rem; border-radius: 10px; text-align: left; margin-bottom: 1.5rem;">
<code style="color: #1f2937; font-family: monospace; font-size: 0.9rem;">
# Install locally for full features:<br>
git clone https://github.com/Ayeeee45/AdvancedLivePortrait-WebUI.git<br>
cd AdvancedLivePortrait-WebUI<br>
pip install -r requirements.txt<br>
python webui.py
</code>
</div>
<button onclick="this.parentElement.parentElement.remove()"
style="background: #6366f1; color: white; border: none; padding: 10px 30px; border-radius: 25px; cursor: pointer; font-weight: bold;">
Got it!
</button>
</div>
`;
document.body.appendChild(modal);
modal.addEventListener('click', (e) => {
if (e.target === modal) {
modal.remove();
}
});
}
// Share result
function shareResult() {
if (navigator.share) {
navigator.share({
title: 'Advanced Live Portrait',
text: 'Check out this AI portrait animation tool!',
url: window.location.href
});
} else {
// Fallback: Copy to clipboard
navigator.clipboard.writeText(window.location.href).then(() => {
alert('Link copied to clipboard!');
});
}
}
// Initialize
document.addEventListener('DOMContentLoaded', () => {
console.log('Advanced Live Portrait Demo Loaded');
// Add some interactive effects
const cards = document.querySelectorAll('.card');
cards.forEach(card => {
card.addEventListener('mouseenter', () => {
card.style.transform = 'translateY(-5px)';
});
card.addEventListener('mouseleave', () => {
card.style.transform = 'translateY(0)';
});
});
});
</script>
</body>
</html>