Crates.io | msedge-tts |
lib.rs | msedge-tts |
version | 0.2.4 |
source | src |
created_at | 2024-01-24 17:14:34.829888 |
updated_at | 2024-11-25 11:15:57.563707 |
description | This library is a wrapper of MSEdge Read aloud function API. You can use it to synthesize text to speech with many voices MS provided. |
homepage | |
repository | https://github.com/hs-CN/msedge-tts |
max_upload_size | |
id | 1112630 |
size | 150,736 |
This library is a wrapper of MSEdge Read aloud function API. You can use it to synthesize text to speech with many voices MS provided.
SpeechConfig
to configure the voice of text to speech.Voice
to SpeechConfig
simply. Use get_voices_list
function to get all available voices.Voice
and SpeechConfig
implemented serde::Serialize
and serde::Deserialize
.use msedge_tts::voice::get_voices_list;
use msedge_tts::tts::SpeechConfig;
fn main() {
let voices = get_voices_list().unwrap();
let speechConfig = SpeechConfig::from(&voices[0]);
}
You can also create SpeechConfig
by yourself. Make sure you know the right voice name and audio format.Client
or Stream
. Both of them have sync and async version. Example below step 3.synthesize
to synthesize text to speech. This function return Type SynthesizedAudio
,
you can get audio_bytes
and audio_metadata
.
use msedge_tts::{tts::client::connect, tts::SpeechConfig, voice::get_voices_list};
fn main() {
let voices = get_voices_list().unwrap();
for voice in &voices {
if voice.name.contains("YunyangNeural") {
let config = SpeechConfig::from(voice);
let mut tts = connect().unwrap();
let audio = tts
.synthesize("Hello, World! 你好,世界!", &config)
.unwrap();
break;
}
}
}
synthesize
to synthesize text to speech. This function return Type SynthesizedAudio
,
you can get audio_bytes
and audio_metadata
.
use msedge_tts::{tts::client::connect_async, tts::SpeechConfig, voice::get_voices_list_async};
fn main() {
smol::block_on(async {
let voices = get_voices_list_async().await.unwrap();
for voice in &voices {
if voice.name.contains("YunyangNeural") {
let config = SpeechConfig::from(voice);
let mut tts = connect_async().await.unwrap();
let audio = tts
.synthesize("Hello, World! 你好,世界!", &config)
.await
.unwrap();
break;
}
}
});
}
send
to synthesize text to speech. Call Reader Stream function read
to get data.read
return Option<SynthesizedResponse>
, the response may be AudioBytes
or AudioMetadata
or None. This is because the MSEdge Read aloud API returns multiple data segment and metadata and other information sequentially.send
corresponds to multiple read
. Next send
call will block until there no data to read.
read
will block before you call a send
.
use msedge_tts::{
tts::stream::{msedge_tts_split, SynthesizedResponse},
tts::SpeechConfig,
voice::get_voices_list,
};
use std::{
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
thread::spawn,
};
fn main() {
let voices = get_voices_list().unwrap();
for voice in &voices {
if voice.name.contains("YunyangNeural") {
let config = SpeechConfig::from(voice);
let (mut sender, mut reader) = msedge_tts_split().unwrap();
let signal = Arc::new(AtomicBool::new(false));
let end = signal.clone();
spawn(move || {
sender.send("Hello, World! 你好,世界!", &config).unwrap();
println!("synthesizing...1");
sender.send("Hello, World! 你好,世界!", &config).unwrap();
println!("synthesizing...2");
sender.send("Hello, World! 你好,世界!", &config).unwrap();
println!("synthesizing...3");
sender.send("Hello, World! 你好,世界!", &config).unwrap();
println!("synthesizing...4");
end.store(true, Ordering::Relaxed);
});
loop {
if signal.load(Ordering::Relaxed) && !reader.can_read() {
break;
}
let audio = reader.read().unwrap();
if let Some(audio) = audio {
match audio {
SynthesizedResponse::AudioBytes(_) => {
println!("read bytes")
}
SynthesizedResponse::AudioMetadata(_) => {
println!("read metadata")
}
}
} else {
println!("read None");
}
}
}
}
}
send
to synthesize text to speech. Call Reader Async function read
to get data.
read
return Option<SynthesizedResponse>
as above.
send
and read
block as above.
use msedge_tts::{
tts::{
stream::{msedge_tts_split_async, SynthesizedResponse},
SpeechConfig,
},
voice::get_voices_list_async,
};
use std::{
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
};
fn main() {
smol::block_on(async {
let voices = get_voices_list_async().await.unwrap();
for voice in &voices {
if voice.name.contains("YunyangNeural") {
let config = SpeechConfig::from(voice);
let (mut sender, mut reader) = msedge_tts_split_async().await.unwrap();
let signal = Arc::new(AtomicBool::new(false));
let end = signal.clone();
smol::spawn(async move {
sender
.send("Hello, World! 你好,世界!", &config)
.await
.unwrap();
println!("synthesizing...1");
sender
.send("Hello, World! 你好,世界!", &config)
.await
.unwrap();
println!("synthesizing...2");
sender
.send("Hello, World! 你好,世界!", &config)
.await
.unwrap();
println!("synthesizing...3");
sender
.send("Hello, World! 你好,世界!", &config)
.await
.unwrap();
println!("synthesizing...4");
end.store(true, Ordering::Relaxed);
})
.detach();
loop {
if signal.load(Ordering::Relaxed) && !reader.can_read().await {
break;
}
let audio = reader.read().await.unwrap();
if let Some(audio) = audio {
match audio {
SynthesizedResponse::AudioBytes(_) => {
println!("read bytes")
}
SynthesizedResponse::AudioMetadata(_) => {
println!("read metadata")
}
}
} else {
println!("read None");
}
}
}
}
});
}
see all examples.