Download index.html from DownFlow/webasmr: direct link, hf CLI and curl.
- Browser
- Download file 11.8 kB
-
https://huggingface.co/spaces/DownFlow/webasmr/resolve/main/index.html
- Command line
-
hf download hf://spaces/DownFlow/webasmr/index.html
-
curl -L -o index.html https://huggingface.co/spaces/DownFlow/webasmr/resolve/main/index.html
11.8 kB
| <html lang="zh-CN"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> | |
| <meta name="color-scheme" content="dark" /> | |
| <title>WebASMR · 浏览器语音合成</title> | |
| <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎧</text></svg>"> | |
| <meta name="description" content="F5-TTS flow-matching speech synthesis running fully in your browser. WebGPU accelerated, nothing leaves your device." /> | |
| <link rel="stylesheet" href="fonts/fonts.css" /> | |
| <script src="/coi-serviceworker.js"></script> | |
| <style> | |
| :root { | |
| --bg: #020203; | |
| --t1: rgba(255, 255, 255, 0.92); | |
| --t2: rgba(255, 255, 255, 0.55); | |
| --t3: rgba(255, 255, 255, 0.32); | |
| --t4: rgba(255, 255, 255, 0.20); | |
| --line: rgba(255, 255, 255, 0.08); | |
| --line-soft: rgba(255, 255, 255, 0.06); | |
| --panel: rgba(255, 255, 255, 0.03); | |
| --panel-hover: rgba(255, 255, 255, 0.06); | |
| --ok: #64ffa0; | |
| --warn: #ffcd6b; | |
| --danger: #ff7a6b; | |
| --display: "Instrument Serif", Georgia, "Songti SC", "Times New Roman", serif; | |
| --body: "Geist", -apple-system, BlinkMacSystemFont, "PingFang SC", "Segoe UI", sans-serif; | |
| --mono: "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace; | |
| --maxw: 860px; | |
| } | |
| * { box-sizing: border-box; margin: 0; padding: 0; } | |
| html { height: 100%; } | |
| body { | |
| background: var(--bg); | |
| color: var(--t1); | |
| font-family: var(--body); | |
| font-size: 16px; | |
| line-height: 1.6; | |
| -webkit-font-smoothing: antialiased; | |
| min-height: 100dvh; | |
| display: flex; | |
| flex-direction: column; | |
| overflow-x: hidden; | |
| } | |
| body::before { | |
| content: ""; | |
| position: fixed; | |
| inset: 0; | |
| background: radial-gradient(58% 42% at 50% -6%, rgba(130, 150, 255, 0.09), transparent 70%); | |
| pointer-events: none; | |
| } | |
| button, textarea, input, select { font: inherit; color: inherit; } | |
| button { appearance: none; background: none; border: 0; cursor: pointer; } | |
| a { color: inherit; text-decoration: none; } | |
| ::selection { background: rgba(255, 255, 255, 0.18); } | |
| .wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 24px; } | |
| /* topbar */ | |
| .topbar { | |
| position: sticky; top: 0; z-index: 10; | |
| border-bottom: 1px solid var(--line-soft); | |
| background: rgba(2, 2, 3, 0.72); | |
| backdrop-filter: blur(14px); | |
| -webkit-backdrop-filter: blur(14px); | |
| } | |
| .topbar-inner { display: flex; align-items: center; justify-content: space-between; height: 56px; } | |
| .brand { font-family: var(--mono); font-size: 12px; font-weight: 500; letter-spacing: 0.22em; text-transform: uppercase; color: var(--t1); } | |
| .chip { | |
| display: inline-flex; align-items: center; gap: 8px; | |
| font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; | |
| color: var(--t2); | |
| border: 1px solid var(--line); | |
| border-radius: 999px; | |
| padding: 5px 12px; | |
| white-space: nowrap; | |
| } | |
| .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--t4); flex-shrink: 0; } | |
| .chip.ready .dot { background: var(--ok); box-shadow: 0 0 8px rgba(100, 255, 160, 0.7); } | |
| .chip.error .dot { background: var(--danger); } | |
| /* hero */ | |
| .hero { padding: 76px 0 8px; } | |
| .eyebrow { | |
| display: inline-flex; align-items: center; gap: 10px; | |
| font-family: var(--mono); font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; | |
| color: var(--t3); margin-bottom: 22px; | |
| } | |
| .eyebrow::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 10px rgba(100, 255, 160, 0.8); } | |
| h1 { | |
| font-family: var(--display); | |
| font-weight: 400; | |
| font-size: clamp(40px, 7vw, 72px); | |
| line-height: 1.06; | |
| letter-spacing: 0.01em; | |
| max-width: 15ch; | |
| } | |
| h1 em { font-style: italic; color: var(--t2); } | |
| .sub { margin-top: 22px; max-width: 52ch; color: var(--t2); font-size: 15.5px; } | |
| .sub b { color: var(--t1); font-weight: 500; } | |
| .stats { | |
| display: flex; flex-wrap: wrap; gap: 10px 28px; | |
| margin-top: 34px; | |
| font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; | |
| color: var(--t3); | |
| } | |
| .stats span b { color: var(--t1); font-weight: 500; } | |
| /* studio */ | |
| .studio { margin: 44px 0 0; border: 1px solid var(--line); border-radius: 18px; background: var(--panel); overflow: hidden; } | |
| .studio-head { | |
| display: flex; align-items: center; justify-content: space-between; gap: 12px; | |
| padding: 14px 20px; border-bottom: 1px solid var(--line-soft); | |
| font-family: var(--mono); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--t3); | |
| } | |
| .studio-body { padding: 20px; } | |
| textarea#text { | |
| width: 100%; min-height: 108px; resize: vertical; | |
| background: rgba(255, 255, 255, 0.02); | |
| border: 1px solid var(--line); | |
| border-radius: 12px; | |
| padding: 16px 18px; | |
| font-size: 17px; line-height: 1.7; | |
| outline: none; | |
| transition: border-color 0.18s ease; | |
| } | |
| textarea#text:focus { border-color: rgba(255, 255, 255, 0.22); } | |
| textarea#text::placeholder { color: var(--t3); } | |
| .chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; } | |
| .chip-btn { | |
| font-size: 13.5px; color: var(--t2); | |
| border: 1px solid var(--line); | |
| border-radius: 999px; | |
| padding: 6px 15px; | |
| transition: all 0.15s ease; | |
| } | |
| .chip-btn:hover { background: var(--panel-hover); color: var(--t1); } | |
| .chip-btn.active { background: rgba(255, 255, 255, 0.1); color: var(--t1); border-color: rgba(255, 255, 255, 0.2); } | |
| .options { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 22px; margin-top: 18px; } | |
| .opt { display: inline-flex; align-items: center; gap: 10px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--t3); } | |
| .voice-pill { color: var(--t1); border: 1px solid var(--line); border-radius: 999px; padding: 5px 14px; font-size: 12px; letter-spacing: 0.02em; } | |
| input[type="range"] { width: 120px; accent-color: rgba(255, 255, 255, 0.8); background: transparent; } | |
| .opt output { color: var(--t1); min-width: 26px; } | |
| .actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 22px; } | |
| button.primary { | |
| display: inline-flex; align-items: center; gap: 10px; | |
| background: var(--t1); color: #050506; | |
| font-weight: 500; font-size: 15px; | |
| border-radius: 999px; padding: 11px 26px; | |
| transition: transform 0.15s ease, opacity 0.15s ease; | |
| } | |
| button.primary:hover { transform: translateY(-1px); } | |
| button.primary:disabled { opacity: 0.45; cursor: default; transform: none; } | |
| button.ghost { | |
| font-size: 14px; color: var(--t2); | |
| border: 1px solid var(--line); border-radius: 999px; padding: 10px 20px; | |
| transition: all 0.15s ease; | |
| } | |
| button.ghost:hover:not(:disabled) { background: var(--panel-hover); color: var(--t1); } | |
| button.ghost:disabled { opacity: 0.35; cursor: default; } | |
| .hint { font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; color: var(--t3); } | |
| /* progress */ | |
| .progress { margin-top: 20px; display: none; } | |
| .progress.on { display: block; } | |
| .bar { height: 3px; border-radius: 999px; background: rgba(255, 255, 255, 0.07); overflow: hidden; } | |
| .bar i { display: block; height: 100%; width: 0%; background: var(--t1); border-radius: 999px; transition: width 0.2s ease; } | |
| .bar.indeterminate i { width: 30% ; animation: slide 1.2s ease-in-out infinite alternate; } | |
| @keyframes slide { from { margin-left: 0; } to { margin-left: 70%; } } | |
| .stage { display: flex; justify-content: space-between; gap: 12px; margin-top: 9px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--t3); } | |
| .stage output { color: var(--t2); text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } | |
| /* result */ | |
| .result { margin-top: 18px; display: none; } | |
| .result.on { display: block; } | |
| audio { width: 100%; height: 40px; margin-top: 4px; opacity: 0.9; } | |
| .meta { display: flex; flex-wrap: wrap; gap: 8px 24px; margin-top: 14px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.08em; color: var(--t3); text-transform: uppercase; } | |
| .meta b { color: var(--t1); font-weight: 500; } | |
| .error { display: none; margin-top: 16px; border: 1px solid rgba(255, 122, 107, 0.35); background: rgba(255, 122, 107, 0.07); color: #ffb3a8; border-radius: 12px; padding: 12px 16px; font-size: 13.5px; } | |
| .error.on { display: block; } | |
| /* footer */ | |
| footer { margin-top: auto; border-top: 1px solid var(--line-soft); } | |
| .footer-inner { display: flex; flex-wrap: wrap; gap: 10px 26px; align-items: center; justify-content: space-between; padding: 22px 0 26px; font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--t3); } | |
| .footer-inner a:hover { color: var(--t1); } | |
| @media (max-width: 640px) { | |
| .hero { padding-top: 48px; } | |
| .studio-body { padding: 16px; } | |
| .footer-inner { justify-content: flex-start; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header class="topbar"> | |
| <div class="wrap topbar-inner"> | |
| <span class="brand">WebASMR</span> | |
| <span class="chip" id="cap-chip"><span class="dot"></span><span id="cap-text">检测中</span></span> | |
| </div> | |
| </header> | |
| <main class="wrap"> | |
| <section class="hero"> | |
| <span class="eyebrow">F5-TTS · FLOW MATCHING · ON-DEVICE</span> | |
| <h1>闭上眼,<em>听见温柔</em>。</h1> | |
| <p class="sub">中文语音合成完整运行在你的浏览器里 — <b>WebGPU</b> 加速的流匹配网络加 24kHz 声码器。文字不离开这台设备,<b>零上传</b>。</p> | |
| <div class="stats" id="stats"> | |
| <span>SAMPLE RATE <b>24 KHZ</b></span> | |
| <span>FLOW STEPS <b id="stat-steps">32</b></span> | |
| <span id="stat-live" hidden>TOTAL <b id="stat-total">–</b></span> | |
| <span id="stat-rt" hidden>REALTIME <b id="stat-realtime">–</b></span> | |
| </div> | |
| </section> | |
| <section class="studio"> | |
| <div class="studio-head"> | |
| <span>STUDIO</span> | |
| <span id="studio-state">IDLE</span> | |
| </div> | |
| <div class="studio-body"> | |
| <textarea id="text" spellcheck="false" placeholder="闭上眼睛,慢慢地呼吸。">闭上眼睛,慢慢地呼吸。</textarea> | |
| <div class="chips" id="presets"></div> | |
| <div class="options"> | |
| <span class="opt">音色 <span class="voice-pill">小莼(纯儿)</span></span> | |
| <span class="opt">增益 <input type="range" id="gain" min="0.5" max="4" step="0.5" value="1"><output id="gain-out">1×</output></span> | |
| </div> | |
| <div class="actions"> | |
| <button class="primary" id="go">生成语音</button> | |
| <button class="ghost" id="dl" disabled>下载 WAV</button> | |
| <span class="hint" id="hint">首次使用需下载约 712 MB 模型(浏览器会缓存)</span> | |
| </div> | |
| <div class="progress" id="progress"> | |
| <div class="bar" id="bar"><i id="bar-fill"></i></div> | |
| <div class="stage"><span id="stage-label">PREPARING</span><output id="stage-detail"></output></div> | |
| </div> | |
| <div class="result" id="result"> | |
| <audio id="player" controls></audio> | |
| <div class="meta" id="meta"></div> | |
| </div> | |
| <div class="error" id="error"></div> | |
| </div> | |
| </section> | |
| </main> | |
| <footer> | |
| <div class="wrap footer-inner"> | |
| <span>WebASMR · 浏览器内的温柔声音</span> | |
| <span> | |
| <a href="https://huggingface.co/DownFlow/webasmr-f5tts" target="_blank" rel="noreferrer">MODEL REPO</a> | |
| · | |
| <a href="https://huggingface.co/spaces/DownFlow/webasmr" target="_blank" rel="noreferrer">SPACE</a> | |
| </span> | |
| </div> | |
| </footer> | |
| <script type="module" src="/app.js"></script> | |
| </body> | |
| </html> | |