[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-travisvn--openai-edge-tts":3,"tool-travisvn--openai-edge-tts":62},[4,18,26,36,46,54],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":17},4358,"openclaw","openclaw\u002Fopenclaw","OpenClaw 是一款专为个人打造的本地化 AI 助手，旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚，能够直接接入你日常使用的各类通讯渠道，包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息，OpenClaw 都能即时响应，甚至支持在 macOS、iOS 和 Android 设备上进行语音交互，并提供实时的画布渲染功能供你操控。\n\n这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地，用户无需依赖云端服务即可享受快速、私密的智能辅助，真正实现了“你的数据，你做主”。其独特的技术亮点在于强大的网关架构，将控制平面与核心助手分离，确保跨平台通信的流畅性与扩展性。\n\nOpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者，以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力（支持 macOS、Linux 及 Windows WSL2），即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你",349277,3,"2026-04-06T06:32:30",[13,14,15,16],"Agent","开发框架","图像","数据工具","ready",{"id":19,"name":20,"github_repo":21,"description_zh":22,"stars":23,"difficulty_score":10,"last_commit_at":24,"category_tags":25,"status":17},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,"2026-04-05T11:01:52",[14,15,13],{"id":27,"name":28,"github_repo":29,"description_zh":30,"stars":31,"difficulty_score":32,"last_commit_at":33,"category_tags":34,"status":17},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",159636,2,"2026-04-17T23:33:34",[14,13,35],"语言模型",{"id":37,"name":38,"github_repo":39,"description_zh":40,"stars":41,"difficulty_score":42,"last_commit_at":43,"category_tags":44,"status":17},8272,"opencode","anomalyco\u002Fopencode","OpenCode 是一款开源的 AI 编程助手（Coding Agent），旨在像一位智能搭档一样融入您的开发流程。它不仅仅是一个代码补全插件，而是一个能够理解项目上下文、自主规划任务并执行复杂编码操作的智能体。无论是生成全新功能、重构现有代码，还是排查难以定位的 Bug，OpenCode 都能通过自然语言交互高效完成，显著减少开发者在重复性劳动和上下文切换上的时间消耗。\n\n这款工具专为软件开发者、工程师及技术研究人员设计，特别适合希望利用大模型能力来提升编码效率、加速原型开发或处理遗留代码维护的专业人群。其核心亮点在于完全开源的架构，这意味着用户可以审查代码逻辑、自定义行为策略，甚至私有化部署以保障数据安全，彻底打破了传统闭源 AI 助手的“黑盒”限制。\n\n在技术体验上，OpenCode 提供了灵活的终端界面（Terminal UI）和正在测试中的桌面应用程序，支持 macOS、Windows 及 Linux 全平台。它兼容多种包管理工具，安装便捷，并能无缝集成到现有的开发环境中。无论您是追求极致控制权的资深极客，还是渴望提升产出的独立开发者，OpenCode 都提供了一个透明、可信",144296,1,"2026-04-16T14:50:03",[13,45],"插件",{"id":47,"name":48,"github_repo":49,"description_zh":50,"stars":51,"difficulty_score":32,"last_commit_at":52,"category_tags":53,"status":17},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",108322,"2026-04-10T11:39:34",[14,15,13],{"id":55,"name":56,"github_repo":57,"description_zh":58,"stars":59,"difficulty_score":32,"last_commit_at":60,"category_tags":61,"status":17},6121,"gemini-cli","google-gemini\u002Fgemini-cli","gemini-cli 是一款由谷歌推出的开源 AI 命令行工具，它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言，它提供了一条从输入提示词到获取模型响应的最短路径，无需切换窗口即可享受智能辅助。\n\n这款工具主要解决了开发过程中频繁上下文切换的痛点，让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用，还是执行复杂的 Git 操作，gemini-cli 都能通过自然语言指令高效处理。\n\n它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口，具备出色的逻辑推理能力；内置 Google 搜索、文件操作及 Shell 命令执行等实用工具；更独特的是，它支持 MCP（模型上下文协议），允许用户灵活扩展自定义集成，连接如图像生成等外部能力。此外，个人谷歌账号即可享受免费的额度支持，且项目基于 Apache 2.0 协议完全开源，是提升终端工作效率的理想助手。",100752,"2026-04-10T01:20:03",[45,13,15,14],{"id":63,"github_repo":64,"name":65,"description_en":66,"description_zh":67,"ai_summary_zh":68,"readme_en":69,"readme_zh":70,"quickstart_zh":71,"use_case_zh":72,"hero_image_url":73,"owner_login":74,"owner_name":75,"owner_avatar_url":76,"owner_bio":77,"owner_company":77,"owner_location":78,"owner_email":79,"owner_twitter":80,"owner_website":81,"owner_url":82,"languages":83,"stars":91,"forks":92,"last_commit_at":93,"license":94,"difficulty_score":32,"env_os":95,"env_gpu":96,"env_ram":97,"env_deps":98,"category_tags":107,"github_topics":109,"view_count":32,"oss_zip_url":77,"oss_zip_packed_at":77,"status":17,"created_at":128,"updated_at":129,"faqs":130,"releases":160},8806,"travisvn\u002Fopenai-edge-tts","openai-edge-tts","Free, high-quality text-to-speech API endpoint to replace OpenAI, Azure, or ElevenLabs","openai-edge-tts 是一个开源的本地文本转语音（TTS）API 服务，旨在为开发者提供完全免费且高质量的语音合成替代方案。它巧妙利用微软 Edge 浏览器的在线 TTS 服务，完美模拟了 OpenAI 的 `\u002Fv1\u002Faudio\u002Fspeech` 接口行为。这意味着用户无需支付 OpenAI、Azure 或 ElevenLabs 等商业服务的昂贵费用，即可在本地部署环境中生成自然流畅的语音内容。\n\n该工具主要解决了高昂的 API 调用成本问题，同时消除了对外部付费服务的依赖。它特别适合需要集成语音功能的软件开发人员、希望降低原型开发成本的研究者，以及正在寻找免费替代方案的技术团队。对于熟悉 OpenAI 接口的用户而言，迁移成本几乎为零，只需更改服务端点即可无缝切换。\n\n技术亮点方面，openai-edge-tts 不仅支持将 OpenAI 的经典音色（如 alloy、nova 等）自动映射到对应的 Edge 高质量嗓音，还允许直接指定数百种 Edge 原生语音。它具备灵活的音频格式转换能力（支持 mp3、wav、opus 等），可调节语速（0.25 倍至 4.0 倍），并原生","openai-edge-tts 是一个开源的本地文本转语音（TTS）API 服务，旨在为开发者提供完全免费且高质量的语音合成替代方案。它巧妙利用微软 Edge 浏览器的在线 TTS 服务，完美模拟了 OpenAI 的 `\u002Fv1\u002Faudio\u002Fspeech` 接口行为。这意味着用户无需支付 OpenAI、Azure 或 ElevenLabs 等商业服务的昂贵费用，即可在本地部署环境中生成自然流畅的语音内容。\n\n该工具主要解决了高昂的 API 调用成本问题，同时消除了对外部付费服务的依赖。它特别适合需要集成语音功能的软件开发人员、希望降低原型开发成本的研究者，以及正在寻找免费替代方案的技术团队。对于熟悉 OpenAI 接口的用户而言，迁移成本几乎为零，只需更改服务端点即可无缝切换。\n\n技术亮点方面，openai-edge-tts 不仅支持将 OpenAI 的经典音色（如 alloy、nova 等）自动映射到对应的 Edge 高质量嗓音，还允许直接指定数百种 Edge 原生语音。它具备灵活的音频格式转换能力（支持 mp3、wav、opus 等），可调节语速（0.25 倍至 4.0 倍），并原生支持 SSE 实时音频流传输。通过 Docker 一键部署的特性，让搭建过程变得异常简单，是构建低成本语音应用的理想选择。","# OpenAI-Compatible Edge-TTS API 🗣️\n\n![GitHub stars](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002Ftravisvn\u002Fopenai-edge-tts?style=social)\n![GitHub forks](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fforks\u002Ftravisvn\u002Fopenai-edge-tts?style=social)\n![GitHub repo size](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Frepo-size\u002Ftravisvn\u002Fopenai-edge-tts)\n![GitHub top language](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flanguages\u002Ftop\u002Ftravisvn\u002Fopenai-edge-tts)\n![GitHub last commit](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flast-commit\u002Ftravisvn\u002Fopenai-edge-tts?color=red)\n[![Discord](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDiscord-Voice_AI_%26_TTS_Tools-blue?logo=discord&logoColor=white)](https:\u002F\u002Fdiscord.gg\u002FGkFbBCBqJ6)\n[![LinkedIn](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FConnect_on_LinkedIn-%230077B5.svg?logo=linkedin&logoColor=white)](https:\u002F\u002Flinkedin.com\u002Fin\u002Ftravisvannimwegen)\n\nThis project provides a local, OpenAI-compatible text-to-speech (TTS) API using `edge-tts`. It emulates the OpenAI TTS endpoint (`\u002Fv1\u002Faudio\u002Fspeech`), enabling users to generate speech from text with various voice options and playback speeds, just like the OpenAI API.\n\n`edge-tts` uses Microsoft Edge's online text-to-speech service, so it is completely free.\n\n[View this project on Docker Hub](https:\u002F\u002Fhub.docker.com\u002Fr\u002Ftravisvn\u002Fopenai-edge-tts)\n\n# Please ⭐️ star this repo if you find it helpful\n\n## Features\n\n- **OpenAI-Compatible Endpoint**: `\u002Fv1\u002Faudio\u002Fspeech` with similar request structure and behavior.\n- **SSE Streaming Support**: Real-time audio streaming via Server-Sent Events when `stream_format: \"sse\"` is specified.\n- **Supported Voices**: Maps OpenAI voices (alloy, echo, fable, onyx, nova, shimmer) to `edge-tts` equivalents.\n- **Flexible Formats**: Supports multiple audio formats (mp3, opus, aac, flac, wav, pcm).\n- **Adjustable Speed**: Option to modify playback speed (0.25x to 4.0x).\n- **Optional Direct Edge-TTS Voice Selection**: Use either OpenAI voice mappings or specify [any edge-tts voice](https:\u002F\u002Ftts.travisvn.com) directly.\n\n## ⚡️ Quick start\n\nThe simplest way to get started without having to configure anything is to run the command below\n\n```bash\ndocker run -d -p 5050:5050 travisvn\u002Fopenai-edge-tts:latest\n```\n\nThis will run the service at port 5050 with all the default configs\n\n_(Docker required, obviously)_\n\n## Setup\n\n### Prerequisites\n\n- **Docker** (recommended): Docker and Docker Compose for containerized setup.\n- **Python** (optional): For local development, install dependencies in `requirements.txt`.\n- **ffmpeg** (optional): Required for audio format conversion. Optional if sticking to mp3.\n\n### Installation\n\n1. **Clone the Repository**:\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts.git\ncd openai-edge-tts\n```\n\n2. **Environment Variables**: Create a `.env` file in the root directory with the following variables:\n\n```\nAPI_KEY=your_api_key_here\nPORT=5050\n\nDEFAULT_VOICE=en-US-AvaNeural\nDEFAULT_RESPONSE_FORMAT=mp3\nDEFAULT_SPEED=1.0\n\nDEFAULT_LANGUAGE=en-US\n\nREQUIRE_API_KEY=True\nREMOVE_FILTER=False\nEXPAND_API=True\nDETAILED_ERROR_LOGGING=True\n```\n\nOr, copy the default `.env.example` with the following:\n\n```bash\ncp .env.example .env\n```\n\n3. **Run with Docker Compose** (recommended):\n\n```bash\ndocker compose up --build\n```\n\nRun with `-d` to run docker compose in \"detached mode\", meaning it will run in the background and free up your terminal.\n\n```bash\ndocker compose up -d\n```\n\n\u003Cdetails>\n\u003Csummary>\n\n#### Building Locally with FFmpeg using Docker Compose\n\n\u003C\u002Fsummary>\n\nBy default, `docker compose up --build` creates a minimal image _without_ `ffmpeg`. If you're building locally (after cloning this repository) and need `ffmpeg` for audio format conversions (beyond MP3), you can include it in the build.\n\nThis is controlled by the `INSTALL_FFMPEG_ARG` build argument. Set this environment variable to `true` in one of these ways:\n\n1.  **Prefixing the command:**\n    ```bash\n    INSTALL_FFMPEG_ARG=true docker compose up --build\n    ```\n2.  **Adding to your `.env` file:**\n    Add this line to the `.env` file in the project root:\n    ```env\n    INSTALL_FFMPEG_ARG=true\n    ```\n    Then, run `docker compose up --build`.\n3.  **Exporting in your shell environment:**\n    Add `export INSTALL_FFMPEG_ARG=true` to your shell configuration (e.g., `~\u002F.zshrc`, `~\u002F.bashrc`) and reload your shell. Then `docker compose up --build` will use it.\n\nThis is for local builds. For pre-built Docker Hub images, add the `latest-ffmpeg` tag to the version\n\n```bash\ndocker run -d -p 5050:5050 -e API_KEY=your_api_key_here -e PORT=5050 travisvn\u002Fopenai-edge-tts:latest-ffmpeg\n```\n\n---\n\n\u003C\u002Fdetails>\n\nAlternatively, **run directly with Docker**:\n\n```bash\ndocker build -t openai-edge-tts .\ndocker run -p 5050:5050 --env-file .env openai-edge-tts\n```\n\nTo run the container in the background, add `-d` after the `docker run` command:\n\n```bash\ndocker run -d -p 5050:5050 --env-file .env openai-edge-tts\n```\n\n4. **Access the API**: Your server will be accessible at `http:\u002F\u002Flocalhost:5050`.\n\n\u003Cdetails>\n\u003Csummary>\n\n## Running with Python\n\n\u003C\u002Fsummary>\n\nIf you prefer to run this project directly with Python, follow these steps to set up a virtual environment, install dependencies, and start the server.\n\n### 1. Clone the Repository\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts.git\ncd openai-edge-tts\n```\n\n### 2. Set Up a Virtual Environment\n\nCreate and activate a virtual environment to isolate dependencies:\n\n```bash\n# For macOS\u002FLinux\npython3 -m venv venv\nsource venv\u002Fbin\u002Factivate\n\n# For Windows\npython -m venv venv\nvenv\\Scripts\\activate\n```\n\n### 3. Install Dependencies\n\nUse `pip` to install the required packages listed in `requirements.txt`:\n\n```bash\npip install -r requirements.txt\n```\n\n### 4. Configure Environment Variables\n\nCreate a `.env` file in the root directory and set the following variables:\n\n```plaintext\nAPI_KEY=your_api_key_here\nPORT=5050\n\nDEFAULT_VOICE=en-US-AvaNeural\nDEFAULT_RESPONSE_FORMAT=mp3\nDEFAULT_SPEED=1.0\n\nDEFAULT_LANGUAGE=en-US\n\nREQUIRE_API_KEY=True\nREMOVE_FILTER=False\nEXPAND_API=True\nDETAILED_ERROR_LOGGING=True\n```\n\n### 5. Run the Server\n\nOnce configured, start the server with:\n\n```bash\npython app\u002Fserver.py\n```\n\nThe server will start running at `http:\u002F\u002Flocalhost:5050`.\n\n### 6. Test the API\n\nYou can now interact with the API at `http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech` and other available endpoints. See the [Usage](#usage) section for request examples.\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\n\n## Usage\n\n\u003C\u002Fsummary>\n\n#### Endpoint: `\u002Fv1\u002Faudio\u002Fspeech`\n\nGenerates audio from the input text. Available parameters:\n\n**Required Parameter:**\n\n- **input** (string): The text to be converted to audio (up to 4096 characters).\n\n**Optional Parameters:**\n\n- **model** (string): Set to \"tts-1\" or \"tts-1-hd\" (default: `\"tts-1\"`).\n- **voice** (string): One of the OpenAI-compatible voices (alloy, echo, fable, onyx, nova, shimmer) or any valid `edge-tts` voice (default: `\"en-US-AvaNeural\"`).\n- **response_format** (string): Audio format. Options: `mp3`, `opus`, `aac`, `flac`, `wav`, `pcm` (default: `mp3`).\n- **speed** (number): Playback speed (0.25 to 4.0). Default is `1.0`.\n- **stream_format** (string): Response format. Options: `\"audio\"` (raw audio data, default) or `\"sse\"` (Server-Sent Events streaming with JSON events).\n\n**Note:** The API is fully compatible with OpenAI's TTS API specification. The `instructions` parameter (for fine-tuning voice characteristics) is not currently supported, but all other parameters work identically to OpenAI's implementation.\n\n#### Standard Audio Generation\n\nExample request with `curl` and saving the output to an mp3 file:\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -d '{\n    \"input\": \"Hello, I am your AI assistant! Just let me know how I can help bring your ideas to life.\",\n    \"voice\": \"echo\",\n    \"response_format\": \"mp3\",\n    \"speed\": 1.1\n  }' \\\n  --output speech.mp3\n```\n\n#### Direct Audio Playback (like OpenAI)\n\nYou can pipe the audio directly to `ffplay` for immediate playback, just like OpenAI's API:\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"model\": \"tts-1\",\n    \"input\": \"Today is a wonderful day to build something people love!\",\n    \"voice\": \"alloy\",\n    \"response_format\": \"mp3\"\n  }' | ffplay -i -\n```\n\nOr for immediate playback without saving to file:\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"input\": \"This will play immediately without saving to disk!\",\n    \"voice\": \"shimmer\"\n  }' | ffplay -autoexit -nodisp -i -\n```\n\nOr, to be in line with the OpenAI API endpoint parameters:\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -d '{\n    \"model\": \"tts-1\",\n    \"input\": \"Hello, I am your AI assistant! Just let me know how I can help bring your ideas to life.\",\n    \"voice\": \"alloy\"\n  }' \\\n  --output speech.mp3\n```\n\n#### Server-Sent Events (SSE) Streaming\n\nFor applications that need structured streaming events (like web applications), use SSE format:\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -d '{\n    \"model\": \"tts-1\",\n    \"input\": \"This will stream as Server-Sent Events with JSON data containing base64-encoded audio chunks.\",\n    \"voice\": \"alloy\",\n    \"stream_format\": \"sse\"\n  }'\n```\n\n**SSE Response Format:**\n\n```\ndata: {\"type\": \"speech.audio.delta\", \"audio\": \"base64-encoded-audio-chunk\"}\n\ndata: {\"type\": \"speech.audio.delta\", \"audio\": \"base64-encoded-audio-chunk\"}\n\ndata: {\"type\": \"speech.audio.done\", \"usage\": {\"input_tokens\": 12, \"output_tokens\": 0, \"total_tokens\": 12}}\n```\n\n#### JavaScript\u002FWeb Usage\n\nExample using fetch API for SSE streaming:\n\n```javascript\nasync function streamTTSWithSSE(text) {\n  const response = await fetch('http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application\u002Fjson',\n      Authorization: 'Bearer your_api_key_here',\n    },\n    body: JSON.stringify({\n      input: text,\n      voice: 'alloy',\n      stream_format: 'sse',\n    }),\n  });\n\n  const reader = response.body.getReader();\n  const decoder = new TextDecoder();\n  const audioChunks = [];\n\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n\n    const chunk = decoder.decode(value);\n    const lines = chunk.split('\\n');\n\n    for (const line of lines) {\n      if (line.startsWith('data: ')) {\n        const data = JSON.parse(line.slice(6));\n\n        if (data.type === 'speech.audio.delta') {\n          \u002F\u002F Decode base64 audio chunk\n          const audioData = atob(data.audio);\n          const audioArray = new Uint8Array(audioData.length);\n          for (let i = 0; i \u003C audioData.length; i++) {\n            audioArray[i] = audioData.charCodeAt(i);\n          }\n          audioChunks.push(audioArray);\n        } else if (data.type === 'speech.audio.done') {\n          console.log('Speech synthesis complete:', data.usage);\n\n          \u002F\u002F Combine all chunks and play\n          const totalLength = audioChunks.reduce(\n            (sum, chunk) => sum + chunk.length,\n            0\n          );\n          const combinedArray = new Uint8Array(totalLength);\n          let offset = 0;\n          for (const chunk of audioChunks) {\n            combinedArray.set(chunk, offset);\n            offset += chunk.length;\n          }\n\n          const audioBlob = new Blob([combinedArray], { type: 'audio\u002Fmpeg' });\n          const audioUrl = URL.createObjectURL(audioBlob);\n          const audio = new Audio(audioUrl);\n          audio.play();\n          return;\n        }\n      }\n    }\n  }\n}\n\n\u002F\u002F Usage\nstreamTTSWithSSE('Hello from SSE streaming!');\n```\n\n#### International Language Example\n\nAnd an example of a language other than English:\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -d '{\n    \"model\": \"tts-1\",\n    \"input\": \"じゃあ、行く。電車の時間、調べておくよ。\",\n    \"voice\": \"ja-JP-KeitaNeural\"\n  }' \\\n  --output speech.mp3\n```\n\n#### JavaScript\u002FWeb Usage\n\nExample using fetch API for SSE streaming:\n\n```javascript\nasync function streamTTSWithSSE(text) {\n  const response = await fetch('http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application\u002Fjson',\n      Authorization: 'Bearer your_api_key_here',\n    },\n    body: JSON.stringify({\n      input: text,\n      voice: 'alloy',\n      stream_format: 'sse',\n    }),\n  });\n\n  const reader = response.body.getReader();\n  const decoder = new TextDecoder();\n  const audioChunks = [];\n\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n\n    const chunk = decoder.decode(value);\n    const lines = chunk.split('\\n');\n\n    for (const line of lines) {\n      if (line.startsWith('data: ')) {\n        const data = JSON.parse(line.slice(6));\n\n        if (data.type === 'speech.audio.delta') {\n          \u002F\u002F Decode base64 audio chunk\n          const audioData = atob(data.audio);\n          const audioArray = new Uint8Array(audioData.length);\n          for (let i = 0; i \u003C audioData.length; i++) {\n            audioArray[i] = audioData.charCodeAt(i);\n          }\n          audioChunks.push(audioArray);\n        } else if (data.type === 'speech.audio.done') {\n          console.log('Speech synthesis complete:', data.usage);\n\n          \u002F\u002F Combine all chunks and play\n          const totalLength = audioChunks.reduce(\n            (sum, chunk) => sum + chunk.length,\n            0\n          );\n          const combinedArray = new Uint8Array(totalLength);\n          let offset = 0;\n          for (const chunk of audioChunks) {\n            combinedArray.set(chunk, offset);\n            offset += chunk.length;\n          }\n\n          const audioBlob = new Blob([combinedArray], { type: 'audio\u002Fmpeg' });\n          const audioUrl = URL.createObjectURL(audioBlob);\n          const audio = new Audio(audioUrl);\n          audio.play();\n          return;\n        }\n      }\n    }\n  }\n}\n\n\u002F\u002F Usage\nstreamTTSWithSSE('Hello from SSE streaming!');\n```\n\n#### Additional Endpoints\n\n- **POST\u002FGET \u002Fv1\u002Fmodels**: Lists available TTS models.\n- **POST\u002FGET \u002Fv1\u002Fvoices**: Lists `edge-tts` voices for a given language \u002F locale.\n- **POST\u002FGET \u002Fv1\u002Fvoices\u002Fall**: Lists all `edge-tts` voices, with language support information.\n\n\u003C\u002Fdetails>\n\n### Contributing\n\nContributions are welcome! Please fork the repository and create a pull request for any improvements.\n\n### License\n\nThis project is licensed under GNU General Public License v3.0 (GPL-3.0), and the acceptable use-case is intended to be personal use. For enterprise or non-personal use of `openai-edge-tts`, contact me at tts@travisvn.com\n\n---\n\n## Example Use Case\n\n> [!TIP]\n> Swap `localhost` to your local IP (ex. `192.168.0.1`) if you have issues\n>\n> _It may be the case that, when accessing this endpoint on a different server \u002F computer or when the call is made from another source (like Open WebUI), you need to change the URL from `localhost` to your local IP (something like `192.168.0.1` or similar)_\n\n# Open WebUI\n\nOpen up the Admin Panel and go to Settings -> Audio\n\nBelow, you can see a screenshot of the correct configuration for using this project to substitute the OpenAI endpoint\n\n![Screenshot of Open WebUI Admin Settings for Audio adding the correct endpoints for this project](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Ftravisvn_openai-edge-tts_readme_6ccf44338313.png)\n\nIf you're running both Open WebUI and this project in Docker, the API endpoint URL is probably `http:\u002F\u002Fhost.docker.internal:5050\u002Fv1`\n\n> [!NOTE]\n> View the official docs for [Open WebUI integration with OpenAI Edge TTS](https:\u002F\u002Fdocs.openwebui.com\u002Ftutorials\u002Ftext-to-speech\u002Fopenai-edge-tts-integration)\n\n# AnythingLLM\n\nIn version 1.6.8, AnythingLLM added support for \"generic OpenAI TTS providers\" — meaning we can use this project as the TTS provider in AnythingLLM\n\nOpen up settings and go to Voice & Speech (Under AI Providers)\n\nBelow, you can see a screenshot of the correct configuration for using this project to substitute the OpenAI endpoint\n\n![Screenshot of AnythingLLM settings for Voice adding the correct endpoints for this project](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Ftravisvn_openai-edge-tts_readme_c33fbbc6b573.png)\n\n---\n\n## Quick Info\n\n- `your_api_key_here` never needs to be replaced — No \"real\" API key is required. Use whichever string you'd like.\n- The quickest way to get this up and running is to install docker and run the command below:\n\n```bash\ndocker run -d -p 5050:5050 -e API_KEY=your_api_key_here -e PORT=5050 travisvn\u002Fopenai-edge-tts:latest\n```\n\n---\n\n# Voice Samples 🎙️\n\n[Play voice samples and see all available Edge TTS voices](https:\u002F\u002Ftts.travisvn.com\u002F)\n","# 兼容 OpenAI 的 Edge-TTS API 🗣️\n\n![GitHub 星标](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002Ftravisvn\u002Fopenai-edge-tts?style=social)\n![GitHub 分支](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fforks\u002Ftravisvn\u002Fopenai-edge-tts?style=social)\n![GitHub 仓库大小](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Frepo-size\u002Ftravisvn\u002Fopenai-edge-tts)\n![GitHub 主要语言](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flanguages\u002Ftop\u002Ftravisvn\u002Fopenai-edge-tts)\n![GitHub 最后一次提交](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flast-commit\u002Ftravisvn\u002Fopenai-edge-tts?color=red)\n[![Discord](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDiscord-Voice_AI_%26_TTS_Tools-blue?logo=discord&logoColor=white)](https:\u002F\u002Fdiscord.gg\u002FGkFbBCBqJ6)\n[![LinkedIn](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FConnect_on_LinkedIn-%230077B5.svg?logo=linkedin&logoColor=white)](https:\u002F\u002Flinkedin.com\u002Fin\u002Ftravisvannimwegen)\n\n本项目使用 `edge-tts` 提供了一个本地的、兼容 OpenAI 的文本转语音（TTS）API。它模拟了 OpenAI TTS 端点 (`\u002Fv1\u002Faudio\u002Fspeech`)，使用户能够像使用 OpenAI API 一样，通过多种语音选项和播放速度从文本生成语音。\n\n`edge-tts` 使用 Microsoft Edge 的在线文本转语音服务，因此完全免费。\n\n[在 Docker Hub 上查看此项目](https:\u002F\u002Fhub.docker.com\u002Fr\u002Ftravisvn\u002Fopenai-edge-tts)\n\n# 如果你觉得这个项目有用，请 ⭐️ 给它加星吧\n\n## 特性\n\n- **兼容 OpenAI 的端点**：`\u002Fv1\u002Faudio\u002Fspeech` 具有相似的请求结构和行为。\n- **SSE 流式传输支持**：当指定 `stream_format: \"sse\"` 时，可通过服务器发送事件进行实时音频流传输。\n- **支持的语音**：将 OpenAI 语音（alloy、echo、fable、onyx、nova、shimmer）映射到 `edge-tts` 对应的语音。\n- **灵活的格式**：支持多种音频格式（mp3、opus、aac、flac、wav、pcm）。\n- **可调速度**：可调整播放速度（0.25 倍至 4.0 倍）。\n- **可选直接选择 edge-tts 语音**：既可以使用 OpenAI 语音映射，也可以直接指定 [任意 edge-tts 语音](https:\u002F\u002Ftts.travisvn.com)。\n\n## ⚡️ 快速入门\n\n无需任何配置的最简单方式是运行以下命令：\n\n```bash\ndocker run -d -p 5050:5050 travisvn\u002Fopenai-edge-tts:latest\n```\n\n这将在端口 5050 上以所有默认配置运行该服务。\n\n_（显然需要 Docker）_\n\n## 设置\n\n### 先决条件\n\n- **Docker**（推荐）：用于容器化部署的 Docker 和 Docker Compose。\n- **Python**（可选）：用于本地开发，安装 `requirements.txt` 中的依赖项。\n- **ffmpeg**（可选）：进行音频格式转换时需要。如果只使用 mp3 格式，则可选。\n\n### 安装\n\n1. **克隆仓库**：\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts.git\ncd openai-edge-tts\n```\n\n2. **环境变量**：在根目录下创建一个 `.env` 文件，设置以下变量：\n\n```\nAPI_KEY=your_api_key_here\nPORT=5050\n\nDEFAULT_VOICE=en-US-AvaNeural\nDEFAULT_RESPONSE_FORMAT=mp3\nDEFAULT_SPEED=1.0\n\nDEFAULT_LANGUAGE=en-US\n\nREQUIRE_API_KEY=True\nREMOVE_FILTER=False\nEXPAND_API=True\nDETAILED_ERROR_LOGGING=True\n```\n\n或者复制默认的 `.env.example` 文件：\n\n```bash\ncp .env.example .env\n```\n\n3. **使用 Docker Compose 运行**（推荐）：\n\n```bash\ndocker compose up --build\n```\n\n加上 `-d` 参数可在“分离模式”下运行 Docker Compose，即在后台运行并释放您的终端。\n\n```bash\ndocker compose up -d\n```\n\n\u003Cdetails>\n\u003Csummary>\n\n#### 使用 Docker Compose 在本地构建并包含 ffmpeg\n\n\u003C\u002Fsummary>\n\n默认情况下，`docker compose up --build` 会创建一个不包含 `ffmpeg` 的最小镜像。如果您是在本地构建（克隆此仓库后），并且需要 `ffmpeg` 进行除 MP3 外的其他音频格式转换，可以在构建过程中将其包含进来。\n\n这由 `INSTALL_FFMPEG_ARG` 构建参数控制。您可以通过以下任一方式将此环境变量设置为 `true`：\n\n1.  **在命令前添加：**\n    ```bash\n    INSTALL_FFMPEG_ARG=true docker compose up --build\n    ```\n2.  **添加到您的 `.env` 文件中：**\n    将以下行添加到项目根目录下的 `.env` 文件中：\n    ```env\n    INSTALL_FFMPEG_ARG=true\n    ```\n    然后运行 `docker compose up --build`。\n3.  **在您的 shell 环境中导出：**\n    将 `export INSTALL_FFMPEG_ARG=true` 添加到您的 shell 配置文件（例如 `~\u002F.zshrc`、`~\u002F.bashrc`），并重新加载 shell。然后 `docker compose up --build` 将会使用该设置。\n\n以上适用于本地构建。对于预构建的 Docker Hub 镜像，请在版本号后添加 `latest-ffmpeg` 标签：\n\n```bash\ndocker run -d -p 5050:5050 -e API_KEY=your_api_key_here -e PORT=5050 travisvn\u002Fopenai-edge-tts:latest-ffmpeg\n```\n\n---\n\n\u003C\u002Fdetails>\n\n或者，您可以直接使用 Docker 运行：\n\n```bash\ndocker build -t openai-edge-tts .\ndocker run -p 5050:5050 --env-file .env openai-edge-tts\n```\n\n要在后台运行容器，可以在 `docker run` 命令后添加 `-d`：\n\n```bash\ndocker run -d -p 5050:5050 --env-file .env openai-edge-tts\n```\n\n4. **访问 API**：您的服务器将可通过 `http:\u002F\u002Flocalhost:5050` 访问。\n\n\u003Cdetails>\n\u003Csummary>\n\n## 使用 Python 运行\n\n\u003C\u002Fsummary>\n\n如果您更倾向于直接使用 Python 运行该项目，可以按照以下步骤设置虚拟环境、安装依赖项并启动服务器。\n\n### 1. 克隆仓库\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts.git\ncd openai-edge-tts\n```\n\n### 2. 设置虚拟环境\n\n创建并激活虚拟环境以隔离依赖项：\n\n```bash\n# 对于 macOS\u002FLinux\npython3 -m venv venv\nsource venv\u002Fbin\u002Factivate\n\n# 对于 Windows\npython -m venv venv\nvenv\\Scripts\\activate\n```\n\n### 3. 安装依赖项\n\n使用 `pip` 安装 `requirements.txt` 中列出的所需包：\n\n```bash\npip install -r requirements.txt\n```\n\n### 4. 配置环境变量\n\n在根目录下创建一个 `.env` 文件，并设置以下变量：\n\n```plaintext\nAPI_KEY=your_api_key_here\nPORT=5050\n\nDEFAULT_VOICE=en-US-AvaNeural\nDEFAULT_RESPONSE_FORMAT=mp3\nDEFAULT_SPEED=1.0\n\nDEFAULT_LANGUAGE=en-US\n\nREQUIRE_API_KEY=True\nREMOVE_FILTER=False\nEXPAND_API=True\nDETAILED_ERROR_LOGGING=True\n```\n\n### 5. 启动服务器\n\n配置完成后，使用以下命令启动服务器：\n\n```bash\npython app\u002Fserver.py\n```\n\n服务器将在 `http:\u002F\u002Flocalhost:5050` 上开始运行。\n\n### 6. 测试 API\n\n现在您可以通过 `http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech` 及其他可用端点与 API 交互。请参阅【使用说明】部分获取请求示例。\n\n\u003C\u002Fdetails>\n\n\u003Cdetails>\n\u003Csummary>\n\n## 使用说明\n\n\u003C\u002Fsummary>\n\n#### 端点：`\u002Fv1\u002Faudio\u002Fspeech`\n\n根据输入文本生成音频。可用参数如下：\n\n**必填参数：**\n\n- **input**（字符串）：要转换为音频的文本（最多 4096 个字符）。\n\n**可选参数：**\n\n- **model**（字符串）：设置为 \"tts-1\" 或 \"tts-1-hd\"（默认值为 `\"tts-1\"`）。\n- **voice**（字符串）：OpenAI 兼容的语音之一（alloy、echo、fable、onyx、nova、shimmer），或任何有效的 `edge-tts` 语音（默认值为 `\"en-US-AvaNeural\"`）。\n- **response_format**（字符串）：音频格式。选项包括：`mp3`、`opus`、`aac`、`flac`、`wav`、`pcm`（默认值为 `mp3`）。\n- **speed**（数字）：播放速度（0.25 至 4.0）。默认值为 `1.0`。\n- **stream_format**（字符串）：响应格式。选项有 `\"audio\"`（原始音频数据，默认）或 `\"sse\"`（使用 JSON 事件的 Server-Sent Events 流式传输）。\n\n**注意**：该 API 完全兼容 OpenAI 的 TTS API 规范。目前不支持 `instructions` 参数（用于微调语音特征），但其他所有参数与 OpenAI 的实现完全一致。\n\n#### 标准音频生成\n\n使用 `curl` 发送请求并将输出保存为 mp3 文件的示例：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -d '{\n    \"input\": \"你好，我是你的 AI 助手！请告诉我如何帮助你将想法变为现实。\",\n    \"voice\": \"echo\",\n    \"response_format\": \"mp3\",\n    \"speed\": 1.1\n  }' \\\n  --output speech.mp3\n```\n\n#### 直接音频播放（类似 OpenAI）\n\n你可以将音频直接通过管道传递给 `ffplay` 进行即时播放，就像 OpenAI 的 API 一样：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"model\": \"tts-1\",\n    \"input\": \"今天是创造人们喜爱事物的美好一天！\",\n    \"voice\": \"alloy\",\n    \"response_format\": \"mp3\"\n  }' | ffplay -i -\n```\n\n或者，无需保存到文件即可立即播放：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"input\": \"这将立即播放，不会保存到磁盘！\",\n    \"voice\": \"shimmer\"\n  }' | ffplay -autoexit -nodisp -i -\n```\n\n或者，为了与 OpenAI API 端点参数保持一致：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -d '{\n    \"model\": \"tts-1\",\n    \"input\": \"你好，我是你的 AI 助手！请告诉我如何帮助你将想法变为现实。\",\n    \"voice\": \"alloy\"\n  }' \\\n  --output speech.mp3\n```\n\n#### Server-Sent Events (SSE) 流式传输\n\n对于需要结构化流式事件的应用程序（如 Web 应用程序），可以使用 SSE 格式：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -d '{\n    \"model\": \"tts-1\",\n    \"input\": \"这将以 Server-Sent Events 的形式进行流式传输，JSON 数据包含 base64 编码的音频片段。\",\n    \"voice\": \"alloy\",\n    \"stream_format\": \"sse\"\n  }'\n```\n\n**SSE 响应格式**：\n\n```\ndata: {\"type\": \"speech.audio.delta\", \"audio\": \"base64-encoded-audio-chunk\"}\n\ndata: {\"type\": \"speech.audio.delta\", \"audio\": \"base64-encoded-audio-chunk\"}\n\ndata: {\"type\": \"speech.audio.done\", \"usage\": {\"input_tokens\": 12, \"output_tokens\": 0, \"total_tokens\": 12}}\n```\n\n#### JavaScript\u002FWeb 使用\n\n使用 fetch API 进行 SSE 流式传输的示例：\n\n```javascript\nasync function streamTTSWithSSE(text) {\n  const response = await fetch('http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application\u002Fjson',\n      Authorization: 'Bearer your_api_key_here',\n    },\n    body: JSON.stringify({\n      input: text,\n      voice: 'alloy',\n      stream_format: 'sse',\n    }),\n  });\n\n  const reader = response.body.getReader();\n  const decoder = new TextDecoder();\n  const audioChunks = [];\n\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n\n    const chunk = decoder.decode(value);\n    const lines = chunk.split('\\n');\n\n    for (const line of lines) {\n      if (line.startsWith('data: ')) {\n        const data = JSON.parse(line.slice(6));\n\n        if (data.type === 'speech.audio.delta') {\n          \u002F\u002F 解码 base64 编码的音频片段\n          const audioData = atob(data.audio);\n          const audioArray = new Uint8Array(audioData.length);\n          for (let i = 0; i \u003C audioData.length; i++) {\n            audioArray[i] = audioData.charCodeAt(i);\n          }\n          audioChunks.push(audioArray);\n        } else if (data.type === 'speech.audio.done') {\n          console.log('语音合成完成：', data.usage);\n\n          \u002F\u002F 将所有音频片段合并并播放\n          const totalLength = audioChunks.reduce(\n            (sum, chunk) => sum + chunk.length,\n            0\n          );\n          const combinedArray = new Uint8Array(totalLength);\n          let offset = 0;\n          for (const chunk of audioChunks) {\n            combinedArray.set(chunk, offset);\n            offset += chunk.length;\n          }\n\n          const audioBlob = new Blob([combinedArray], { type: 'audio\u002Fmpeg' });\n          const audioUrl = URL.createObjectURL(audioBlob);\n          const audio = new Audio(audioUrl);\n          audio.play();\n          return;\n        }\n      }\n    }\n  }\n}\n\n\u002F\u002F 使用\nstreamTTSWithSSE('来自 SSE 流式传输的问候！');\n```\n\n#### 国际语言示例\n\n以下是一个非英语语言的示例：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -d '{\n    \"model\": \"tts-1\",\n    \"input\": \"じゃあ、行く。電車の時間、調べておくよ。\",\n    \"voice\": \"ja-JP-KeitaNeural\"\n  }' \\\n  --output speech.mp3\n```\n\n#### JavaScript\u002FWeb 使用\n\n使用 fetch API 进行 SSE 流式传输的示例：\n\n```javascript\nasync function streamTTSWithSSE(text) {\n  const response = await fetch('http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application\u002Fjson',\n      Authorization: 'Bearer your_api_key_here',\n    },\n    body: JSON.stringify({\n      input: text,\n      voice: 'alloy',\n      stream_format: 'sse',\n    }),\n  });\n\n  const reader = response.body.getReader();\n  const decoder = new TextDecoder();\n  const audioChunks = [];\n\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n\n    const chunk = decoder.decode(value);\n    const lines = chunk.split('\\n');\n\n    for (const line of lines) {\n      if (line.startsWith('data: ')) {\n        const data = JSON.parse(line.slice(6));\n\n        if (data.type === 'speech.audio.delta') {\n          \u002F\u002F 解码 base64 编码的音频片段\n          const audioData = atob(data.audio);\n          const audioArray = new Uint8Array(audioData.length);\n          for (let i = 0; i \u003C audioData.length; i++) {\n            audioArray[i] = audioData.charCodeAt(i);\n          }\n          audioChunks.push(audioArray);\n        } else if (data.type === 'speech.audio.done') {\n          console.log('语音合成完成：', data.usage);\n\n\u002F\u002F 将所有分块合并并播放\n          const totalLength = audioChunks.reduce(\n            (sum, chunk) => sum + chunk.length,\n            0\n          );\n          const combinedArray = new Uint8Array(totalLength);\n          let offset = 0;\n          for (const chunk of audioChunks) {\n            combinedArray.set(chunk, offset);\n            offset += chunk.length;\n          }\n\n          const audioBlob = new Blob([combinedArray], { type: 'audio\u002Fmpeg' });\n          const audioUrl = URL.createObjectURL(audioBlob);\n          const audio = new Audio(audioUrl);\n          audio.play();\n          return;\n        }\n      }\n    }\n  }\n}\n\n\u002F\u002F 使用示例\nstreamTTSWithSSE('来自 SSE 流的问候！');\n```\n\n#### 其他端点\n\n- **POST\u002FGET \u002Fv1\u002Fmodels**：列出可用的 TTS 模型。\n- **POST\u002FGET \u002Fv1\u002Fvoices**：列出给定语言\u002F区域设置的 `edge-tts` 音色。\n- **POST\u002FGET \u002Fv1\u002Fvoices\u002Fall**：列出所有 `edge-tts` 音色，并提供语言支持信息。\n\n\u003C\u002Fdetails>\n\n\n\n### 贡献\n\n欢迎贡献！请先 fork 本仓库，然后针对任何改进创建 pull request。\n\n### 许可证\n\n本项目采用 GNU 通用公共许可证 v3.0（GPL-3.0）授权，其预期的合理使用场景为个人用途。如需将 `openai-edge-tts` 用于企业或其他非个人用途，请联系我：tts@travisvn.com\n\n---\n\n## 示例用法\n\n> [!TIP]\n> 如果遇到问题，请将 `localhost` 替换为您的本地 IP 地址（例如 `192.168.0.1`）\n>\n> _可能的情况是，在不同服务器或计算机上访问此端点，或者从其他来源（如 Open WebUI）发起调用时，需要将 URL 中的 `localhost` 更改为您的本地 IP 地址（例如 `192.168.0.1` 等）。_\n\n# Open WebUI\n\n打开管理面板，进入“设置”->“音频”。\n\n下方截图展示了使用本项目替换 OpenAI 端点的正确配置：\n\n![Open WebUI 管理设置中音频部分添加本项目正确端点的截图](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Ftravisvn_openai-edge-tts_readme_6ccf44338313.png)\n\n如果您同时在 Docker 中运行 Open WebUI 和本项目，API 端点 URL 很可能是 `http:\u002F\u002Fhost.docker.internal:5050\u002Fv1`。\n\n> [!NOTE]\n> 请参阅官方文档中的 [Open WebUI 与 OpenAI Edge TTS 集成指南](https:\u002F\u002Fdocs.openwebui.com\u002Ftutorials\u002Ftext-to-speech\u002Fopenai-edge-tts-integration)。\n\n# AnythingLLM\n\n在版本 1.6.8 中，AnythingLLM 增加了对“通用 OpenAI TTS 提供者”的支持——这意味着我们可以将本项目用作 AnythingLLM 中的 TTS 提供者。\n\n打开设置，进入“语音与声音”（位于 AI 提供者下）。\n\n下方截图展示了使用本项目替换 OpenAI 端点的正确配置：\n\n![AnythingLLM 设置中语音部分添加本项目正确端点的截图](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Ftravisvn_openai-edge-tts_readme_c33fbbc6b573.png)\n\n---\n\n## 快速信息\n\n- `your_api_key_here` 无需替换——不需要真正的 API 密钥。您可以使用任意字符串。\n- 启动并运行本项目的最快方式是安装 Docker 并执行以下命令：\n\n```bash\ndocker run -d -p 5050:5050 -e API_KEY=your_api_key_here -e PORT=5050 travisvn\u002Fopenai-edge-tts:latest\n```\n\n---\n\n# 音色样本 🎙️\n\n[播放音色样本并查看所有可用的 Edge TTS 音色](https:\u002F\u002Ftts.travisvn.com\u002F)","# openai-edge-tts 快速上手指南\n\n`openai-edge-tts` 是一个本地部署的文本转语音（TTS）API，完全兼容 OpenAI 的 `\u002Fv1\u002Faudio\u002Fspeech` 接口。它基于微软 Edge 的免费 TTS 服务 (`edge-tts`)，支持多种音色、语速及音频格式，是替代 OpenAI TTS 服务的免费开源方案。\n\n## 环境准备\n\n在开始之前，请确保您的系统满足以下要求：\n\n*   **操作系统**：Linux, macOS 或 Windows\n*   **核心依赖**：\n    *   **Docker** (推荐)：用于容器化部署，最简单快捷。\n    *   **Python 3.x** (可选)：如果您希望直接在本地源码运行。\n    *   **ffmpeg** (可选)：如果需要转换除 MP3 以外的音频格式（如 wav, opus 等），Docker 构建时需开启相关参数或本地安装。\n\n## 安装步骤\n\n### 方式一：使用 Docker（推荐）\n\n这是最简单的启动方式，无需配置复杂的环境变量即可立即运行。\n\n1.  **拉取并运行镜像**\n    执行以下命令，将在后台启动服务并映射端口 `5050`：\n\n    ```bash\n    docker run -d -p 5050:5050 travisvn\u002Fopenai-edge-tts:latest\n    ```\n\n    > **提示**：如果您需要支持更多音频格式转换，请使用包含 ffmpeg 的版本：\n    > ```bash\n    > docker run -d -p 5050:5050 travisvn\u002Fopenai-edge-tts:latest-ffmpeg\n    > ```\n\n2.  **验证服务**\n    服务启动后，可通过 `http:\u002F\u002Flocalhost:5050` 访问。\n\n### 方式二：本地源码运行 (Python)\n\n如果您需要进行二次开发或调试，可以选择此方式。\n\n1.  **克隆仓库**\n    ```bash\n    git clone https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts.git\n    cd openai-edge-tts\n    ```\n\n2.  **创建虚拟环境并安装依赖**\n    ```bash\n    # macOS\u002FLinux\n    python3 -m venv venv\n    source venv\u002Fbin\u002Factivate\n\n    # Windows\n    python -m venv venv\n    venv\\Scripts\\activate\n\n    pip install -r requirements.txt\n    ```\n    *(注：国内用户如遇 pip 下载慢，可添加 `-i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple` 使用清华源)*\n\n3.  **配置环境变量**\n    复制示例配置文件：\n    ```bash\n    cp .env.example .env\n    ```\n    编辑 `.env` 文件，至少设置 API Key（可自定义）和端口：\n    ```env\n    API_KEY=your_api_key_here\n    PORT=5050\n    REQUIRE_API_KEY=True\n    ```\n\n4.  **启动服务**\n    ```bash\n    python app\u002Fserver.py\n    ```\n\n## 基本使用\n\n服务启动后，接口地址为 `http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech`。其行为与 OpenAI 官方接口完全一致。\n\n### 1. 生成音频文件\n\n使用 `curl` 发送请求并将结果保存为 MP3 文件：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -d '{\n    \"input\": \"你好，我是你的 AI 助手！\",\n    \"voice\": \"alloy\",\n    \"response_format\": \"mp3\",\n    \"speed\": 1.0\n  }' \\\n  --output speech.mp3\n```\n\n**参数说明：**\n*   `input`: 要转换的文本（必填）。\n*   `voice`: 音色。支持 OpenAI 风格名称 (`alloy`, `echo`, `fable`, `onyx`, `nova`, `shimmer`) 或直接使用 edge-tts 音色代码 (如 `zh-CN-XiaoxiaoNeural`)。\n*   `response_format`: 输出格式 (`mp3`, `opus`, `aac`, `flac`, `wav`, `pcm`)。\n*   `speed`: 语速 (0.25 - 4.0)。\n\n### 2. 直接播放音频\n\n如果您安装了 `ffplay` (FFmpeg 组件)，可以直接管道传输进行实时播放，无需保存文件：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"input\": \"今天是个好日子，适合构建人们喜爱的产品！\",\n    \"voice\": \"alloy\"\n  }' | ffplay -autoexit -nodisp -i -\n```\n\n### 3. SSE 流式输出\n\n适用于 Web 前端或需要实时流式处理的场景，设置 `stream_format: \"sse\"`：\n\n```bash\ncurl -X POST http:\u002F\u002Flocalhost:5050\u002Fv1\u002Faudio\u002Fspeech \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -H \"Authorization: Bearer your_api_key_here\" \\\n  -d '{\n    \"input\": \"这是一段流式输出的测试文本。\",\n    \"voice\": \"alloy\",\n    \"stream_format\": \"sse\"\n  }'\n```","一家初创教育科技公司正在开发一款面向全球用户的 AI 有声读物应用，需要为海量文本内容生成自然流畅的多语言语音。\n\n### 没有 openai-edge-tts 时\n- **成本压力巨大**：调用 OpenAI、Azure 或 ElevenLabs 等商业 API 按字符计费，随着用户量和内容库激增，每月语音合成账单高达数千美元，严重压缩利润空间。\n- **集成迁移困难**：若为了省钱切换到其他免费但接口不兼容的 TTS 服务，需要重构后端代码中的请求逻辑和参数处理，开发周期长且容易引入 Bug。\n- **功能受限明显**：免费方案往往不支持实时流式传输（SSE），导致用户必须等待整段音频生成完毕才能播放，首字延迟高，体验卡顿。\n- **音色选择单一**：难以灵活映射主流大模型预设音色（如 alloy, nova），也无法精细调节语速以适应不同年龄段听众的收听习惯。\n\n### 使用 openai-edge-tts 后\n- **实现零成本运营**：利用微软 Edge 的免费服务接口，通过 Docker 一键部署本地 API，彻底消除了按量计费的支出，将预算重新投入到内容创作中。\n- **无缝平滑迁移**：openai-edge-tts 完美模拟 OpenAI 的 `\u002Fv1\u002Faudio\u002Fspeech` 接口，现有代码无需修改任何请求结构即可直接切换后端，即插即用。\n- **提升交互体验**：开启 SSE 流式支持后，音频数据实时推送到前端，用户几乎在点击播放的瞬间即可听到声音，显著降低等待焦虑。\n- **灵活定制音效**：不仅自动映射主流音色，还能直接指定任意 edge-tts 原生语音，并自由调整 0.25x 至 4.0x 的播放速度，满足个性化教学需求。\n\nopenai-edge-tts 让开发者在保持零成本的前提下，获得了与企业级付费服务同等甚至更灵活的语音合成能力。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Ftravisvn_openai-edge-tts_8cbd73cb.png","travisvn","Travis Van Nimwegen","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Ftravisvn_4cc65fb5.jpg",null,"Seattle","github@travis.engineer","Travis_Engineer","https:\u002F\u002Ftravis.engineer","https:\u002F\u002Fgithub.com\u002Ftravisvn",[84,88],{"name":85,"color":86,"percentage":87},"Python","#3572A5",98,{"name":89,"color":90,"percentage":32},"Dockerfile","#384d54",1790,267,"2026-04-17T08:33:58","GPL-3.0","Linux, macOS, Windows","不需要 GPU","未说明",{"notes":99,"python":100,"dependencies":101},"该工具主要依赖 Microsoft Edge 的在线 TTS 服务，因此需要网络连接。推荐使用 Docker 部署；若本地运行 Python，需安装 ffmpeg 才能使用除 mp3 以外的音频格式。","3.x (未指定具体小版本，需支持 venv)",[102,103,104,105,106],"edge-tts","fastapi","uvicorn","python-dotenv","ffmpeg (可选，用于格式转换)",[108,15,35,13,14],"音频",[110,111,102,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127],"ai","chatgpt","llm","llm-webui","llms","ollama","ollama-webui","open-webui","openai","speech","text-to-speech","tts","self-hosted","claude","gpt","local-llm","azure","elevenlabs","2026-03-27T02:49:30.150509","2026-04-18T09:20:10.716646",[131,136,141,146,151,156],{"id":132,"question_zh":133,"answer_zh":134,"source_url":135},39492,"服务突然停止工作并报错 '403 Invalid response status' 或 'WSServerHandshakeError' 怎么办？","这通常是因为 Microsoft 更新了后端接口或令牌，导致旧版本失效。解决方案是更新到最新的 Docker 镜像。如果标准镜像仍有问题，可以尝试使用 `canary`（金丝雀）版本的镜像，该版本通常包含最新的修复补丁。\n\n运行命令如下：\n```bash\ndocker run -d -p 5050:5050 travisvn\u002Fopenai-edge-tts:canary\n```\n建议优先使用 docker compose 部署方式以确保稳定性。","https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts\u002Fissues\u002F48",{"id":137,"question_zh":138,"answer_zh":139,"source_url":140},39493,"遇到 'SSL certificate verify failed: certificate has expired' 错误如何解决？","此错误是由于 Microsoft 服务的 SSL 证书过期或更新导致的。通常不需要手动干预，只需将项目升级到最新版本即可解决。维护者确认在版本 7.2.3 及更高版本中已适配新的证书。如果您使用的是旧版本（如 7.0.2），请尝试升级；如果问题持续，等待微软续期证书或项目发布新补丁即可自动恢复。","https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts\u002Fissues\u002F40",{"id":142,"question_zh":143,"answer_zh":144,"source_url":145},39494,"处理长文本（如 500 词以上）时频繁报错或触发速率限制怎么办？","这通常是因为触发了 Microsoft 服务器的隐性速率限制（Rate Limit）。建议采取以下措施：\n1. 确保发送的负载（文本量）在合理范围内。\n2. 避免过快发送大量请求。\n3. 如果可能，在请求之间增加延迟（例如 1-5 秒）。\n4. 尝试使用 Docker 容器运行，有时网络环境的改变会有所帮助。\n注意：目前无法完全阻止此类错误，因为限制策略由微软控制且不透明。","https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts\u002Fissues\u002F7",{"id":147,"question_zh":148,"answer_zh":149,"source_url":150},39495,"为什么请求 wav、pcm 或 opus 格式时，返回的文件仍然是 mp3 格式？","这是因为基础 Docker 镜像中未安装 `ffmpeg`，导致无法进行格式转换。解决方法有两个：\n1. 使用预装了 ffmpeg 的专用镜像：`travisvn\u002Fopenai-edge-tts:latest-ffmpeg`。\n2. 如果使用 docker-compose 或自行构建，设置环境变量 `INSTALL_FFMPEG_ARG=true` 以在安装过程中包含 ffmpeg。\n\n示例运行命令：\n```bash\ndocker run -d ... -e DEFAULT_RESPONSE_FORMAT=wav travisvn\u002Fopenai-edge-tts:latest-ffmpeg\n```","https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts\u002Fissues\u002F24",{"id":152,"question_zh":153,"answer_zh":154,"source_url":155},39496,"如何在 TTS 处理过程中过滤 Markdown 中的特殊字符（如 $, *, _ 等）以避免干扰朗读？","虽然该项目主要关注 API 服务，但针对 Markdown 特殊字符干扰朗读的问题，可以通过正则表达式过滤来解决。建议将以下符号序列替换为单个空格，以减少对语音合成的干扰（特别是 LaTeX 公式中的 $ 符号）：\n匹配模式：`@#$%^&*()_=[]{}|'\"\u003C>\u002F`~`\n注意：标点符号（如逗号、句号、问号）通常应保留以保证语调自然，仅移除非文本的特殊格式字符。","https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts\u002Fissues\u002F12",{"id":157,"question_zh":158,"answer_zh":159,"source_url":135},39497,"Docker 部署后服务不可用，是否有推荐的部署方式？","如果遇到直接运行 docker run 命令不稳定的情况，维护者强烈推荐使用 `docker compose` 方式进行部署。这种方式能更好地管理环境变量和网络配置。此外，确保拉取的是最新镜像，或者在紧急情况下使用 `:canary` 标签的镜像来获取最新的修复补丁。",[161],{"id":162,"version":163,"summary_zh":164,"released_at":165},315444,"v2.0.0","# 🚀 **v2.0.0 - Markdown 过滤、扩展 API 支持与简化部署** 🌟\n\n🔥 **迄今为止最大更新！** 我们一直致力于为您带来强大的新功能，并让部署流程比以往更加顺畅。以下是本次更新的内容：\n\n## ✨ **新增功能？**  \n1. **📝 Markdown 过滤（可选！）**  \n   - 现在您可以轻松过滤 Markdown 输出！  \n   - 如果想禁用此功能，只需在 `.env` 文件中添加：  \n     ```env\n     REMOVE_FILTER=True\n     ```\n\n2. **🌐 ElevenLabs 和 Azure AI Speech（测试版）**  \n   - 提供对 ElevenLabs 和 Azure AI Speech API 端点的即插即用支持，使用方式与 OpenAI 的 Text-to-Speech 完全一致。  \n   - 如果您更倾向于保持简单，可以通过以下配置禁用这些功能：  \n     ```env\n     EXPAND_API=False\n     ```\n\n3. **🔗 简化 API 端点配置**  \n   - 再也不用纠结 `\u002Fv1` 前缀了！现在 `\u002Fv1` 路由前缀已成为可选配置，使您的设置更加**简洁**且**易用**。🚀  \n\n## 🛠 **如何升级？**  \n\n### 对于 Git 用户：  \n1. 使用 `rebase` 拉取最新更改，避免冲突：  \n   ```bash\n   git pull --rebase origin main\n   ```\n2. 如有需要，请更新 `.env` 文件中的环境变量。\n\n### 对于 Docker 用户：  \n1. 从 Docker Hub 拉取最新镜像：  \n   ```bash\n   docker pull travisvn\u002Fopenai-edge-tts:latest\n   ```\n2. 重启容器以应用更改：  \n   ```bash\n   docker run -d -p 5050:5050 -e API_KEY=your_api_key_here -e PORT=5050 travisvn\u002Fopenai-edge-tts:latest\n   ```\n\n## 🎉 **加入 Discord 社区吧！**  \n我们已上线了一个 **Discord 服务器**，在这里您可以：  \n- 💬 讨论任何与 TTS 相关的话题。  \n- 🛠 获取部署方面的支持。  \n- 🚀 分享您的想法或反馈。  \n\n**[立即加入](https:\u002F\u002Ftts.travisvn.com\u002Fdiscord)**，参与我们的交流吧！我们非常期待您的到来。🤝  \n\n## 💡 **注意事项**  \n- ElevenLabs 和 Azure AI Speech 端点目前处于**测试阶段**，我们非常欢迎您的反馈，帮助我们进一步完善它们！  \n- 请务必查看更新后的 README 文件，获取详细的使用说明。\n\n---\n\n⭐ **喜欢这次更新吗？** 别忘了为本项目 [点赞](https:\u002F\u002Fgithub.com\u002Ftravisvn\u002Fopenai-edge-tts) 并分享给您的朋友！您的支持对我们意义重大。🌍✨  \n\n如果您有任何问题或建议，欢迎在 Issues 或 Discussions 标签页中留言，或者直接到 [Discord 与我们交流](https:\u002F\u002Ftts.travisvn.com\u002Fdiscord)！👂💬  \n\n---\n\n# **🎉 祝您 TTS 使用愉快！** 🚀","2024-12-28T23:01:19"]