mirror of
https://github.com/ndarilek/tts-rs.git
synced 2024-11-23 07:09:37 +00:00
Implement utterance_stop callback on most platforms.
This commit is contained in:
parent
174011bbb4
commit
8c783205c3
|
@ -34,4 +34,4 @@ objc = "0.2"
|
||||||
|
|
||||||
[target.wasm32-unknown-unknown.dependencies]
|
[target.wasm32-unknown-unknown.dependencies]
|
||||||
wasm-bindgen = "0.2"
|
wasm-bindgen = "0.2"
|
||||||
web-sys = { version = "0.3", features = ["EventTarget", "SpeechSynthesis", "SpeechSynthesisEvent", "SpeechSynthesisUtterance", "Window", ] }
|
web-sys = { version = "0.3", features = ["EventTarget", "SpeechSynthesis", "SpeechSynthesisErrorCode", "SpeechSynthesisErrorEvent", "SpeechSynthesisEvent", "SpeechSynthesisUtterance", "Window", ] }
|
||||||
|
|
|
@ -46,9 +46,16 @@ impl SpeechDispatcher {
|
||||||
f(utterance_id);
|
f(utterance_id);
|
||||||
}
|
}
|
||||||
})));
|
})));
|
||||||
sd.0.on_cancel(Some(Box::new(|_msg_id, client_id| {
|
sd.0.on_cancel(Some(Box::new(|msg_id, client_id| {
|
||||||
let mut speaking = SPEAKING.lock().unwrap();
|
let mut speaking = SPEAKING.lock().unwrap();
|
||||||
speaking.insert(client_id, false);
|
speaking.insert(client_id, false);
|
||||||
|
let mut callbacks = CALLBACKS.lock().unwrap();
|
||||||
|
let backend_id = BackendId::SpeechDispatcher(client_id);
|
||||||
|
let cb = callbacks.get_mut(&backend_id).unwrap();
|
||||||
|
let utterance_id = UtteranceId::SpeechDispatcher(msg_id);
|
||||||
|
if let Some(f) = cb.utterance_stop.as_mut() {
|
||||||
|
f(utterance_id);
|
||||||
|
}
|
||||||
})));
|
})));
|
||||||
sd.0.on_pause(Some(Box::new(|_msg_id, client_id| {
|
sd.0.on_pause(Some(Box::new(|_msg_id, client_id| {
|
||||||
let mut speaking = SPEAKING.lock().unwrap();
|
let mut speaking = SPEAKING.lock().unwrap();
|
||||||
|
|
|
@ -5,7 +5,10 @@ use lazy_static::lazy_static;
|
||||||
use log::{info, trace};
|
use log::{info, trace};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
use web_sys::{SpeechSynthesisEvent, SpeechSynthesisUtterance};
|
use web_sys::{
|
||||||
|
SpeechSynthesisErrorCode, SpeechSynthesisErrorEvent, SpeechSynthesisEvent,
|
||||||
|
SpeechSynthesisUtterance,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{Backend, BackendId, Error, Features, UtteranceId, CALLBACKS};
|
use crate::{Backend, BackendId, Error, Features, UtteranceId, CALLBACKS};
|
||||||
|
|
||||||
|
@ -85,6 +88,18 @@ impl Backend for Web {
|
||||||
mappings.retain(|v| v.1 != utterance_id);
|
mappings.retain(|v| v.1 != utterance_id);
|
||||||
}) as Box<dyn Fn(_)>);
|
}) as Box<dyn Fn(_)>);
|
||||||
utterance.set_onend(Some(callback.as_ref().unchecked_ref()));
|
utterance.set_onend(Some(callback.as_ref().unchecked_ref()));
|
||||||
|
let callback = Closure::wrap(Box::new(move |evt: SpeechSynthesisErrorEvent| {
|
||||||
|
if evt.error() == SpeechSynthesisErrorCode::Cancel {
|
||||||
|
let mut callbacks = CALLBACKS.lock().unwrap();
|
||||||
|
let callback = callbacks.get_mut(&id).unwrap();
|
||||||
|
if let Some(f) = callback.utterance_stop.as_mut() {
|
||||||
|
f(utterance_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||||
|
mappings.retain(|v| v.1 != utterance_id);
|
||||||
|
}) as Box<dyn Fn(_)>);
|
||||||
|
utterance.set_onerror(Some(callback.as_ref().unchecked_ref()));
|
||||||
if interrupt {
|
if interrupt {
|
||||||
self.stop()?;
|
self.stop()?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ impl WinRT {
|
||||||
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
let mut mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||||
let mut callbacks = CALLBACKS.lock().unwrap();
|
let mut callbacks = CALLBACKS.lock().unwrap();
|
||||||
let callbacks = callbacks.get_mut(&self.id).unwrap();
|
let callbacks = callbacks.get_mut(&self.id).unwrap();
|
||||||
if let Some(callback) = callbacks.utterance_end.as_mut() {
|
if let Some(callback) = callbacks.utterance_stop.as_mut() {
|
||||||
let mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
let mappings = UTTERANCE_MAPPINGS.lock().unwrap();
|
||||||
for mapping in &*mappings {
|
for mapping in &*mappings {
|
||||||
callback(mapping.2);
|
callback(mapping.2);
|
||||||
|
|
22
src/lib.rs
22
src/lib.rs
|
@ -134,6 +134,7 @@ pub trait Backend {
|
||||||
struct Callbacks {
|
struct Callbacks {
|
||||||
utterance_begin: Option<Box<dyn FnMut(UtteranceId)>>,
|
utterance_begin: Option<Box<dyn FnMut(UtteranceId)>>,
|
||||||
utterance_end: Option<Box<dyn FnMut(UtteranceId)>>,
|
utterance_end: Option<Box<dyn FnMut(UtteranceId)>>,
|
||||||
|
utterance_stop: Option<Box<dyn FnMut(UtteranceId)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Callbacks {}
|
unsafe impl Send for Callbacks {}
|
||||||
|
@ -474,6 +475,27 @@ impl TTS {
|
||||||
Err(Error::UnsupportedFeature)
|
Err(Error::UnsupportedFeature)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Called when this speech synthesizer is stopped and still has utterances in its queue.
|
||||||
|
*/
|
||||||
|
pub fn on_utterance_stop(
|
||||||
|
&self,
|
||||||
|
callback: Option<Box<dyn FnMut(UtteranceId)>>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let Features {
|
||||||
|
utterance_callbacks,
|
||||||
|
..
|
||||||
|
} = self.supported_features();
|
||||||
|
if utterance_callbacks {
|
||||||
|
let mut callbacks = CALLBACKS.lock().unwrap();
|
||||||
|
let id = self.0.id().unwrap();
|
||||||
|
let mut callbacks = callbacks.get_mut(&id).unwrap();
|
||||||
|
callbacks.utterance_stop = callback;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(Error::UnsupportedFeature)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for TTS {
|
impl Drop for TTS {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user