diff --git a/VideoAnalysis/Components/Pages/VideoTaskPage.razor b/VideoAnalysis/Components/Pages/VideoTaskPage.razor index a869289..7945f48 100644 --- a/VideoAnalysis/Components/Pages/VideoTaskPage.razor +++ b/VideoAnalysis/Components/Pages/VideoTaskPage.razor @@ -20,7 +20,6 @@ - diff --git a/VideoAnalysis/Components/Pages/VideoTaskPage.razor.cs b/VideoAnalysis/Components/Pages/VideoTaskPage.razor.cs index 3823d4e..742af62 100644 --- a/VideoAnalysis/Components/Pages/VideoTaskPage.razor.cs +++ b/VideoAnalysis/Components/Pages/VideoTaskPage.razor.cs @@ -71,7 +71,7 @@ namespace Learn.VideoAnalysis.Components.Pages { await RedisExpand.SetTaskErrorMessage(reStartTask.Id, null); _=Task.Run(() => - RedisExpand.InsertChannel((RedisChannelEnum)selectEnum, reStartTask.Id) + RedisExpand.InsertChannel((RedisChannelEnum)selectEnum, reStartTask.Id) ); modalShow = false; } diff --git a/VideoAnalysis/Components/Pages/VideoTaskShow.razor b/VideoAnalysis/Components/Pages/VideoTaskShow.razor index 547416a..9249477 100644 --- a/VideoAnalysis/Components/Pages/VideoTaskShow.razor +++ b/VideoAnalysis/Components/Pages/VideoTaskShow.razor @@ -6,8 +6,7 @@

- - @nowTask.MediaName

+ @for (int i = 0; i < videoKnows.Length; i++) { var item = videoKnows[i]; @@ -20,16 +19,19 @@
概览: @item.Content

- @foreach (var q in item.QuestionArr) + @if (item.QuestionArr != null) { - -
-

问题: @q.StartTime 秒

-
@q.TopicStem
-
@q.Question
- -
-
+ @foreach (var q in item.QuestionArr) + { + +
+

问题: @q.StartTime 秒

+
@q.TopicStem
+
@q.Question
+ +
+
+ } }

diff --git a/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs b/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs index aab917f..3f27f34 100644 --- a/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs +++ b/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs @@ -82,9 +82,8 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT .Where(s => s.Course_Id == 27 && s.Depth == 2) .Select(s => s.Name).ToArrayAsync(); - string title = taskInfo.MediaName; var fileNameResFormat = "{授课章节: string|null, 授课内容:string}"; - var fileNamePostMessages = title + + var fileNamePostMessages = " 这是一堂课的标题,请你帮我分析一些关于课堂方面的内容." + $"1.分析出高中{subject}课堂授课的主要章节(例如 章节: 数列),章节范围限定在[{string.Join(',', xkwKnows)}]范围." + $"2.分析出这堂课的主要授课内容." + diff --git a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs index da82af3..476432c 100644 --- a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs +++ b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs @@ -386,7 +386,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek foreach (var item in farmeArr) { var knowInfoArr = videoKnowArr - .Where(s => item+30 >= s.StartTime && item <= s.EndTime) + .Where(s => item+20 >= s.StartTime && item < s.EndTime) .ToArray(); if (knowInfoArr is null || knowInfoArr.Count() ==0) continue; @@ -414,7 +414,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek $"排除不是试题内容的文字,优化试题排版并且去除题号,尽量保留latex数学公式。" + $"如果存在多道题,则需要拆分成为多个试题对象!" + $"试题的类型约束在 填空题/判断题/选择题/解答题/填空题 范围内。" + - $"如果存在题干中存在下划线则试题的题型应该是填空题。" + + $"如果是有效试题且题干中存在下划线则试题的题型应该是填空题。" + $"请检查我提供的字符串内容,如果不能识别知识点则不处理知识点,如不包含问题试题则返回`[]`" + $"输出内容只返回json格式为({resFormat})" + $"以下是试题内容" + diff --git a/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs b/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs index 80e4489..0551155 100644 --- a/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs +++ b/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs @@ -179,9 +179,11 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx .Where(it => it.Id == long.Parse(task)) .ExecuteCommandAsync(); await RedisExpand.Redis.HMSetAsync(RedisExpandKey.Task(task), "Captions", res); + //RedisExpand.InsertChannel(Enum.RedisChannelEnum.ParsingSpeaker, task); + //分析完成视频字幕后继续接收任务 - RedisExpand.NewTask(); + await RedisExpand.NewTaskAsync(); RedisExpand.InsertChannel(RedisChannelEnum.ChatModelAnalysis, task); } diff --git a/VideoAnalysisCore/Common/RedisExpand.cs b/VideoAnalysisCore/Common/RedisExpand.cs index 711352e..7eae9b4 100644 --- a/VideoAnalysisCore/Common/RedisExpand.cs +++ b/VideoAnalysisCore/Common/RedisExpand.cs @@ -176,7 +176,8 @@ namespace VideoAnalysisCore.Common // .HMGetAsync(RedisExpandKey.Task(task), "ChatAnalysis")).FirstOrDefault(); //if (gptRes is null) // throw new Exception("未能读取到GPT处理结果"); - + //删除任务执行状态 + await Redis.HDelAsync(RedisExpandKey.IDTask,task); var taskData = await DbScoped.Sugar.Queryable() .FirstAsync(s => s.Id == tId); if (taskData.Captions == "[]") @@ -215,29 +216,23 @@ namespace VideoAnalysisCore.Common if (Redis is null) throw new Exception("redis未初始化"); SubscribeList.Add(RedisChannelEnum.DownloadFile, - (Action)((msg) => { - TouchChannel(RedisChannelEnum.DownloadFile, msg, - (Func)((task) => + (msg) => TouchChannel(RedisChannelEnum.DownloadFile, msg, + (task) => { using var scope = AppCommon.Services?.CreateScope(); - if (scope is null || ServiceProviderServiceExtensions.GetService(scope.ServiceProvider) is null) + if (scope is null || scope.ServiceProvider.GetService() is null) throw new Exception("DownloadFile 未注入"); else - return (Task)(scope.ServiceProvider.GetService()?.RunTask(task) ?? Task.CompletedTask); + return scope.ServiceProvider.GetService()?.RunTask(task) ?? Task.CompletedTask; })); - })); - SubscribeList.Add(RedisChannelEnum.SeparateAudio, - (msg) => { TouchChannel(RedisChannelEnum.SeparateAudio, msg, FFMPGEHandle.RunAsync); }); - + (msg) => TouchChannel(RedisChannelEnum.SeparateAudio, msg, FFMPGEHandle.RunAsync)); SubscribeList.Add(RedisChannelEnum.ParsingCaptions, - (msg) => { TouchChannel(RedisChannelEnum.ParsingCaptions, msg, SenseVoice.RunTask); }); + (msg) => TouchChannel(RedisChannelEnum.ParsingCaptions, msg, SenseVoice.RunTask)); SubscribeList.Add(RedisChannelEnum.ParsingSpeaker, - (msg) => { TouchChannel(RedisChannelEnum.ParsingSpeaker, msg, Speaker.Run); }); + (msg) => TouchChannel(RedisChannelEnum.ParsingSpeaker, msg, Speaker.Run)); SubscribeList.Add(RedisChannelEnum.ChatModelAnalysis, - (msg) => - { - TouchChannel(RedisChannelEnum.ChatModelAnalysis, msg, + (msg) => TouchChannel(RedisChannelEnum.ChatModelAnalysis, msg, (task) => { using var scope = AppCommon.Services?.CreateScope(); @@ -245,63 +240,70 @@ namespace VideoAnalysisCore.Common throw new Exception("IBserGPT 未注入"); else return scope.ServiceProvider.GetService()?.GetKnow(task) ?? Task.CompletedTask; - }); - }); + })); SubscribeList.Add(RedisChannelEnum.EndTask, - (msg) => { TouchChannel(RedisChannelEnum.EndTask, msg, TaskEnd); }); + (msg) => TouchChannel(RedisChannelEnum.EndTask, msg, TaskEnd)); - await ReceivingTaskAsync(); + ReceivingTaskAsync(); } + /// /// 重新执行新任务 /// /// - public static void NewTask() + public static async Task NewTaskAsync() { - Task.Run(async () => - { - await Redis.DelAsync(RedisExpandKey.IDTask); - await ReceivingTaskAsync(); - }); + ReceivingTaskAsync(); } /// /// 重新接收新任务 /// - public static async Task ReceivingTaskAsync() + public static void ReceivingTaskAsync() { if (AppCommon.Config.TaskSetting.IS_Server) { Console.WriteLine($"{DateTime.Now} =>服务端不接收任务"); return; } - var oldTask = await Redis.GetAsync(RedisExpandKey.IDTask); - if (!string.IsNullOrEmpty(oldTask)) + Task.Run(async () => { - var lastEnum = (await Redis.HMGetAsync(RedisExpandKey.Task(oldTask), "LastEnum")).FirstOrDefault(); - await SetTaskErrorMessage(long.Parse(oldTask), null); - InsertChannel(lastEnum, oldTask); - return; - } - if (Subscribe?.IsUnsubscribed == false)//排除重试机制后 多次接收任务导致内存泄露 - return; - Subscribe = Redis.SubscribeList(RedisExpandKey.ChannelKey, (taskId) => - { - if (taskId is null) return; - Subscribe?.Dispose(); - //存储当前机器的任务 - Redis.Set(RedisExpandKey.IDTask, taskId); - Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "-------------> 接收到任务 " + taskId); - InsertChannel(RedisChannelEnum.DownloadFile, taskId); + //todo 项目接收任务进程池 + //接收任务加入池 + //重试任务加入池 + //失败任务删除池 + //停止任务删除池 + //重启项目运行池内所有可用任务 + var oldTask = await Redis.GetAsync(RedisExpandKey.IDTask); + if (!string.IsNullOrEmpty(oldTask)) + { + Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "-------------> 接收重试任务 " + oldTask); + var lastEnum = (await Redis.HMGetAsync(RedisExpandKey.Task(oldTask), "LastEnum")).FirstOrDefault(); + await SetTaskErrorMessage(long.Parse(oldTask), null); + InsertChannel(lastEnum, oldTask); + return; + } + if (Subscribe?.IsUnsubscribed == false)//排除重试机制后 多次接收任务导致内存泄露 + return; + Subscribe = Redis.SubscribeList(RedisExpandKey.ChannelKey, (taskId) => + { + if (taskId is null) return; + Subscribe?.Dispose();//取消接收任务监听 + //存储当前机器的任务 + Redis.HSet(RedisExpandKey.IDTask, taskId,true); + Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "-------------> 接收到任务 " + taskId); + InsertChannel(RedisChannelEnum.DownloadFile, taskId); + }); }); } + /// /// 写入任务异常 /// /// - /// + /// /// public static async Task SetTaskErrorMessage(long taskID, Exception? ex) { @@ -315,8 +317,7 @@ namespace VideoAnalysisCore.Common Console.WriteLine(ex.StackTrace); Console.WriteLine("=============================================="); //清除失败任务 重新接收任务 - await Redis.DelAsync(RedisExpandKey.IDTask); - await ReceivingTaskAsync(); + await NewTaskAsync(); } Redis.HMSet(RedisExpandKey.Task(taskID), "ErrorMessage", error); diff --git a/VideoAnalysisCore/Controllers/ApiController.cs b/VideoAnalysisCore/Controllers/ApiController.cs index 6df1a0b..c1161a6 100644 --- a/VideoAnalysisCore/Controllers/ApiController.cs +++ b/VideoAnalysisCore/Controllers/ApiController.cs @@ -190,7 +190,6 @@ namespace VideoAnalysisCore.Controllers Subject = req.Subject, Tag = req.Tag, TagId = req.TagId, - MediaName = req.Name, PPTVideoCode = req.PPTVideoCode, VideoType=req.VideoType }; diff --git a/VideoAnalysisCore/Controllers/Dto/ApiDto.cs b/VideoAnalysisCore/Controllers/Dto/ApiDto.cs index 203b783..d58f525 100644 --- a/VideoAnalysisCore/Controllers/Dto/ApiDto.cs +++ b/VideoAnalysisCore/Controllers/Dto/ApiDto.cs @@ -132,11 +132,6 @@ namespace VideoAnalysisCore.Controllers.Dto [Required(ErrorMessage = "资源URL是必填项")] public string MediaUrl { get; set; } = string.Empty; /// - /// 资源名称 - /// - [Required(ErrorMessage = "资源名称是必要的")] - public string Name { get; set; } = string.Empty; - /// /// ApiKey /// [Required(ErrorMessage = "接口Token是必填项")]