优化 数据存储同步到数据库

This commit is contained in:
小肥羊 2025-02-27 18:28:12 +08:00
parent c12c8ebfcd
commit 1b239201a2
11 changed files with 184 additions and 26 deletions

View File

@ -19,14 +19,16 @@ namespace Learn.VideoAnalysis.Controllers
private readonly ILogger<ApiController> _logger; private readonly ILogger<ApiController> _logger;
private readonly IMapper mp; private readonly IMapper mp;
private readonly Repository<VideoTask> videoTaskDB; private readonly Repository<VideoTask> videoTaskDB;
private readonly Repository<VideoKonwPoint> videoKonwDB;
private readonly IBserGPT chatGPT; private readonly IBserGPT chatGPT;
public ApiController(ILogger<ApiController> logger, Repository<VideoTask> videoTaskDB, public ApiController(ILogger<ApiController> logger, Repository<VideoTask> videoTaskDB,
IMapper mp, IBserGPT chatGPT) IMapper mp, IBserGPT chatGPT, Repository<VideoKonwPoint> videoKonwDB)
{ {
_logger = logger; _logger = logger;
this.videoTaskDB = videoTaskDB; this.videoTaskDB = videoTaskDB;
this.mp = mp; this.mp = mp;
this.chatGPT = chatGPT; this.chatGPT = chatGPT;
this.videoKonwDB = videoKonwDB;
} }
private string GetClientIpAddress() private string GetClientIpAddress()
@ -151,6 +153,53 @@ namespace Learn.VideoAnalysis.Controllers
, task.Id); , task.Id);
return Ok(); return Ok();
} }
/// <summary>
/// 获取视频知识点片段<para>taskId/tagId二选一</para>
/// </summary>
/// <param name="taskId"></param>
/// <param name="tagId">自定义id</param>
/// <returns></returns>
[HttpGet(Name = "TaskKnowInfo")]
public async Task<IActionResult> TaskKnowInfo(long taskId, string? tagId)
{
if (taskId == 0 && string.IsNullOrEmpty(tagId))
return BadRequest();
var task = await videoTaskDB.AsQueryable()
.WhereIF(taskId != 0, s => s.Id == taskId)
.WhereIF(!string.IsNullOrEmpty(tagId), s => s.TagId == tagId)
.FirstAsync();
if(task is null)
return BadRequest("无效任务");
var konwArr = await videoKonwDB.AsQueryable()
.Where(s=>s.VideoTaskId == task.Id)
.ToArrayAsync();
if (konwArr is null || konwArr.Length ==0)
return BadRequest("无效任务");
return Ok(new TaskKnowRes()
{
TagId = task.TagId,
Status = task.LastEnum,
VideoTaskId = task.Id,
KnowBlockArr = konwArr
.GroupBy(s=>s.StartTime)
.Select(s=>new TaskKnowBlock()
{
Id = s.First().Id,
Content = s.First().Content,
StartTime = s.First().StartTime,
EndTime = s.First().EndTime,
Theme =s.First().Theme,
Know=s.Select(x=>new TaskKnowInfo()
{
Id=x.Id,
KnowPoint=x.KnowPoint,
KnowPointId = x.KnowPointId
}).ToArray()
}).ToArray()
});
}
/// <summary> /// <summary>
/// »ñÈ¡ÊÓÆµÐÅÏ¢<para>taskId/tagId¶þѡһ</para> /// »ñÈ¡ÊÓÆµÐÅÏ¢<para>taskId/tagId¶þѡһ</para>
/// </summary> /// </summary>

View File

@ -1,4 +1,5 @@
using AntDesign; using AntDesign;
using SqlSugar;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using UserCenter.Model.Enum; using UserCenter.Model.Enum;
using VideoAnalysisCore.AICore.GPT.Dto; using VideoAnalysisCore.AICore.GPT.Dto;
@ -71,6 +72,76 @@ namespace Learn.VideoAnalysis.Controllers.Dto
public string Text { get; set; } public string Text { get; set; }
public object Value { get; set; } public object Value { get; set; }
} }
public class TaskKnowInfo
{
/// <summary>
///视频片段知识点 id
/// </summary>
public long Id { get; set; }
/// <summary>
/// 知识点
/// </summary>
public string KnowPoint { get; set; }
/// <summary>
/// 知识点ID
/// </summary>
public string KnowPointId { get; set; }
}
public class TaskKnowBlock
{
public long Id { get; set; }
/// <summary>
/// 开始时间
/// </summary>
public float? StartTime { get; set; }
/// <summary>
/// 结束时间
/// </summary>
public float? EndTime { get; set; }
/// <summary>
/// 持续时间
/// </summary>
[SugarColumn(IsIgnore = true)]
public float? KeepTime => (EndTime ?? 0) - StartTime ?? 0;
/// <summary>
/// 主题
/// </summary>
public string? Theme { get; set; }
/// <summary>
/// 内容总结
/// </summary>
public string? Content { get; set; }
/// <summary>
/// 知识点列表
/// </summary>
public TaskKnowInfo[] Know { get; set; }
}
/// <summary>
/// 视频片段知识点结果
/// </summary>
public class TaskKnowRes
{
/// <summary>
/// 自定义Id [任务视频自定义id]
/// <see cref="VideoTask.TagId"/>
/// </summary>
public string? TagId { get; set; }
/// <summary>
/// 任务当前执行状态
/// </summary>
public RedisChannelEnum Status { get; set; }
/// <summary>
/// 视频任务id
/// </summary>
public long VideoTaskId { get; set; }
/// <summary>
/// 视频知识快
/// </summary>
public TaskKnowBlock[] KnowBlockArr { get; set; }
}
public class TaskInfoRes: TaskRes public class TaskInfoRes: TaskRes
{ {
public TaskInfoRes() public TaskInfoRes()
@ -81,19 +152,19 @@ namespace Learn.VideoAnalysis.Controllers.Dto
/// 任务当前执行状态 /// 任务当前执行状态
/// </summary> /// </summary>
public RedisChannelEnum Status { get; set; } public RedisChannelEnum Status { get; set; }
/// <summary> ///// <summary>
/// 时间轴状态枚举 ///// 时间轴状态枚举
/// </summary> ///// </summary>
public Dictionary<int, string> TimeTypeEnum => //public Dictionary<int, string> TimeTypeEnum =>
Enum.GetValues(typeof(TimeBaseTypeEnum)) // Enum.GetValues(typeof(TimeBaseTypeEnum))
.Cast<TimeBaseTypeEnum>() // .Cast<TimeBaseTypeEnum>()
.ToDictionary(x => (int)x, x => x.ToString()); // .ToDictionary(x => (int)x, x => x.ToString());
/// <summary> ///// <summary>
/// 时间轴合计 ///// 时间轴合计
/// </summary> ///// </summary>
public Dictionary<TimeBaseTypeEnum, TextValue>? TimeBaseTotal => //public Dictionary<TimeBaseTypeEnum, TextValue>? TimeBaseTotal =>
TimeBase?.GroupBy(s => s.TimeBaseType??TimeBaseTypeEnum.)? // TimeBase?.GroupBy(s => s.TimeBaseType??TimeBaseTypeEnum.教师讲授)?
.ToDictionary(s => s.Key, s => new TextValue(s.Sum(x => x.End - x.Start))); // .ToDictionary(s => s.Key, s => new TextValue(s.Sum(x => x.End - x.Start)));
} }
} }

View File

@ -6,6 +6,8 @@ using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType; using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Xml.Linq; using System.Xml.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SqlSugar.IOC;
using VideoAnalysisCore.Model;
namespace VideoAnalysisCore.AICore.FFMPGE namespace VideoAnalysisCore.AICore.FFMPGE
{ {
@ -30,7 +32,10 @@ namespace VideoAnalysisCore.AICore.FFMPGE
public static async Task Audio2WAV16KAsync(string task) public static async Task Audio2WAV16KAsync(string task)
{ {
Task = task; Task = task;
var filePath = RedisExpand.Redis.HGet(RedisExpandKey.Task(task), "LocalMediaPath"); var filePath = await DbScoped.SugarScope
.Queryable<VideoTask>()
.Where(s => s.Id == long.Parse(task))
.Select(s=>s.LocalMediaPath).FirstAsync();
if (string.IsNullOrEmpty(filePath)) if (string.IsNullOrEmpty(filePath))
throw new Exception($"任务id[{task}] 无效"); throw new Exception($"任务id[{task}] 无效");

View File

@ -9,6 +9,7 @@ using VideoAnalysisCore.Model.Dto;
using VideoAnalysisCore.AICore.GPT.Dto; using VideoAnalysisCore.AICore.GPT.Dto;
using VideoAnalysisCore.AICore.GPT; using VideoAnalysisCore.AICore.GPT;
using System.Threading.Tasks; using System.Threading.Tasks;
using VideoAnalysisCore.AICore.SherpaOnnx;
namespace VideoAnalysisCore.AICore.GPT.ChatGPT namespace VideoAnalysisCore.AICore.GPT.ChatGPT
{ {
@ -89,7 +90,10 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
$"输出格式 json字符串 对象格式{fileNameResFormat}"; $"输出格式 json字符串 对象格式{fileNameResFormat}";
var fileNameInfoRes = await ChatAsync<FileNameInfo>(task, fileNamePostMessages, null, fileNameResFormat); var fileNameInfoRes = await ChatAsync<FileNameInfo>(task, fileNamePostMessages, null, fileNameResFormat);
var captions = ExpandFunction.GetSpeakerCaptions(task); var speakerArr = JsonSerializer.Deserialize<OfflineSpeakerRes[]>(taskInfo.Speaker);
var captionsArr = JsonSerializer.Deserialize<SenseVoiceRes[]>(taskInfo.Captions);
var captions = ExpandFunction.GetSpeakerCaptions(captionsArr, speakerArr);
var maxVideoTime = captions?.TimeBase?.LastOrDefault()?.End ?? 0; var maxVideoTime = captions?.TimeBase?.LastOrDefault()?.End ?? 0;
var criteriaBuilder = new StringBuilder(); var criteriaBuilder = new StringBuilder();
@ -245,7 +249,10 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
var taskInfo = await videoTaskDB.AsQueryable() var taskInfo = await videoTaskDB.AsQueryable()
.Where(s => s.Id == taskId) .Where(s => s.Id == taskId)
.FirstAsync(); .FirstAsync();
var captions = ExpandFunction.GetSpeakerCaptions(task);
var speakerArr = JsonSerializer.Deserialize<OfflineSpeakerRes[]>(taskInfo.Speaker);
var captionsArr = JsonSerializer.Deserialize<SenseVoiceRes[]>(taskInfo.Captions);
var captions = ExpandFunction.GetSpeakerCaptions(captionsArr, speakerArr);
var criteriaArr = await criteriaDB.GetListAsync(s => s.Subject == taskInfo.Subject); var criteriaArr = await criteriaDB.GetListAsync(s => s.Subject == taskInfo.Subject);
var criteriaBuilder = new StringBuilder(); var criteriaBuilder = new StringBuilder();
foreach (var item in criteriaArr) foreach (var item in criteriaArr)

View File

@ -9,6 +9,7 @@ using VideoAnalysisCore.Model.Dto;
using VideoAnalysisCore.AICore.GPT.Dto; using VideoAnalysisCore.AICore.GPT.Dto;
using System.Threading.Tasks; using System.Threading.Tasks;
using VideoAnalysisCore.AICore.GPT.ChatGPT; using VideoAnalysisCore.AICore.GPT.ChatGPT;
using VideoAnalysisCore.AICore.SherpaOnnx;
namespace VideoAnalysisCore.AICore.GPT.DeepSeek namespace VideoAnalysisCore.AICore.GPT.DeepSeek
{ {
@ -62,7 +63,9 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
$"输出格式 json字符串 对象格式{fileNameResFormat}"; $"输出格式 json字符串 对象格式{fileNameResFormat}";
var fileNameInfoRes = await ChatAsync<FileNameInfo>(task, fileNamePostMessages, null);//, "deepseek-chat"); var fileNameInfoRes = await ChatAsync<FileNameInfo>(task, fileNamePostMessages, null);//, "deepseek-chat");
var captions = ExpandFunction.GetSpeakerCaptions(task); var speakerArr = JsonSerializer.Deserialize<OfflineSpeakerRes[]>(taskInfo.Speaker);
var captionsArr = JsonSerializer.Deserialize<SenseVoiceRes[]>(taskInfo.Captions);
var captions = ExpandFunction.GetSpeakerCaptions(captionsArr, speakerArr);
var maxVideoTime = captions?.TimeBase?.LastOrDefault()?.End ?? 0; var maxVideoTime = captions?.TimeBase?.LastOrDefault()?.End ?? 0;
var criteriaBuilder = new StringBuilder(); var criteriaBuilder = new StringBuilder();
@ -123,7 +126,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
{ {
Console.WriteLine(DateTime.Now + $"=>{task} 得分过低 " + checkRes?.Score ); Console.WriteLine(DateTime.Now + $"=>{task} 得分过低 " + checkRes?.Score );
Console.WriteLine( checkRes.Evaluation); Console.WriteLine( checkRes.Evaluation);
Console.WriteLine( ); Console.WriteLine();
} }
} }

View File

@ -53,7 +53,9 @@ namespace VideoAnalysisCore.AICore.GPT.KIMI
var taskInfo = await videoTaskDB.AsQueryable() var taskInfo = await videoTaskDB.AsQueryable()
.Where(s => s.Id == taskId) .Where(s => s.Id == taskId)
.FirstAsync(); .FirstAsync();
var captions = ExpandFunction.GetSpeakerCaptions(task); var speakerArr = JsonSerializer.Deserialize<OfflineSpeakerRes[]>(taskInfo.Speaker);
var captionsArr = JsonSerializer.Deserialize<SenseVoiceRes[]>(taskInfo.Captions);
var captions = ExpandFunction.GetSpeakerCaptions(captionsArr, speakerArr);
var criteriaArr = await criteriaDB.GetListAsync(s => s.Subject == taskInfo.Subject); var criteriaArr = await criteriaDB.GetListAsync(s => s.Subject == taskInfo.Subject);
var criteriaBuilder = new StringBuilder(); var criteriaBuilder = new StringBuilder();
foreach (var item in criteriaArr) foreach (var item in criteriaArr)

View File

@ -1,14 +1,17 @@
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using SherpaOnnx; using SherpaOnnx;
using SqlSugar.IOC;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using VideoAnalysisCore.Common; using VideoAnalysisCore.Common;
using VideoAnalysisCore.Model;
using static System.Runtime.InteropServices.JavaScript.JSType; using static System.Runtime.InteropServices.JavaScript.JSType;
namespace VideoAnalysisCore.AICore.SherpaOnnx namespace VideoAnalysisCore.AICore.SherpaOnnx
@ -256,6 +259,12 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx
} }
Console.WriteLine(DateTime.Now + "=> SenseVoice 字幕数量"+ res.Count); Console.WriteLine(DateTime.Now + "=> SenseVoice 字幕数量"+ res.Count);
var captionsStr = JsonSerializer.Serialize(res);
DbScoped.SugarScope
.Updateable<VideoTask>()
.SetColumns(it => it.Captions == captionsStr)
.Where(it => it.Id == long.Parse(task));
await RedisExpand.Redis.HMSetAsync(RedisExpandKey.Task(task), "Captions", res); await RedisExpand.Redis.HMSetAsync(RedisExpandKey.Task(task), "Captions", res);
//RedisExpand.InsertChannel(Enum.RedisChannelEnum.ParsingSpeaker, task); //RedisExpand.InsertChannel(Enum.RedisChannelEnum.ParsingSpeaker, task);
RedisExpand.InsertChannel(Enum.RedisChannelEnum.ChatModelAnalysis, task); RedisExpand.InsertChannel(Enum.RedisChannelEnum.ChatModelAnalysis, task);

View File

@ -4,6 +4,9 @@ using System.Linq;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using VideoAnalysisCore.Common; using VideoAnalysisCore.Common;
using SherpaOnnx; using SherpaOnnx;
using SqlSugar.IOC;
using VideoAnalysisCore.Model;
using System.Text.Json;
namespace VideoAnalysisCore.AICore.SherpaOnnx namespace VideoAnalysisCore.AICore.SherpaOnnx
{ {
@ -72,6 +75,11 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx
}, nint.Zero); }, nint.Zero);
var res = segments.Select(s => new OfflineSpeakerRes(s)); var res = segments.Select(s => new OfflineSpeakerRes(s));
await RedisExpand.Redis.HSetAsync(RedisExpandKey.Task(task), "Speaker", res); await RedisExpand.Redis.HSetAsync(RedisExpandKey.Task(task), "Speaker", res);
var speakerStr = JsonSerializer.Serialize(res);
DbScoped.SugarScope
.Updateable<VideoTask>()
.SetColumns(it => it.Speaker == speakerStr)
.Where(it => it.Id == long.Parse(task));
//加入下一队列 //加入下一队列
RedisExpand.InsertChannel(Enum.RedisChannelEnum.ChatModelAnalysis, task); RedisExpand.InsertChannel(Enum.RedisChannelEnum.ChatModelAnalysis, task);

View File

@ -178,10 +178,8 @@ namespace VideoAnalysisCore.Common
/// <summary> /// <summary>
/// 获取Task处理后的 说话人字幕 /// 获取Task处理后的 说话人字幕
/// </summary> /// </summary>
public static TotalCaptionsDto GetSpeakerCaptions(string task) public static TotalCaptionsDto GetSpeakerCaptions(SenseVoiceRes[] captionsArr, OfflineSpeakerRes[] speakerArr)
{ {
var captionsArr = RedisExpand.Redis.HMGet<SenseVoiceRes[]>(RedisExpandKey.Task(task), "Captions").FirstOrDefault();
var speakerArr = RedisExpand.Redis.HMGet<OfflineSpeakerRes[]>(RedisExpandKey.Task(task), "Speaker").FirstOrDefault();
if (captionsArr is null || captionsArr.Length == 0) if (captionsArr is null || captionsArr.Length == 0)
//|| speakerArr is null || speakerArr.Length == 0) //|| speakerArr is null || speakerArr.Length == 0)
throw new Exception("音频解析数据异常"); throw new Exception("音频解析数据异常");
@ -193,9 +191,9 @@ namespace VideoAnalysisCore.Common
var teacherSpeaking = 0f; var teacherSpeaking = 0f;
var studentSpeaking = 0f; var studentSpeaking = 0f;
var results = new Dictionary<SenseVoiceRes, List<int>>(); var results = new Dictionary<SenseVoiceRes, List<int>>();
var ss = new List<int> { 1 };
if (speakerArr is null || speakerArr.Count() == 0) if (speakerArr is null || speakerArr.Count() == 0)
{ {
var ss = new List<int> { 1 };
results = captionsArr.ToDictionary(s => s, s=> ss); results = captionsArr.ToDictionary(s => s, s=> ss);
} }
else else

View File

@ -1,11 +1,13 @@
using AntDesign; using AntDesign;
using Downloader; using Downloader;
using SqlSugar.IOC;
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using VideoAnalysisCore.Model;
namespace VideoAnalysisCore.Common namespace VideoAnalysisCore.Common
{ {
@ -122,7 +124,11 @@ namespace VideoAnalysisCore.Common
var outputPath = Path.Combine(localPath, task + fileExtension); var outputPath = Path.Combine(localPath, task + fileExtension);
if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath); if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath);
RedisExpand.Redis.HSet(RedisExpandKey.Task(task), "LocalMediaPath", outputPath); DbScoped.SugarScope
.Updateable<VideoTask>()
.SetColumns(it => it.LocalMediaPath == outputPath)
.Where(it => it.Id == long.Parse(task));
IDownload download = DownloadBuilder.New() IDownload download = DownloadBuilder.New()
.WithUrl(fileUrl) .WithUrl(fileUrl)
.WithDirectory(localPath) .WithDirectory(localPath)

View File

@ -12,7 +12,7 @@ using Whisper.net;
namespace VideoAnalysisCore.Model namespace VideoAnalysisCore.Model
{ {
/// <summary> /// <summary>
/// 视频任务知识片段 /// 视频片段知识点
/// </summary> /// </summary>
[SugarTable("videokonwpoint")] [SugarTable("videokonwpoint")]
public class VideoKonwPoint : IDB public class VideoKonwPoint : IDB