From 4ab527c388385f2ba73b6c8b5aa2179a55cc933c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=B0=8F=E8=82=A5=E7=BE=8A?= <1048382248@qq.com>
Date: Wed, 18 Jun 2025 10:33:36 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=BB=E5=8A=A1=E8=B0=83?=
=?UTF-8?q?=E5=BA=A6=E6=B5=81=E7=A8=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Components/Pages/VideoTaskPage.razor | 23 +-
.../Components/Pages/VideoTaskPage.razor.cs | 4 +-
.../Components/Pages/VideoTaskShow.razor.cs | 2 +-
VideoAnalysis/Program.cs | 1 -
VideoAnalysisCore/AICore/GPT/BserGPT.cs | 6 +
.../AICore/GPT/ChatGPT/Chat_GPT.cs | 5 +
.../AICore/GPT/DeepSeek/DeepSeekClient.cs | 4 +-
.../AICore/GPT/DeepSeek/DeepSeekModel.cs | 1 -
.../AICore/GPT/DeepSeek/DeepSeek_GPT.cs | 46 ++-
VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs | 229 -----------
.../AICore/GPT/KIMI/MoonshotClient.cs | 356 -----------------
.../AICore/GPT/KIMI/MoonshotModel.cs | 365 ------------------
VideoAnalysisCore/Common/AppCommon.cs | 3 +
VideoAnalysisCore/Common/RedisExpand.cs | 76 ++--
VideoAnalysisCore/Job/TaskFileClearJob.cs | 2 +-
.../Model/Enum/RedisChannelEnum.cs | 8 +-
16 files changed, 122 insertions(+), 1009 deletions(-)
delete mode 100644 VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs
delete mode 100644 VideoAnalysisCore/AICore/GPT/KIMI/MoonshotClient.cs
delete mode 100644 VideoAnalysisCore/AICore/GPT/KIMI/MoonshotModel.cs
diff --git a/VideoAnalysis/Components/Pages/VideoTaskPage.razor b/VideoAnalysis/Components/Pages/VideoTaskPage.razor
index 7945f48..dc2bb05 100644
--- a/VideoAnalysis/Components/Pages/VideoTaskPage.razor
+++ b/VideoAnalysis/Components/Pages/VideoTaskPage.razor
@@ -8,6 +8,7 @@
@using VideoAnalysisCore.Model.Dto
@using VideoAnalysisCore.Model.Enum;
+
-
+
@@ -50,25 +51,25 @@
-
+
+ Description="@RowST(rowData,RedisChannelEnum.下载文件)" />
+ Description="@RowST(rowData,RedisChannelEnum.分离音频)" />
+ Description="@RowST(rowData,RedisChannelEnum.解析字幕)" />
-
-
+
+
+ Description="@RowST(rowData,RedisChannelEnum.结束任务)" />
@@ -101,4 +102,4 @@
-
+
\ No newline at end of file
diff --git a/VideoAnalysis/Components/Pages/VideoTaskPage.razor.cs b/VideoAnalysis/Components/Pages/VideoTaskPage.razor.cs
index f66a4c8..e5f3890 100644
--- a/VideoAnalysis/Components/Pages/VideoTaskPage.razor.cs
+++ b/VideoAnalysis/Components/Pages/VideoTaskPage.razor.cs
@@ -128,8 +128,8 @@ namespace Learn.VideoAnalysis.Components.Pages
var data = RedisExpand.Redis.HMGet(RedisExpandKey.Task(item.Id),
"Progress", "LastEnum", "StartTime", "ErrorMessage");
item.Progress = data[0];
- item.LastEnum = data[1].ToEnum() ?? default;
- item.StartTimeDic = System.Text.Json.JsonSerializer.Deserialize>(data[2]) ?? null;
+ item.LastEnum = data[1] == null ?default:data[1].ToEnum() ?? default;
+ item.StartTimeDic = data[2]==null?null: System.Text.Json.JsonSerializer.Deserialize>(data[2]) ?? null;
item.ErrorMessage = data[3];
rowRestartLoading = false;
var statusStr = "wait";
diff --git a/VideoAnalysis/Components/Pages/VideoTaskShow.razor.cs b/VideoAnalysis/Components/Pages/VideoTaskShow.razor.cs
index 12d5be4..164728c 100644
--- a/VideoAnalysis/Components/Pages/VideoTaskShow.razor.cs
+++ b/VideoAnalysis/Components/Pages/VideoTaskShow.razor.cs
@@ -95,7 +95,7 @@ namespace Learn.VideoAnalysis.Components.Pages
}).ToArray();
videoPath = AppCommon.GetVideoPath(nowTask.Id.ToString());
- if (nowTask.VideoType == AttachmentsInfoType.Review)
+ if (nowTask.VideoType == AttachmentsInfoType.复习)
{
var questionArr = await videoQuestionDB
.AsQueryable().Where(s => s.VideoTaskId == nowTask.Id)
diff --git a/VideoAnalysis/Program.cs b/VideoAnalysis/Program.cs
index 25a8e03..3cf4074 100644
--- a/VideoAnalysis/Program.cs
+++ b/VideoAnalysis/Program.cs
@@ -4,7 +4,6 @@ using Microsoft.OpenApi.Models;
using VideoAnalysisCore.AICore.SherpaOnnx;
using Mapster;
using VideoAnalysisCore.AICore.GPT;
-using VideoAnalysisCore.AICore.GPT.KIMI;
using VideoAnalysisCore.AICore.GPT.ChatGPT;
using Microsoft.Extensions.FileProviders;
using VideoAnalysisCore.AICore.GPT.DeepSeek;
diff --git a/VideoAnalysisCore/AICore/GPT/BserGPT.cs b/VideoAnalysisCore/AICore/GPT/BserGPT.cs
index 0c46d53..855fddf 100644
--- a/VideoAnalysisCore/AICore/GPT/BserGPT.cs
+++ b/VideoAnalysisCore/AICore/GPT/BserGPT.cs
@@ -16,5 +16,11 @@ namespace VideoAnalysisCore.AICore.GPT
/// 任务id
///
public Task GetKnow(string task);
+ ///
+ /// 获取 视频分段内的 试题
+ ///
+ /// 任务id
+ ///
+ public Task GetVideoQuestion(string task);
}
}
diff --git a/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs b/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs
index 9b78718..fc84ad9 100644
--- a/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs
+++ b/VideoAnalysisCore/AICore/GPT/ChatGPT/Chat_GPT.cs
@@ -418,5 +418,10 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
return gptRes;
}
+
+ public Task GetVideoQuestion(string task)
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekClient.cs b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekClient.cs
index 978e454..4bbfbde 100644
--- a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekClient.cs
+++ b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekClient.cs
@@ -7,7 +7,6 @@ using System.Net.Http;
using Newtonsoft.Json;
using System.Net.Http.Json;
using System.Net;
-using VideoAnalysisCore.AICore.GPT.KIMI;
using System.Threading;
using System;
using System.IO;
@@ -121,8 +120,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
Console.WriteLine("==============================================");
-
- Thread.Sleep(1000);
+ Thread.Sleep(1000);
}
}
throw errorMSG.Last(s => s != null);
diff --git a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekModel.cs b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekModel.cs
index 2e4b41c..3e6df08 100644
--- a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekModel.cs
+++ b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekModel.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using VideoAnalysisCore.AICore.GPT.KIMI;
namespace VideoAnalysisCore.AICore.GPT.DeepSeek
{
diff --git a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs
index 4aaab68..964e024 100644
--- a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs
+++ b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs
@@ -556,10 +556,50 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
await RedisExpand.Redis
.HMSetAsync(RedisExpandKey.Task(task), "VideoKnows", questionRes);
- if (taskInfo.VideoType == AttachmentsInfoType.复习)
- await AnalysisVideoQuestions(taskInfo, knowledgeInfos);
-
return null;
}
+
+
+ ///
+ /// 获取 视频分段内的 试题
+ ///
+ /// 任务id
+ ///
+ public async Task GetVideoQuestion(string task)
+ {
+ var taskId = long.Parse(task);
+ var taskInfo = await videoTaskDB.AsQueryable()
+ .Where(s => s.Id == taskId)
+ .FirstAsync();
+
+ if (taskInfo.VideoType != AttachmentsInfoType.复习)
+ return;
+ var subject = taskInfo.Subject.ToString();
+ var Course_Id = 27;
+ switch (taskInfo.Type)//处理不同任务类型的知识点树
+ {
+ case TaskTypeEnum.蓝鲸智库_中职视频分段:
+ Course_Id = 51;
+ break;
+ case TaskTypeEnum.蓝鲸智库_视频分段:
+ default:
+ Course_Id = 27;
+ break;
+ }
+
+ 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);
+ var kInfo = await knowledgeInfoDB.GetByIdAsync(know.Parent_Id);
+ var knowledgeInfos = await knowledgeInfoDB.AsQueryable()
+ .ToChildListAsync(s => s.Parent_Id, kInfo.Parent_Id == 0 ? kInfo.Id : kInfo.Parent_Id);
+ //开始分析复习课 试题
+ await AnalysisVideoQuestions(taskInfo, knowledgeInfos);
+
+ return;
+ }
}
}
diff --git a/VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs b/VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs
deleted file mode 100644
index 2d6b9c4..0000000
--- a/VideoAnalysisCore/AICore/GPT/KIMI/KIMI_GPT.cs
+++ /dev/null
@@ -1,229 +0,0 @@
-using VideoAnalysisCore.AICore.SherpaOnnx;
-using VideoAnalysisCore.Common;
-using System.Threading.Tasks;
-using Whisper.net;
-using System.Text.Json;
-using VideoAnalysisCore.Model;
-using System.Text;
-using FFmpeg.NET.Services;
-using Microsoft.Extensions.Primitives;
-using System.ComponentModel.DataAnnotations;
-using System.Reflection;
-using FreeRedis;
-using VideoAnalysisCore.Model.Dto;
-using SqlSugar.IOC;
-using VideoAnalysisCore.AICore.GPT.Dto;
-using VideoAnalysisCore.AICore.GPT;
-using VideoAnalysisCore.AICore.GPT.ChatGPT;
-using VideoAnalysisCore.Model.Enum;
-
-namespace VideoAnalysisCore.AICore.GPT.KIMI
-{
- ///
- /// kimi 文本模型
- ///
- public class KIMI_GPT // : IBserGPT
- {
- private readonly MoonshotClient moonshotClient;
- private readonly Repository criteriaDB;
- private readonly Repository videoTaskDB;
- ///
- /// 初始化
- ///
- ///
- ///
- public KIMI_GPT(MoonshotClient moonshotClient, Repository criteria, Repository videoTaskDB)
- {
- MoonshotClient.Host = AppCommon.Config.ChatGpt.KIMI.Host;
- MoonshotClient.ApiKey = AppCommon.Config.ChatGpt.KIMI.ApiKey;
-
- this.moonshotClient = moonshotClient;
- criteriaDB = criteria;
- this.videoTaskDB = videoTaskDB;
- }
- ///
- /// 访问GPT
- ///
- /// 任务id
- ///
- public async Task CallGPT(string task)
- {
- var taskId = long.Parse(task);
- var taskInfo = await videoTaskDB.AsQueryable()
- .Where(s => s.Id == taskId)
- .FirstAsync();
- var speakerArr = JsonSerializer.Deserialize(taskInfo.Speaker);
- var captionsArr = JsonSerializer.Deserialize(taskInfo.Captions);
- var captions = ExpandFunction.GetSpeakerCaptions(captionsArr, speakerArr);
- var criteriaArr = await criteriaDB.GetListAsync(s => s.Subject == taskInfo.Subject);
- var criteriaBuilder = new StringBuilder();
- foreach (var item in criteriaArr)
- {
- criteriaBuilder.Append(item.Id);
- criteriaBuilder.Append(":");
- criteriaBuilder.Append(item.NamePrompt);
- criteriaBuilder.Append("? 请基于问题的回答苛刻的给出[优/良/中/差]作为得分");
- //criteriaBuilder.Append("0-");
- //criteriaBuilder.Append((int)(item.TotalScore * 10));
- //criteriaBuilder.Append("分");
- //criteriaBuilder.Append((int)(item.PassScore * 10));
- //criteriaBuilder.Append("分为及格");
- criteriaBuilder.Append(":");
- criteriaBuilder.Append("array=[得分,问题的回答,问题的详细改进意见,问题的详细扣分原因]|");
-
- }
- //拼接枚举提问
- foreach (var value in System.Enum.GetValues(typeof(QuestionTypeEnum)))
- {
- var enumValue = (QuestionTypeEnum)value;
- var displayAttribute = enumValue.GetType()
- .GetField(enumValue.ToString())?
- .GetCustomAttribute();
- if (displayAttribute == null) continue;
- criteriaBuilder.Append(enumValue.GetHashCode());
- criteriaBuilder.Append(":");
- criteriaBuilder.Append(displayAttribute.Prompt);
- criteriaBuilder.Append("|");
- }
-
- var resFormat = """{"问题编号":number,"结果":array|bool|object,"问题解释":string}""";
- var postMessages =
- $"你是一个教学经验老道老师对教学工作有着深入的理解和丰富的经验,能够准确把握教学大纲的要求和教学重点。" +
- $"熟练掌握各种教学管理方法和手段,能够制定科学合理的教学计划和教学评估体系。" +
- $"善于发现教学中的问题,并能迅速提出有效的解决方案,确保教学工作的顺利进行。" +
- $"以下是一段音频的字幕,分析这段字幕 字幕格式(说话人:开始秒:结束秒:内容|下一段字幕)." +
- $"字幕列表 {captions.Captions} " +
- $"基于字幕内容回答提出的所有问题 问题格式(问题编号:问题描述:结束秒:结果类型|下一个问题)" +
- $"问题列表 {criteriaBuilder} "
- + $"返回固定的JSON数组格式({resFormat})";
-
-
- var reqTokenCount = await moonshotClient.GetAsTiMateTokenCount(postMessages);
- var maxTokens = 4000;
- var modelId = reqTokenCount > 32 * 1000 - maxTokens ? "moonshot-v1-128k" : "moonshot-v1-32k";
- var chatRep = new ChatReq
- {
- max_tokens = maxTokens,
- temperature = 0.3f,
- frequency_penalty = 0,
- presence_penalty = 0,
- model = modelId,
- messages = new List(){
- new MessagesItem(postMessages,"system"),
- //new MessagesItem(resFormat,"assistant",true),
- }
- };
-
- var time = DateTime.Now.ToString("MMddHHmmss");
- RedisExpand.SetTaskGPTCached(task, time,chatRep);
- var chatResp = await moonshotClient.ChatSSE(chatRep);
- //chatResp = await moonshotClient.Chat(chatRep);
- var chatResContent = chatResp?.res;
- if (string.IsNullOrEmpty(chatResContent))
- throw new Exception("KIMIGPT返回message无效结果");
- if (chatResp != null)
- RedisExpand.SetTaskGPTCached(task, time, new object[] { chatResp.Value.res, chatResp.Value.u });
- //chatResContent = """[{ "问题编号": 10, "结果": [ "良", "教学目标在授课中有提及,如提到了圆锥曲线的学习以及数列的概念和简单表示,但未明确指出具体的教学目标,如学生应掌握的具体知识点或技能。", "教师可以在课程开始时明确列出本节课的教学目标,让学生清楚知道本节课的学习重点。", "教学目标不够明确,缺乏具体的教学目标描述。" ], "问题解释": "授课中提到了学习圆锥曲线和数列的概念及简单表示,但未明确具体的教学目标。"},{ "问题编号": 11, "结果": [ "优", "授课语言简明、准确,且在解释概念时使用了生动的例子,如通过王芳同学的身高数据来解释数列的概念。", "无需改进,授课语言已经非常清晰和生动。", "无" ], "问题解释": "授课中使用了简明、准确、生动的语言,并通过实例来解释概念。"},{ "问题编号": 12, "结果": [ "优", "教师在授课过程中表现出对学生的重视,语言友善温和,如在解释概念时多次询问学生是否理解。", "无需改进,教师已经很好地表现出对学生的重视和友善。", "无" ], "问题解释": "教师在授课中重视学生需求,表现出友善和温和的态度。"},{ "问题编号": 13, "结果": [ "良", "授课中教师给学生留有一定的思考时间,但部分时间较短,可能不足以让学生充分思考。", "教师可以在解释概念或提出问题后,适当延长学生的思考时间,确保学生能够充分理解和消化。", "部分思考留白时间较短,不足以让学生充分思考。" ], "问题解释": "授课中给学生留有思考时间,但部分时间较短。"},{ "问题编号": 14, "结果": [ "优", "教学重难点突出,如对数列的概念、表示方法等进行了详细讲解,并使用了实例来帮助学生理解。", "无需改进,教学重难点已经很好地突出。", "无" ], "问题解释": "教学中对重难点进行了突出讲解,并使用实例帮助学生理解。"},{ "问题编号": 15, "结果": [ "中", "学生在授课中的参与度一般,教师虽有询问学生是否理解,但缺乏更积极的互动方式。", "教师可以通过提问、让学生回答问题等方式,增加学生的参与度和互动。", "学生参与度一般,缺乏更积极的互动。" ], "问题解释": "授课中教师虽有询问学生是否理解,但学生参与互动的程度一般。"},{ "问题编号": 16, "结果": [ "优", "知识点讲解逻辑清晰明了,如对数列的概念、分类、表示方法等进行了条理清晰的讲解。", "无需改进,知识点讲解逻辑已经非常清晰。", "无" ], "问题解释": "授课中知识点讲解逻辑清晰明了,条理性强。"},{ "问题编号": 17, "结果": [ "良", "例题讲解过程中,教师进行了一定的留白,但留白的时间和深度可以进一步加强。", "教师可以在例题讲解中设置更多的问题,引导学生思考,增加留白的时间和深度。", "例题讲解中的留白时间和深度有待加强。" ], "问题解释": "授课中例题讲解进行了留白,但可以进一步加强。"},{ "问题编号": 18, "结果": [ "良", "练习时给到学生的时间一般,部分练习时间较短,可能不足以让学生充分练习。", "教师可以在练习环节给学生更多的时间,确保学生能够充分练习和理解。", "练习时间部分较短,不足以让学生充分练习。" ], "问题解释": "授课中练习环节给到学生的时间一般。"},{ "问题编号": 19, "结果": [ "优", "课程内容不冗杂,讲解清楚,如对数列的概念、分类、表示方法等进行了清晰的讲解。", "无需改进,课程内容和讲解已经非常清晰。", "无" ], "问题解释": "授课中课程内容不冗杂,讲解清楚。"},{ "问题编号": 20, "结果": [ "优", "授课中进行了举例阐述知识点,如通过王芳同学的身高数据来解释数列的概念,便于学生理解。", "无需改进,授课中已经很好地使用了举例来阐述知识点。", "无" ], "问题解释": "授课中使用了举例来阐述知识点,便于学生理解。"},{ "问题编号": 5001, "结果": [ "数列", "圆锥曲线", "学习", "例子", "身高", "数据", "表示", "函数", "同向公式" ], "问题解释": "分析了授课中的高频词,提取了出现频率最高的10个词汇。"},{ "问题编号": 5002, "结果": [ { "Start": 0, "End": 120, "Content": "课程开始,教师介绍了圆锥曲线的学习情况,并提到了数列的学习。" }, { "Start": 120, "End": 240, "Content": "教师详细讲解了数列的概念,并通过王芳同学的身高数据作为例子。" }, { "Start": 240, "End": 360, "Content": "教师解释了数列的分类,包括递增数列、递减数列和常数列,并给出了相应的定义。" }, { "Start": 360, "End": 480, "Content": "教师讨论了数列的表示方法,包括列表法、图像法和通项公式,并提供了相应的例子。" } ], "问题解释": "基于课堂情况提取了课堂上的事件,并分析了每个事件的时间片段和内容概览。"},{ "问题编号": 5003, "结果": { "重复回答": 3, "老师追问": 5, "简单性表扬": 2, "老师补充答案": 4, "表扬并补充答案": 1 }, "问题解释": "统计了授课中教师回答类型的次数,包括重复回答、老师追问、简单性表扬、老师补充答案和表扬并补充答案。"},{ "问题编号": 5004, "结果": [ { "Start": 150, "End": 180, "Content": "独立学习" }, { "Start": 300, "End": 330, "Content": "小组合作" }, { "Start": 450, "End": 480, "Content": "随堂练习" } ], "问题解释": "分析了授课中教师提到独立学习、小组合作和随堂练习的时间段,并提取了相应的字幕开始秒和结束秒。"}]""";
-
- chatResContent = chatResContent?.Replace("字幕内容", "课堂情况");
- chatResContent = chatResContent?.Replace("\n", "");
- chatResContent = chatResContent?.Replace("}{", "},{");
- chatResContent = chatResContent?.Replace("}|{", "},{");
- chatResContent = chatResContent?.Trim();
- if (!chatResContent.StartsWith("["))
- chatResContent = "[" + chatResContent;
- if (!chatResContent.EndsWith("]"))
- chatResContent = chatResContent + "]";
- var questionRes = JsonSerializer.Deserialize(chatResContent);
- var gptRes = new TaskRes(captions);
- if (questionRes is null)
- throw new Exception("KIMIGPT返回无效结果");
- var qEnum = (int)QuestionTypeEnum.高频词;
- //处理 ai问答提问
- var arr1 = questionRes.Where(s => s.问题编号 < qEnum);
- var arr2 = questionRes.Where(s => s.问题编号 >= qEnum)
- .ToDictionary(s => s.问题编号);
- //AI综合评估
- var criteriaDic = criteriaArr.ToDictionary(s => s.Id);
-
- var random = new Random();
- var ccArr = new List(arr1.Count());
- foreach (var s in arr1) //处理问题
- {
- var Id = criteriaDic[s.问题编号].Id;
- var PassScore = criteriaDic[s.问题编号].PassScore;
- var TotalScore = criteriaDic[s.问题编号].TotalScore;
- var Score = Math.Round(criteriaDic[s.问题编号].TotalScore * 0.01m
- * ((int)(s.ToObject