From 871de41ba5aae7d2df0a2087da16855ec4d7899b Mon Sep 17 00:00:00 2001 From: owenchen Date: Thu, 4 Jun 2026 08:16:49 +0800 Subject: [PATCH] ow --- Lib/CloudBuilder.AI.dll | Bin 87552 -> 88576 bytes Program.cs | 1 + Properties/launchSettings.json | 2 +- Python/Hanlp2.cs | 21 ++++ Task/AI/ChineseNameExtractorTask.cs | 54 ++++++---- Task/TTS/TtsTask.cs | 43 ++++++-- Utility/ConsoleHelper.cs | 14 +++ Utility/SaveAudioToFileHelper.cs | 16 +-- Utility/SpeakerAnalysisHelper.cs | 157 +++++++++++++++++++++++++--- 9 files changed, 259 insertions(+), 49 deletions(-) diff --git a/Lib/CloudBuilder.AI.dll b/Lib/CloudBuilder.AI.dll index 1cefadc18ef660fa149c653ffb64e4aededc27ad..c9f799193ef180b41ac1abe8f8e969717c72d001 100644 GIT binary patch literal 88576 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 G3H(1*Hv)VB diff --git a/Program.cs b/Program.cs index 1b1bfd5..49b2dc9 100644 --- a/Program.cs +++ b/Program.cs @@ -33,6 +33,7 @@ public partial class Program string taskName = null; Dictionary bodyDict = new Dictionary(); + File.AppendAllText("log.txt", "Main:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); if (args != null && args.Length > 0) { diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json index ea2989a..44ac99d 100644 --- a/Properties/launchSettings.json +++ b/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "CloudBuilder.Topshelf": { "commandName": "Project", - "commandLineArgs": "task:ChineseNameExtractorTask book_id:B000008" + "commandLineArgs": "task:TtsTask book_id:B000008 chapter_id:4 speed:1 voice:Sherpa2 actor:韩立 actor_voice:Sherpa1 save_path:D:\\\\Net8\\\\FileServer\\\\Backup\\\\DmsFile\\\\voice" } } } \ No newline at end of file diff --git a/Python/Hanlp2.cs b/Python/Hanlp2.cs index a6af3e6..e474525 100644 --- a/Python/Hanlp2.cs +++ b/Python/Hanlp2.cs @@ -156,6 +156,27 @@ namespace CloudBuilder.Topshelf.Python return null; } + public List GetSurnames() + { + try + { + //必须定义方法的方式使用 + using (Py.GIL()) + { + string json = python.GetValueExec($"processor.get_surnames_json()"); + // 反序列化 + if (json == "[]") return null; + return JsonSerializer.Deserialize>(json); + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + return null; + } + + public string Get(string arg) { return python.GetValueExec(arg); diff --git a/Task/AI/ChineseNameExtractorTask.cs b/Task/AI/ChineseNameExtractorTask.cs index a8501bc..8e7b361 100644 --- a/Task/AI/ChineseNameExtractorTask.cs +++ b/Task/AI/ChineseNameExtractorTask.cs @@ -3,15 +3,16 @@ using CloudBuilder.Core.DatabaseAccessor.Entity; using CloudBuilder.Core.DependencyInjection.Task; using CloudBuilder.Topshelf.Python; using CloudBuilder.Topshelf.Utility; +using System.Text.RegularExpressions; using static System.Net.Mime.MediaTypeNames; namespace CloudBuilder.Topshelf.Task { - //task:ChineseNameExtractorTask book_id:B000008 + //task:ChineseNameExtractorTask book_id:B000008 chapter_id:3 public class ChineseNameExtractorTask : IScheduleTask { private readonly IApplicationService service; - + private List commonSurnames; public ChineseNameExtractorTask(IApplicationService service) { this.service = service; @@ -19,14 +20,20 @@ namespace CloudBuilder.Topshelf.Task public void Run(Dictionary bodyDict) { + File.AppendAllText("log.txt", "ChineseNameExtractorTask:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); + if (!bodyDict.ContainsKey("book_id")) return; - string guid = bodyDict["book_id"]; + string bookId = bodyDict["book_id"]; + string chapterId = string.Empty; + if (bodyDict.ContainsKey("chapter_id")) + chapterId = bodyDict["chapter_id"]; PythonCommand python = new PythonCommand(service); try { Hanlp2 hanlp = new Hanlp2(python); + commonSurnames = hanlp.GetSurnames(); IRepository repository = service.GetRepository>(); @@ -34,6 +41,9 @@ namespace CloudBuilder.Topshelf.Task IRepository repositoryAiChapterPersonEntity = service.GetRepository>(); + AiChapterPersonEntity[] dels = repositoryAiChapterPersonEntity.DetachedEntities.Where(x => x.BookId == bookId).ToArray(); + if (dels != null && dels.Length > 0) repositoryAiChapterPersonEntity.DeleteNow(dels); + string depRoot; List ners; @@ -44,7 +54,7 @@ namespace CloudBuilder.Topshelf.Task SpeakerAnalysisHelper speakerAnalysisHelper = new SpeakerAnalysisHelper(); - AiSentenceViewEntity[] ents = repository.DetachedEntities.Where(x => x.BookId == guid).OrderBy(x => x.ChapterId).ThenBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray(); + AiSentenceViewEntity[] ents = repository.DetachedEntities.Where(x => x.BookId == bookId && (string.IsNullOrEmpty(chapterId) || x.ChapterId == Convert.ToInt32(chapterId))).OrderBy(x => x.ChapterId).ThenBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray(); if (ents == null || ents.Length == 0) return; AiSentenceEntity aiSentenceEntity; @@ -70,22 +80,23 @@ namespace CloudBuilder.Topshelf.Task { if (p.Length == 1) continue; aiChapterPerson = new AiChapterPersonEntity(); - aiChapterPerson.PersonName = p; + aiChapterPerson.PersonName = KeepChineseCharactersOnly(p); aiChapterPerson.BookId = ent.BookId; aiChapterPerson.ChapterId = ent.ChapterId; aiChapterPerson.ParagraphIndex = ent.ParagraphId; - aiChapterPerson.SentenceIndex= ent.SentenceIndex; + aiChapterPerson.SentenceIndex = ent.SentenceIndex; + aiChapterPerson.DialogueIndc = ent.DialogueIndc; aiChapterPerson.OrderIndex = orderIndex++; cps.Add(aiChapterPerson); repositoryAiChapterPersonEntity.InsertNow(aiChapterPerson); } } - UpdateProgress(processedLines, totalLines); + ConsoleOutput.UpdateProgress(processedLines, totalLines); } speakerAnalysisHelper.AiChapterPersons = cps.ToArray(); - + speakerAnalysisHelper.CommonSurnames = commonSurnames; speakerAnalysisHelper.MatchPerson(ents, repositoryAiSentenceEntity); } catch (Exception ex) @@ -99,18 +110,25 @@ namespace CloudBuilder.Topshelf.Task } } - private static void UpdateProgress(int processed, int total) + + private string KeepChineseCharactersOnly(string input) { - double progressPercent = (double)processed / total * 100; - int progressBarLength = 50; // 进度条总长度 - int filledLength = (int)(progressPercent / 100 * progressBarLength); + if (string.IsNullOrEmpty(input)) + return input; - // 构建进度条(如:[██████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░]) - string progressBar = "[" + new string('█', filledLength) + new string('░', progressBarLength - filledLength) + "]"; - - string progressInfo = $"{progressBar} {progressPercent:F2}% | 已处理:{processed}/{total} "; - Console.Write($"\r{progressInfo}"); - Console.Out.Flush(); + // 方法1:使用正则表达式 + //return Regex.Replace(input, @"[^\u4e00-\u9fff]", ""); + return Regex.Replace(input, @"[^\u4e00-\u9fff\【\】]", ""); + // 方法2:手动遍历(性能更好) + // var sb = new StringBuilder(); + // foreach (char c in input) + // { + // if (c >= 0x4e00 && c <= 0x9fff) + // sb.Append(c); + // } + // return sb.ToString(); } + + } } diff --git a/Task/TTS/TtsTask.cs b/Task/TTS/TtsTask.cs index d8a54a7..f12929f 100644 --- a/Task/TTS/TtsTask.cs +++ b/Task/TTS/TtsTask.cs @@ -17,7 +17,7 @@ using static System.Runtime.InteropServices.JavaScript.JSType; namespace CloudBuilder.Topshelf.Task.TTS { - //task:TtsTask book_id:B000008 voice:Sherpa2 actor:韩立 actor_voice:Sherpa1 save_path:D:\\Net8\\FileServer\\Backup\\DmsFile\\voice + //task:TtsTask book_id:B000008 chapter_id:3 speed:1 voice:Sherpa2 actor:韩立 actor_voice:Sherpa1 save_path:D:\\Net8\\FileServer\\Backup\\DmsFile\\voice //task:TtsTask voice:Sherpa2 save_path:D:\\Net8\\FileServer\\Backup\\DmsFile\\voice\\20260528112739.mp3 text:二愣子睁大着双眼,直直望着茅草和烂泥糊成的黑屋顶,身上盖着的旧棉被,已呈深黄色,看不出原来的本来面目,还若有若无的散发着淡淡的霉味。 public class TtsTask : IScheduleTask { @@ -38,7 +38,11 @@ namespace CloudBuilder.Topshelf.Task.TTS if (bodyDict.ContainsKey("book_id")) bookId = bodyDict["book_id"]; - AiSentenceViewEntity[] ents = repository.DetachedEntities.Where(x => x.BookId == bookId).OrderBy(x => x.ChapterId).ThenBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray(); + string chapterId = string.Empty; + if (bodyDict.ContainsKey("chapter_id")) + chapterId = bodyDict["chapter_id"]; + + AiSentenceViewEntity[] ents = repository.DetachedEntities.Where(x => x.BookId == bookId && (string.IsNullOrEmpty(chapterId) || x.ChapterId == Convert.ToInt32(chapterId))).OrderBy(x => x.ChapterId).ThenBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray(); if (ents == null || ents.Length == 0) return; @@ -55,10 +59,15 @@ namespace CloudBuilder.Topshelf.Task.TTS if (bodyDict.ContainsKey("save_path")) save_path = bodyDict["save_path"]; - GenerateAndMergeChapterAudio(ents, actor, actor_voice, voice, save_path); + float speed = 1.0f; + + if (bodyDict.ContainsKey("speed")) + speed = Convert.ToSingle(bodyDict["speed"]); + + GenerateAndMergeChapterAudio(ents, speed, actor, actor_voice, voice, save_path); } - public void GenerateAndMergeChapterAudio(AiSentenceViewEntity[] ents, string actor, string actor_voice, string mainVoice, string save_path) + public void GenerateAndMergeChapterAudio(AiSentenceViewEntity[] ents, float speed, string actor, string actor_voice, string mainVoice, string save_path) { // 1. 按 BookId + ChapterId 分组(关键!) var chapterGroups = ents @@ -69,7 +78,7 @@ namespace CloudBuilder.Topshelf.Task.TTS int totalLines = ents.Count(); int processedLines = 0; // 已处理行数计数器 UpdateProgress(processedLines, totalLines); - + Dictionary personMapping = new Dictionary(); foreach (var chapter in chapterGroups) { string bookId = chapter.Key.BookId; @@ -85,9 +94,27 @@ namespace CloudBuilder.Topshelf.Task.TTS if (ent.DialogueIndc == YesNoPolicy.YES) { if (ent.PersonName == actor) - voice = actor_voice; + { + if (personMapping.ContainsKey(ent.PersonName)) + voice = personMapping[ent.PersonName]; + else + { + voice = actor_voice; + personMapping.Add(ent.PersonName, voice); + } + + } else - voice = AI.Policy.ChineseTtsVoiceRandom.GetRandom().ToString(); + { + if (!string.IsNullOrEmpty(ent.PersonName) && personMapping.ContainsKey(ent.PersonName)) + voice = personMapping[ent.PersonName]; + else + { + voice = AI.Policy.ChineseTtsVoiceRandom.GetRandom(80).ToString(); + personMapping.Add(ent.PersonName, voice); + } + + } } else { @@ -102,7 +129,7 @@ namespace CloudBuilder.Topshelf.Task.TTS string filePath = Path.Combine(save_path, fileName); // 生成音频 - SaveAudioToFileHelper.AudioToFile(EnumHelper.ToEnum(voice), ent.Content, filePath); + SaveAudioToFileHelper.AudioToFile(EnumHelper.ToEnum(voice), speed, ent.Content, filePath); tempMp3List.Add(filePath); // 加入合并列表 diff --git a/Utility/ConsoleHelper.cs b/Utility/ConsoleHelper.cs index 2b01adf..355cfd3 100644 --- a/Utility/ConsoleHelper.cs +++ b/Utility/ConsoleHelper.cs @@ -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(); + } } } diff --git a/Utility/SaveAudioToFileHelper.cs b/Utility/SaveAudioToFileHelper.cs index 756ff22..71af4ec 100644 --- a/Utility/SaveAudioToFileHelper.cs +++ b/Utility/SaveAudioToFileHelper.cs @@ -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; } diff --git a/Utility/SpeakerAnalysisHelper.cs b/Utility/SpeakerAnalysisHelper.cs index 18b3b1e..21608a7 100644 --- a/Utility/SpeakerAnalysisHelper.cs +++ b/Utility/SpeakerAnalysisHelper.cs @@ -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 CommonSurnames { get; set; } } } /*