mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Upload speech marks file to gcs too
This commit is contained in:
parent
c482ad320b
commit
02ba753375
4 changed files with 48 additions and 13 deletions
|
|
@ -25,7 +25,7 @@ export class Speech {
|
|||
audioUrl!: string
|
||||
|
||||
@Column('text')
|
||||
speechMarks!: string
|
||||
speechMarksUrl!: string
|
||||
|
||||
@Column('text')
|
||||
voice!: string
|
||||
|
|
|
|||
|
|
@ -72,10 +72,11 @@ export function articleRouter() {
|
|||
})
|
||||
|
||||
router.get(
|
||||
'/:id/mp3',
|
||||
'/:id/:outputFormat',
|
||||
cors<express.Request>(corsConfig),
|
||||
async (req, res) => {
|
||||
const id = req.params.id
|
||||
const outputFormat = req.params.outputFormat
|
||||
const token = req.cookies?.auth || req.headers?.authorization
|
||||
if (!token || !jwt.verify(token, env.server.jwtSecret)) {
|
||||
return res.status(401).send({ errorCode: 'UNAUTHORIZED' })
|
||||
|
|
@ -83,15 +84,27 @@ export function articleRouter() {
|
|||
const { uid } = jwt.decode(token) as Claims
|
||||
|
||||
const startTime = Date.now()
|
||||
logger.info('Get article speech in mp3 format', {
|
||||
logger.info(`Get article speech in ${outputFormat} format`, {
|
||||
params: req.params,
|
||||
labels: {
|
||||
userId: uid,
|
||||
source: 'GetArticleSpeechMp3',
|
||||
articleId: id,
|
||||
outputFormat,
|
||||
},
|
||||
})
|
||||
|
||||
const existingSpeech = await getRepository(Speech).findOneBy({
|
||||
elasticPageId: id,
|
||||
})
|
||||
if (existingSpeech) {
|
||||
logger.info('Found existing speech', {
|
||||
audioUrl: existingSpeech.audioUrl,
|
||||
speechMarksUrl: existingSpeech.speechMarksUrl,
|
||||
})
|
||||
return res.redirect(redirectUrl(existingSpeech, outputFormat))
|
||||
}
|
||||
|
||||
logger.debug('Text to speech request', { articleId: id })
|
||||
const userPersonalization = await getRepository(
|
||||
UserPersonalization
|
||||
|
|
@ -112,27 +125,39 @@ export function articleRouter() {
|
|||
return res.status(200).send('Page has no text')
|
||||
}
|
||||
|
||||
const speech = await synthesizeTextToSpeech({
|
||||
const speechOutput = await synthesizeTextToSpeech({
|
||||
id,
|
||||
text,
|
||||
languageCode: page.language,
|
||||
voice: userPersonalization.speechVoice,
|
||||
})
|
||||
|
||||
await getRepository(Speech).save({
|
||||
const speech = await getRepository(Speech).save({
|
||||
elasticPageId: id,
|
||||
audioUrl: speech.audioUrl,
|
||||
speechMarks: JSON.stringify(speech.speechMarks),
|
||||
audioUrl: speechOutput.audioUrl,
|
||||
speechMarksUrl: speechOutput.speechMarksUrl,
|
||||
user: { id: uid },
|
||||
})
|
||||
|
||||
logger.info('Found speech mp3', {
|
||||
logger.info('Created speech', {
|
||||
audioUrl: speech.audioUrl,
|
||||
speechMarksUrl: speech.speechMarksUrl,
|
||||
duration: Date.now() - startTime,
|
||||
})
|
||||
res.redirect(speech.audioUrl)
|
||||
res.redirect(redirectUrl(speech, outputFormat))
|
||||
}
|
||||
)
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
const redirectUrl = (speech: Speech, outputFormat: string) => {
|
||||
switch (outputFormat) {
|
||||
case 'mp3':
|
||||
return speech.audioUrl
|
||||
case 'json':
|
||||
return speech.speechMarksUrl
|
||||
default:
|
||||
return speech.audioUrl
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { buildLogger } from './logger'
|
||||
import { createGCSFile, getFilePublicUrl } from './uploads'
|
||||
import { createGCSFile, getFilePublicUrl, uploadToBucket } from './uploads'
|
||||
import {
|
||||
CancellationDetails,
|
||||
CancellationReason,
|
||||
|
|
@ -21,7 +21,7 @@ export interface TextToSpeechInput {
|
|||
|
||||
export interface TextToSpeechOutput {
|
||||
audioUrl: string
|
||||
speechMarks: SpeechMark[]
|
||||
speechMarksUrl: string
|
||||
}
|
||||
|
||||
export interface SpeechMark {
|
||||
|
|
@ -142,9 +142,19 @@ export const synthesizeTextToSpeech = async (
|
|||
|
||||
logger.debug(`audio file: ${audioFile}`)
|
||||
|
||||
// upload Speech Marks file to GCS
|
||||
const speechMarksFile = `speech/${input.id}.json`
|
||||
await uploadToBucket(
|
||||
speechMarksFile,
|
||||
Buffer.from(JSON.stringify(speechMarks)),
|
||||
{
|
||||
public: true,
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
audioUrl: getFilePublicUrl(audioFile),
|
||||
speechMarks,
|
||||
speechMarksUrl: getFilePublicUrl(speechMarksFile),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ CREATE TABLE omnivore.speech (
|
|||
elastic_page_id TEXT NOT NULL,
|
||||
voice text,
|
||||
audio_url text NOT NULL,
|
||||
speech_marks text NOT NULL,
|
||||
speech_marks_url text NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT current_timestamp,
|
||||
updated_at timestamptz NOT NULL DEFAULT current_timestamp
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue