genie-tts-t / README.md
clown145's picture
Update README.md
9c78e6e verified
metadata
title: Genie Tts
emoji: 😻
colorFrom: green
colorTo: pink
sdk: docker
pinned: false

Genie TTS API 使用文档

1. 概述

本文档旨在指导开发者如何调用部署在 Hugging Face Spaces 上的 Genie TTS 服务。该服务允许您通过 API 请求,使用预加载的角色模型将文本转换为高质量的语音。

API 基地址 (Base URL):

https://clown145-genie-tts-t.hf.space

2. 核心使用流程

本 API 的核心工作流程分为两步,每次语音合成都需要完整执行这两个步骤

  1. 设置参考音频 (/set_reference_audio): 为指定的角色设置一段参考音频和对应的文本。这一步是为了让模型能够克隆出参考音频中的情感和语调。
  2. 请求语音合成 (/tts): 发送你想要合成的文本,服务器将返回对应的原始音频数据流。

3. API 端点详解

3.1 设置参考音频

此端点用于为即将进行的 TTS 任务设置声音克隆所需的参考音频。

  • Endpoint: POST /set_reference_audio

  • Method: POST

  • 描述: 为指定角色设置参考音频及其文本。这是成功进行语音合成的前提条件

  • 请求体 (Request Body): JSON

    {
      "character_name": "aoi",
      "audio_path": "reference_audio/12b00400a02.ogg",
      "audio_text": "世界の外に電波発信してるの"
    }
    
  • 参数说明:

    • character_name (string, 必需): 你想要使用的角色名称。此名称必须与服务器启动时加载的某个角色匹配 (例如: "aoi", "kisaki", "may")。
    • audio_path (string, 必需): 参考音频文件在 Hugging Face 仓库中的相对路径。服务器会在其下载的代码库中自动查找此文件。
    • audio_text (string, 必需): 与参考音频文件内容完全匹配的文本。
  • 响应 (Response):

    • 成功:
      • 状态码: 200 OK
      • 内容: {"message": "Reference audio set successfully."}
    • 失败:
      • 状态码: 404 Not Found (如果角色未找到)

3.2 请求语音合成

在设置好参考音频后,使用此端点来生成语音。

  • Endpoint: POST /tts

  • Method: POST

  • 描述: 根据传入的文本,为当前设置了参考音频的角色生成语音,并以原始音频流的形式返回。

  • 请求体 (Request Body): JSON

    {
      "character_name": "aoi",
      "text": "これからもし同じようなことがあっても",
      "split_sentence": true
    }
    
  • 参数说明:

    • character_name (string, 必需): 你想要使用的角色名称,必须与上一步中设置的角色一致。
    • text (string, 必需): 你想要转换为语音的文本。
    • split_sentence (boolean, 可选): 是否自动切分句子,默认为 false。推荐设置为 true 以获得更好的效果。
  • 响应 (Response):

    • 成功:

      • 状态码: 200 OK
      • 内容: **纯原始音频数据流 (Raw PCM Audio Stream)**。
        • 格式: 单声道 (1 Channel)
        • 采样率: 32000 Hz
        • 位深: 16-bit PCM
    • 失败:

      • 状态码: 400 Bad Request (如果未先设置参考音频)

4. 重要注意事项

  • 合成文本限制: 只能合成日语。
  • 模型加载限制: 当前服务配置为在启动时加载 最多 3 个 角色模型。请确保你请求的角色在预加载的名单中。
  • 音频输出格式: /tts 接口返回的不是一个 .wav 文件,而是构成 .wav 文件的核心——原始 PCM 音频数据。客户端接收到数据后,需要自行使用 wave 等库来构建一个可播放的 .wav 文件。
  • 关于 /load_character: 你可能在文档中看到过此接口,但在当前部署中,所有模型都在服务器启动时加载。客户端无需也不应调用 /load_character 接口

5. 完整 Python 客户端示例

这是一个可以直接运行的 Python 脚本,展示了如何正确调用 API 并将返回的音频流保存为可播放的 .wav 文件。

# client_example.py

import requests
import time
import os
import wave  # 导入 Python 标准的 wave 库,用于正确生成 .wav 文件

# --- API 配置 ---
BASE_URL = "https://clown145-genie-tts.hf.space"

# --- 音频参数 (必须与服务器输出匹配) ---
BYTES_PER_SAMPLE = 2  # 16-bit 音频
CHANNELS = 1          # 单声道
SAMPLE_RATE = 32000   # 32kHz 采样率

# --- 角色配置 ---
CHARACTERS = {
    "aoi": {
        "ref_audio": "reference_audio/12b00400a02.ogg",
        "ref_text": "世界の外に電波発信してるの"
    },
    "kisaki": {
        "ref_audio": "reference_audio/Kisaki_802.ogg",
        "ref_text": "ほら、ホタルもとても喜んでいます。ルリもそう呼んであげてくださいね。"
    },
    # 你可以在这里添加 'may' 或其他预加载的角色
}

def synthesize_speech_to_file(character_name, text_to_synthesize, output_path):
    """
    一个完整的调用流程:设置参考 -> 合成语音 -> 构建WAV文件。
    """
    if character_name not in CHARACTERS:
        print(f"错误:角色 '{character_name}' 未在配置中定义。")
        return

    print(f"\n--- 开始为角色 '{character_name}' 合成语音 ---")
    char_info = CHARACTERS[character_name]

    # 步骤 1: 动态设置参考音频
    print("[Client] 步骤 1: 正在设置参考音频...")
    ref_payload = {
        "character_name": character_name,
        "audio_path": char_info["ref_audio"],
        "audio_text": char_info["ref_text"]
    }
    try:
        response = requests.post(f"{BASE_URL}/set_reference_audio", json=ref_payload, timeout=60)
        response.raise_for_status()
        print(f"[Client] 角色 '{character_name}' 的参考音频设置成功。")
    except requests.exceptions.RequestException as e:
        print(f"[Client] 设置参考音频失败: {e}")
        return

    # 步骤 2: 请求 TTS 并将返回的原始音频流构建为 WAV 文件
    print(f"[Client] 步骤 2: 正在请求 TTS 并准备构建 WAV 文件到 {output_path}...")
    tts_payload = {
        "character_name": character_name,
        "text": text_to_synthesize,
        "split_sentence": True
    }

    try:
        with requests.post(f"{BASE_URL}/tts", json=tts_payload, stream=True, timeout=300) as response:
            response.raise_for_status()
            
            # 使用 wave 库来正确写入文件
            with wave.open(output_path, 'wb') as wf:
                # 这三行代码至关重要,它们会为原始音频数据写入正确的 WAV 文件头
                wf.setnchannels(CHANNELS)
                wf.setsampwidth(BYTES_PER_SAMPLE)
                wf.setframerate(SAMPLE_RATE)
                
                # 接收原始音频流数据块,并写入文件
                print("[Client] 正在接收音频流并写入 WAV 文件...")
                for chunk in response.iter_content(chunk_size=8192):
                    if chunk:
                        wf.writeframes(chunk)
            
            print(f"[Client] 🎉 恭喜!音频已成功构建并保存到: {output_path}")

    except requests.exceptions.RequestException as e:
        print(f"[Client] TTS 请求失败: {e}")
    except Exception as e:
        print(f"[Client] 保存文件时发生错误: {e}")

if __name__ == "__main__":
    # 确保输出文件夹存在
    if not os.path.exists("outputs"):
        os.makedirs("outputs")

    # --- 示例调用 ---
    print("\n" + "="*50)
    synthesize_speech_to_file(
        character_name="aoi", 
        text_to_synthesize="これは最初のテストです。",
        output_path="outputs/aoi_output.wav"
    )
    
    time.sleep(1) # 短暂间隔,避免请求过于频繁

    print("\n" + "="*50)
    synthesize_speech_to_file(
        character_name="kisaki", 
        text_to_synthesize="次の音声合成もお願いします。",
        output_path="outputs/kisaki_output.wav"
    )