VietAutoSub / index.html
CVNSS's picture
Upload 5 files
56ff7e6 verified
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Viet AutoSub Editor</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=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="static/styles.css" />
</head>
<body>
<!-- ===== OFFLINE BANNER ===== -->
<div class="offline-banner" id="offlineBanner" hidden>
<svg viewBox="0 0 20 20" fill="currentColor" class="offline-banner-icon">
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
</svg>
<span id="offlineBannerText">Đang chạy offline — Chức năng AI (auto sub, xuất MP4) cần kết nối server HF Space.</span>
<button class="offline-banner-close" id="offlineBannerClose" title="Đóng">&times;</button>
</div>
<!-- ===== TOP NAV ===== -->
<nav class="topbar">
<div class="topbar-inner">
<div class="logo-group">
<svg class="logo-icon" viewBox="0 0 32 32" fill="none" aria-label="Viet AutoSub">
<rect x="2" y="6" width="28" height="20" rx="4" stroke="currentColor" stroke-width="2"/>
<rect x="6" y="20" width="20" height="4" rx="1.5" fill="currentColor" opacity="0.25"/>
<rect x="8" y="21" width="7" height="2" rx="1" fill="currentColor"/>
<rect x="17" y="21" width="5" height="2" rx="1" fill="currentColor" opacity="0.6"/>
<circle cx="16" cy="13" r="4" stroke="currentColor" stroke-width="1.5"/>
<polygon points="14.5,11.5 18.5,13 14.5,14.5" fill="currentColor"/>
</svg>
<span class="logo-text">Viet AutoSub</span>
</div>
<div class="topbar-right">
<span class="badge badge-env" id="badgeEnv">
<span class="pulse-dot" id="pulseDot"></span>
<span id="badgeEnvText">Đang kiểm tra...</span>
</span>
<span class="badge badge-model" id="modelBadge">whisper-small</span>
</div>
</div>
</nav>
<!-- ===== MAIN LAYOUT ===== -->
<main class="main">
<!-- ===== STEP INDICATOR ===== -->
<div class="steps">
<div class="step active" data-step="1">
<div class="step-num">1</div>
<div class="step-label">Upload video</div>
</div>
<div class="step-line"></div>
<div class="step" data-step="2">
<div class="step-num">2</div>
<div class="step-label">Auto sub tiếng Việt</div>
</div>
<div class="step-line"></div>
<div class="step" data-step="3">
<div class="step-num">3</div>
<div class="step-label">Chỉnh sửa subtitle</div>
</div>
<div class="step-line"></div>
<div class="step" data-step="4">
<div class="step-num">4</div>
<div class="step-label">Xuất SRT / MP4</div>
</div>
</div>
<!-- ===== UPLOAD ZONE ===== -->
<section class="panel upload-panel" id="uploadPanel">
<div class="drop-zone" id="dropZone">
<svg class="drop-icon" viewBox="0 0 48 48" fill="none">
<rect x="4" y="8" width="40" height="32" rx="6" stroke="currentColor" stroke-width="2" stroke-dasharray="4 3"/>
<path d="M24 18v12M18 24l6-6 6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<p class="drop-title">Kéo thả video vào đây</p>
<p class="drop-hint">hoặc click để chọn file &mdash; MP4, MOV, MKV, AVI, WebM &le; 250 MB</p>
<input id="videoFile" type="file" accept="video/*" hidden />
</div>
<div class="file-info" id="fileInfo" hidden>
<div class="file-meta">
<svg viewBox="0 0 20 20" fill="currentColor" class="file-icon"><path d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V7.414A2 2 0 0017.414 6L14 2.586A2 2 0 0012.586 2H4zm8 1.414L15.586 8H13a1 1 0 01-1-1V4.414zM4 5h6v2a3 3 0 003 3h2v5a1 1 0 01-1 1H4a1 1 0 01-1-1V5a1 1 0 011-1z"/></svg>
<span id="fileName">video.mp4</span>
<span class="file-size" id="fileSize">0 MB</span>
</div>
<button class="btn btn-ghost btn-sm" id="btnClearFile">Đổi file</button>
</div>
</section>
<!-- ===== TWO-COLUMN: VIDEO + CONTROLS ===== -->
<div class="grid-two">
<!-- LEFT: Video Preview -->
<section class="panel video-panel">
<div class="panel-head">
<h2 class="panel-title">
<svg viewBox="0 0 20 20" fill="currentColor" class="icon-sm"><path d="M6.672 1.911a1 1 0 10-1.932.518l.259.966a1 1 0 001.932-.518l-.26-.966zM2.429 4.74a1 1 0 10-.517 1.932l.966.259a1 1 0 00.517-1.932l-.966-.26zm8.814-.569a1 1 0 00-1.415-1.414l-.707.707a1 1 0 101.415 1.415l.707-.708zm-7.071 7.072l.707-.707A1 1 0 003.465 9.12l-.708.707a1 1 0 001.415 1.415zm3.2-5.171a1 1 0 00-1.3 1.3l4 10a1 1 0 001.823.075l1.38-2.759 3.018 3.02a1 1 0 001.414-1.415l-3.019-3.02 2.76-1.379a1 1 0 00-.076-1.822l-10-4z"/></svg>
Xem trước
</h2>
</div>
<div class="video-wrap">
<video id="preview" controls playsinline></video>
<div class="video-placeholder" id="videoPlaceholder">
<svg viewBox="0 0 64 64" fill="none" class="placeholder-icon">
<rect x="8" y="14" width="48" height="36" rx="6" stroke="currentColor" stroke-width="2"/>
<polygon points="26,24 42,32 26,40" fill="currentColor" opacity="0.3"/>
</svg>
<span>Chưa có video</span>
</div>
</div>
</section>
<!-- RIGHT: Action Panel -->
<section class="panel action-panel">
<div class="panel-head">
<h2 class="panel-title">
<svg viewBox="0 0 20 20" fill="currentColor" class="icon-sm"><path fill-rule="evenodd" d="M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd"/></svg>
Điều khiển
</h2>
</div>
<div class="action-stack">
<!-- Transcribe -->
<button id="btnTranscribe" class="btn btn-primary btn-lg btn-full">
<svg viewBox="0 0 20 20" fill="currentColor" class="icon-btn"><path fill-rule="evenodd" d="M7 4a3 3 0 016 0v4a3 3 0 11-6 0V4zm4 10.93A7.001 7.001 0 0017 8a1 1 0 10-2 0A5 5 0 015 8a1 1 0 00-2 0 7.001 7.001 0 006 6.93V17H6a1 1 0 100 2h8a1 1 0 100-2h-3v-2.07z" clip-rule="evenodd"/></svg>
Auto sub tiếng Việt
</button>
<!-- Progress Bar -->
<div class="progress-wrap" id="progressWrap" hidden>
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
<span class="progress-text" id="progressText">Đang xử lý...</span>
</div>
<!-- Status -->
<div id="status" class="status-box status-idle">
<svg viewBox="0 0 20 20" fill="currentColor" class="status-icon"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"/></svg>
<span id="statusText">Sẵn sàng. Hãy upload video để bắt đầu.</span>
</div>
<hr class="divider" />
<!-- Edit Actions -->
<div class="btn-row">
<button id="btnAddRow" class="btn btn-outline" disabled>
<svg viewBox="0 0 20 20" fill="currentColor" class="icon-btn"><path fill-rule="evenodd" d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z" clip-rule="evenodd"/></svg>
Thêm dòng
</button>
</div>
<hr class="divider" />
<!-- Export Actions -->
<div class="export-group">
<h3 class="export-title">Xuất file</h3>
<div class="btn-row">
<button id="btnExportSrt" class="btn btn-outline" disabled>
<svg viewBox="0 0 20 20" fill="currentColor" class="icon-btn"><path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
Xuất .SRT
</button>
<button id="btnExportMp4" class="btn btn-success" disabled>
<svg viewBox="0 0 20 20" fill="currentColor" class="icon-btn"><path d="M4 3a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V5a2 2 0 00-2-2H4zm12 12H4l4-8 3 6 2-4 3 6z"/></svg>
Xuất .MP4 burn sub
</button>
</div>
</div>
<!-- Download Links -->
<div class="download-group" id="downloadGroup" hidden>
<a id="downloadSrt" class="dl-link dl-srt" href="#" download>
<svg viewBox="0 0 20 20" fill="currentColor" class="icon-btn"><path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
Tải .SRT
</a>
<a id="downloadMp4" class="dl-link dl-mp4" href="#" download>
<svg viewBox="0 0 20 20" fill="currentColor" class="icon-btn"><path fill-rule="evenodd" d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
Tải .MP4
</a>
</div>
</div>
</section>
</div>
<!-- ===== SUBTITLE TABLE ===== -->
<section class="panel table-panel">
<div class="panel-head">
<h2 class="panel-title">
<svg viewBox="0 0 20 20" fill="currentColor" class="icon-sm"><path fill-rule="evenodd" d="M4 4a2 2 0 012-2h4.586A2 2 0 0112 2.586L15.414 6A2 2 0 0116 7.414V16a2 2 0 01-2 2H6a2 2 0 01-2-2V4z" clip-rule="evenodd"/></svg>
Bảng Subtitle
</h2>
<div class="table-meta">
<span class="seg-count" id="segmentCount">0 dòng</span>
<button class="btn btn-ghost btn-sm" id="btnCollapseTable" title="Thu gọn">
<svg viewBox="0 0 20 20" fill="currentColor" class="icon-xs"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
</button>
</div>
</div>
<div class="table-scroll" id="tableScroll">
<table>
<thead>
<tr>
<th class="col-idx">#</th>
<th class="col-time">Bắt đầu</th>
<th class="col-time">Kết thúc</th>
<th class="col-text">Nội dung</th>
<th class="col-act">Thao tác</th>
</tr>
</thead>
<tbody id="subtitleBody">
<tr class="empty-row">
<td colspan="5">
<div class="empty-state">
<svg viewBox="0 0 48 48" fill="none" class="empty-icon">
<rect x="6" y="10" width="36" height="28" rx="4" stroke="currentColor" stroke-width="1.5"/>
<line x1="12" y1="20" x2="36" y2="20" stroke="currentColor" stroke-width="1.5" opacity="0.3"/>
<line x1="12" y1="26" x2="30" y2="26" stroke="currentColor" stroke-width="1.5" opacity="0.3"/>
<line x1="12" y1="32" x2="24" y2="32" stroke="currentColor" stroke-width="1.5" opacity="0.3"/>
</svg>
<p>Chưa có subtitle. Upload video rồi bấm <strong>Auto sub tiếng Việt</strong> để bắt đầu.</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</section>
</main>
<!-- ===== FOOTER ===== -->
<footer class="footer">
<span>Viet AutoSub Editor &mdash; Nhận diện giọng nói tiếng Việt bằng Whisper</span>
</footer>
<script src="static/app.js"></script>
</body>
</html>