mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Detect word boundary only in speech marks
This commit is contained in:
parent
174afe0085
commit
d279790e81
1 changed files with 8 additions and 19 deletions
|
|
@ -1,10 +1,8 @@
|
|||
import {
|
||||
CancellationDetails,
|
||||
CancellationReason,
|
||||
PropertyId,
|
||||
ResultReason,
|
||||
SpeechConfig,
|
||||
SpeechSynthesisBoundaryType,
|
||||
SpeechSynthesisOutputFormat,
|
||||
SpeechSynthesisResult,
|
||||
SpeechSynthesizer,
|
||||
|
|
@ -32,7 +30,7 @@ export interface SpeechMark {
|
|||
start?: number
|
||||
length?: number
|
||||
word: string
|
||||
type: 'word' | 'bookmark' | 'punctuation' | 'sentence'
|
||||
type: 'word' | 'bookmark'
|
||||
}
|
||||
|
||||
export const synthesizeTextToSpeech = async (
|
||||
|
|
@ -49,17 +47,11 @@ export const synthesizeTextToSpeech = async (
|
|||
)
|
||||
speechConfig.speechSynthesisOutputFormat =
|
||||
SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3
|
||||
// Required for sentence-level WordBoundary events
|
||||
speechConfig.setProperty(
|
||||
PropertyId.SpeechServiceResponse_RequestSentenceBoundary,
|
||||
'true'
|
||||
)
|
||||
|
||||
// Create the speech synthesizer.
|
||||
const synthesizer = new SpeechSynthesizer(speechConfig)
|
||||
const speechMarks: SpeechMark[] = []
|
||||
let timeOffset = 0
|
||||
// let wordOffset = 0
|
||||
|
||||
synthesizer.synthesizing = function (s, e) {
|
||||
// convert arrayBuffer to stream and write to stream
|
||||
|
|
@ -94,14 +86,13 @@ export const synthesizeTextToSpeech = async (
|
|||
|
||||
// The unit of e.audioOffset is tick (1 tick = 100 nanoseconds), divide by 10,000 to convert to milliseconds.
|
||||
synthesizer.wordBoundary = (s, e) => {
|
||||
e.boundaryType === SpeechSynthesisBoundaryType.Sentence &&
|
||||
speechMarks.push({
|
||||
word: e.text,
|
||||
time: (timeOffset + e.audioOffset) / 10000,
|
||||
start: e.textOffset,
|
||||
length: e.text.length,
|
||||
type: 'sentence',
|
||||
})
|
||||
speechMarks.push({
|
||||
word: e.text,
|
||||
time: (timeOffset + e.audioOffset) / 10000,
|
||||
start: e.textOffset,
|
||||
length: e.text.length,
|
||||
type: 'word',
|
||||
})
|
||||
}
|
||||
|
||||
synthesizer.bookmarkReached = (s, e) => {
|
||||
|
|
@ -150,8 +141,6 @@ export const synthesizeTextToSpeech = async (
|
|||
const startSsmlTag = startSsml(ssmlOptions)
|
||||
const text = _.escape(input.text)
|
||||
const ssml = `${startSsmlTag}${text}${endSsml()}`
|
||||
// set the text offset to be the end of SSML start tag
|
||||
// wordOffset -= startSsmlTag.length
|
||||
const result = await speakSsmlAsyncPromise(ssml)
|
||||
if (result.reason === ResultReason.Canceled) {
|
||||
throw new Error(result.errorDetails)
|
||||
|
|
|
|||
Loading…
Reference in a new issue