Preload media assets and refine process cursors
This commit is contained in:
@@ -39,6 +39,7 @@ class SentenceQueueModule extends BaseModule {
|
||||
'getPreparedSentence',
|
||||
'prefetchAhead',
|
||||
'prepareSpeechMetadata',
|
||||
'preloadAssetsForItem',
|
||||
'normalizeTtsText',
|
||||
'runTtsPreloadWithTimeout',
|
||||
'cancelBlockingGeneration',
|
||||
@@ -400,12 +401,7 @@ class SentenceQueueModule extends BaseModule {
|
||||
|
||||
try {
|
||||
if (metadata.type && !['paragraph', 'heading'].includes(metadata.type)) {
|
||||
if (metadata.type === 'music') {
|
||||
const audioManager = this.getModule('audio-manager');
|
||||
if (audioManager && typeof audioManager.playMusic === 'function') {
|
||||
audioManager.getAssetUrl('music', metadata.filename);
|
||||
}
|
||||
}
|
||||
await this.preloadAssetsForItem(metadata, { blocking: true, sentenceId: id });
|
||||
|
||||
return {
|
||||
id,
|
||||
@@ -425,7 +421,10 @@ class SentenceQueueModule extends BaseModule {
|
||||
|
||||
const audioManager = this.getModule('audio-manager');
|
||||
if (audioManager && typeof audioManager.preloadMediaCues === 'function') {
|
||||
await audioManager.preloadMediaCues(metadata.cueMarkers || []);
|
||||
await this.preloadAssetsForItem({
|
||||
type: 'paragraph',
|
||||
cueMarkers: metadata.cueMarkers || []
|
||||
}, { blocking: true, sentenceId: id });
|
||||
}
|
||||
|
||||
const ttsData = await this.prepareSpeechMetadata(text, {
|
||||
@@ -597,6 +596,44 @@ class SentenceQueueModule extends BaseModule {
|
||||
}
|
||||
}
|
||||
|
||||
async preloadAssetsForItem(item = {}, context = {}) {
|
||||
const audioManager = this.getModule('audio-manager');
|
||||
if (!audioManager) return;
|
||||
|
||||
const tasks = [];
|
||||
const type = String(item.type || item.kind || '').toLowerCase();
|
||||
if (['image', 'music', 'sfx', 'sound'].includes(type) && typeof audioManager.preloadStructuredBlock === 'function') {
|
||||
tasks.push(audioManager.preloadStructuredBlock(item));
|
||||
}
|
||||
if (Array.isArray(item.cueMarkers) && item.cueMarkers.length > 0 && typeof audioManager.preloadMediaCues === 'function') {
|
||||
tasks.push(audioManager.preloadMediaCues(item.cueMarkers));
|
||||
}
|
||||
|
||||
const pending = tasks.filter(Boolean);
|
||||
if (pending.length === 0) return;
|
||||
|
||||
const state = context.blocking ? 'waiting-generating' : 'playing-generating';
|
||||
document.dispatchEvent(new CustomEvent('story:process-state', {
|
||||
detail: {
|
||||
state,
|
||||
reason: 'asset-preload-start',
|
||||
sentenceId: context.sentenceId || item.id || null,
|
||||
assetType: type || 'cue'
|
||||
}
|
||||
}));
|
||||
|
||||
await Promise.all(pending);
|
||||
|
||||
document.dispatchEvent(new CustomEvent('story:process-state', {
|
||||
detail: {
|
||||
state: 'playing-ready',
|
||||
reason: 'asset-preload-complete',
|
||||
sentenceId: context.sentenceId || item.id || null,
|
||||
assetType: type || 'cue'
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
shouldPauseAfterSentence(sentence) {
|
||||
if (sentence.kind !== 'paragraph' || this.shouldAutoplay()) {
|
||||
return false;
|
||||
@@ -684,16 +721,26 @@ class SentenceQueueModule extends BaseModule {
|
||||
}));
|
||||
console.log(`Process state: ${state}`, { reason: 'prefetch-start', sentenceId: nextItem.id, queueIndex: index });
|
||||
|
||||
const promise = (this.isSpeechItem(nextItem)
|
||||
? this.prepareSpeechMetadata(nextItem.text || '', {
|
||||
const promise = (async () => {
|
||||
await this.preloadAssetsForItem(nextItem, {
|
||||
sentenceId: nextItem.id,
|
||||
blocking: false,
|
||||
prefetch: true
|
||||
});
|
||||
|
||||
if (!this.isSpeechItem(nextItem)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.prepareSpeechMetadata(nextItem.text || '', {
|
||||
sentenceId: nextItem.id,
|
||||
blockId: nextItem.blockId ?? null,
|
||||
turnId: nextItem.turnId ?? null,
|
||||
queueIndex: index,
|
||||
prefetch: true,
|
||||
blocking: false
|
||||
})
|
||||
: Promise.resolve(null))
|
||||
});
|
||||
})()
|
||||
.then(() => {
|
||||
console.log('SentenceQueue: Prefetched queued speech/media', { sentenceId: nextItem.id, queueIndex: index });
|
||||
document.dispatchEvent(new CustomEvent('story:process-state', {
|
||||
|
||||
Reference in New Issue
Block a user