ow
This commit is contained in:
1 parent
39494fb5c3
commit
871de41ba5
9 files changed
+259
-49
No files matched your search
@@ -62,6 +62,20 @@ namespace CloudBuilder.Topshelf.Utility
|
||||
_originalErrorHandle = GetStdHandle(STD_ERROR_HANDLE);
|
||||
SetStdHandle(STD_ERROR_HANDLE, IntPtr.Zero);
|
||||
}
|
||||
|
||||
public static void UpdateProgress(int processed, int total)
|
||||
{
|
||||
double progressPercent = (double)processed / total * 100;
|
||||
int progressBarLength = 50; // 进度条总长度
|
||||
int filledLength = (int)(progressPercent / 100 * progressBarLength);
|
||||
|
||||
// 构建进度条(如:[██████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░])
|
||||
string progressBar = "[" + new string('█', filledLength) + new string('░', progressBarLength - filledLength) + "]";
|
||||
|
||||
string progressInfo = $"{progressBar} {progressPercent:F2}% | 已处理:{processed}/{total} ";
|
||||
Console.Write($"\r{progressInfo}");
|
||||
Console.Out.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace CloudBuilder.Topshelf.Utility
|
||||
|
||||
|
||||
|
||||
public static void AudioToFile(ChineseTtsVoice actorName, string text, string saveFilePath)
|
||||
public static void AudioToFile(ChineseTtsVoice actorName, float speed, string text, string saveFilePath)
|
||||
{
|
||||
InitConfig();
|
||||
int sid = 0;
|
||||
@@ -113,7 +113,7 @@ namespace CloudBuilder.Topshelf.Utility
|
||||
case ChineseTtsVoice.Fanchen14:
|
||||
case ChineseTtsVoice.Fanchen36:
|
||||
sid = actorName.GetSidId();
|
||||
audio = fanchenTTs.Generate(text, 1.0f, sid);
|
||||
audio = fanchenTTs.Generate(text, speed, sid);
|
||||
break;
|
||||
case ChineseTtsVoice.Sherpa0:
|
||||
case ChineseTtsVoice.Sherpa1:
|
||||
@@ -121,19 +121,19 @@ namespace CloudBuilder.Topshelf.Utility
|
||||
case ChineseTtsVoice.Sherpa3:
|
||||
case ChineseTtsVoice.Sherpa4:
|
||||
sid = actorName.GetSidId();
|
||||
audio = sherpaTTs.Generate(text, 1.0f, sid);
|
||||
audio = sherpaTTs.Generate(text, speed, sid);
|
||||
break;
|
||||
case ChineseTtsVoice.Melo:
|
||||
sid = actorName.GetSidId();
|
||||
audio = meloTTs.Generate(text, 1.0f, sid);
|
||||
audio = meloTTs.Generate(text, speed, sid);
|
||||
break;
|
||||
case ChineseTtsVoice.Eula:
|
||||
sid = actorName.GetSidId();
|
||||
audio = eulaTTs.Generate(text, 1.0f, sid);
|
||||
audio = eulaTTs.Generate(text, speed, sid);
|
||||
break;
|
||||
case ChineseTtsVoice.Theresa:
|
||||
sid = actorName.GetSidId();
|
||||
audio = theresaTTs.Generate(text, 1.0f, sid);
|
||||
audio = theresaTTs.Generate(text, speed, sid);
|
||||
break;
|
||||
case ChineseTtsVoice.Aaishe1:
|
||||
case ChineseTtsVoice.Aaishe6:
|
||||
@@ -142,11 +142,11 @@ namespace CloudBuilder.Topshelf.Utility
|
||||
case ChineseTtsVoice.Aaishe18:
|
||||
case ChineseTtsVoice.Aaishe10:
|
||||
sid = actorName.GetSidId();
|
||||
audio = icefallTTs.Generate(text, 1.0f, sid);
|
||||
audio = icefallTTs.Generate(text, speed, sid);
|
||||
break;
|
||||
default:
|
||||
sid = actorName.GetSidId();
|
||||
audio = matchaTTs.Generate(text, 1.0f, sid);
|
||||
audio = matchaTTs.Generate(text, speed, sid);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
using CloudBuilder.AI.Entity;
|
||||
using CloudBuilder.Core.DatabaseAccessor.Entity;
|
||||
using CloudBuilder.Topshelf.Python;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace CloudBuilder.Topshelf.Utility
|
||||
{
|
||||
@@ -104,7 +95,7 @@ namespace CloudBuilder.Topshelf.Utility
|
||||
}
|
||||
|
||||
//如果主语==动作发出者
|
||||
//if (!string.IsNullOrEmpty(person) && !ps.Contains(person) && !ps.Contains(string.Format("[{0}]", person))) ps.Add(string.Format("[{0}]", person));
|
||||
if (!string.IsNullOrEmpty(person) && !ps.Contains(person) && !ps.Contains(string.Format("[{0}]", person))) ps.Add(string.Format("【{0}】", person));
|
||||
//动作接受者
|
||||
//if (!string.IsNullOrEmpty(arg1) && !ps.Contains(arg1)) ps.Add(arg1);
|
||||
|
||||
@@ -191,22 +182,83 @@ namespace CloudBuilder.Topshelf.Utility
|
||||
|
||||
AiSentenceEntity aiSentence;
|
||||
string dialogueName = string.Empty;
|
||||
int totalLines = aiSentences.Length;
|
||||
int processedLines = 0; // 已处理行数计数器
|
||||
Console.WriteLine($"\r");
|
||||
foreach (AiSentenceViewEntity aiSentenceView in aiSentences)
|
||||
{
|
||||
dialogueName= string.Empty;
|
||||
aiSentenceView.PersonName = null;
|
||||
processedLines++;
|
||||
ConsoleOutput.UpdateProgress(processedLines, totalLines);
|
||||
if (aiSentenceView.DialogueIndc != YesNoPolicy.YES) continue;
|
||||
|
||||
//A说:“B,你好!”/“A,你好!”B对A说。
|
||||
if (aiSentences.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphId == aiSentenceView.ParagraphId).Count() > 1)
|
||||
{
|
||||
dialogueName = string.Empty;
|
||||
|
||||
//提取对话中的人物
|
||||
if (AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex == x.SentenceIndex).Any())
|
||||
{
|
||||
dialogueName = AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex == x.SentenceIndex).FirstOrDefault().PersonName;
|
||||
}
|
||||
//提取对话段落中,非对话内容中的人物
|
||||
if (AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex != x.SentenceIndex && x.PersonName != dialogueName).Any())
|
||||
{
|
||||
aiSentenceView.PersonName = AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex != x.SentenceIndex && x.PersonName != dialogueName).OrderBy(x => x.OrderIndex).FirstOrDefault().PersonName;
|
||||
|
||||
if (aiSentenceView.PersonName.Contains("【"))
|
||||
{
|
||||
aiSentenceView.PersonName = AiChapterPersons.Where(x => !x.PersonName.Contains("【") && x.PersonName.Contains(aiSentenceView.PersonName.Replace("【", "").Replace("】", ""))).FirstOrDefault()!.PersonName;
|
||||
}
|
||||
}
|
||||
//说话者在前面
|
||||
if (aiSentenceView.SentenceIndex == 2)
|
||||
{
|
||||
//如果没有提取到人物,优先向前,再向后
|
||||
if (string.IsNullOrEmpty(aiSentenceView.PersonName))
|
||||
{
|
||||
aiSentenceView.PersonName = GetForwardName(dialogueName, aiSentenceView, aiSentences);
|
||||
}
|
||||
//如果没有提取到人物,优先向前,再向后
|
||||
if (string.IsNullOrEmpty(aiSentenceView.PersonName))
|
||||
{
|
||||
aiSentenceView.PersonName = GetBackwardName(dialogueName, aiSentenceView, aiSentences);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrEmpty(aiSentenceView.PersonName))
|
||||
{
|
||||
aiSentenceView.PersonName = GetBackwardName(dialogueName, aiSentenceView, aiSentences);
|
||||
}
|
||||
if (string.IsNullOrEmpty(aiSentenceView.PersonName))
|
||||
{
|
||||
aiSentenceView.PersonName = GetForwardName(dialogueName, aiSentenceView, aiSentences);
|
||||
}
|
||||
}
|
||||
//如果“你好”,前后面有說話者的,单独内容,下下文不能是同一個人
|
||||
dialogueName = aiSentenceView.PersonName;
|
||||
//dialogueName = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex == x.SentenceIndex).Any())
|
||||
{
|
||||
dialogueName = AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex == x.SentenceIndex).FirstOrDefault().PersonName;
|
||||
}
|
||||
//"你好,"張三說道
|
||||
//"你好"
|
||||
if (aiSentences.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphId == aiSentenceView.ParagraphId - 1 && x.DialogueIndc == YesNoPolicy.NO).Count() > 0 && aiSentences.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphId == aiSentenceView.ParagraphId + 1 && x.DialogueIndc == YesNoPolicy.YES).Count() == 1) dialogueName = string.Empty;
|
||||
|
||||
if (AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex != x.SentenceIndex && x.PersonName != dialogueName).Any())
|
||||
//如果没有提取到人物,优先向前,再向后
|
||||
aiSentenceView.PersonName = GetForwardName(dialogueName, aiSentenceView, aiSentences, 3);
|
||||
//如果没有提取到人物,优先向前,再向后
|
||||
if (string.IsNullOrEmpty(aiSentenceView.PersonName))
|
||||
{
|
||||
aiSentenceView.PersonName = AiChapterPersons.Where(x =>x.ChapterId==aiSentenceView.ChapterId && x.ParagraphIndex == aiSentenceView.ParagraphId && aiSentenceView.SentenceIndex != x.SentenceIndex && x.PersonName != dialogueName).OrderBy(x => x.OrderIndex).FirstOrDefault().PersonName;
|
||||
aiSentenceView.PersonName = GetBackwardName(dialogueName, aiSentenceView, aiSentences, 5);
|
||||
}
|
||||
//如果“你好”,前后面有說話者的,单独内容,下下文不能是同一個人
|
||||
dialogueName = aiSentenceView.PersonName;
|
||||
}
|
||||
|
||||
aiSentence = new AiSentenceEntity();
|
||||
@@ -215,9 +267,86 @@ namespace CloudBuilder.Topshelf.Utility
|
||||
}
|
||||
}
|
||||
|
||||
public string GetForwardName(string excludeName, AiSentenceViewEntity aiSentenceView, AiSentenceViewEntity[] aiSentences, int maxLength = 10)
|
||||
{
|
||||
foreach (var cp in AiChapterPersons.Where(x => x.DialogueIndc != YesNoPolicy.YES && x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex < aiSentenceView.ParagraphId && x.OrderIndex == 1).OrderByDescending(x => x.ParagraphIndex).ToArray())
|
||||
{
|
||||
if (aiSentences.Where(x => x.ChapterId == cp.ChapterId && x.ParagraphId == cp.ParagraphIndex
|
||||
&& x.DialogueIndc == YesNoPolicy.YES).Any())
|
||||
{
|
||||
if (aiSentences.Where(x => x.ChapterId == cp.ChapterId && x.ParagraphId == cp.ParagraphIndex
|
||||
&& x.DialogueIndc == YesNoPolicy.NO).Any())
|
||||
{
|
||||
if (string.IsNullOrEmpty(cp.PersonName) || cp.PersonName.Contains("【")) continue;
|
||||
if (!string.IsNullOrEmpty(excludeName) && excludeName == cp.PersonName) continue;
|
||||
if (!string.IsNullOrEmpty(excludeName) && AreSamePerson(excludeName, cp.PersonName)) continue;
|
||||
|
||||
if (aiSentenceView.ParagraphId - cp.ParagraphIndex > maxLength) break;
|
||||
return cp.PersonName;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(cp.PersonName) || cp.PersonName.Contains("【")) continue;
|
||||
if (!string.IsNullOrEmpty(excludeName) && excludeName == cp.PersonName) continue;
|
||||
if (!string.IsNullOrEmpty(excludeName) && AreSamePerson(excludeName, cp.PersonName)) continue;
|
||||
|
||||
if (aiSentenceView.ParagraphId - cp.ParagraphIndex > maxLength) break;
|
||||
return cp.PersonName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public string GetBackwardName(string excludeName, AiSentenceViewEntity aiSentenceView, AiSentenceViewEntity[] aiSentences, int maxLength = 10)
|
||||
{
|
||||
foreach (var cp in AiChapterPersons.Where(x => x.ChapterId == aiSentenceView.ChapterId && x.ParagraphIndex > aiSentenceView.ParagraphId).OrderBy(x => x.ParagraphIndex).ThenBy(x => x.OrderIndex).ToArray())
|
||||
{
|
||||
if (aiSentences.Where(x => x.ChapterId == cp.ChapterId && x.ParagraphId == cp.ParagraphIndex && x.DialogueIndc == YesNoPolicy.YES).Any()) break;
|
||||
|
||||
if (string.IsNullOrEmpty(cp.PersonName) || cp.PersonName.Contains("【")) continue;
|
||||
if (!string.IsNullOrEmpty(excludeName) && aiSentenceView.PersonName == cp.PersonName) continue;
|
||||
if (!string.IsNullOrEmpty(excludeName) && AreSamePerson(excludeName, cp.PersonName)) continue;
|
||||
|
||||
if (cp.ParagraphIndex - aiSentenceView.ParagraphId > maxLength) break;
|
||||
return cp.PersonName;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public bool AreSamePerson(string nameA, string nameB)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(nameA) || string.IsNullOrWhiteSpace(nameB))
|
||||
return false;
|
||||
|
||||
if (nameA.Substring(0, 1) == nameB.Substring(0, 1) && nameA != nameB)
|
||||
return false;
|
||||
|
||||
string surnameA = ExtractSurname(nameA);
|
||||
string surnameB = ExtractSurname(nameB);
|
||||
|
||||
return !string.IsNullOrEmpty(surnameA) && surnameA == surnameB;
|
||||
}
|
||||
|
||||
private string ExtractSurname(string name)
|
||||
{
|
||||
// 优先提取第一个字符(常见“姓+后缀”模式)
|
||||
if (name.Length > 0 && CommonSurnames.Contains(name[0].ToString()))
|
||||
return name[0].ToString();
|
||||
|
||||
// 对于“韩胖子”这类姓不在首位的情况,扫描整个字符串
|
||||
foreach (char c in name)
|
||||
{
|
||||
if (CommonSurnames.Contains(c.ToString()))
|
||||
return c.ToString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public AiSentenceEntity[] AiSentences { get; set; }
|
||||
|
||||
public AiChapterPersonEntity[] AiChapterPersons { get; set; }
|
||||
|
||||
public List<string> CommonSurnames { get; set; }
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
Reference in new issue
Block a user