TTS (Text-to-Speech)
An AI Pod has been deployed with the Kokoro tts service, which offers fast performance.
If you need an OpenAI-compatible multi-voice TTS service, please refer to Qwen3TTS API.
The entry point for the qwen3tts-ai service can be accessed via . .
Online Demo
You can access the online demo at . .
The API of tts service can be accessed via .
The API interface of Qwen3TTS is documented in Qwen3TTS API.
If you need OpenAI-style POST /v1/audio/speech, or require querying /v1/audio/voices, using extended parameters instruct / language, or performing startup validation based on /health's ready=true, you should use qwen3tts-ai instead of the tts-ai described in this page.
qwen3tts-ai This document explicitly states:
- OpenAI-style interface supports request-level
language - OpenAI-style interface supports request-level
instruct - OpenAI interface now supports request-level
seed - Under the same container image version, model, and request parameters, fixed
seedensures reproducible audio output - This document only includes request fields actually recommended for public use; parameters like
speedthat are compatible but not effective are omitted from formal parameter descriptions
Standalone Deployment
- Save the following content into a
docker-compose.ymlfile
yml
services:
tts:
image: registry.lazycat.cloud/x/lzc-aipod-tts:763ebf7
ports:
- 8880:8880
environment:
- PYTHONPATH=/app:/app/api
- USE_GPU=true
- PYTHONUNBUFFERED=1
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8880/health"]
interval: 30s
timeout: 5s
retries: 100
start_period: 1s- Run
docker-compose up -dto start the AI Pod in the current directory - After startup, access
http://127.0.0.1:8880/docs
Example
vue
<template>
<div class="tts-player">
<div class="input-section">
<textarea
v-model="text"
placeholder="请输入要转换的文本..."
class="text-input"
rows="4"
></textarea>
<button
@click="synthesizeSpeech"
:disabled="isLoading"
class="synthesize-btn"
>
{{ isLoading ? "转换中..." : "转换为语音" }}
</button>
</div>
<div class="player-section" v-if="audioUrl">
<audio
ref="audioPlayer"
:src="audioUrl"
controls
class="audio-player"
></audio>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
const text = ref("欢迎使用算力舱,玩的开心。welcome use AI pod, happy hack!");
const audioUrl = ref("");
const isLoading = ref(false);
const audioPlayer = ref(null);
const domain = () => {
const currentHost = window.location.host;
const host = currentHost.replace(/^([^.]+)/, "tts-ai");
const protocol = window.location.protocol;
return `${protocol}//${host}`;
};
const synthesizeSpeech = async () => {
if (!text.value.trim()) {
alert("请输入要转换的文本");
return;
}
isLoading.value = true;
try {
const response = await fetch(`${domain()}/v1/audio/speech`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
input: text.value,
voice: "zf_044",
response_format: "mp3",
download_format: "wav",
stream: true,
speed: 1,
return_download_link: true,
}),
});
if (!response.ok) {
throw new Error("语音合成请求失败");
}
const blob = await response.blob();
audioUrl.value = URL.createObjectURL(blob);
// 自动播放
if (audioPlayer.value) {
audioPlayer.value.play();
}
} catch (error) {
console.error("语音合成错误:", error);
alert("语音合成失败,请重试");
} finally {
isLoading.value = false;
}
};
</script>
<style>
.tts-player {
margin: 0 auto;
}
.input-section {
margin-bottom: 20px;
}
.text-input {
width: 100%;
padding: 12px;
border: 1px solid #ddd;
border-radius: 4px;
margin-bottom: 10px;
font-size: 16px;
resize: vertical;
}
.synthesize-btn {
background-color: #4caf50;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}
.synthesize-btn:hover {
background-color: #45a049;
}
.synthesize-btn:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
.player-section {
margin-top: 20px;
}
.audio-player {
width: 100%;
}
</style>