feat: play cached TTS audio immediately on auto-start if already generated
This commit is contained in:
@@ -2922,21 +2922,43 @@ const chapterTmpl = `
|
||||
navigator.mediaSession.setActionHandler('seekto', function(d) { if (isFinite(d.seekTime)) { audio.currentTime = d.seekTime; updateSeek(); } });
|
||||
}
|
||||
|
||||
function loadAndPlay(url) {
|
||||
// Always set autoplay=true before load(): the browser needs this hint set
|
||||
// synchronously before load() regardless of whether we got here via a user
|
||||
// gesture or a programmatic trigger (e.g. chapter transition). The canplay
|
||||
// handler will call play() as well, but autoplay on the element is the only
|
||||
// reliable path after an async fetch where the gesture stack is gone.
|
||||
audio.autoplay = true;
|
||||
audio.src = url; audio.load();
|
||||
audio.playbackRate = getSpeed();
|
||||
registerMediaSession();
|
||||
}
|
||||
|
||||
function startAudio(autoplay) {
|
||||
setGenerating();
|
||||
highlightPara(0);
|
||||
generateAudio(CHAPTER_N, function (url) {
|
||||
if (stale()) return;
|
||||
// Always set autoplay=true before load(): the browser needs this hint set
|
||||
// synchronously before load() regardless of whether we got here via a user
|
||||
// gesture or a programmatic trigger (e.g. chapter transition). The canplay
|
||||
// handler will call play() as well, but autoplay on the element is the only
|
||||
// reliable path after an async fetch where the gesture stack is gone.
|
||||
audio.autoplay = true;
|
||||
audio.src = url; audio.load();
|
||||
audio.playbackRate = getSpeed();
|
||||
registerMediaSession();
|
||||
});
|
||||
// Check if audio was already generated for this chapter this session.
|
||||
// If so, play it directly without re-generating.
|
||||
fetch('/ui/audio/' + SLUG + '/' + CHAPTER_N + '?voice=' + encodeURIComponent(voiceSel.value) + '&speed=1')
|
||||
.then(function(res) {
|
||||
if (stale()) return;
|
||||
if (res.ok) {
|
||||
return res.json().then(function(data) {
|
||||
if (stale()) return;
|
||||
if (data && data.url) { loadAndPlay(data.url); return; }
|
||||
throw new Error('no url in response');
|
||||
});
|
||||
}
|
||||
// Not cached yet — fall through to generation.
|
||||
generateAudio(CHAPTER_N, function(url) {
|
||||
if (stale()) return;
|
||||
loadAndPlay(url);
|
||||
});
|
||||
})
|
||||
.catch(function(e) {
|
||||
if (stale()) return;
|
||||
setError(e.message);
|
||||
});
|
||||
}
|
||||
|
||||
window.ttsToggle = function () {
|
||||
|
||||
Reference in New Issue
Block a user