mirror of
https://github.com/mii443/ncb-tts-r2.git
synced 2025-08-22 16:15:29 +00:00
auto load voiecvox speaker list
This commit is contained in:
@ -7,8 +7,8 @@ use serenity::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
data::DatabaseClientData,
|
||||
tts::{tts_type::TTSType, voicevox::voicevox::VOICEVOX},
|
||||
data::{DatabaseClientData, TTSClientData},
|
||||
tts::tts_type::TTSType,
|
||||
};
|
||||
|
||||
pub async fn config_command(
|
||||
@ -30,6 +30,12 @@ pub async fn config_command(
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let tts_client = data_read
|
||||
.get::<TTSClientData>()
|
||||
.expect("Cannot get TTSClientData")
|
||||
.clone();
|
||||
let voicevox_speakers = tts_client.lock().await.1.get_styles().await;
|
||||
|
||||
let voicevox_speaker = config.voicevox_speaker.unwrap_or(1);
|
||||
let tts_type = config.tts_type.unwrap_or(TTSType::GCP);
|
||||
|
||||
@ -65,7 +71,7 @@ pub async fn config_command(
|
||||
m.custom_id("TTS_CONFIG_VOICEVOX_SPEAKER")
|
||||
.options(|o| {
|
||||
let mut o = o;
|
||||
for (name, value) in VOICEVOX::get_speakers() {
|
||||
for (name, value) in voicevox_speakers {
|
||||
o = o.create_option(|co| {
|
||||
co.label(name)
|
||||
.value(format!(
|
||||
|
@ -6,7 +6,10 @@ use serenity::{
|
||||
prelude::Context,
|
||||
};
|
||||
|
||||
use crate::{data::TTSData, tts::instance::TTSInstance};
|
||||
use crate::{
|
||||
data::{TTSClientData, TTSData},
|
||||
tts::instance::TTSInstance,
|
||||
};
|
||||
|
||||
pub async fn setup_command(
|
||||
ctx: &Context,
|
||||
@ -138,11 +141,29 @@ pub async fn setup_command(
|
||||
.await?;
|
||||
let _handler = manager.join(guild.id.0, channel_id.0).await;
|
||||
|
||||
text_channel_id.send_message(&ctx.http, |f| f.embed(|e| e.title("読み上げ (Serenity)")
|
||||
.field("クレジット", "```\n四国めたん ずんだもん\n春日部つむぎ 雨晴はう\n波音リツ 玄野武宏\n白上虎太郎 青山龍星\n冥鳴ひまり 九州そら\nモチノ・キョウコ\nナースロボ_タイプT```", false)
|
||||
let tts_client = ctx
|
||||
.data
|
||||
.read()
|
||||
.await
|
||||
.get::<TTSClientData>()
|
||||
.expect("Cannot get TTSClientData")
|
||||
.clone();
|
||||
let voicevox_speakers = tts_client.lock().await.1.get_speakers().await;
|
||||
|
||||
text_channel_id
|
||||
.send_message(&ctx.http, |f| {
|
||||
f.embed(|e| {
|
||||
e.title("読み上げ (Serenity)")
|
||||
.field(
|
||||
"VOICEVOXクレジット",
|
||||
format!("```\n{}\n```", voicevox_speakers.join("\n")),
|
||||
false,
|
||||
)
|
||||
.field("設定コマンド", "`/config`", false)
|
||||
.field("フィードバック", "https://feedback.mii.codes/", false)
|
||||
)).await?;
|
||||
})
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
data::{DatabaseClientData, TTSData},
|
||||
data::{DatabaseClientData, TTSClientData, TTSData},
|
||||
implement::{
|
||||
member_name::ReadName,
|
||||
voice_move_state::{VoiceMoveState, VoiceMoveStateTrait},
|
||||
@ -65,10 +65,30 @@ pub async fn voice_state_update(ctx: Context, old: Option<VoiceState>, new: Voic
|
||||
);
|
||||
|
||||
let _handler = manager.join(guild_id.0, new_channel.0).await;
|
||||
new_channel.send_message(&ctx.http, |f| f.embed(|e| e.title("読み上げ (Serenity)")
|
||||
.field("クレジット", "```\n四国めたん ずんだもん\n春日部つむぎ 雨晴はう\n波音リツ 玄野武宏\n白上虎太郎 青山龍星\n冥鳴ひまり 九州そら\nモチノ・キョウコ\nナースロボ_タイプT```", false)
|
||||
.field("設定コマンド", "`/config`", false)
|
||||
.field("フィードバック", "https://feedback.mii.codes/", false))).await.unwrap();
|
||||
let tts_client = ctx
|
||||
.data
|
||||
.read()
|
||||
.await
|
||||
.get::<TTSClientData>()
|
||||
.expect("Cannot get TTSClientData")
|
||||
.clone();
|
||||
let voicevox_speakers = tts_client.lock().await.1.get_speakers().await;
|
||||
|
||||
new_channel
|
||||
.send_message(&ctx.http, |f| {
|
||||
f.embed(|e| {
|
||||
e.title("自動参加 読み上げ (Serenity)")
|
||||
.field(
|
||||
"VOICEVOXクレジット",
|
||||
format!("```\n{}\n```", voicevox_speakers.join("\n")),
|
||||
false,
|
||||
)
|
||||
.field("設定コマンド", "`/config`", false)
|
||||
.field("フィードバック", "https://feedback.mii.codes/", false)
|
||||
})
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub mod accent_phrase;
|
||||
pub mod audio_query;
|
||||
pub mod mora;
|
||||
pub mod speaker;
|
||||
|
21
src/tts/voicevox/structs/speaker.rs
Normal file
21
src/tts/voicevox/structs/speaker.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Speaker {
|
||||
pub supported_features: SupportedFeatures,
|
||||
pub name: String,
|
||||
pub speaker_uuid: String,
|
||||
pub styles: Vec<Style>,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct SupportedFeatures {
|
||||
pub permitted_synthesis_morphing: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct Style {
|
||||
pub name: String,
|
||||
pub id: i64,
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
const API_URL: &str = "https://api.su-shiki.com/v2/voicevox/audio";
|
||||
use super::structs::speaker::Speaker;
|
||||
|
||||
const BASE_API_URL: &str = "https://deprecatedapis.tts.quest/v2/";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct VOICEVOX {
|
||||
@ -6,40 +8,47 @@ pub struct VOICEVOX {
|
||||
}
|
||||
|
||||
impl VOICEVOX {
|
||||
pub fn get_speakers() -> Vec<(String, i64)> {
|
||||
vec![
|
||||
("四国めたん - ノーマル".to_string(), 2),
|
||||
("四国めたん - あまあま".to_string(), 0),
|
||||
("四国めたん - ツンツン".to_string(), 6),
|
||||
("四国めたん - セクシー".to_string(), 4),
|
||||
("ずんだもん - ノーマル".to_string(), 3),
|
||||
("ずんだもん - あまあま".to_string(), 1),
|
||||
("ずんだもん - ツンツン".to_string(), 7),
|
||||
("ずんだもん - セクシー".to_string(), 5),
|
||||
("春日部つむぎ - ノーマル".to_string(), 8),
|
||||
("雨晴はう - ノーマル".to_string(), 10),
|
||||
("波音リツ - ノーマル".to_string(), 9),
|
||||
("玄野武宏 - ノーマル".to_string(), 11),
|
||||
("白上虎太郎 - ノーマル".to_string(), 12),
|
||||
("青山龍星 - ノーマル".to_string(), 13),
|
||||
("冥鳴ひまり - ノーマル".to_string(), 14),
|
||||
("九州そら - ノーマル".to_string(), 16),
|
||||
("九州そら - あまあま".to_string(), 15),
|
||||
("九州そら - ツンツン".to_string(), 18),
|
||||
("九州そら - セクシー".to_string(), 17),
|
||||
("九州そら - ささやき".to_string(), 19),
|
||||
("モチノ・キョウコ - ノーマル".to_string(), 20),
|
||||
("ナースロボ_タイプT - ノーマル".to_string(), 47),
|
||||
("ナースロボ_タイプT - 楽々".to_string(), 48),
|
||||
("ナースロボ_タイプT - 恐怖".to_string(), 49),
|
||||
("ナースロボ_タイプT - 内緒話".to_string(), 50),
|
||||
]
|
||||
pub async fn get_styles(&self) -> Vec<(String, i64)> {
|
||||
let speakers = self.get_speaker_list().await;
|
||||
let mut speaker_list = vec![];
|
||||
for speaker in speakers {
|
||||
for style in speaker.styles {
|
||||
speaker_list.push((format!("{} - {}", speaker.name, style.name), style.id))
|
||||
}
|
||||
}
|
||||
|
||||
speaker_list
|
||||
}
|
||||
|
||||
pub async fn get_speakers(&self) -> Vec<String> {
|
||||
let speakers = self.get_speaker_list().await;
|
||||
let mut speaker_list = vec![];
|
||||
for speaker in speakers {
|
||||
speaker_list.push(speaker.name)
|
||||
}
|
||||
|
||||
speaker_list
|
||||
}
|
||||
|
||||
pub fn new(key: String) -> Self {
|
||||
Self { key }
|
||||
}
|
||||
|
||||
async fn get_speaker_list(&self) -> Vec<Speaker> {
|
||||
let client = reqwest::Client::new();
|
||||
match client
|
||||
.post(BASE_API_URL.to_string() + "voicevox/speakers/")
|
||||
.query(&[("key", self.key.clone())])
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(response) => response.json().await.unwrap(),
|
||||
Err(err) => {
|
||||
panic!("Cannot get speaker list. {err:?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn synthesize(
|
||||
&self,
|
||||
text: String,
|
||||
@ -47,7 +56,7 @@ impl VOICEVOX {
|
||||
) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
|
||||
let client = reqwest::Client::new();
|
||||
match client
|
||||
.post(API_URL)
|
||||
.post(BASE_API_URL.to_string() + "voicevox/audio/")
|
||||
.query(&[
|
||||
("speaker", speaker.to_string()),
|
||||
("text", text),
|
||||
|
Reference in New Issue
Block a user