diff --git a/VideoAnalysisCore/AICore/FFMPGE/FFMPGEHandle.cs b/VideoAnalysisCore/AICore/FFMPGE/FFMPGEHandle.cs index e28afbe..fdc4445 100644 --- a/VideoAnalysisCore/AICore/FFMPGE/FFMPGEHandle.cs +++ b/VideoAnalysisCore/AICore/FFMPGE/FFMPGEHandle.cs @@ -61,7 +61,7 @@ namespace VideoAnalysisCore.AICore.FFMPGE var intervalSec = 5; var threshold = 8.15; var ssimThreshold = 0.9; - var taskInfo = await videoTaskDB.AsQueryable() + var taskInfo = await videoTaskDB.CopyNew().AsQueryable() .Where(s => s.Id == long.Parse(task)).FirstAsync(); if (string.IsNullOrEmpty(taskInfo.PPTVideoCode) || string.IsNullOrEmpty(taskInfo.PPTVideoUrl)) return; //视频切帧 @@ -77,7 +77,7 @@ namespace VideoAnalysisCore.AICore.FFMPGE redisManager.SetTaskProgress(task, "Frame=>10%"); foreach (string jpgFile in Directory.GetFiles(localPath, "*.jpg")) - FileSystem.DeleteFile(jpgFile, UIOption.OnlyErrorDialogs, RecycleOption.DeletePermanently); + File.Delete(jpgFile); redisManager.SetTaskProgress(task, "Frame=>20%"); await ffmpeg.ExecuteAsync($"-i {filePath} -vf \"fps=1/{intervalSec},scale=960:540\" {localPath}/{ExpandFunction.FrameName}%03d.jpg", cToken); @@ -122,7 +122,7 @@ namespace VideoAnalysisCore.AICore.FFMPGE } //写入数据库 var keyFramStr = keyFrames.Where(s => s != -1).ToJson(); - await videoTaskDB.AsUpdateable() + await videoTaskDB.CopyNew().AsUpdateable() .SetColumns(it => it.PPTKeyFrame == keyFramStr) .Where(it => it.Id == taskID) .ExecuteCommandAsync(); @@ -176,7 +176,7 @@ namespace VideoAnalysisCore.AICore.FFMPGE /// public async Task Audio2WAV16KAsync(string task) { - var filePath = await videoTaskDB.AsQueryable() + var filePath = await videoTaskDB.CopyNew().AsQueryable() .Where(s => s.Id == long.Parse(task)) .Select(s=>s.LocalMediaPath).FirstAsync(); if (string.IsNullOrEmpty(filePath)) diff --git a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs index 20a8bf5..164414a 100644 --- a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs +++ b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs @@ -84,14 +84,21 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek $"这是我的分段 {thems}。" + $"课堂内容与{sections}章节相关" + $"最后请确保分配的知识点是用户提供的,并且一定正确合理!" + + $"返回的片段数量与传入片段数量一致!" + $"输出内容只返回json格式({checkResFormat1})" + $" 格式 (方法点Id|方法点名称) " + $"提供的知识点名称({knows})。"; Console.WriteLine(DateTime.Now + "=>2.开始分析视频内容知识点"); - var konwRes = await chatGPTClient.ChatAsync(taskInfo.Id.ToString(), knowMessages, "知识点"); - - for (int i = 0; i < konwRes.Count(); i++) - questionRes[i].KnowPoint = konwRes[i].KnowPoint; + VideoKnowRes[] konwRes; + for (int i = 0; i < 5; i++) + { + konwRes = await chatGPTClient.ChatAsync(taskInfo.Id.ToString(), knowMessages, "知识点"); + // 分析结果的片段数量与预期不匹配 + if (questionRes.Length != konwRes.Length) continue; + for (int xi = 0; xi < konwRes.Count(); xi++) + questionRes[i].KnowPoint = konwRes[i].KnowPoint; + break; + } diff --git a/VideoAnalysisCore/Common/RedisExpand.cs b/VideoAnalysisCore/Common/RedisExpand.cs index 7cf7572..5be3555 100644 --- a/VideoAnalysisCore/Common/RedisExpand.cs +++ b/VideoAnalysisCore/Common/RedisExpand.cs @@ -70,9 +70,9 @@ namespace VideoAnalysisCore.Common /// /// 任务对象地址 /// - public static string Task(object taskId) => BaseKey + "TaskInfo:" + taskId; + public static string Task(object taskId) => BaseKey + "Info:" + taskId; public static string IDTask => BaseKey + "Services:" + AppCommon.Config.ID; - public static string TaskGPT(object taskId) => Task(taskId) + ":GPTCached"; + public static string TaskGPT(object taskId) => BaseKey + "GPTCached:" + taskId; /// /// 初始化 redis /// 需要在初始化配置文件时候调用 @@ -113,13 +113,17 @@ namespace VideoAnalysisCore.Common public void Init() { var SubscribeList = RedisManager.SubscribeList; + SubscribeList.Add(RedisChannelEnum.排队中, async (task) => + { + await Task.CompletedTask; + }); SubscribeList.Add(RedisChannelEnum.下载文件, async (task) => { using var scope = AppCommon.Services?.CreateScope(); if (scope is null || scope.ServiceProvider.GetService() is null) throw new Exception("DownloadFile 未注入"); else - await scope.ServiceProvider.GetService()?.RunTask(task) ; + await scope.ServiceProvider.GetService()?.RunTask(task); }); SubscribeList.Add(RedisChannelEnum.分离音频, FFMPGE.RunAsync); SubscribeList.Add(RedisChannelEnum.解析字幕, senseVoice.RunTask); @@ -225,7 +229,6 @@ namespace VideoAnalysisCore.Common if (Redis is null) throw new Exception("redis未初始化"); //设置任务Redis缓存过期时间 - Redis.Expire(RedisExpandKey.Task(taskId), 60 * 60 * 24 * 14); var startTime = Redis.HMGet>(RedisExpandKey.Task(taskId), "StartTime").FirstOrDefault(); if (startTime is null) @@ -233,6 +236,8 @@ namespace VideoAnalysisCore.Common if (!SubscribeList.ContainsKey(@enum)) throw new Exception(@enum + " 未实现"); var tId = taskId.ToString(); + + Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "-------------> 开始执行任务 " + tId); try { while (true) @@ -256,6 +261,8 @@ namespace VideoAnalysisCore.Common { await SetTaskErrorMessage(long.Parse(tId), ex); } + + Redis.Expire(RedisExpandKey.Task(taskId), 60 * 60 * 24 * 15); } public async Task TaskEnd(string task) @@ -318,15 +325,23 @@ namespace VideoAnalysisCore.Common var oldTaskArr = Redis.LRange(RedisExpandKey.IDTask, 0, oldTaskCount); //不自动清理未完成任务 等待执行完毕/失败后自动清理 //Redis.LTrim(RedisExpandKey.IDTask, 1, 0);//删除 redis 列表 - foreach (var oldTask in oldTaskArr) + foreach (var oldTask in oldTaskArr.Take(10)) { _ = Task.Run(async () => - { - Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "-------------> 接收上次未完成任务 " + oldTask); - await ClearTaskError(long.Parse(oldTask)); - var lastEnum = (await Redis.HMGetAsync(RedisExpandKey.Task(oldTask), "LastEnum")).FirstOrDefault(); - await InsertChannel(lastEnum, oldTask); - }); + { + try + { + Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "-------------> 接收上次未完成任务 " + oldTask); + await ClearTaskError(long.Parse(oldTask)); + var lastEnum = (await Redis.HMGetAsync(RedisExpandKey.Task(oldTask), "LastEnum")).FirstOrDefault(); + await InsertChannel(lastEnum, oldTask); + } + catch (Exception ex) + { + await SetTaskErrorMessage(long.Parse(oldTask), ex); + throw; + } + }); } } else @@ -387,24 +402,19 @@ namespace VideoAnalysisCore.Common Console.WriteLine($"{DateTime.Now} =>服务端不接收任务"); return; } - Task.Run(() => + lock (Redis) { - lock (Redis) + if (Subscribe?.IsUnsubscribed == false)//排除重试机制后 多次接收任务导致内存泄露 + return; + Subscribe = Redis.SubscribeList(RedisExpandKey.ChannelKey, async (taskId) => { - if (Subscribe?.IsUnsubscribed == false)//排除重试机制后 多次接收任务导致内存泄露 - return; - Subscribe = Redis.SubscribeList(RedisExpandKey.ChannelKey, async (taskId) => - { - if (taskId is null) return; - Subscribe?.Dispose();//取消接收任务监听 - //存储当前机器的任务 - Redis.LPush(RedisExpandKey.IDTask, taskId); - Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "-------------> 接收到任务 " + taskId); - await InsertChannel(RedisChannelEnum.下载文件, taskId); - }); - } - - }); + if (taskId is null) return; + Subscribe?.Dispose();//取消接收任务监听 + Redis.LPush(RedisExpandKey.IDTask, taskId); + Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "-------------> 接收到任务 " + taskId); + await InsertChannel(RedisChannelEnum.下载文件, taskId); + }); + } } /// diff --git a/VideoAnalysisCore/Controllers/LJZK_Controller.cs b/VideoAnalysisCore/Controllers/LJZK_Controller.cs index ee45ae9..42c382a 100644 --- a/VideoAnalysisCore/Controllers/LJZK_Controller.cs +++ b/VideoAnalysisCore/Controllers/LJZK_Controller.cs @@ -77,6 +77,12 @@ namespace VideoAnalysisCore.Controllers { SubjectEnum.ѧ }; + var courseTypeArr = new List + { + AttachmentsInfoType., + AttachmentsInfoType.¿, + AttachmentsInfoType.ϰ + }; foreach (var sGroup in reqArr.GroupBy(s => s.ContentId)) { var s = sGroup.FirstOrDefault(s => s.VideoType == VideoType.ͷ); @@ -84,6 +90,10 @@ namespace VideoAnalysisCore.Controllers return BadRequest("ЧʦڿƵ"); //УѧЧ if (!subjectArr.Contains(s.SubjectId)) continue; + //ЧĿγ + if (!courseTypeArr.Contains(s.CourseType)) continue; + + var stageId = s.StageId.GetHashCode(); var subjectId = s.SubjectId.GetHashCode(); var course = courseArr.FirstOrDefault(x => stageId == x.Stage_Id && subjectId == x.Subject_Id);