llm 旁白解决
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m58s
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3m58s
This commit is contained in:
parent
ef45abd19e
commit
2d08a3963f
@ -1,5 +1,35 @@
|
|||||||
// 以流式方式请求LLM大模型接口,并打印流式返回内容
|
// 以流式方式请求LLM大模型接口,并打印流式返回内容
|
||||||
|
|
||||||
|
// 过滤旁白内容的函数
|
||||||
|
function filterNarration(text) {
|
||||||
|
if (!text) return text;
|
||||||
|
|
||||||
|
// 匹配各种括号内的旁白内容
|
||||||
|
// 包括:()、【】、[]、{}、〈〉、《》等
|
||||||
|
const narrationPatterns = [
|
||||||
|
/([^)]*)/g, // 中文圆括号
|
||||||
|
/\([^)]*\)/g, // 英文圆括号
|
||||||
|
/【[^】]*】/g, // 中文方括号
|
||||||
|
/\[[^\]]*\]/g, // 英文方括号
|
||||||
|
/\{[^}]*\}/g, // 花括号
|
||||||
|
/〈[^〉]*〉/g, // 中文尖括号
|
||||||
|
/《[^》]*》/g, // 中文书名号
|
||||||
|
/<[^>]*>/g // 英文尖括号
|
||||||
|
];
|
||||||
|
|
||||||
|
let filteredText = text;
|
||||||
|
|
||||||
|
// 逐个应用过滤规则
|
||||||
|
narrationPatterns.forEach(pattern => {
|
||||||
|
filteredText = filteredText.replace(pattern, '');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 清理多余的空格和换行
|
||||||
|
filteredText = filteredText.replace(/\s+/g, ' ').trim();
|
||||||
|
|
||||||
|
return filteredText;
|
||||||
|
}
|
||||||
|
|
||||||
async function requestLLMStream({ apiKey, model, messages, onSegment }) {
|
async function requestLLMStream({ apiKey, model, messages, onSegment }) {
|
||||||
const response = await fetch('https://ark.cn-beijing.volces.com/api/v3/bots/chat/completions', {
|
const response = await fetch('https://ark.cn-beijing.volces.com/api/v3/bots/chat/completions', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -54,7 +84,14 @@ async function requestLLMStream({ apiKey, model, messages, onSegment }) {
|
|||||||
// 处理最后的待处理文本(无论长度是否大于5个字)
|
// 处理最后的待处理文本(无论长度是否大于5个字)
|
||||||
if (pendingText.trim() && onSegment) {
|
if (pendingText.trim() && onSegment) {
|
||||||
console.log('处理最后的待处理文本:', pendingText.trim());
|
console.log('处理最后的待处理文本:', pendingText.trim());
|
||||||
await onSegment(pendingText.trim(), true);
|
// 过滤旁白内容
|
||||||
|
const filteredText = filterNarration(pendingText.trim());
|
||||||
|
if (filteredText.trim()) {
|
||||||
|
console.log('过滤旁白后的最后文本:', filteredText);
|
||||||
|
await onSegment(filteredText, true);
|
||||||
|
} else {
|
||||||
|
console.log('最后的文本被完全过滤,跳过');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -65,12 +102,15 @@ async function requestLLMStream({ apiKey, model, messages, onSegment }) {
|
|||||||
const deltaContent = obj.choices[0].delta.content;
|
const deltaContent = obj.choices[0].delta.content;
|
||||||
content += deltaContent;
|
content += deltaContent;
|
||||||
pendingText += deltaContent;
|
pendingText += deltaContent;
|
||||||
console.log('LLM内容片段:', deltaContent);
|
console.log('【未过滤】LLM内容片段:', pendingText);
|
||||||
|
|
||||||
// 检查是否包含分段分隔符
|
// 先过滤旁白,再检查分段分隔符
|
||||||
if (segmentDelimiters.test(pendingText)) {
|
const filteredPendingText = filterNarration(pendingText);
|
||||||
// 按分隔符分割文本
|
|
||||||
const segments = pendingText.split(segmentDelimiters);
|
// 检查过滤后的文本是否包含分段分隔符
|
||||||
|
if (segmentDelimiters.test(filteredPendingText)) {
|
||||||
|
// 按分隔符分割已过滤的文本
|
||||||
|
const segments = filteredPendingText.split(segmentDelimiters);
|
||||||
|
|
||||||
// 重新组合处理:只处理足够长的完整段落
|
// 重新组合处理:只处理足够长的完整段落
|
||||||
let accumulatedText = '';
|
let accumulatedText = '';
|
||||||
@ -81,25 +121,30 @@ async function requestLLMStream({ apiKey, model, messages, onSegment }) {
|
|||||||
if (segment) {
|
if (segment) {
|
||||||
accumulatedText += segment;
|
accumulatedText += segment;
|
||||||
// 找到分隔符
|
// 找到分隔符
|
||||||
const delimiterMatch = pendingText.match(segmentDelimiters);
|
const delimiterMatch = filteredPendingText.match(segmentDelimiters);
|
||||||
if (delimiterMatch) {
|
if (delimiterMatch) {
|
||||||
accumulatedText += delimiterMatch[0];
|
accumulatedText += delimiterMatch[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果累积文本长度大于5个字,处理它
|
// 如果累积文本长度大于5个字,处理它
|
||||||
if (accumulatedText.length > 6 && onSegment) {
|
if (accumulatedText.length > 8 && onSegment) {
|
||||||
console.log('检测到完整段落:', accumulatedText);
|
console.log('【已过滤】检测到完整段落:', accumulatedText);
|
||||||
|
// 文本已经过滤过旁白,直接使用
|
||||||
|
if (accumulatedText.trim()) {
|
||||||
|
console.log('处理过滤后的文本:', accumulatedText);
|
||||||
await onSegment(accumulatedText, false);
|
await onSegment(accumulatedText, false);
|
||||||
|
}
|
||||||
hasProcessed = true;
|
hasProcessed = true;
|
||||||
accumulatedText = ''; // 重置
|
accumulatedText = ''; // 重置
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新pendingText
|
// 更新pendingText - 使用原始文本但需要相应调整
|
||||||
if (hasProcessed) {
|
if (hasProcessed) {
|
||||||
// 保留未处理的累积文本和最后一个不完整段落
|
// 计算已处理的原始文本长度,更新pendingText
|
||||||
pendingText = accumulatedText + (segments[segments.length - 1] || '');
|
const processedLength = pendingText.length - (segments[segments.length - 1] || '').length;
|
||||||
|
pendingText = pendingText.substring(processedLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user