This commit is contained in:
owenchen 2026-06-04 16:02:14 +08:00
parent 4ea68c801f
commit dbfa9bd1e8
8 changed files with 70 additions and 34 deletions

Binary file not shown.

Binary file not shown.

View File

@ -29,11 +29,12 @@ public partial class Program
// 设置控制台编码为UTF-8解决中文乱码问题 // 设置控制台编码为UTF-8解决中文乱码问题
Console.OutputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8;
Console.InputEncoding = Encoding.UTF8; Console.InputEncoding = Encoding.UTF8;
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
string taskName = null; string taskName = null;
Dictionary<string, string> bodyDict = new Dictionary<string, string>(); Dictionary<string, string> bodyDict = new Dictionary<string, string>();
//File.AppendAllText("log.txt", "Main:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); File.AppendAllText("log.txt", "Main:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n");
if (args != null && args.Length > 0) if (args != null && args.Length > 0)
{ {

View File

@ -2,7 +2,7 @@
"profiles": { "profiles": {
"CloudBuilder.Topshelf": { "CloudBuilder.Topshelf": {
"commandName": "Project", "commandName": "Project",
"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" "commandLineArgs": "task:ChineseNameExtractorTask book_id:B000010 chapter_id:73"
} }
} }
} }

View File

@ -92,6 +92,11 @@ namespace CloudBuilder.Topshelf.Python
import os import os
import json import json
import logging import logging
import sys
# web api通過cmd調用
sys.stdout = open(os.devnull, 'w')
sys.stderr = open(os.devnull, 'w')
os.environ['TQDM_DISABLE'] = '1'
# #
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
@ -656,8 +661,21 @@ class HanLPProcessor:
# #
return value return value
def get_surnames_json(self):
"""返回姓氏词典数组的JSON格式字符串供C#使用"""
try:
with open(self.surnames_path, 'r', encoding='utf-8') as f:
surnames = [line.strip() for line in f if line.strip()]
return json.dumps(surnames, ensure_ascii=False)
except Exception as e:
logger.error(f"获取姓氏词典失败: {e}")
return json.dumps([])
processor=HanLPProcessor() processor=HanLPProcessor()
# split函数
# split函数 # split函数
def test_split_function(): def test_split_function():
# 1: # 1:
@ -838,4 +856,5 @@ if __name__ == "__main__":
# processor=HanLPProcessor() # processor=HanLPProcessor()
print("") print("")
*/ */

View File

@ -8,7 +8,8 @@ using static System.Net.Mime.MediaTypeNames;
namespace CloudBuilder.Topshelf.Task namespace CloudBuilder.Topshelf.Task
{ {
//task:ChineseNameExtractorTask book_id:B000008 chapter_id:3 //task:ChineseNameExtractorTask book_id:B000010 chapter_id:74 from_chapter_id:74
//task:ChineseNameExtractorTask book_id:B000010 from_chapter_id:500
public class ChineseNameExtractorTask : IScheduleTask public class ChineseNameExtractorTask : IScheduleTask
{ {
private readonly IApplicationService service; private readonly IApplicationService service;
@ -20,8 +21,6 @@ namespace CloudBuilder.Topshelf.Task
public void Run(Dictionary<string, string> bodyDict) public void Run(Dictionary<string, string> bodyDict)
{ {
//File.AppendAllText("log.txt", "ChineseNameExtractorTask:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
if (!bodyDict.ContainsKey("book_id")) return; if (!bodyDict.ContainsKey("book_id")) return;
string bookId = bodyDict["book_id"]; string bookId = bodyDict["book_id"];
@ -29,19 +28,22 @@ namespace CloudBuilder.Topshelf.Task
if (bodyDict.ContainsKey("chapter_id")) if (bodyDict.ContainsKey("chapter_id"))
chapterId = bodyDict["chapter_id"]; chapterId = bodyDict["chapter_id"];
string from_chapter_id = string.Empty;
if (bodyDict.ContainsKey("from_chapter_id"))
from_chapter_id = bodyDict["from_chapter_id"];
PythonCommand python = new PythonCommand(service); PythonCommand python = new PythonCommand(service);
try try
{ {
Hanlp2 hanlp = new Hanlp2(python); Hanlp2 hanlp = new Hanlp2(python);
commonSurnames = hanlp.GetSurnames(); commonSurnames = hanlp.GetSurnames();
IRepository<AiSentenceViewEntity> repository = service.GetRepository<IRepository<AiSentenceViewEntity>>(); IRepository<AiSentenceViewEntity> repository = service.GetRepository<IRepository<AiSentenceViewEntity>>();
IRepository<AiSentenceEntity> repositoryAiSentenceEntity = service.GetRepository<IRepository<AiSentenceEntity>>(); IRepository<AiSentenceEntity> repositoryAiSentenceEntity = service.GetRepository<IRepository<AiSentenceEntity>>();
IRepository<AiChapterPersonEntity> repositoryAiChapterPersonEntity = service.GetRepository<IRepository<AiChapterPersonEntity>>(); IRepository<AiChapterPersonEntity> repositoryAiChapterPersonEntity = service.GetRepository<IRepository<AiChapterPersonEntity>>();
AiChapterPersonEntity[] dels = repositoryAiChapterPersonEntity.DetachedEntities.Where(x => x.BookId == bookId).ToArray(); AiChapterPersonEntity[] dels = repositoryAiChapterPersonEntity.DetachedEntities.Where(x => x.BookId == bookId && (string.IsNullOrEmpty(chapterId) || x.ChapterId == Convert.ToInt32(chapterId)) && (string.IsNullOrEmpty(from_chapter_id) || x.ChapterId >= Convert.ToInt32(from_chapter_id))).ToArray();
if (dels != null && dels.Length > 0) repositoryAiChapterPersonEntity.DeleteNow(dels); if (dels != null && dels.Length > 0) repositoryAiChapterPersonEntity.DeleteNow(dels);
string depRoot; string depRoot;
@ -54,7 +56,7 @@ namespace CloudBuilder.Topshelf.Task
SpeakerAnalysisHelper speakerAnalysisHelper = new SpeakerAnalysisHelper(); SpeakerAnalysisHelper speakerAnalysisHelper = new SpeakerAnalysisHelper();
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(); AiSentenceViewEntity[] ents = repository.DetachedEntities.Where(x => x.BookId == bookId && (string.IsNullOrEmpty(chapterId) || x.ChapterId == Convert.ToInt32(chapterId)) && (string.IsNullOrEmpty(from_chapter_id) || x.ChapterId >= Convert.ToInt32(from_chapter_id))).OrderBy(x => x.ChapterId).ThenBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray();
if (ents == null || ents.Length == 0) return; if (ents == null || ents.Length == 0) return;
AiSentenceEntity aiSentenceEntity; AiSentenceEntity aiSentenceEntity;
@ -65,36 +67,45 @@ namespace CloudBuilder.Topshelf.Task
int processedLines = 0; // 已处理行数计数器 int processedLines = 0; // 已处理行数计数器
AiChapterPersonEntity aiChapterPerson; AiChapterPersonEntity aiChapterPerson;
List<AiChapterPersonEntity> cps = new List<AiChapterPersonEntity>(); List<AiChapterPersonEntity> cps = new List<AiChapterPersonEntity>();
foreach (var ent in ents) foreach (var ent in ents)
{ {
processedLines++; processedLines++;
try
person = speakerAnalysisHelper.GetPerson(hanlp, ent.Content);
paragraphIndex = ent.ParagraphId;
if (!string.IsNullOrEmpty(person))
{ {
string[] ps = person.Split(','); person = speakerAnalysisHelper.GetPerson(hanlp, ent.Content);
int orderIndex = 1; paragraphIndex = ent.ParagraphId;
foreach (var p in ps)
if (!string.IsNullOrEmpty(person))
{ {
if (p.Length == 1) continue; string[] ps = person.Split(',');
aiChapterPerson = new AiChapterPersonEntity(); int orderIndex = 1;
aiChapterPerson.PersonName = KeepChineseCharactersOnly(p); foreach (var p in ps)
aiChapterPerson.BookId = ent.BookId; {
aiChapterPerson.ChapterId = ent.ChapterId; if (p.Length == 1) continue;
aiChapterPerson.ParagraphIndex = ent.ParagraphId; aiChapterPerson = new AiChapterPersonEntity();
aiChapterPerson.SentenceIndex = ent.SentenceIndex; aiChapterPerson.PersonName = KeepChineseCharactersOnly(p);
aiChapterPerson.DialogueIndc = ent.DialogueIndc; aiChapterPerson.BookId = ent.BookId;
aiChapterPerson.OrderIndex = orderIndex++; aiChapterPerson.ChapterId = ent.ChapterId;
cps.Add(aiChapterPerson); aiChapterPerson.ParagraphIndex = ent.ParagraphId;
repositoryAiChapterPersonEntity.InsertNow(aiChapterPerson); aiChapterPerson.SentenceIndex = ent.SentenceIndex;
aiChapterPerson.DialogueIndc = ent.DialogueIndc;
aiChapterPerson.OrderIndex = orderIndex++;
repositoryAiChapterPersonEntity.InsertNow(aiChapterPerson);
cps.Add(aiChapterPerson);
}
} }
} }
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
ConsoleOutput.UpdateProgress(processedLines, totalLines); ConsoleOutput.UpdateProgress(processedLines, totalLines);
} }
speakerAnalysisHelper.AiChapterPersons = cps.ToArray(); speakerAnalysisHelper.AiChapterPersons = cps.ToArray();
speakerAnalysisHelper.CommonSurnames = commonSurnames; speakerAnalysisHelper.CommonSurnames = commonSurnames;
speakerAnalysisHelper.MatchPerson(ents, repositoryAiSentenceEntity); speakerAnalysisHelper.MatchPerson(ents, repositoryAiSentenceEntity);

View File

@ -110,7 +110,7 @@ namespace CloudBuilder.Topshelf.Task.TTS
voice = personMapping[ent.PersonName]; voice = personMapping[ent.PersonName];
else else
{ {
voice = AI.Policy.ChineseTtsVoiceRandom.GetRandom(80).ToString(); voice = CloudBuilder.AI.Policy.ChineseTtsVoiceRandom.GetRandom(80).ToString();
personMapping.Add(ent.PersonName, voice); personMapping.Add(ent.PersonName, voice);
} }

View File

@ -68,12 +68,15 @@ namespace CloudBuilder.Topshelf.Utility
{ {
HanlpConstituencyNode[] nodesSon; HanlpConstituencyNode[] nodesSon;
nodef = HanlpResultHelper.GetNodeById(cons, node.ItemId + 1); nodef = HanlpResultHelper.GetNodeById(cons, node.ItemId + 1);
if (nps.Contains(nodef.Label)) if (nodef != null)
{ {
nodesSon = HanlpResultHelper.GetNodeSonById(cons, nodef.ItemId); if (nps.Contains(nodef.Label))
if (nodesSon != null && nodesSon.Where(x => x.Children == 0).Any())
{ {
feature += string.Concat(nodesSon.Select(x => x.Label)); nodesSon = HanlpResultHelper.GetNodeSonById(cons, nodef.ItemId);
if (nodesSon != null && nodesSon.Where(x => x.Children == 0).Any())
{
feature += string.Concat(nodesSon.Select(x => x.Label));
}
} }
} }
} }
@ -152,7 +155,7 @@ namespace CloudBuilder.Topshelf.Utility
} }
} }
} }
/*arg1
foreach (var mrp in srl) foreach (var mrp in srl)
{ {
if (mrp.Type.ToUpper() != "ARG0") continue; if (mrp.Type.ToUpper() != "ARG0") continue;
@ -170,6 +173,7 @@ namespace CloudBuilder.Topshelf.Utility
arg1 = mrp.Text; arg1 = mrp.Text;
} }
} }
*/
} }
} }
@ -208,7 +212,8 @@ namespace CloudBuilder.Topshelf.Utility
if (aiSentenceView.PersonName.Contains("【")) if (aiSentenceView.PersonName.Contains("【"))
{ {
aiSentenceView.PersonName = AiChapterPersons.Where(x => !x.PersonName.Contains("【") && x.PersonName.Contains(aiSentenceView.PersonName.Replace("【", "").Replace("】", ""))).FirstOrDefault()!.PersonName; if (AiChapterPersons.Where(x => !x.PersonName.Contains("【") && x.PersonName.Contains(aiSentenceView.PersonName.Replace("【", "").Replace("】", ""))).Any())
aiSentenceView.PersonName = AiChapterPersons.Where(x => !x.PersonName.Contains("【") && x.PersonName.Contains(aiSentenceView.PersonName.Replace("【", "").Replace("】", ""))).FirstOrDefault()!.PersonName;
} }
} }
//说话者在前面 //说话者在前面