250 lines
11 KiB
HTML
250 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Video Optimizer - Social Media Platform Tool</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="style.css">
|
|
<!-- MSAL Browser Library for Microsoft SSO -->
|
|
<script src="https://cdn.jsdelivr.net/npm/@azure/msal-browser@3.5.0/lib/msal-browser.min.js"></script>
|
|
</head>
|
|
<body>
|
|
<!-- Login Page (shown when not authenticated) -->
|
|
<div id="loginPage" class="login-page" style="display: none;">
|
|
<div class="login-container">
|
|
<div class="login-card">
|
|
<h1>Video Optimizer</h1>
|
|
<p class="subtitle">Social Media Platform Optimization Tool</p>
|
|
<p class="login-message">Please sign in with your Microsoft account to continue</p>
|
|
<button class="btn-login" id="loginBtn">
|
|
<span>Sign in with Microsoft</span>
|
|
</button>
|
|
<div id="loginError" class="error-message" style="display: none;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Main Application (shown when authenticated) -->
|
|
<div class="container" id="mainApp" style="display: none;">
|
|
<!-- Auth Header -->
|
|
<div class="auth-header">
|
|
<div class="auth-user-info">
|
|
<span class="user-email" id="userEmail"></span>
|
|
</div>
|
|
<div class="auth-actions">
|
|
<a href="help.html" class="btn-help" title="Help & Documentation">Help</a>
|
|
<a href="admin.html" class="btn-admin" title="Admin Panel">Admin</a>
|
|
<button class="btn-logout" id="logoutBtn">Logout</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Header -->
|
|
<header class="header">
|
|
<h1>Video Optimizer</h1>
|
|
<p class="subtitle">Social Media Platform Optimization Tool</p>
|
|
</header>
|
|
|
|
<!-- Upload Section -->
|
|
<section class="upload-section" id="uploadSection">
|
|
<div class="upload-area" id="dropZone">
|
|
<div class="upload-icon">📁</div>
|
|
<h2>Drag & Drop Video File</h2>
|
|
<p>or click to browse</p>
|
|
<input type="file" id="fileInput" accept="video/*" hidden>
|
|
<p class="file-hint">Supported formats: MP4, MOV, AVI, MKV, WEBM</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Configuration Section -->
|
|
<section class="config-section" id="configSection" style="display: none;">
|
|
<h2>Video Configuration</h2>
|
|
|
|
<div class="video-info" id="videoInfo">
|
|
<!-- Video info will be populated here -->
|
|
</div>
|
|
|
|
<div class="config-grid">
|
|
<div class="config-item">
|
|
<label for="platformSelect">Platform</label>
|
|
<select id="platformSelect" class="select-input">
|
|
<option value="">Select Platform...</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="config-item">
|
|
<label for="aspectRatioSelect">Aspect Ratio</label>
|
|
<select id="aspectRatioSelect" class="select-input">
|
|
<option value="">Select Aspect Ratio...</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="config-item">
|
|
<label for="bitrateInput">Video Bitrate (optional)</label>
|
|
<input type="text" id="bitrateInput" class="text-input" placeholder="e.g., 1500k (leave blank for recommended)">
|
|
<small class="hint" id="bitrateHint"></small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="format-info" id="formatInfo">
|
|
<!-- Format specifications will be shown here -->
|
|
</div>
|
|
|
|
<div class="warning-message" id="aspectRatioWarning" style="display: none;">
|
|
<strong>⚠️ Warning:</strong> The selected aspect ratio differs from your original video. This may cause distortion, stretching, or cropping of the video content.
|
|
</div>
|
|
|
|
<button class="btn-primary" id="convertBtn" disabled>
|
|
<span id="convertBtnText">Convert Video</span>
|
|
</button>
|
|
|
|
<div class="progress-bar" id="progressBar" style="display: none;">
|
|
<div class="progress-fill" id="progressFill"></div>
|
|
<span class="progress-text" id="progressText">Converting...</span>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Comparison Section -->
|
|
<section class="comparison-section" id="comparisonSection" style="display: none;">
|
|
<h2>Video Comparison</h2>
|
|
|
|
<div class="stats-bar">
|
|
<div class="stat-item">
|
|
<span class="stat-label">Original Size:</span>
|
|
<span class="stat-value" id="originalSize">-</span>
|
|
</div>
|
|
<div class="stat-item">
|
|
<span class="stat-label">Optimized Size:</span>
|
|
<span class="stat-value" id="optimizedSize">-</span>
|
|
</div>
|
|
<div class="stat-item reduction">
|
|
<span class="stat-label">Reduction:</span>
|
|
<span class="stat-value" id="reduction">-</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="warning-message warning-red" id="aspectRatioChangedWarning" style="display: none;">
|
|
<strong>⚠️ Aspect Ratio Changed:</strong> This video was converted to a different aspect ratio than the original. The video may appear distorted, stretched, or cropped.
|
|
</div>
|
|
|
|
<div class="video-grid">
|
|
<div class="video-player-container">
|
|
<h3>Original</h3>
|
|
<video id="originalVideo" controls class="video-player">
|
|
<source id="originalSource" type="video/mp4">
|
|
Your browser does not support the video tag.
|
|
</video>
|
|
<div class="video-specs" id="originalSpecs">
|
|
<!-- Video specs will be populated here -->
|
|
</div>
|
|
<div class="video-controls">
|
|
<button class="btn-mute" id="muteOriginal">🔊 Mute</button>
|
|
<button class="btn-secondary" id="downloadOriginal">Download Original</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="video-player-container">
|
|
<h3>Optimized</h3>
|
|
<video id="optimizedVideo" controls class="video-player">
|
|
<source id="optimizedSource" type="video/mp4">
|
|
Your browser does not support the video tag.
|
|
</video>
|
|
<div class="video-specs" id="optimizedSpecs">
|
|
<!-- Video specs will be populated here -->
|
|
</div>
|
|
<div class="video-controls">
|
|
<button class="btn-mute" id="muteOptimized">🔊 Mute</button>
|
|
<button class="btn-secondary" id="downloadOptimized">Download Optimized</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="playback-controls">
|
|
<button class="btn-secondary" id="syncPlayBtn">⏯️ Sync Playback</button>
|
|
<button class="btn-secondary" id="pauseAllBtn">⏸️ Pause Both</button>
|
|
</div>
|
|
|
|
<button class="btn-primary" id="newFileBtn">Upload New File</button>
|
|
</section>
|
|
|
|
<!-- Footer -->
|
|
<footer class="footer">
|
|
<p>Video Optimization Tool for Social Media Platforms</p>
|
|
<p><a href="admin.html" style="color: #FFC407; text-decoration: none;">Admin Panel →</a></p>
|
|
</footer>
|
|
</div>
|
|
|
|
<script src="config.js"></script>
|
|
<script src="auth.js"></script>
|
|
<script src="toast.js"></script>
|
|
<script src="utils.js"></script>
|
|
<script src="app.js"></script>
|
|
<script src="app-enhancements.js"></script>
|
|
<script>
|
|
// Initialize authentication and check login status
|
|
async function initializeApp() {
|
|
try {
|
|
// Fetch Azure AD configuration from backend
|
|
const response = await fetch(`${CONFIG.API_BASE}/config`);
|
|
const config = await response.json();
|
|
|
|
// Initialize MSAL
|
|
await window.initAuth(config);
|
|
|
|
// Check authentication status
|
|
if (window.isAuthenticated()) {
|
|
// User is authenticated - show main app
|
|
const userEmail = window.getUserEmail();
|
|
document.getElementById('userEmail').textContent = userEmail || 'User';
|
|
document.getElementById('mainApp').style.display = 'block';
|
|
document.getElementById('loginPage').style.display = 'none';
|
|
} else {
|
|
// User not authenticated - show login page
|
|
document.getElementById('loginPage').style.display = 'flex';
|
|
document.getElementById('mainApp').style.display = 'none';
|
|
}
|
|
} catch (error) {
|
|
console.error('Initialization error:', error);
|
|
|
|
// Show error on login page
|
|
const loginError = document.getElementById('loginError');
|
|
if (loginError) {
|
|
loginError.textContent = error.message || 'Failed to initialize authentication. Please try again.';
|
|
loginError.style.display = 'block';
|
|
}
|
|
|
|
// Show login page even on error
|
|
document.getElementById('loginPage').style.display = 'flex';
|
|
document.getElementById('mainApp').style.display = 'none';
|
|
}
|
|
}
|
|
|
|
// Login button handler
|
|
document.getElementById('loginBtn').addEventListener('click', async () => {
|
|
try {
|
|
document.getElementById('loginError').style.display = 'none';
|
|
await window.login();
|
|
} catch (error) {
|
|
console.error('Login error:', error);
|
|
const loginError = document.getElementById('loginError');
|
|
loginError.textContent = error.message || 'Login failed. Please try again.';
|
|
loginError.style.display = 'block';
|
|
}
|
|
});
|
|
|
|
// Logout button handler
|
|
document.getElementById('logoutBtn').addEventListener('click', async () => {
|
|
try {
|
|
await window.logout();
|
|
} catch (error) {
|
|
console.error('Logout error:', error);
|
|
}
|
|
});
|
|
|
|
// Initialize app on page load
|
|
document.addEventListener('DOMContentLoaded', initializeApp);
|
|
</script>
|
|
</body>
|
|
</html>
|