From ac7ec56997d29f859719194f1e7c28efe5452fdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E8=82=A5=E7=BE=8A?= <1048382248@qq.com> Date: Fri, 18 Apr 2025 18:07:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E8=BF=9B=E5=BA=A6=E6=98=BE=E7=A4=BA=E6=96=87=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Pages/VideoTaskPage.razor | 2 +- .../AICore/FFMPGE/FFMPGEHandle.cs | 22 +++++++++++++++---- .../AICore/GPT/DeepSeek/DeepSeekClient.cs | 10 ++++----- .../AICore/GPT/DeepSeek/DeepSeekModel.cs | 4 ++++ .../AICore/GPT/DeepSeek/DeepSeek_GPT.cs | 9 ++++---- .../AICore/SherpaOnnx/SenseVoice.cs | 2 +- 6 files changed, 33 insertions(+), 16 deletions(-) diff --git a/VideoAnalysis/Components/Pages/VideoTaskPage.razor b/VideoAnalysis/Components/Pages/VideoTaskPage.razor index da3b871..a869289 100644 --- a/VideoAnalysis/Components/Pages/VideoTaskPage.razor +++ b/VideoAnalysis/Components/Pages/VideoTaskPage.razor @@ -33,7 +33,7 @@ - @rowData.Data.Progress% + @rowData.Data.Progress diff --git a/VideoAnalysisCore/AICore/FFMPGE/FFMPGEHandle.cs b/VideoAnalysisCore/AICore/FFMPGE/FFMPGEHandle.cs index e673c20..0e3f4dc 100644 --- a/VideoAnalysisCore/AICore/FFMPGE/FFMPGEHandle.cs +++ b/VideoAnalysisCore/AICore/FFMPGE/FFMPGEHandle.cs @@ -13,6 +13,8 @@ using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using System.Text.Json; +using System; +using Microsoft.VisualBasic.FileIO; namespace VideoAnalysisCore.AICore.FFMPGE { @@ -51,16 +53,21 @@ namespace VideoAnalysisCore.AICore.FFMPGE throw new Exception("存在PPTCOde但未能找到对应资源文件"); var ffmpeg = new Engine(FFmpegPath); var cToken = new CancellationToken(); + RedisExpand.SetTaskProgress(task, "Frame=>10%"); + + foreach (string jpgFile in Directory.GetFiles(localPath, "*.jpg")) + FileSystem.DeleteFile(jpgFile, UIOption.OnlyErrorDialogs, RecycleOption.DeletePermanently); + RedisExpand.SetTaskProgress(task, "Frame=>20%"); + await ffmpeg.ExecuteAsync($"-i {filePath} -vf \"fps=1/{intervalSec},scale=320:180\" {localPath}/frame_%03d.jpg", cToken); //视频关键帧分析 var frameFiles = Directory.GetFiles(localPath, "*.jpg") .OrderBy(f => f) .ToList(); - + + RedisExpand.SetTaskProgress(task, "Frame=>50%"); Image prevFrame = null; - string outputDir = "output"; - Directory.CreateDirectory(outputDir); var keyFrames = new List(); foreach (var frameFile in frameFiles) { @@ -82,9 +89,16 @@ namespace VideoAnalysisCore.AICore.FFMPGE prevFrame?.Dispose(); prevFrame = currFrame.Clone(); } + } + // 遍历数组 + for (int i = 1; i < keyFrames.Count(); i++) + { + keyFrames[i] += 10;//ppt与课堂视频时间修正 + if (keyFrames[i] - keyFrames[i - 1] < 10) + keyFrames[i] = -1; } //写入数据库 - var keyFramStr = JsonSerializer.Serialize(keyFrames); + var keyFramStr = JsonSerializer.Serialize(keyFrames.Where(s=>s!=-1)); await DbScoped.Sugar .Updateable() .SetColumns(it => it.PPTKeyFrame == keyFramStr) diff --git a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekClient.cs b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekClient.cs index 8bc087e..4b9e6e7 100644 --- a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekClient.cs +++ b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekClient.cs @@ -12,6 +12,7 @@ using System.Threading; using System; using System.IO; using VideoAnalysisCore.AICore.GPT.ChatGPT; +using System.Threading.Tasks; namespace VideoAnalysisCore.AICore.GPT.DeepSeek { @@ -153,7 +154,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek var lastChat = new ChatResSSE(); var splitCount = "data:".Length; var maxLoop = 60*1000; - int threshold = 50; + int threshold = 0; while (maxLoop>0) { line = reader.ReadLine(); @@ -191,11 +192,8 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek if (!string.IsNullOrEmpty(strReasoning)) messageBuilder1.Append(strReasoning); var steamCount = messageBuilder.Length + messageBuilder1.Length; - if (steamCount> threshold) - { - threshold += threshold; - Console.WriteLine(DateTime.Now + "=>接收到流 " + steamCount); - } + if (++threshold%30==0) + RedisExpand.SetTaskProgress(chatReq.taskId, "steam=>"+ steamCount); } catch (Exception e) { diff --git a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekModel.cs b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekModel.cs index 20aaaef..6ae5c77 100644 --- a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekModel.cs +++ b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeekModel.cs @@ -53,6 +53,10 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek /// 该模型还可用于生成音频。自 请求此模型同时生成文本和音频响应,您可以 用:gpt-4o-audio-preview["text", "audio"] /// public string modalities { get; set; } = "[\"json\"]"; + /// + /// 任务id + /// + public string taskId { get; set; } public object stream_options { get; set; } = new { include_usage = true }; } diff --git a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs index 7986995..29fbb83 100644 --- a/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs +++ b/VideoAnalysisCore/AICore/GPT/DeepSeek/DeepSeek_GPT.cs @@ -519,13 +519,13 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek .Select(s => s.Start + ":" + s.Text)); var keyFrameArr = string.IsNullOrEmpty(taskInfo?.PPTVideoCode) ?string.Empty - : $"通过分析视频图像得到了视频授课内容发生了变化的时间节点{taskInfo.PPTKeyFrame},授课阶段应当在附近时间发生变化。" ; + : $"视频授课内容发生了变化的时间节点{taskInfo.PPTKeyFrame},授课阶段应当在附近时间发生变化。" ; var resFormat = """[{"StartTime":开始秒(number),"EndTime":结束秒(number),"Stage":阶段(string),"Theme":主题(string),"Content":内容总结(string)}]"""; var postMessages = $"请通过视频字幕内容分析出视频中{subject}课堂的授课阶段。" + - $"课堂内容与{fileNameInfoRes.授课章节}章节相关" + + $"课堂内容与{fileNameInfoRes.授课章节}章节相关。" + $"{keyFrameArr}" + - $"完整的课堂标准流程包含以下5个阶段:课程引入/新知讲解/例题精讲/课堂练习/课程总结。" + + $"完整的课堂标准流程包含以下5个阶段:课程引入/新知讲解/例题精讲/课堂练习/知识总结。" + $"通过授课阶段的主要讲解内容分析出对应的授课阶段内容总结。" + $"通过生成的内容总结分析出对应的授课阶段主题。 " + $"请注意 本次分析的视频字幕只是其中一部分 不需要分析出所有类型的授课阶段。" + @@ -647,7 +647,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek public async Task ChatAsync(string task, string postMessages, string postMessages1, string model = "deepseek-reasoner") { - var maxTokens = 4000; + var maxTokens = 6000; Message[] messageArr = [ new Message(postMessages,"user"), string.IsNullOrEmpty(postMessages1)?null:new Message(postMessages1,"user"), @@ -655,6 +655,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek messageArr = messageArr.Where(s => s != null).ToArray(); var chatRep = new ChatRequest { + taskId = task, model = model, stream = model == "deepseek-reasoner", max_tokens = maxTokens, diff --git a/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs b/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs index 6d8f3c9..80e4489 100644 --- a/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs +++ b/VideoAnalysisCore/AICore/SherpaOnnx/SenseVoice.cs @@ -220,7 +220,7 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx End = (float)Math.Round(startTime + duration, 2, MidpointRounding.AwayFromZero), }); if (!string.IsNullOrEmpty(task)) - RedisExpand.SetTaskProgress(task, (double)(startTime + duration) / (totalSecond) * 100); + RedisExpand.SetTaskProgress(task, Math.Round((double)(startTime + duration) / (totalSecond) * 100,2)+"%"); } VAD.Pop(); }