ow
This commit is contained in:
parent
dbfa9bd1e8
commit
a8789b2e42
Binary file not shown.
@ -2,7 +2,7 @@
|
|||||||
"profiles": {
|
"profiles": {
|
||||||
"CloudBuilder.Topshelf": {
|
"CloudBuilder.Topshelf": {
|
||||||
"commandName": "Project",
|
"commandName": "Project",
|
||||||
"commandLineArgs": "task:ChineseNameExtractorTask book_id:B000010 chapter_id:73"
|
"commandLineArgs": "task:TtsTask book_id:B000010 from_chapter_id:181 to_chapter_id:200 speed:1 voice:Sherpa2 actor:韩立 actor_voice:Sherpa1 save_path:D:\\\\Net8\\\\FileServer\\\\Backup\\\\DmsFile\\\\voice"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,7 +9,7 @@ using static System.Net.Mime.MediaTypeNames;
|
|||||||
namespace CloudBuilder.Topshelf.Task
|
namespace CloudBuilder.Topshelf.Task
|
||||||
{
|
{
|
||||||
//task:ChineseNameExtractorTask book_id:B000010 chapter_id:74 from_chapter_id:74
|
//task:ChineseNameExtractorTask book_id:B000010 chapter_id:74 from_chapter_id:74
|
||||||
//task:ChineseNameExtractorTask book_id:B000010 from_chapter_id:500
|
//task:ChineseNameExtractorTask book_id:B000010 from_chapter_id:177 to_chapter_id:200
|
||||||
public class ChineseNameExtractorTask : IScheduleTask
|
public class ChineseNameExtractorTask : IScheduleTask
|
||||||
{
|
{
|
||||||
private readonly IApplicationService service;
|
private readonly IApplicationService service;
|
||||||
@ -32,6 +32,10 @@ namespace CloudBuilder.Topshelf.Task
|
|||||||
if (bodyDict.ContainsKey("from_chapter_id"))
|
if (bodyDict.ContainsKey("from_chapter_id"))
|
||||||
from_chapter_id = bodyDict["from_chapter_id"];
|
from_chapter_id = bodyDict["from_chapter_id"];
|
||||||
|
|
||||||
|
string to_chapter_id = string.Empty;
|
||||||
|
if (bodyDict.ContainsKey("to_chapter_id"))
|
||||||
|
to_chapter_id = bodyDict["to_chapter_id"];
|
||||||
|
|
||||||
PythonCommand python = new PythonCommand(service);
|
PythonCommand python = new PythonCommand(service);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -43,7 +47,7 @@ namespace CloudBuilder.Topshelf.Task
|
|||||||
|
|
||||||
IRepository<AiChapterPersonEntity> repositoryAiChapterPersonEntity = service.GetRepository<IRepository<AiChapterPersonEntity>>();
|
IRepository<AiChapterPersonEntity> repositoryAiChapterPersonEntity = service.GetRepository<IRepository<AiChapterPersonEntity>>();
|
||||||
|
|
||||||
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();
|
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)) && (string.IsNullOrEmpty(to_chapter_id) || x.ChapterId <= Convert.ToInt32(to_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;
|
||||||
@ -56,7 +60,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)) && (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();
|
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)) && (string.IsNullOrEmpty(to_chapter_id) || x.ChapterId <= Convert.ToInt32(to_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;
|
||||||
|
|||||||
70
Task/AI/NameGenderPredictorTask.cs
Normal file
70
Task/AI/NameGenderPredictorTask.cs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
using CloudBuilder.AI.Entity;
|
||||||
|
using CloudBuilder.AI.Utility;
|
||||||
|
using CloudBuilder.Core.DatabaseAccessor.Entity;
|
||||||
|
using CloudBuilder.Core.DependencyInjection.Task;
|
||||||
|
using CloudBuilder.Topshelf.Python;
|
||||||
|
using CloudBuilder.Topshelf.Utility;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace CloudBuilder.Topshelf.Task.AI
|
||||||
|
{
|
||||||
|
//task:NameGenderPredictorTask book_id:B000010 from_chapter_id:177 to_chapter_id:200
|
||||||
|
public class NameGenderPredictorTask : IScheduleTask
|
||||||
|
{
|
||||||
|
private readonly IApplicationService service;
|
||||||
|
|
||||||
|
public NameGenderPredictorTask(IApplicationService service)
|
||||||
|
{
|
||||||
|
this.service = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Run(Dictionary<string, string> bodyDict)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!bodyDict.ContainsKey("book_id")) return;
|
||||||
|
|
||||||
|
string bookId = bodyDict["book_id"];
|
||||||
|
string chapterId = string.Empty;
|
||||||
|
if (bodyDict.ContainsKey("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"];
|
||||||
|
|
||||||
|
string to_chapter_id = string.Empty;
|
||||||
|
if (bodyDict.ContainsKey("to_chapter_id"))
|
||||||
|
to_chapter_id = bodyDict["to_chapter_id"];
|
||||||
|
|
||||||
|
IRepository<AiSentenceEntity> repositoryAiSentenceEntity = service.GetRepository<IRepository<AiSentenceEntity>>();
|
||||||
|
|
||||||
|
AiSentenceEntity[] aiSentences = repositoryAiSentenceEntity.DetachedEntities.Where(x => !string.IsNullOrEmpty(x.PersonName) && x.BookId == bookId && (string.IsNullOrEmpty(chapterId) || x.ChapterId == Convert.ToInt32(chapterId)) && (string.IsNullOrEmpty(from_chapter_id) || x.ChapterId >= Convert.ToInt32(from_chapter_id)) && (string.IsNullOrEmpty(to_chapter_id) || x.ChapterId <= Convert.ToInt32(to_chapter_id))).OrderBy(x => x.ChapterId).ThenBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray();
|
||||||
|
|
||||||
|
if (aiSentences == null || aiSentences.Length == 0) return;
|
||||||
|
|
||||||
|
int totalLines = aiSentences.Length;
|
||||||
|
int processedLines = 0; // 已处理行数计数器
|
||||||
|
|
||||||
|
foreach (AiSentenceEntity aiSentence in aiSentences)
|
||||||
|
{
|
||||||
|
processedLines++;
|
||||||
|
|
||||||
|
aiSentence.Gender = NameGenderPredictor.PredictGender(aiSentence.PersonName);
|
||||||
|
|
||||||
|
ConsoleOutput.UpdateProgress(processedLines, totalLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
repositoryAiSentenceEntity.UpdateNow(aiSentences);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,6 +18,7 @@ using static System.Runtime.InteropServices.JavaScript.JSType;
|
|||||||
namespace CloudBuilder.Topshelf.Task.TTS
|
namespace CloudBuilder.Topshelf.Task.TTS
|
||||||
{
|
{
|
||||||
//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 book_id:B000008 chapter_id:3 speed:1 voice:Sherpa2 actor:韩立 actor_voice:Sherpa1 save_path:D:\\Net8\\FileServer\\Backup\\DmsFile\\voice
|
||||||
|
//task:TtsTask book_id:B000010 from_chapter_id:177 to_chapter_id:200 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:二愣子睁大着双眼,直直望着茅草和烂泥糊成的黑屋顶,身上盖着的旧棉被,已呈深黄色,看不出原来的本来面目,还若有若无的散发着淡淡的霉味。
|
//task:TtsTask voice:Sherpa2 save_path:D:\\Net8\\FileServer\\Backup\\DmsFile\\voice\\20260528112739.mp3 text:二愣子睁大着双眼,直直望着茅草和烂泥糊成的黑屋顶,身上盖着的旧棉被,已呈深黄色,看不出原来的本来面目,还若有若无的散发着淡淡的霉味。
|
||||||
public class TtsTask : IScheduleTask
|
public class TtsTask : IScheduleTask
|
||||||
{
|
{
|
||||||
@ -42,7 +43,19 @@ namespace CloudBuilder.Topshelf.Task.TTS
|
|||||||
if (bodyDict.ContainsKey("chapter_id"))
|
if (bodyDict.ContainsKey("chapter_id"))
|
||||||
chapterId = bodyDict["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();
|
string from_chapter_id = string.Empty;
|
||||||
|
if (bodyDict.ContainsKey("from_chapter_id"))
|
||||||
|
from_chapter_id = bodyDict["from_chapter_id"];
|
||||||
|
|
||||||
|
string to_chapter_id = string.Empty;
|
||||||
|
if (bodyDict.ContainsKey("to_chapter_id"))
|
||||||
|
to_chapter_id = bodyDict["to_chapter_id"];
|
||||||
|
|
||||||
|
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))
|
||||||
|
&& (string.IsNullOrEmpty(to_chapter_id) || x.ChapterId <= Convert.ToInt32(to_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;
|
||||||
|
|
||||||
@ -88,51 +101,72 @@ namespace CloudBuilder.Topshelf.Task.TTS
|
|||||||
// 2. 生成本章所有句子音频
|
// 2. 生成本章所有句子音频
|
||||||
foreach (AiSentenceViewEntity ent in chapter)
|
foreach (AiSentenceViewEntity ent in chapter)
|
||||||
{
|
{
|
||||||
processedLines++;
|
try
|
||||||
|
|
||||||
string voice = ChineseTtsVoice.Sherpa2.ToString();
|
|
||||||
if (ent.DialogueIndc == YesNoPolicy.YES)
|
|
||||||
{
|
{
|
||||||
if (ent.PersonName == actor)
|
processedLines++;
|
||||||
|
|
||||||
|
string voice = ChineseTtsVoice.Sherpa2.ToString();
|
||||||
|
if (ent.DialogueIndc == YesNoPolicy.YES)
|
||||||
{
|
{
|
||||||
if (personMapping.ContainsKey(ent.PersonName))
|
string key = string.IsNullOrEmpty(ent.PersonName) ? "NULL" : ent.PersonName;
|
||||||
voice = personMapping[ent.PersonName];
|
if (key == actor)
|
||||||
|
{
|
||||||
|
if (personMapping.ContainsKey(key))
|
||||||
|
voice = personMapping[key];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
voice = actor_voice;
|
||||||
|
personMapping.Add(key, voice);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
voice = actor_voice;
|
if (!string.IsNullOrEmpty(key) && personMapping.ContainsKey(key))
|
||||||
personMapping.Add(ent.PersonName, voice);
|
voice = personMapping[key];
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
if (ent.Gender == YesNoPolicy.YES)
|
||||||
|
{
|
||||||
|
voice = CloudBuilder.AI.Policy.ChineseTtsVoiceRandom.GetRandomFemaleExclude(80, EnumHelper.ToEnum<CloudBuilder.AI.Policy.ChineseTtsVoice>(actor_voice)).ToString();
|
||||||
|
personMapping.Add(key, voice);
|
||||||
|
}
|
||||||
|
else if (ent.Gender == YesNoPolicy.NO)
|
||||||
|
{
|
||||||
|
voice = CloudBuilder.AI.Policy.ChineseTtsVoiceRandom.GetRandomFemale(80).ToString();
|
||||||
|
personMapping.Add(key, voice);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
voice = CloudBuilder.AI.Policy.ChineseTtsVoiceRandom.GetRandom(50).ToString();
|
||||||
|
personMapping.Add(key, voice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(ent.PersonName) && personMapping.ContainsKey(ent.PersonName))
|
voice = mainVoice;
|
||||||
voice = personMapping[ent.PersonName];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
voice = CloudBuilder.AI.Policy.ChineseTtsVoiceRandom.GetRandom(80).ToString();
|
|
||||||
personMapping.Add(ent.PersonName, voice);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(voice) || string.IsNullOrEmpty(ent.Content))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// 碎片文件名:BookId_ChapterId_ParagraphId_SentenceId.mp3
|
||||||
|
string fileName = string.Format("{0}_{1}_{2}_{3}.mp3", ent.BookId, ent.ChapterId, ent.ParagraphId, ent.SentenceId);
|
||||||
|
string filePath = Path.Combine(save_path, fileName);
|
||||||
|
|
||||||
|
// 生成音频
|
||||||
|
SaveAudioToFileHelper.AudioToFile(EnumHelper.ToEnum<ChineseTtsVoice>(voice), speed, ent.Content, filePath);
|
||||||
|
|
||||||
|
tempMp3List.Add(filePath); // 加入合并列表
|
||||||
}
|
}
|
||||||
else
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
voice = mainVoice;
|
Console.WriteLine($"❌ 失败:{ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(voice) || string.IsNullOrEmpty(ent.Content))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// 碎片文件名:BookId_ChapterId_ParagraphId_SentenceId.mp3
|
|
||||||
string fileName = string.Format("{0}_{1}_{2}_{3}.mp3", ent.BookId, ent.ChapterId, ent.ParagraphId, ent.SentenceId);
|
|
||||||
string filePath = Path.Combine(save_path, fileName);
|
|
||||||
|
|
||||||
// 生成音频
|
|
||||||
SaveAudioToFileHelper.AudioToFile(EnumHelper.ToEnum<ChineseTtsVoice>(voice), speed, ent.Content, filePath);
|
|
||||||
|
|
||||||
tempMp3List.Add(filePath); // 加入合并列表
|
|
||||||
|
|
||||||
UpdateProgress(processedLines, totalLines);
|
UpdateProgress(processedLines, totalLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user