# FishStudio **Repository Path**: kzc_666/fish-studio ## Basic Information - **Project Name**: FishStudio - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-03 - **Last Updated**: 2026-07-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # VoxWeaver Studio **[English](#english)** · **[中文](#中文)** --- ## English VoxWeaver Studio is a local voice production WebUI that combines **Fish Audio** (`s2.1-pro-free`) and **DeepSeek** (`deepseek-v4-flash` / `deepseek-v4-pro`) for AI text optimization, multi-role scripting, voice cloning, batch TTS, and ffmpeg audio merging. ### Features - **Bilingual UI** — Chinese default in the app; switch **中文 / English** from the top-right of the main area - Single-text workspace with optional DeepSeek optimization - Batch `.txt` upload with per-file AI optimization and ZIP export - Multi-role Studio with role voice audition → lock as persistent clone, AI coverage review, preview/final queues, and merged output - Voice binding: default, `reference_id`, instant clone (MessagePack), persistent clone - Role clone history on the Voices page (style + sample text preserved) - Full Fish `s2.1-pro-free` parameter panel with presets (collapsed by default) - Emotion/style bracket cue toolbar for Fish S2 models - Voice library CRUD and persistent cloning (`train_mode: fast`) - History (latest **50** records, details collapsed by default) - Settings with **manual** Fish / DeepSeek / ffmpeg health checks (no auto probe on page load) - Timestamped audio download filenames (`YYYYMMDD-HHMMSS-first20chars.mp3`) ### Fish Audio API Key 1. Sign up at [https://fish.audio](https://fish.audio) 2. Open your developer dashboard and create an API key 3. Copy the key into `.env` as `FISH_API_KEY` ### DeepSeek API Key 1. Sign up at [https://platform.deepseek.com](https://platform.deepseek.com) 2. Create an API key in the API keys section 3. Copy the key into `.env` as `DEEPSEEK_API_KEY` ### Environment Configuration Copy `.env.example` to `.env` and fill in your keys: ```env FISH_API_KEY=your_fish_audio_key DEEPSEEK_API_KEY=your_deepseek_key FISH_BASE_URL=https://api.fish.audio FISH_TTS_MODEL=s2.1-pro-free DEEPSEEK_BASE_URL=https://api.deepseek.com DEEPSEEK_DEFAULT_MODEL=deepseek-v4-flash OUTPUT_DIR=outputs UPLOAD_DIR=uploads TEMP_DIR=temp MAX_TXT_FILE_SIZE_MB=10 MAX_AUDIO_FILE_SIZE_MB=50 MAX_BATCH_FILES=50 MAX_PARALLEL_TTS=2 MAX_PARALLEL_AI=2 PORT=3001 CLIENT_URL=http://localhost:5173 ``` API keys are read **only on the server** and must never be placed in client code or committed to git. ### Install Dependencies Requirements: Node.js 18+, pnpm, ffmpeg on PATH. ```bash pnpm install pnpm -F @voxweaver/shared build ``` ### ffmpeg Installation - **macOS**: `brew install ffmpeg` - **Ubuntu/Debian**: `sudo apt install ffmpeg` - **Windows**: download from [https://ffmpeg.org/download.html](https://ffmpeg.org/download.html) and add to PATH Verify: `ffmpeg -version` ### Start Frontend and Backend Development (hot reload): ```bash cp .env.example .env # then edit with your keys pnpm dev ``` - Frontend: [http://localhost:5173](http://localhost:5173) - Backend API: [http://localhost:3001/api](http://localhost:3001/api) Production-style (serve built client from Express): ```bash pnpm build pnpm start ``` Open [http://localhost:3001](http://localhost:3001) ### Single-Text Generation 1. Open **Workspace** (`/`) 2. Type text or upload a `.txt` file 3. Choose AI mode (or **No optimization**) 4. Click **AI Optimize** (optional), edit TTS text, insert emotion tags 5. Configure voice binding and Fish parameters 6. **Preview / Generate Audio** — download uses a timestamped filename ### Batch TXT Generation 1. Open **Batch** (`/batch`) 2. Upload multiple `.txt` files (per-file AI optimization) 3. Set global or per-file voice binding 4. **Batch generate & ZIP** → `batch-output.zip` ### Multi-Role Studio 1. Open **Studio** (`/studio`) 2. Paste long text → **AI split roles** (default model: `deepseek-v4-pro`) 3. Optional: auto or manual **AI review** for missing segments 4. Per role: **audition** → **regenerate** → **lock as role voice** (saved to clone history) 5. **Preview queue** / **Final queue + merge** → download merged audio and exports ### Voice Library - **Role clone history** — entries created when locking voices in Studio - **My clones** — Fish account voices - Registry loads in stages; health/state sync is manual via **Refresh status** - Removing a record deletes the local registry file only (not the Fish model) ### reference_id Usage 1. Copy a voice `_id` from **Voices** 2. Set Voice Binding type to `reference_id` and paste the ID Example curl (use your server env key, never embed in frontend): ```bash curl --request POST \ --url https://api.fish.audio/v1/tts \ --header "Authorization: Bearer $FISH_API_KEY" \ --header "Content-Type: application/json" \ --header "model: s2.1-pro-free" \ --data '{"text":"Hello","reference_id":"YOUR_VOICE_ID","format":"mp3"}' ``` ### Instant Clone 1. Prepare reference audio with accurate transcripts 2. Voice Binding → **Instant clone** → upload samples 3. Backend uses MessagePack for direct Fish requests (no base64 in JSON) ### Persistent Clone 1. **Voices** → upload samples → **Create clone** (`train_mode: fast`) 2. Or lock from Studio audition via **Lock as role voice** 3. Wait until `state === trained` before batch/studio generation ### Fish s2.1-pro-free Parameters | Parameter | Description | Default | |-----------|-------------|---------| | `format` | mp3 / wav / pcm / opus | mp3 | | `sample_rate` | Format-dependent sample rate | 44100 | | `mp3_bitrate` | 64 / 128 / 192 | 128 | | `latency` | normal / balanced / low | normal | | `temperature` | Expression variation 0–1 | 0.7 | | `top_p` | Nucleus sampling 0–1 | 0.7 | | `prosody.speed` | Speech speed | 1.0 | | `chunk_length` | Text chunk size 100–300 | 300 | | `normalize` | Text normalization | true | UI presets: High-quality narration, Quick preview, Real-time, Long-text stable. ### DeepSeek Models - Default: `deepseek-v4-flash`; Studio role-split default: `deepseek-v4-pro` - OpenAI-compatible `POST /chat/completions` with `response_format: json_object` - `mode: none` bypasses DeepSeek (passthrough project) ### Troubleshooting | Issue | Fix | |-------|-----| | `FISH_API_KEY is not configured` | Add key to `.env`, restart server | | `DEEPSEEK_API_KEY is not configured` | Add key to `.env`, restart server | | `ffmpeg is not installed` | Install ffmpeg; verify `ffmpeg -version` | | Fish 401/402 | Check key validity and account balance | | Clone still `training` | Use **Refresh status** on Voices | | Duplicate role in clone history | Remove extras; same `role_id` now upserts one record | | Test data reappeared after `pnpm test` | Tests use an isolated temp dir (not project `outputs/`) | ### Security & Privacy - **Never** commit `.env`, `.env.local`, or real API keys - `.gitignore` excludes `outputs/`, `uploads/`, `temp/`, and all `.env*` except `.env.example` - All Fish and DeepSeek traffic goes through the Express backend - Persistent clones default to `visibility: private` - Generated audio and registry JSON live under `outputs/` locally — treat as sensitive if your scripts contain private content - If a key was ever committed or shared, **rotate it** in the Fish / DeepSeek dashboards immediately ### Project Structure ``` voxweaver-studio/ client/ Vite + React + TypeScript UI (i18n) server/ Express + TypeScript API shared/ Types, zod schemas, pure logic outputs/ Generated audio, projects, voice-registry (gitignored) uploads/ Uploaded reference audio (gitignored) temp/ Temporary merge/silence files (gitignored) ``` ### Tests ```bash pnpm test ``` Integration tests mock Fish/DeepSeek with nock and write to a **temporary** output directory, not your project `outputs/`. ### License Local development tool — comply with Fish Audio and DeepSeek terms of service. --- ## 中文 VoxWeaver Studio 是本地语音制作 WebUI,整合 **Fish Audio**(`s2.1-pro-free`)与 **DeepSeek**(`deepseek-v4-flash` / `deepseek-v4-pro`),支持 AI 文本优化、多角色分镜、音色克隆、批量 TTS 与 ffmpeg 音频合并。 ### 功能 - **中英文界面** — 应用内默认中文;主区域右上角可切换 **中文 / English** - 单文本工作台(可选 DeepSeek 优化) - 批量 `.txt` 上传、逐文件 AI 优化与 ZIP 导出 - 多角色工作室:试听 → 锁定角色音色、AI 覆盖复查、预览/终稿队列与合并输出 - 音色绑定:默认、`reference_id`、即时克隆(MessagePack)、持久克隆 - 音色库「角色克隆历史」(保留 Style 与试听文本) - Fish 参数面板(默认折叠)与情绪标签工具栏 - 音色库增删改查与持久克隆(`train_mode: fast`) - 历史记录(仅保留最近 **50** 条,详情默认折叠) - 设置页健康检查为**手动触发**(进入页面不自动探测) - 音频下载文件名带时间戳(`YYYYMMDD-HHMMSS-文本前20字.mp3`) ### 获取 Fish Audio API Key 1. 注册 [https://fish.audio](https://fish.audio) 2. 在开发者后台创建 API Key 3. 写入 `.env`:`FISH_API_KEY=...` ### 获取 DeepSeek API Key 1. 注册 [https://platform.deepseek.com](https://platform.deepseek.com) 2. 在 API Keys 页面创建密钥 3. 写入 `.env`:`DEEPSEEK_API_KEY=...` ### 环境配置 复制 `.env.example` 为 `.env` 并填入密钥: ```env FISH_API_KEY=your_fish_audio_key DEEPSEEK_API_KEY=your_deepseek_key FISH_BASE_URL=https://api.fish.audio FISH_TTS_MODEL=s2.1-pro-free DEEPSEEK_BASE_URL=https://api.deepseek.com DEEPSEEK_DEFAULT_MODEL=deepseek-v4-flash OUTPUT_DIR=outputs UPLOAD_DIR=uploads TEMP_DIR=temp MAX_TXT_FILE_SIZE_MB=10 MAX_AUDIO_FILE_SIZE_MB=50 MAX_BATCH_FILES=50 MAX_PARALLEL_TTS=2 MAX_PARALLEL_AI=2 PORT=3001 CLIENT_URL=http://localhost:5173 ``` 密钥**仅在后端读取**,切勿写入前端代码或提交到 git。 ### 安装依赖 需要:Node.js 18+、pnpm、系统 PATH 中的 ffmpeg。 ```bash pnpm install pnpm -F @voxweaver/shared build ``` ### 安装 ffmpeg - **macOS**:`brew install ffmpeg` - **Ubuntu/Debian**:`sudo apt install ffmpeg` - **Windows**:从 [ffmpeg.org](https://ffmpeg.org/download.html) 下载并加入 PATH 验证:`ffmpeg -version` ### 启动前后端 开发模式(热更新): ```bash cp .env.example .env # 编辑填入密钥 pnpm dev ``` - 前端:[http://localhost:5173](http://localhost:5173) - 后端 API:[http://localhost:3001/api](http://localhost:3001/api) 生产式启动(Express 托管构建后的前端): ```bash pnpm build pnpm start ``` 访问 [http://localhost:3001](http://localhost:3001) ### 单文本生成 1. 打开 **工作台**(`/`) 2. 输入文本或上传 `.txt` 3. 选择 AI 模式(可选 **不优化**) 4. **AI 优化**(可选)→ 编辑 TTS 文本、插入情绪标签 5. 配置音色绑定与 Fish 参数 6. **预览 / 生成音频**(下载文件名含时间戳) ### 批量 TXT 生成 1. 打开 **批量生成**(`/batch`) 2. 上传多个 `.txt`(逐文件 AI 优化) 3. 设置全局或单文件音色绑定 4. **批量生成并打包 ZIP** ### 多角色工作室 1. 打开 **多角色工作室**(`/studio`) 2. 粘贴长文本 → **AI 分角色**(默认 `deepseek-v4-pro`) 3. 可选:自动或手动 **AI 复查** 遗漏片段 4. 每角色:**试听** → **重新生成** → **锁定为角色音色**(写入克隆历史) 5. **预览队列** / **终稿队列 + 合并** → 下载合并音频与导出文件 ### 音色库 - **角色克隆历史** — Studio 锁定音色后自动记录 - **我的克隆** — Fish 账户音色列表 - 列表分段加载;训练状态需手动 **刷新状态** - **移除记录** 仅删除本地注册信息,不删除 Fish 云端模型 ### reference_id 用法 1. 在 **音色库** 复制音色 `_id` 2. 音色绑定选 `reference_id` 并粘贴 curl 示例(密钥放在服务端环境变量,不要写进前端): ```bash curl --request POST \ --url https://api.fish.audio/v1/tts \ --header "Authorization: Bearer $FISH_API_KEY" \ --header "Content-Type: application/json" \ --header "model: s2.1-pro-free" \ --data '{"text":"你好","reference_id":"YOUR_VOICE_ID","format":"mp3"}' ``` ### 即时克隆 1. 准备参考音频与准确转写 2. 音色绑定 → **即时克隆** → 上传样本 3. 后端通过 MessagePack 调用 Fish(JSON 中不使用 base64) ### 持久克隆 1. **音色库** 上传样本 → **创建克隆**(`train_mode: fast`) 2. 或在 Studio 试听后 **锁定为角色音色** 3. 等待 `state === trained` 后再用于批量/工作室生成 ### Fish s2.1-pro-free 主要参数 | 参数 | 说明 | 默认 | |------|------|------| | `format` | mp3 / wav / pcm / opus | mp3 | | `sample_rate` | 采样率 | 44100 | | `mp3_bitrate` | 64 / 128 / 192 | 128 | | `latency` | normal / balanced / low | normal | | `temperature` | 表现力 0–1 | 0.7 | | `top_p` | 核采样 0–1 | 0.7 | | `prosody.speed` | 语速 | 1.0 | | `chunk_length` | 分块长度 100–300 | 300 | | `normalize` | 文本标准化 | true | UI 预设:高质量旁白、快速预览、实时、长文本稳定。 ### DeepSeek 模型 - 默认 `deepseek-v4-flash`;Studio 分角色默认 `deepseek-v4-pro` - 兼容 OpenAI 的 `POST /chat/completions`,`response_format: json_object` - `mode: none` 跳过 DeepSeek,直接透传文本 ### 常见问题 | 现象 | 处理 | |------|------| | `FISH_API_KEY is not configured` | 在 `.env` 填入密钥并重启后端 | | `DEEPSEEK_API_KEY is not configured` | 同上 | | `ffmpeg is not installed` | 安装 ffmpeg 并验证 `ffmpeg -version` | | Fish 401/402 | 检查密钥与账户余额 | | 克隆一直 `training` | 在音色库点 **刷新状态** | | 克隆历史出现重复角色 | 删除多余项;同 `role_id` 现已自动合并为一条 | | 跑 `pnpm test` 后又出现假数据 | 测试已改用临时目录,不会写入项目 `outputs/` | ### 安全与隐私 - **切勿**提交 `.env`、`.env.local` 或真实 API 密钥 - `.gitignore` 已忽略 `outputs/`、`uploads/`、`temp/` 及除 `.env.example` 外的所有 `.env*` - Fish / DeepSeek 请求均经 Express 后端转发 - 持久克隆默认 `visibility: private` - 生成的音频与注册表 JSON 在本地 `outputs/` — 若文稿涉密请妥善保管 - 若密钥曾误提交或外泄,请立即在 Fish / DeepSeek 控制台**轮换密钥** ### 项目结构 ``` voxweaver-studio/ client/ Vite + React + TypeScript 前端(i18n) server/ Express + TypeScript API shared/ 类型、zod 校验、纯逻辑 outputs/ 生成音频、项目、voice-registry(已 gitignore) uploads/ 上传的参考音频(已 gitignore) temp/ 临时合并/静音文件(已 gitignore) ``` ### 测试 ```bash pnpm test ``` 集成测试使用 nock 模拟 Fish/DeepSeek,输出写入**系统临时目录**,不会污染项目 `outputs/`。 ### 许可 本地开发工具 — 请遵守 Fish Audio 与 DeepSeek 服务条款。