diff --git a/Learn.VideoAnalysis.API/appsettings.json b/Learn.VideoAnalysis.API/appsettings.json index 7738f9c..235afa9 100644 --- a/Learn.VideoAnalysis.API/appsettings.json +++ b/Learn.VideoAnalysis.API/appsettings.json @@ -42,8 +42,7 @@ "ApiKey": "sk-8BvvhESZIkgUbiaaJhglPxFa4o2X9H3xEv9lXELrWWwGxHWY" }, "ChatGpt": { - "Host": "https://api.g4f.icu/", - //"Host": "https://api.oaibest.com/", + "Host": "https://api.oaibest.com/", "ApiKey": "sk-D15tBln31N7dI9Fi7lds7OySFv5tOEK7DMNsG5rY2E6DCr4s" }, "DeepSeek": { diff --git a/VideoAnalysisCore/AICore/GPT/ChatGPTType.cs b/VideoAnalysisCore/AICore/GPT/ChatGPTType.cs index 6cf0102..cb3a0dd 100644 --- a/VideoAnalysisCore/AICore/GPT/ChatGPTType.cs +++ b/VideoAnalysisCore/AICore/GPT/ChatGPTType.cs @@ -24,6 +24,7 @@ namespace VideoAnalysisCore.AICore.GPT //public const string Gemini_3_Chat_thinking = "gemini-3-pro-preview-thinking"; public const string Gemini_3_Chat = "gemini-3.1-pro-preview"; //public const string Gemini_3_Chat_flash = "gemini-3-flash-preview"; - public const string Gemini_31_Chat_flash = "gemini-3.1-flash-lite-preview"; + //已失效 + //public const string Gemini_31_Chat_flash = "gemini-3.1-flash-lite-preview"; } } diff --git a/VideoAnalysisCore/AICore/GPT/GTP_Analysis_1.cs b/VideoAnalysisCore/AICore/GPT/GTP_Analysis_1.cs index c3e30cf..39fe375 100644 --- a/VideoAnalysisCore/AICore/GPT/GTP_Analysis_1.cs +++ b/VideoAnalysisCore/AICore/GPT/GTP_Analysis_1.cs @@ -27,6 +27,7 @@ using Dm.util; using static System.Net.Mime.MediaTypeNames; using VideoAnalysisCore.AICore.GPT.DeepSeek; using VideoAnalysisCore.AICore.GPT.Gemini; +using static System.Collections.Specialized.BitVector32; namespace VideoAnalysisCore.AICore.GPT { @@ -115,10 +116,10 @@ namespace VideoAnalysisCore.AICore.GPT await _workflowManager.AddTaskLog(taskInfo.Id, "==>2.开始分析视频内容知识点"); List konwRes; var knowOK = false; - var chatClentArr = new GPTClient[] { chatGPTClient, geminiClient, bset_deepSeekClient }; + //var chatClentArr = new GPTClient[] { chatGPTClient, geminiClient, bset_deepSeekClient }; for (int i = 0; i < 3; i++) { - konwRes = await chatClentArr[i].ChatAsync>(taskInfo.Id.ToString(), knowMessages, "知识点"); + konwRes = await chatGPTClient.ChatAsync>(taskInfo.Id.ToString(), knowMessages, "知识点"); // 分析结果的片段数量与预期不匹配 if (questionRes.Count() != konwRes.Count()) continue; for (int xi = 0; xi < konwRes.Count(); xi++) @@ -193,7 +194,7 @@ namespace VideoAnalysisCore.AICore.GPT $"字幕列表 {rCaptionArr}。" + $"输出格式 json字符串 对象格式{fileNameResFormat}"; var task = taskInfo.Id.ToString(); - var fileNameInfoRes = await geminiClient.ChatAsync(task, fileNamePostMessages, "授课章节"); + var fileNameInfoRes = await chatGPTClient.ChatAsync(task, fileNamePostMessages, "授课章节"); taskInfo.Sections = fileNameInfoRes.授课章节; await videoTaskDB.AsUpdateable() .SetColumns(it => it.Sections == fileNameInfoRes.授课章节) @@ -282,11 +283,43 @@ namespace VideoAnalysisCore.AICore.GPT 输出格式(仅 JSON):{resFormat} """; - var improved = await geminiClient.ChatAsync>(taskInfo.Id.ToString(), message, "分段优化"); - if (improved is null || improved.Count() != questionRes.Count()) + //var improved = await geminiClient.ChatAsync>(taskInfo.Id.ToString(), message, "分段优化"); + //if (improved is null || improved.Count() != questionRes.Count()) return null; - return improved.OrderBy(s => s.StartTime ?? 0).ToList(); + //return improved.OrderBy(s => s.StartTime ?? 0).ToList(); + } + private async Task<(string, List)> GetKnowledgeInfos(VideoTask taskInfo,long Course_Id) + { + List? knowledgeInfos =null; + string? sections = null; + for (int i = 0; i < 3; i++) + { + sections = await GetSections(taskInfo, Course_Id); + var know = await knowledgeInfoDB.GetFirstAsync(s => s.Course_Id == Course_Id && s.Name == sections); + if (know is null) + { + await _workflowManager.AddTaskLog(taskInfo.Id, $"==>识别的知识点无效 {sections}"); + continue; + } + var kInfo = await knowledgeInfoDB.GetByIdAsync(know.Parent_Id); + if (know.Parent_Id == 0) + kInfo = know; + try + { + knowledgeInfos = await knowledgeInfoDB.AsQueryable() + .ToChildListAsync(s => s.Parent_Id, kInfo.Parent_Id == 0 ? kInfo.Id : kInfo.Parent_Id); + } + catch (Exception) + { + await _workflowManager.AddTaskLog(taskInfo.Id, $"==>识别的知识没有对应的子知识点 {sections } {kInfo?.Name}"); + continue; + } + } + if(knowledgeInfos is null) + throw new Exception("多次识别后未能识别到有效课堂知识点=>" + sections); + return new(sections, knowledgeInfos); + } /// @@ -308,12 +341,13 @@ namespace VideoAnalysisCore.AICore.GPT [ async (m)=>await bset_deepSeekClient .ChatAsync>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.Deepseek_v32,8_000), - async (m)=>await bset_deepSeekClient - .ChatAsync>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.Deepseek_Chat,8_000), - async (m)=>await chatGPTClient - .ChatAsync>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.GPT54_mini,16_000), - async (m)=>await geminiClient - .ChatAsync>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.Gemini_3_Chat,16_000), ]; + //async (m)=>await bset_deepSeekClient + // .ChatAsync>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.Deepseek_Chat,8_000), + //async (m)=>await chatGPTClient + // .ChatAsync>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.GPT54_mini,16_000), + //async (m)=>await geminiClient + // .ChatAsync>(taskInfo.Id.ToString(), m, "优化字幕",ChatGPTType.Gemini_3_Chat,16_000), + ]; await Parallel.ForAsync(0, totalCount, new ParallelOptions() #if DEBUG @@ -731,24 +765,10 @@ namespace VideoAnalysisCore.AICore.GPT var captionsArr = JsonSerializer.Deserialize(taskInfo.Captions); //处理视频授课章节 - var sections = await GetSections(taskInfo, Course_Id); - - var know = await knowledgeInfoDB.GetFirstAsync(s => s.Course_Id == Course_Id && s.Name == sections); - if (know is null) - throw new Exception("未能找到对应知识点=>" + sections); - List? knowledgeInfos = new List(); - var kInfo = await knowledgeInfoDB.GetByIdAsync(know.Parent_Id); - if (know.Parent_Id == 0) - kInfo = know; - try - { - knowledgeInfos = await knowledgeInfoDB.AsQueryable() - .ToChildListAsync(s => s.Parent_Id, kInfo.Parent_Id == 0 ? kInfo.Id : kInfo.Parent_Id); - } - catch (Exception) - { - throw new Exception("没有对应的子知识点=>" + sections + " " + kInfo?.Name); - } + var kr = await GetKnowledgeInfos(taskInfo, Course_Id); + var sections = kr.Item1; + List? knowledgeInfos = kr.Item2; + //AI优化字幕 captionsArr = await OptimizeSubtitles(taskInfo, captionsArr, sections); @@ -801,7 +821,7 @@ namespace VideoAnalysisCore.AICore.GPT // } //} - if (checkRes != null && checkRes.Score >= 90) + if (checkRes != null && checkRes.Score >= 88) { //写入知识点 await videoKonwPointDB.DeleteAsync(s => s.VideoTaskId == taskInfo.Id); @@ -838,7 +858,7 @@ namespace VideoAnalysisCore.AICore.GPT continue; } } - if (tryCount == 0) + if (tryCount < 1) { throw new Exception("重试次数过多!"); } diff --git a/VideoAnalysisCore/AICore/GPT/Gemini/GeminiGPTClient.cs b/VideoAnalysisCore/AICore/GPT/Gemini/GeminiGPTClient.cs index 0bfe55f..c0dcc85 100644 --- a/VideoAnalysisCore/AICore/GPT/Gemini/GeminiGPTClient.cs +++ b/VideoAnalysisCore/AICore/GPT/Gemini/GeminiGPTClient.cs @@ -46,7 +46,7 @@ namespace VideoAnalysisCore.AICore.GPT.Gemini Message[] messageArr = [ new Message(postMessages,"user"), ]; - model = model ?? ChatGPTType.Gemini_31_Chat_flash; + model = model ?? ChatGPTType.Gemini_3_Chat; messageArr = messageArr.Where(s => s != null).ToArray(); var chatReq = new ChatRequest { diff --git a/VideoAnalysisCore/Common/RedisExpand.cs b/VideoAnalysisCore/Common/RedisExpand.cs index 7eeb6bb..5666594 100644 --- a/VideoAnalysisCore/Common/RedisExpand.cs +++ b/VideoAnalysisCore/Common/RedisExpand.cs @@ -81,6 +81,7 @@ namespace VideoAnalysisCore.Common /// public static string Task(object taskId) => BaseKey + "Info:" + taskId; public static string IDTask => BaseKey + "Services:" + AppCommon.Config.ID; + public static string DeviceTaskLog(string deviceId) => BaseKey + "Services:" + deviceId; /// /// 在线设备Key集合 (已弃用,直接扫描 Heartbeat) /// diff --git a/VideoAnalysisCore/Common/TidySlideWorkflowManager.cs b/VideoAnalysisCore/Common/TidySlideWorkflowManager.cs index 4387cfa..544ccda 100644 --- a/VideoAnalysisCore/Common/TidySlideWorkflowManager.cs +++ b/VideoAnalysisCore/Common/TidySlideWorkflowManager.cs @@ -94,7 +94,7 @@ namespace VideoAnalysisCore.Common public override async Task TaskEnd(string task) { var tId = long.Parse(task); - await base.TaskEnd(task); + //await base.TaskEnd(task); // TidySlide 工作流结束时清理文件 try diff --git a/VideoAnalysisCore/Controllers/Dto/ApiDto.cs b/VideoAnalysisCore/Controllers/Dto/ApiDto.cs index 15ccfe1..d3ba6f5 100644 --- a/VideoAnalysisCore/Controllers/Dto/ApiDto.cs +++ b/VideoAnalysisCore/Controllers/Dto/ApiDto.cs @@ -350,7 +350,7 @@ namespace VideoAnalysisCore.Controllers.Dto public GradeEnum? GradeId { get; set; } public GradeSemesterEnum? GradeSemester { get; set; } public long? TextBookVersionId { get; set; } - public string[]? KnowPointIdArr { get; set; } + public string[]? KnowPointStrArr { get; set; } public string? Theme { get; set; } public string? Content { get; set; } public int PageIndex { get; set; } = 0; diff --git a/VideoAnalysisCore/Controllers/LJZK_Controller.cs b/VideoAnalysisCore/Controllers/LJZK_Controller.cs index 261304d..3132f02 100644 --- a/VideoAnalysisCore/Controllers/LJZK_Controller.cs +++ b/VideoAnalysisCore/Controllers/LJZK_Controller.cs @@ -306,14 +306,14 @@ namespace VideoAnalysisCore.Controllers var pageIndex = req.PageIndex < 0 ? 0 : req.PageIndex; var pageSize = req.PageSize <= 0 ? 200 : req.PageSize > 500 ? 500 : req.PageSize; - - if (req.KnowPointIdArr is not null && req.KnowPointIdArr.Length > 0) + string[]? knowArr = null; + if (req.KnowPointStrArr is not null && req.KnowPointStrArr.Length > 0) { - var knowArr = req.KnowPointIdArr.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToArray(); + knowArr = req.KnowPointStrArr.Where(s => !string.IsNullOrWhiteSpace(s)).Select(s=>s.Trim()).Distinct().ToArray(); if (knowArr.Length > 0) { stageQuery = stageQuery.Where(s => SqlFunc.Subqueryable() - .Where(k => k.StageId == s.Id && k.KnowPointId != null && knowArr.Contains(k.KnowPointId)) + .Where(k => k.StageId == s.Id && k.KnowPoint != null && knowArr.Contains(k.KnowPoint)) .Any()); } } @@ -326,12 +326,8 @@ namespace VideoAnalysisCore.Controllers var taskIdArr = stagePageArr.Select(s => s.VideoTaskId).ToArray(); var kpQuery = videoKonwPointDB.AsQueryable() .Where(s => taskIdArr.Contains(s.VideoTaskId) && s.KnowPointId != null); - if (req.KnowPointIdArr is not null && req.KnowPointIdArr.Length > 0) - { - var knowArr = req.KnowPointIdArr.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToArray(); - if (knowArr.Length > 0) - kpQuery = kpQuery.Where(s => knowArr.Contains(s.KnowPointId)); - } + if (knowArr.Length > 0) + kpQuery = kpQuery.Where(s => knowArr.Contains(s.KnowPointId)); var kpArr = await kpQuery .Select(s => new { s.StageId, s.KnowPoint }) diff --git a/VideoAnalysisCore/Controllers/VideoTaskController.cs b/VideoAnalysisCore/Controllers/VideoTaskController.cs index c7e4834..bec6860 100644 --- a/VideoAnalysisCore/Controllers/VideoTaskController.cs +++ b/VideoAnalysisCore/Controllers/VideoTaskController.cs @@ -527,7 +527,7 @@ namespace VideoAnalysisCore.Controllers foreach (var deviceId in onlineDevices) { - var key = RedisExpandKey.BaseKey + "Services:" + deviceId; + var key = RedisExpandKey.DeviceTaskLog(deviceId) ; var tasks = redisManager.Redis.LRange(key, 0, 999); oldTaskArr.AddRange(tasks); } @@ -535,7 +535,7 @@ namespace VideoAnalysisCore.Controllers else { // 获取指定节点 - var key = RedisExpandKey.BaseKey + "Services:" + model.DeviceId; + var key = RedisExpandKey.DeviceTaskLog(model.DeviceId); oldTaskArr = redisManager.Redis.LRange(key, 0, 999).ToList(); } diff --git a/VideoAnalysisCore/Model/蓝鲸智库/KnowledgeInfo.cs b/VideoAnalysisCore/Model/蓝鲸智库/KnowledgeInfo.cs index dba8523..4a5bff7 100644 --- a/VideoAnalysisCore/Model/蓝鲸智库/KnowledgeInfo.cs +++ b/VideoAnalysisCore/Model/蓝鲸智库/KnowledgeInfo.cs @@ -11,7 +11,7 @@ namespace VideoAnalysisCore.Model.蓝鲸智库 /// /// 蓝鲸智库 知识点表 /// - [SugarTable("knowledgeinfo")] + [SugarTable("knowledgeinfo_hy")] [Tenant("1001")] public class KnowledgeInfo {