Merge pull request #1173 from omnivore-app/fix/speech

fix/speech
This commit is contained in:
Hongbo Wu 2022-09-08 11:21:51 +08:00 committed by GitHub
commit 3d11e9df8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 13 additions and 19 deletions

View file

@ -29,7 +29,7 @@ interface SpeechInput {
secondaryVoice?: string
priority?: 'low' | 'high'
}
const outputFormats = ['mp3', 'speech-marks', 'speech-file']
const outputFormats = ['mp3', 'speech-marks', 'speech']
const logger = buildLogger('app.dispatch')
export function articleRouter() {
@ -102,7 +102,7 @@ export function articleRouter() {
},
})
if (outputFormat === 'speech-file') {
if (outputFormat === 'speech') {
const page = await getPageById(articleId)
if (!page) {
return res.status(404).send('Page not found')
@ -112,7 +112,7 @@ export function articleRouter() {
secondaryVoice: secondaryVoice,
language: page.language,
})
return res.send(speechFile)
return res.send({ ...speechFile, pageId: articleId })
}
const existingSpeech = await getRepository(Speech).findOne({

View file

@ -7,7 +7,7 @@ declare module '@omnivore/text-to-speech-handler' {
export interface SSMLOptions {
primaryVoice?: string
secondaryVoice?: string
rate?: number
rate?: string
language?: string
}
@ -21,7 +21,6 @@ declare module '@omnivore/text-to-speech-handler' {
export interface SpeechFile {
wordCount: number
averageWPM: number
language: string
defaultVoice: string
utterances: Utterance[]

View file

@ -16,7 +16,6 @@ export interface Utterance {
export interface SpeechFile {
wordCount: number
averageWPM: number
language: string
defaultVoice: string
utterances: Utterance[]
@ -33,14 +32,13 @@ export type SSMLItem = {
export type SSMLOptions = {
primaryVoice?: string
secondaryVoice?: string
rate?: number
rate?: string
language?: string
}
const WORDS_PER_MINUTE = 200
const DEFAULT_LANGUAGE = 'en-US'
const DEFAULT_VOICE = 'en-US-JennyNeural'
const DEFAULT_RATE = 1.25
const DEFAULT_RATE = '1.0'
const ANCHOR_ELEMENTS_BLOCKED_ATTRIBUTES = [
'omnivore-highlight-id',
@ -300,14 +298,13 @@ export const htmlToSpeechFile = (
wordOffset,
node.nodeName === 'BLOCKQUOTE' ? options.secondaryVoice : undefined
)
utterances.push(utterance)
utterance.wordCount > 0 && utterances.push(utterance)
wordOffset += utterance.wordCount
}
}
return {
wordCount: wordOffset,
averageWPM: WORDS_PER_MINUTE,
language: options.language || DEFAULT_LANGUAGE,
defaultVoice: options.primaryVoice || DEFAULT_VOICE,
utterances,

View file

@ -13,7 +13,7 @@ import { htmlToSpeechFile } from './htmlToSsml'
interface UtteranceInput {
voice?: string
rate?: number
rate?: string
language?: string
text: string
idx: string
@ -24,7 +24,7 @@ interface HTMLInput {
text: string
voice?: string
language?: string
rate?: number
rate?: string
complimentaryVoice?: string
bucket: string
}
@ -160,9 +160,6 @@ export const textToSpeechStreamingHandler = Sentry.GCPFunction.wrapHttpFunction(
try {
const utteranceInput = req.body as UtteranceInput
if (!utteranceInput.text) {
return res.status(400).send({ errorCode: 'INVALID_DATA' })
}
const input: TextToSpeechInput = {
...utteranceInput,
textType: 'utterance',

View file

@ -8,13 +8,14 @@ import {
SpeechSynthesizer,
} from 'microsoft-cognitiveservices-speech-sdk'
import { endSsml, htmlToSsmlItems, ssmlItemText, startSsml } from './htmlToSsml'
import * as _ from 'underscore'
export interface TextToSpeechInput {
text: string
voice?: string
language?: string
textType?: 'html' | 'utterance'
rate?: number
rate?: string
secondaryVoice?: string
audioStream?: NodeJS.ReadWriteStream
}
@ -150,7 +151,7 @@ export const synthesizeTextToSpeech = async (
// for utterance
const start = startSsml(ssmlOptions)
wordOffset = -start.length
const ssml = `${start}${input.text}${endSsml()}`
const ssml = `${start}${_.escape(input.text)}${endSsml()}`
const result = await speakSsmlAsyncPromise(ssml)
return {
audioData: Buffer.from(result.audioData),

View file

@ -7,7 +7,7 @@ describe('htmlToSsmlItems', () => {
primaryVoice: 'test-primary',
secondaryVoice: 'test-secondary',
language: 'en-US',
rate: 1,
rate: '1.0',
}
describe('a simple html file', () => {