电子书馆增加听书功能
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
import { getBookTtsConfig, synthesizeBookTts } from '@/lib/book-tts';
|
||||
|
||||
import { getAuthorizedBooksUsername } from '../../_utils';
|
||||
|
||||
export const runtime = 'nodejs';
|
||||
|
||||
type SynthesizePayload = {
|
||||
sourceId?: string;
|
||||
bookId?: string;
|
||||
chapterHref?: string;
|
||||
text?: string;
|
||||
voice?: string;
|
||||
rate?: string;
|
||||
pitch?: string;
|
||||
volume?: string;
|
||||
};
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
const username = await getAuthorizedBooksUsername(request);
|
||||
if (username instanceof NextResponse) return username;
|
||||
|
||||
try {
|
||||
const config = await getBookTtsConfig();
|
||||
const payload = await request.json() as SynthesizePayload;
|
||||
if (!payload.sourceId?.trim() || !payload.bookId?.trim() || !payload.chapterHref?.trim()) {
|
||||
return NextResponse.json({ error: '缺少 sourceId / bookId / chapterHref' }, { status: 400 });
|
||||
}
|
||||
|
||||
const result = await synthesizeBookTts({
|
||||
sourceId: payload.sourceId.trim(),
|
||||
bookId: payload.bookId.trim(),
|
||||
chapterHref: payload.chapterHref.trim(),
|
||||
text: payload.text?.trim() || '',
|
||||
voice: payload.voice?.trim() || config.defaultVoice,
|
||||
rate: payload.rate?.trim() || config.defaultRate,
|
||||
pitch: payload.pitch?.trim() || config.defaultPitch,
|
||||
volume: payload.volume?.trim() || config.defaultVolume,
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
audioBase64: result.audioBuffer.toString('base64'),
|
||||
mimeType: result.mimeType,
|
||||
boundaries: result.boundaries,
|
||||
cacheKey: result.cacheKey,
|
||||
cacheHit: result.cacheHit,
|
||||
});
|
||||
} catch (error) {
|
||||
return NextResponse.json({ error: (error as Error).message || '语音合成失败' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
import { getBookTtsConfig, listBookTtsVoices } from '@/lib/book-tts';
|
||||
|
||||
import { getAuthorizedBooksUsername } from '../../_utils';
|
||||
|
||||
export const runtime = 'nodejs';
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const username = await getAuthorizedBooksUsername(request);
|
||||
if (username instanceof NextResponse) return username;
|
||||
|
||||
try {
|
||||
const config = await getBookTtsConfig();
|
||||
const voices = await listBookTtsVoices();
|
||||
return NextResponse.json({
|
||||
voices,
|
||||
defaults: {
|
||||
voice: config.defaultVoice,
|
||||
rate: config.defaultRate,
|
||||
pitch: config.defaultPitch,
|
||||
volume: config.defaultVolume,
|
||||
maxCharsPerChunk: config.maxCharsPerChunk,
|
||||
prefetchChunks: config.prefetchChunks,
|
||||
maxTextLengthPerRequest: config.maxTextLengthPerRequest,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
return NextResponse.json({ error: (error as Error).message || '获取音色列表失败' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user