- Add API token authentication middleware (X-API-Key header) - Add CORS configuration with ALLOWED_ORIGINS - Add security HTTP headers (X-Frame-Options, CSP, etc.) - Add web interface for API token configuration with localStorage - Add toggle visibility for token input - Add connection status indicator - Add auto-save token functionality - Update API documentation with authentication examples - Add deployment guides (OVH specific and general) - Add local testing guide 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
633 lines
29 KiB
HTML
633 lines
29 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Video to MP3 Transcriptor</title>
|
|
<link rel="stylesheet" href="style.css">
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<header>
|
|
<h1>Video to MP3 Transcriptor</h1>
|
|
<p class="subtitle">Download YouTube videos, transcribe and translate them</p>
|
|
</header>
|
|
|
|
<!-- API Configuration Panel -->
|
|
<div class="api-config-panel" id="api-config-panel">
|
|
<div class="config-header">
|
|
<div class="config-title">
|
|
<span class="config-icon">🔐</span>
|
|
<h3>API Configuration</h3>
|
|
</div>
|
|
<button type="button" id="toggle-config" class="btn-toggle" aria-label="Toggle configuration">
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<polyline points="6 9 12 15 18 9"></polyline>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
<div class="config-content" id="config-content" style="display: none;">
|
|
<div class="config-status" id="config-status">
|
|
<span class="status-indicator status-disconnected"></span>
|
|
<span class="status-text">Not configured</span>
|
|
</div>
|
|
<form id="api-config-form">
|
|
<div class="form-group">
|
|
<label for="api-token">API Token</label>
|
|
<div class="input-group">
|
|
<input
|
|
type="password"
|
|
id="api-token"
|
|
placeholder="Enter your API token..."
|
|
autocomplete="off"
|
|
>
|
|
<button type="button" id="toggle-token-visibility" class="btn-icon" aria-label="Toggle visibility">
|
|
<svg id="eye-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
|
<circle cx="12" cy="12" r="3"></circle>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="config-actions">
|
|
<button type="submit" class="btn btn-primary btn-small">
|
|
<span>Save & Test</span>
|
|
</button>
|
|
<button type="button" id="clear-token" class="btn btn-secondary btn-small">
|
|
<span>Clear</span>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
<div class="config-help">
|
|
<p><strong>Where to get your token?</strong></p>
|
|
<p>Your API token is configured in the server's <code>.env</code> file (<code>API_TOKEN</code>). Contact your administrator if you don't have it.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Global API error display -->
|
|
<div id="api-error" class="result"></div>
|
|
|
|
<!-- Tabs -->
|
|
<nav class="tabs">
|
|
<button class="tab active" data-tab="download">Download</button>
|
|
<button class="tab" data-tab="convert">Video to MP3</button>
|
|
<button class="tab" data-tab="transcribe">Transcribe</button>
|
|
<button class="tab" data-tab="process">Download + Transcribe</button>
|
|
<button class="tab" data-tab="translate">Translate</button>
|
|
<button class="tab" data-tab="summarize">Summarize</button>
|
|
</nav>
|
|
|
|
<!-- Download Tab -->
|
|
<section id="download" class="tab-content active">
|
|
<h2>Download YouTube Video/Playlist</h2>
|
|
<form id="download-form">
|
|
<div class="form-group">
|
|
<label for="download-url">YouTube URL</label>
|
|
<input type="url" id="download-url" placeholder="https://youtube.com/watch?v=..." required>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary">
|
|
<span class="btn-text">Download MP3</span>
|
|
<span class="btn-loading">Downloading...</span>
|
|
</button>
|
|
</form>
|
|
<div id="download-progress" class="progress-container" style="display: none;">
|
|
<div class="progress-header">
|
|
<span id="progress-title">Downloading...</span>
|
|
<span id="progress-eta"></span>
|
|
</div>
|
|
<div class="progress-bar">
|
|
<div id="progress-fill" class="progress-fill"></div>
|
|
</div>
|
|
<div class="progress-details">
|
|
<span id="progress-percent">0%</span>
|
|
<span id="progress-info"></span>
|
|
<span id="progress-speed"></span>
|
|
</div>
|
|
<div id="progress-current" class="progress-current"></div>
|
|
</div>
|
|
<div id="download-result" class="result"></div>
|
|
</section>
|
|
|
|
<!-- Convert Tab -->
|
|
<section id="convert" class="tab-content">
|
|
<h2>Convert Video/Audio to MP3</h2>
|
|
<div id="convert-drop-zone" class="drop-zone">
|
|
<div class="drop-zone-content">
|
|
<div class="drop-zone-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
|
<polyline points="17 8 12 3 7 8"/>
|
|
<line x1="12" y1="3" x2="12" y2="15"/>
|
|
</svg>
|
|
</div>
|
|
<p class="drop-zone-text">Drag & drop video/audio files here</p>
|
|
<p class="drop-zone-hint">or click to select files</p>
|
|
<p class="drop-zone-formats">Supported: MP4, M4A, AVI, MKV, MOV, WAV, FLAC, OGG</p>
|
|
<input type="file" id="convert-file-input" multiple accept="video/*,audio/*,.mp4,.avi,.mkv,.mov,.m4a,.wav,.flac,.ogg" style="display: none;">
|
|
</div>
|
|
</div>
|
|
<div id="convert-selected-files" class="selected-files" style="display: none;">
|
|
<h3>Selected Files</h3>
|
|
<ul id="convert-files-list"></ul>
|
|
<button type="button" id="convert-clear-files" class="btn btn-small btn-secondary">Clear</button>
|
|
</div>
|
|
<form id="convert-form">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="convert-bitrate">Audio Bitrate</label>
|
|
<select id="convert-bitrate">
|
|
<option value="128k">128 kbps</option>
|
|
<option value="192k" selected>192 kbps (Recommended)</option>
|
|
<option value="256k">256 kbps</option>
|
|
<option value="320k">320 kbps (High Quality)</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="convert-quality">VBR Quality</label>
|
|
<select id="convert-quality">
|
|
<option value="0">0 - Best Quality</option>
|
|
<option value="2" selected>2 - High Quality</option>
|
|
<option value="4">4 - Standard</option>
|
|
<option value="6">6 - Good</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary" id="convert-btn" disabled>
|
|
<span class="btn-text">Convert to MP3</span>
|
|
<span class="btn-loading">Converting...</span>
|
|
</button>
|
|
</form>
|
|
<div id="convert-progress" class="progress-container" style="display: none;">
|
|
<div class="progress-header">
|
|
<span id="convert-progress-title">Converting...</span>
|
|
<span id="convert-progress-info"></span>
|
|
</div>
|
|
<div class="progress-bar">
|
|
<div id="convert-progress-fill" class="progress-fill"></div>
|
|
</div>
|
|
<div class="progress-details">
|
|
<span id="convert-progress-percent">0%</span>
|
|
<span id="convert-progress-current"></span>
|
|
</div>
|
|
</div>
|
|
<div id="convert-result" class="result"></div>
|
|
</section>
|
|
|
|
<!-- Transcribe Tab -->
|
|
<section id="transcribe" class="tab-content">
|
|
<h2>Transcribe Audio File</h2>
|
|
<div id="drop-zone" class="drop-zone">
|
|
<div class="drop-zone-content">
|
|
<div class="drop-zone-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
|
<polyline points="17 8 12 3 7 8"/>
|
|
<line x1="12" y1="3" x2="12" y2="15"/>
|
|
</svg>
|
|
</div>
|
|
<p class="drop-zone-text">Drag & drop audio files here</p>
|
|
<p class="drop-zone-hint">or click to select files</p>
|
|
<input type="file" id="file-input" multiple accept="audio/*,.mp3,.wav,.m4a,.ogg,.flac" style="display: none;">
|
|
</div>
|
|
</div>
|
|
<div id="selected-files" class="selected-files" style="display: none;">
|
|
<h3>Selected Files</h3>
|
|
<ul id="files-list"></ul>
|
|
<button type="button" id="clear-files" class="btn btn-small btn-secondary">Clear</button>
|
|
</div>
|
|
<form id="transcribe-form">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="transcribe-lang">Language</label>
|
|
<select id="transcribe-lang">
|
|
<option value="">Auto-detect</option>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="transcribe-model">Model</label>
|
|
<select id="transcribe-model">
|
|
<option value="gpt-4o-transcribe">gpt-4o-transcribe (Best)</option>
|
|
<option value="gpt-4o-mini-transcribe">gpt-4o-mini-transcribe (Faster)</option>
|
|
<option value="whisper-1">whisper-1 (Legacy)</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<!-- Translate option -->
|
|
<div class="form-group checkbox-group">
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" id="transcribe-translate">
|
|
<span>Translate after transcription (GPT-4o-mini)</span>
|
|
</label>
|
|
<select id="transcribe-translate-lang" class="translate-lang-select" disabled>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary" id="transcribe-btn" disabled>
|
|
<span class="btn-text">Transcribe</span>
|
|
<span class="btn-loading">Transcribing...</span>
|
|
</button>
|
|
</form>
|
|
<div id="transcribe-progress" class="progress-container" style="display: none;">
|
|
<div class="progress-header">
|
|
<span id="transcribe-progress-title">Transcribing...</span>
|
|
<span id="transcribe-progress-info"></span>
|
|
</div>
|
|
<div class="progress-bar">
|
|
<div id="transcribe-progress-fill" class="progress-fill"></div>
|
|
</div>
|
|
<div class="progress-details">
|
|
<span id="transcribe-progress-percent">0%</span>
|
|
<span id="transcribe-progress-current"></span>
|
|
</div>
|
|
</div>
|
|
<div id="transcribe-result" class="result"></div>
|
|
</section>
|
|
|
|
<!-- Process Tab -->
|
|
<section id="process" class="tab-content">
|
|
<h2>Download + Transcribe</h2>
|
|
<form id="process-form">
|
|
<div class="form-group">
|
|
<label for="process-url">YouTube URL</label>
|
|
<input type="url" id="process-url" placeholder="https://youtube.com/watch?v=..." required>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="process-lang">Language</label>
|
|
<select id="process-lang">
|
|
<option value="">Auto-detect</option>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="process-model">Model</label>
|
|
<select id="process-model">
|
|
<option value="gpt-4o-transcribe">gpt-4o-transcribe (Best)</option>
|
|
<option value="gpt-4o-mini-transcribe">gpt-4o-mini-transcribe (Faster)</option>
|
|
<option value="whisper-1">whisper-1 (Legacy)</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<!-- Translate option -->
|
|
<div class="form-group checkbox-group">
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" id="process-translate">
|
|
<span>Translate after transcription (GPT-4o-mini)</span>
|
|
</label>
|
|
<select id="process-translate-lang" class="translate-lang-select" disabled>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary">
|
|
<span class="btn-text">Download + Transcribe</span>
|
|
<span class="btn-loading">Processing...</span>
|
|
</button>
|
|
</form>
|
|
<div id="process-progress" class="progress-container" style="display: none;">
|
|
<div class="progress-header">
|
|
<span id="process-progress-title">Processing...</span>
|
|
<span id="process-progress-eta"></span>
|
|
</div>
|
|
<div class="progress-bar">
|
|
<div id="process-progress-fill" class="progress-fill"></div>
|
|
</div>
|
|
<div class="progress-details">
|
|
<span id="process-progress-percent">0%</span>
|
|
<span id="process-progress-phase"></span>
|
|
<span id="process-progress-speed"></span>
|
|
</div>
|
|
<div id="process-progress-current" class="progress-current"></div>
|
|
</div>
|
|
<div id="process-result" class="result"></div>
|
|
</section>
|
|
|
|
<!-- Translate Tab -->
|
|
<section id="translate" class="tab-content">
|
|
<h2>Translate Text</h2>
|
|
|
|
<!-- Mode selector -->
|
|
<div class="translate-mode-selector">
|
|
<button type="button" class="mode-btn active" data-mode="text">Text</button>
|
|
<button type="button" class="mode-btn" data-mode="file">Files</button>
|
|
</div>
|
|
|
|
<!-- Text mode -->
|
|
<div id="translate-text-mode" class="translate-mode">
|
|
<form id="translate-text-form">
|
|
<div class="form-group">
|
|
<label for="translate-input">Text to translate</label>
|
|
<textarea id="translate-input" rows="8" placeholder="Enter text to translate..."></textarea>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="translate-source">Source language</label>
|
|
<select id="translate-source">
|
|
<option value="">Auto-detect</option>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="translate-target">Target language</label>
|
|
<select id="translate-target" required>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary" id="translate-text-btn">
|
|
<span class="btn-text">Translate</span>
|
|
<span class="btn-loading">Translating...</span>
|
|
</button>
|
|
</form>
|
|
<div id="translate-text-result" class="result"></div>
|
|
</div>
|
|
|
|
<!-- File mode -->
|
|
<div id="translate-file-mode" class="translate-mode" style="display: none;">
|
|
<div id="translate-drop-zone" class="drop-zone">
|
|
<div class="drop-zone-content">
|
|
<div class="drop-zone-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
|
<polyline points="17 8 12 3 7 8"/>
|
|
<line x1="12" y1="3" x2="12" y2="15"/>
|
|
</svg>
|
|
</div>
|
|
<p class="drop-zone-text">Drag & drop text files here</p>
|
|
<p class="drop-zone-hint">or click to select files (.txt)</p>
|
|
<input type="file" id="translate-file-input" multiple accept=".txt,text/plain" style="display: none;">
|
|
</div>
|
|
</div>
|
|
<div id="translate-selected-files" class="selected-files" style="display: none;">
|
|
<h3>Selected Files</h3>
|
|
<ul id="translate-files-list"></ul>
|
|
<button type="button" id="translate-clear-files" class="btn btn-small btn-secondary">Clear</button>
|
|
</div>
|
|
<form id="translate-file-form">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="translate-file-source">Source language</label>
|
|
<select id="translate-file-source">
|
|
<option value="">Auto-detect</option>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="translate-file-target">Target language</label>
|
|
<select id="translate-file-target" required>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary" id="translate-file-btn" disabled>
|
|
<span class="btn-text">Translate Files</span>
|
|
<span class="btn-loading">Translating...</span>
|
|
</button>
|
|
</form>
|
|
<div id="translate-file-result" class="result"></div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Summarize Tab -->
|
|
<section id="summarize" class="tab-content">
|
|
<h2>Summarize Text (GPT-5.1)</h2>
|
|
|
|
<!-- Mode selector -->
|
|
<div class="summarize-mode-selector">
|
|
<button type="button" class="mode-btn active" data-mode="text">Text</button>
|
|
<button type="button" class="mode-btn" data-mode="file">Files</button>
|
|
<button type="button" class="mode-btn" data-mode="link">YouTube Link</button>
|
|
</div>
|
|
|
|
<!-- Text mode -->
|
|
<div id="summarize-text-mode" class="summarize-mode">
|
|
<form id="summarize-text-form">
|
|
<div class="form-group">
|
|
<label for="summarize-input">Text to summarize</label>
|
|
<textarea id="summarize-input" rows="8" placeholder="Enter text to summarize..."></textarea>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="summarize-style">Style</label>
|
|
<select id="summarize-style">
|
|
<option value="concise">Concise</option>
|
|
<option value="detailed">Detailed</option>
|
|
<option value="bullet">Bullet Points</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="summarize-language">Output Language</label>
|
|
<select id="summarize-language">
|
|
<option value="same">Same as input</option>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary" id="summarize-text-btn">
|
|
<span class="btn-text">Summarize</span>
|
|
<span class="btn-loading">Summarizing...</span>
|
|
</button>
|
|
</form>
|
|
<div id="summarize-text-result" class="result"></div>
|
|
</div>
|
|
|
|
<!-- File mode -->
|
|
<div id="summarize-file-mode" class="summarize-mode" style="display: none;">
|
|
<div id="summarize-drop-zone" class="drop-zone">
|
|
<div class="drop-zone-content">
|
|
<div class="drop-zone-icon">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
|
<polyline points="17 8 12 3 7 8"/>
|
|
<line x1="12" y1="3" x2="12" y2="15"/>
|
|
</svg>
|
|
</div>
|
|
<p class="drop-zone-text">Drag & drop text files here</p>
|
|
<p class="drop-zone-hint">or click to select files (.txt)</p>
|
|
<input type="file" id="summarize-file-input" multiple accept=".txt,text/plain" style="display: none;">
|
|
</div>
|
|
</div>
|
|
<div id="summarize-selected-files" class="selected-files" style="display: none;">
|
|
<h3>Selected Files</h3>
|
|
<ul id="summarize-files-list"></ul>
|
|
<button type="button" id="summarize-clear-files" class="btn btn-small btn-secondary">Clear</button>
|
|
</div>
|
|
<form id="summarize-file-form">
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="summarize-file-style">Style</label>
|
|
<select id="summarize-file-style">
|
|
<option value="concise">Concise</option>
|
|
<option value="detailed">Detailed</option>
|
|
<option value="bullet">Bullet Points</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="summarize-file-language">Output Language</label>
|
|
<select id="summarize-file-language">
|
|
<option value="same">Same as input</option>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary" id="summarize-file-btn" disabled>
|
|
<span class="btn-text">Summarize Files</span>
|
|
<span class="btn-loading">Summarizing...</span>
|
|
</button>
|
|
</form>
|
|
<div id="summarize-file-result" class="result"></div>
|
|
</div>
|
|
|
|
<!-- Link mode (YouTube) -->
|
|
<div id="summarize-link-mode" class="summarize-mode" style="display: none;">
|
|
<form id="summarize-link-form">
|
|
<div class="form-group">
|
|
<label for="summarize-url">YouTube URL (video or playlist)</label>
|
|
<input type="url" id="summarize-url" placeholder="https://youtube.com/watch?v=..." required>
|
|
</div>
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="summarize-link-style">Summary Style</label>
|
|
<select id="summarize-link-style">
|
|
<option value="concise">Concise</option>
|
|
<option value="detailed">Detailed</option>
|
|
<option value="bullet">Bullet Points</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="summarize-link-language">Output Language</label>
|
|
<select id="summarize-link-language">
|
|
<option value="same">Same as video</option>
|
|
<option value="en">English</option>
|
|
<option value="fr">French</option>
|
|
<option value="es">Spanish</option>
|
|
<option value="de">German</option>
|
|
<option value="it">Italian</option>
|
|
<option value="pt">Portuguese</option>
|
|
<option value="zh">Chinese</option>
|
|
<option value="ja">Japanese</option>
|
|
<option value="ko">Korean</option>
|
|
<option value="ru">Russian</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<button type="submit" class="btn btn-primary" id="summarize-link-btn">
|
|
<span class="btn-text">Download + Transcribe + Summarize</span>
|
|
<span class="btn-loading">Processing...</span>
|
|
</button>
|
|
</form>
|
|
<div id="summarize-link-progress" class="progress-container" style="display: none;">
|
|
<div class="progress-header">
|
|
<span id="summarize-link-progress-title">Processing...</span>
|
|
<span id="summarize-link-progress-eta"></span>
|
|
</div>
|
|
<div class="progress-bar">
|
|
<div id="summarize-link-progress-fill" class="progress-fill"></div>
|
|
</div>
|
|
<div class="progress-details">
|
|
<span id="summarize-link-progress-percent">0%</span>
|
|
<span id="summarize-link-progress-phase"></span>
|
|
<span id="summarize-link-progress-speed"></span>
|
|
</div>
|
|
<div id="summarize-link-progress-current" class="progress-current"></div>
|
|
</div>
|
|
<div id="summarize-link-result" class="result"></div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
|
|
<script src="app.js"></script>
|
|
</body>
|
|
</html>
|