diff --git a/modules/tts/tts-text.js b/modules/tts/tts-text.js index 80c186d..97aa756 100644 --- a/modules/tts/tts-text.js +++ b/modules/tts/tts-text.js @@ -169,7 +169,7 @@ export function parseTtsSegments(text) { // ============ 非鉴权分段切割 ============ -const FREE_MAX_TEXT = 200; +const FREE_MAX_TEXT = 1000; const FREE_MIN_TEXT = 50; const FREE_SENTENCE_DELIMS = new Set(['。', '!', '?', '!', '?', ';', ';', '…', '.', ',', ',', '、', ':', ':']); @@ -230,8 +230,46 @@ function splitTextForFree(text, maxLength = FREE_MAX_TEXT) { export function splitTtsSegmentsForFree(segments, maxLength = FREE_MAX_TEXT) { if (!Array.isArray(segments) || !segments.length) return []; - const out = []; + const normalizedSegments = []; + + // In free mode, only explicit speaker directives are semantic split points. + // Adjacent segments without speaker= are merged to reduce request count. + let mergeBuffer = null; + const flushMergeBuffer = () => { + if (!mergeBuffer) return; + normalizedSegments.push(mergeBuffer); + mergeBuffer = null; + }; + for (const seg of segments) { + const hasExplicitSpeaker = !!String(seg?.speaker || '').trim(); + const text = String(seg?.text || '').trim(); + if (!text) continue; + + if (hasExplicitSpeaker) { + flushMergeBuffer(); + normalizedSegments.push({ + ...seg, + text, + }); + continue; + } + + if (!mergeBuffer) { + mergeBuffer = { + ...seg, + text, + speaker: '', + }; + continue; + } + + mergeBuffer.text += `\n${text}`; + } + flushMergeBuffer(); + + const out = []; + for (const seg of normalizedSegments) { const parts = splitTextForFree(seg.text, maxLength); if (!parts.length) continue; let buffer = '';