videotomp3transcriptor/public/index.html
Trouve Alexis 23bb4cd2d9 Add video/audio to MP3 conversion feature
Implement drag-and-drop interface for converting video and audio files to MP3 format using FFmpeg. Users can now upload files (MP4, M4A, AVI, MKV, MOV, WAV, FLAC, OGG) and convert them with customizable bitrate and quality settings.

- Add conversion service with FFmpeg integration
- Add /convert-to-mp3 and /supported-formats API endpoints
- Add new "Video to MP3" tab with drag-and-drop UI
- Support multiple file uploads with batch conversion
- Add bitrate (128k-320k) and VBR quality options

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 22:56:58 +08:00

578 lines
26 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>
<!-- 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>