You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
6.8 KiB
95 lines
6.8 KiB
import type { ModelParameter } from "@/lib/providers/types";
|
|
|
|
const SPEECH_VOICE_OPTIONS = [
|
|
{ value: "male-qn-qingse", label: "青涩青年音色 (male-qn-qingse)" },
|
|
{ value: "male-qn-jingying", label: "精英青年音色 (male-qn-jingying)" },
|
|
{ value: "male-qn-badao", label: "霸道青年音色 (male-qn-badao)" },
|
|
{ value: "male-qn-daxuesheng", label: "青年大学生音色 (male-qn-daxuesheng)" },
|
|
{ value: "female-shaonv", label: "少女音色 (female-shaonv)" },
|
|
{ value: "female-yujie", label: "御姐音色 (female-yujie)" },
|
|
{ value: "female-chengshu", label: "成熟女性音色 (female-chengshu)" },
|
|
{ value: "female-tianmei", label: "甜美女性音色 (female-tianmei)" },
|
|
{ value: "male-qn-qingse-jingpin", label: "青涩青年音色-beta (male-qn-qingse-jingpin)" },
|
|
{ value: "male-qn-jingying-jingpin", label: "精英青年音色-beta (male-qn-jingying-jingpin)" },
|
|
{ value: "male-qn-badao-jingpin", label: "霸道青年音色-beta (male-qn-badao-jingpin)" },
|
|
{ value: "male-qn-daxuesheng-jingpin", label: "青年大学生音色-beta (male-qn-daxuesheng-jingpin)" },
|
|
{ value: "female-shaonv-jingpin", label: "少女音色-beta (female-shaonv-jingpin)" },
|
|
{ value: "female-yujie-jingpin", label: "御姐音色-beta (female-yujie-jingpin)" },
|
|
{ value: "female-chengshu-jingpin", label: "成熟女性音色-beta (female-chengshu-jingpin)" },
|
|
{ value: "female-tianmei-jingpin", label: "甜美女性音色-beta (female-tianmei-jingpin)" },
|
|
{ value: "clever_boy", label: "聪明男童 (clever_boy)" },
|
|
{ value: "cute_boy", label: "可爱男童 (cute_boy)" },
|
|
{ value: "lovely_girl", label: "萌萌女童 (lovely_girl)" },
|
|
{ value: "cartoon_pig", label: "卡通猪小琪 (cartoon_pig)" },
|
|
{ value: "bingjiao_didi", label: "病娇弟弟 (bingjiao_didi)" },
|
|
{ value: "junlang_nanyou", label: "俊朗男友 (junlang_nanyou)" },
|
|
{ value: "chunzhen_xuedi", label: "纯真学弟 (chunzhen_xuedi)" },
|
|
{ value: "lengdan_xiongzhang", label: "冷淡学长 (lengdan_xiongzhang)" },
|
|
{ value: "badao_shaoye", label: "霸道少爷 (badao_shaoye)" },
|
|
{ value: "tianxin_xiaoling", label: "甜心小玲 (tianxin_xiaoling)" },
|
|
{ value: "qiaopi_mengmei", label: "俏皮萌妹 (qiaopi_mengmei)" },
|
|
{ value: "wumei_yujie", label: "妩媚御姐 (wumei_yujie)" },
|
|
{ value: "diadia_xuemei", label: "嗲嗲学妹 (diadia_xuemei)" },
|
|
{ value: "danya_xuejie", label: "淡雅学姐 (danya_xuejie)" },
|
|
{ value: "Chinese (Mandarin)_Reliable_Executive", label: "沉稳高管 (Chinese (Mandarin)_Reliable_Executive)" },
|
|
{ value: "Chinese (Mandarin)_News_Anchor", label: "新闻女声 (Chinese (Mandarin)_News_Anchor)" },
|
|
{ value: "Chinese (Mandarin)_Mature_Woman", label: "傲娇御姐 (Chinese (Mandarin)_Mature_Woman)" },
|
|
{ value: "Chinese (Mandarin)_Unrestrained_Young_Man", label: "不羁青年 (Chinese (Mandarin)_Unrestrained_Young_Man)" },
|
|
{ value: "Arrogant_Miss", label: "嚣张小姐 (Arrogant_Miss)" },
|
|
{ value: "Robot_Armor", label: "机械战甲 (Robot_Armor)" },
|
|
{ value: "Chinese (Mandarin)_Kind-hearted_Antie", label: "热心大婶 (Chinese (Mandarin)_Kind-hearted_Antie)" },
|
|
{ value: "Chinese (Mandarin)_HK_Flight_Attendant", label: "港普空姐 (Chinese (Mandarin)_HK_Flight_Attendant)" },
|
|
{ value: "Chinese (Mandarin)_Humorous_Elder", label: "搞笑大爷 (Chinese (Mandarin)_Humorous_Elder)" },
|
|
{ value: "Chinese (Mandarin)_Gentleman", label: "温润男声 (Chinese (Mandarin)_Gentleman)" },
|
|
{ value: "Chinese (Mandarin)_Warm_Bestie", label: "温暖闺蜜 (Chinese (Mandarin)_Warm_Bestie)" },
|
|
{ value: "Chinese (Mandarin)_Male_Announcer", label: "播报男声 (Chinese (Mandarin)_Male_Announcer)" },
|
|
{ value: "Chinese (Mandarin)_Sweet_Lady", label: "甜美女声 (Chinese (Mandarin)_Sweet_Lady)" },
|
|
{ value: "Chinese (Mandarin)_Southern_Young_Man", label: "南方小哥 (Chinese (Mandarin)_Southern_Young_Man)" },
|
|
{ value: "Chinese (Mandarin)_Wise_Women", label: "阅历姐姐 (Chinese (Mandarin)_Wise_Women)" },
|
|
{ value: "Chinese (Mandarin)_Gentle_Youth", label: "温润青年 (Chinese (Mandarin)_Gentle_Youth)" },
|
|
{ value: "Chinese (Mandarin)_Warm_Girl", label: "温暖少女 (Chinese (Mandarin)_Warm_Girl)" },
|
|
{ value: "Chinese (Mandarin)_Kind-hearted_Elder", label: "花甲奶奶 (Chinese (Mandarin)_Kind-hearted_Elder)" },
|
|
{ value: "Chinese (Mandarin)_Cute_Spirit", label: "憨憨萌兽 (Chinese (Mandarin)_Cute_Spirit)" },
|
|
{ value: "Chinese (Mandarin)_Radio_Host", label: "电台男主播 (Chinese (Mandarin)_Radio_Host)" },
|
|
{ value: "Chinese (Mandarin)_Lyrical_Voice", label: "抒情男声 (Chinese (Mandarin)_Lyrical_Voice)" },
|
|
{ value: "Chinese (Mandarin)_Straightforward_Boy", label: "率真弟弟 (Chinese (Mandarin)_Straightforward_Boy)" },
|
|
{ value: "Chinese (Mandarin)_Sincere_Adult", label: "真诚青年 (Chinese (Mandarin)_Sincere_Adult)" },
|
|
{ value: "Chinese (Mandarin)_Gentle_Senior", label: "温柔学姐 (Chinese (Mandarin)_Gentle_Senior)" },
|
|
{ value: "Chinese (Mandarin)_Stubborn_Friend", label: "嘴硬竹马 (Chinese (Mandarin)_Stubborn_Friend)" },
|
|
{ value: "Chinese (Mandarin)_Crisp_Girl", label: "清脆少女 (Chinese (Mandarin)_Crisp_Girl)" },
|
|
{ value: "Chinese (Mandarin)_Pure-hearted_Boy", label: "清澈邻家弟弟 (Chinese (Mandarin)_Pure-hearted_Boy)" },
|
|
{ value: "Chinese (Mandarin)_Soft_Girl", label: "柔和少女 (Chinese (Mandarin)_Soft_Girl)" },
|
|
{ value: "Cantonese_ProfessionalHost(F)", label: "专业女主持 (Cantonese_ProfessionalHost(F))" },
|
|
{ value: "Cantonese_GentleLady", label: "温柔女声 (Cantonese_GentleLady)" },
|
|
{ value: "Cantonese_ProfessionalHost(M)", label: "专业男主持 (Cantonese_ProfessionalHost(M))" },
|
|
{ value: "Cantonese_PlayfulMan", label: "活泼男声 (Cantonese_PlayfulMan)" },
|
|
{ value: "Cantonese_CuteGirl", label: "可爱女孩 (Cantonese_CuteGirl)" },
|
|
{ value: "Cantonese_KindWoman", label: "善良女声 (Cantonese_KindWoman)" },
|
|
] satisfies Array<{ value: string; label: string }>;
|
|
|
|
const SPEECH_VOICE_PARAMETER: ModelParameter = {
|
|
name: "voiceId",
|
|
type: "string",
|
|
label: "音色",
|
|
description: "Speech 模型合成音色",
|
|
default: "Chinese (Mandarin)_Reliable_Executive",
|
|
options: SPEECH_VOICE_OPTIONS,
|
|
};
|
|
|
|
const SPEECH_VOICE_PARAMETER_NAMES = new Set(["voiceId", "voice_id"]);
|
|
|
|
export function isSpeechAudioModel(...identifiers: Array<string | null | undefined>): boolean {
|
|
return identifiers.some((identifier) => {
|
|
const normalized = (identifier ?? "").trim().toLowerCase();
|
|
return normalized === "speech" || normalized.startsWith("speech-");
|
|
});
|
|
}
|
|
|
|
export function withSpeechVoiceParameter(
|
|
schema: ModelParameter[] | undefined,
|
|
...modelIdentifiers: Array<string | null | undefined>
|
|
): ModelParameter[] {
|
|
const nextSchema = (schema ?? []).filter((param) => !SPEECH_VOICE_PARAMETER_NAMES.has(param.name));
|
|
if (!isSpeechAudioModel(...modelIdentifiers)) return nextSchema;
|
|
return [SPEECH_VOICE_PARAMETER, ...nextSchema];
|
|
}
|
|
|