50 lines
1.8 KiB
JavaScript
50 lines
1.8 KiB
JavaScript
let _rehPrefetchRunning = false;
|
|
async function _rehPrefetchLines(fromIndex) {
|
|
if (_rehPrefetchRunning) return;
|
|
_rehPrefetchRunning = true;
|
|
try {
|
|
let prefetched = 0;
|
|
for (let i = fromIndex; i < rehState.lines.length && prefetched < 2; i++) {
|
|
if (!rehState.playing) break;
|
|
const l = rehState.lines[i];
|
|
if (!l || l.ignored || l.hidden || l.type === 'pagebreak') continue;
|
|
|
|
const isDialog = l.type === 'dialog';
|
|
const cast = isDialog ? (rehState.cast[l.speaker] || { voice: '' }) : null;
|
|
if (isDialog && (!cast.voice || cast.voice === 'me')) continue;
|
|
if (!isDialog && (!rehState.narratorVoice || !(l.text || '').trim() || rehState.skipDescriptions)) continue;
|
|
|
|
if (rehState.synthCache.has(i) && !rehState.staleLines.has(i)) {
|
|
prefetched++;
|
|
continue;
|
|
}
|
|
|
|
const voice = isDialog ? cast.voice : rehState.narratorVoice;
|
|
const cleanTxt = stripMarkdown(l.text);
|
|
const instruct = isDialog ? _buildInstruct((cast.instruct || '').trim(), l.emotion, voice) : '';
|
|
const text = isDialog ? _rehInlineTone(cleanTxt, l.emotion) : cleanTxt;
|
|
|
|
const book = _lineAudioBookName();
|
|
const cacheKey = await _lineAudioCacheKey(text, voice, instruct);
|
|
let blob = await _lineAudioCacheGet(book, cacheKey);
|
|
|
|
if (!blob) {
|
|
try {
|
|
blob = await fetchTtsPreviewBlob(voice, text, 'wav', instruct, _ttsBackendForVoice(voice, rehState.backend));
|
|
_lineAudioCachePut(book, cacheKey, blob);
|
|
} catch(e) {
|
|
console.warn('Prefetch failed for line', i, e);
|
|
continue; // skip counting as prefetched if it failed
|
|
}
|
|
}
|
|
|
|
rehState.synthCache.set(i, blob);
|
|
rehState.staleLines.delete(i);
|
|
_markSynthDot(i, 'ok');
|
|
prefetched++;
|
|
}
|
|
} finally {
|
|
_rehPrefetchRunning = false;
|
|
}
|
|
}
|