Release standalone PPT template workflow 0.5.0
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
"""Alibaba Qwen TTS backend for narration audio generation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from tts_backends.backend_common import download_audio, post_json, read_api_key
|
||||
|
||||
|
||||
DEFAULT_ENDPOINT = "https://dashscope-intl.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"
|
||||
DEFAULT_MODEL = "qwen3-tts-flash"
|
||||
|
||||
|
||||
def output_extension() -> str:
|
||||
return ".wav"
|
||||
|
||||
|
||||
def read_qwen_api_key(env_name: str | None = None) -> str:
|
||||
if env_name:
|
||||
return read_api_key(env_name, label="Qwen/DashScope")
|
||||
return read_api_key("QWEN_API_KEY", "DASHSCOPE_API_KEY", label="Qwen/DashScope")
|
||||
|
||||
|
||||
def resolve_url(base_url: str | None = None) -> str:
|
||||
base = (base_url or os.environ.get("QWEN_TTS_BASE_URL") or DEFAULT_ENDPOINT).rstrip("/")
|
||||
if base.endswith("/generation"):
|
||||
return base
|
||||
return base + "/api/v1/services/aigc/multimodal-generation/generation"
|
||||
|
||||
|
||||
def generate(
|
||||
text: str,
|
||||
output_path: Path,
|
||||
*,
|
||||
api_key: str,
|
||||
voice_id: str,
|
||||
model: str,
|
||||
language_type: str,
|
||||
instructions: str | None,
|
||||
optimize_instructions: bool | None,
|
||||
base_url: str | None,
|
||||
) -> None:
|
||||
input_payload: dict[str, object] = {
|
||||
"text": text,
|
||||
"voice": voice_id,
|
||||
}
|
||||
if language_type:
|
||||
input_payload["language_type"] = language_type
|
||||
if instructions:
|
||||
input_payload["instructions"] = instructions
|
||||
if optimize_instructions is not None:
|
||||
input_payload["optimize_instructions"] = optimize_instructions
|
||||
|
||||
data = post_json(
|
||||
resolve_url(base_url),
|
||||
headers={"Authorization": f"Bearer {api_key}"},
|
||||
payload={
|
||||
"model": model,
|
||||
"input": input_payload,
|
||||
},
|
||||
timeout=180,
|
||||
)
|
||||
audio = (data.get("output") or {}).get("audio") or {}
|
||||
audio_url = audio.get("url")
|
||||
if not audio_url:
|
||||
raise RuntimeError(f"Qwen TTS response missing audio URL: {data}")
|
||||
download_audio(audio_url, output_path)
|
||||
|
||||
|
||||
def print_voices() -> None:
|
||||
print("Qwen TTS voices are selected by voice.")
|
||||
print("Use a system voice name or a cloned voice from Qwen voice cloning.")
|
||||
print("Example system voice from Alibaba Cloud docs: Cherry")
|
||||
print("Current Qwen TTS responses do not include word/character timestamps.")
|
||||
Reference in New Issue
Block a user