修复 测试完善后的新流程

This commit is contained in:
小肥羊 2025-09-14 15:17:06 +08:00
parent 776c2b9b52
commit a0e00c8b5d
9 changed files with 95 additions and 56 deletions

View File

@ -41,16 +41,18 @@ namespace VideoAnalysisCore.AICore.FFMPGE
var intervalSec = 5; var intervalSec = 5;
var threshold = 8.15; var threshold = 8.15;
var ssimThreshold = 0.9; var ssimThreshold = 0.9;
var PPTVideoCode = await DbScoped.Sugar var taskInfo = await DbScoped.Sugar
.Queryable<VideoTask>() .Queryable<VideoTask>()
.Where(s => s.Id == long.Parse(task)) .Where(s => s.Id == long.Parse(task)).FirstAsync();
.Select(s => s.PPTVideoCode).FirstAsync(); if (string.IsNullOrEmpty(taskInfo.PPTVideoCode) || string.IsNullOrEmpty(taskInfo.PPTVideoUrl)) return;
if (string.IsNullOrEmpty(PPTVideoCode)) return;
//视频切帧 //视频切帧
var localPath = task.LocalPath(); var localPath = task.LocalPath();
var filePath = Path.Combine(localPath, "ppt.mp4"); var filePath = Path.Combine(localPath, "ppt.mp4");
if (!File.Exists(filePath)) if (!File.Exists(filePath))
throw new Exception("存在PPTCOde但未能找到对应资源文件"); {
Console.WriteLine("存在PPT Code但未能找到对应资源文件");
return;
}
var ffmpeg = new Engine(FFmpegPath); var ffmpeg = new Engine(FFmpegPath);
var cToken = new CancellationToken(); var cToken = new CancellationToken();
RedisExpand.SetTaskProgress(task, "Frame=>10%"); RedisExpand.SetTaskProgress(task, "Frame=>10%");
@ -65,7 +67,7 @@ namespace VideoAnalysisCore.AICore.FFMPGE
var frameFiles = Directory.GetFiles(localPath, "*.jpg") var frameFiles = Directory.GetFiles(localPath, "*.jpg")
.OrderBy(f => f) .OrderBy(f => f)
.ToList(); .ToList();
RedisExpand.SetTaskProgress(task, "Frame=>50%"); RedisExpand.SetTaskProgress(task, "Frame=>80%");
Image<Rgb24> prevFrame = null; Image<Rgb24> prevFrame = null;
var keyFrames = new List<int>(10) { 5}; var keyFrames = new List<int>(10) { 5};
foreach (var frameFile in frameFiles) foreach (var frameFile in frameFiles)

View File

@ -257,7 +257,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
{ {
try try
{ {
var keyFrameArr = string.IsNullOrEmpty(taskInfo?.PPTVideoCode) var keyFrameArr = string.IsNullOrEmpty(taskInfo?.PPTVideoCode) || string.IsNullOrEmpty(taskInfo?.PPTKeyFrame)
? string.Empty ? string.Empty
: $"授课PPT发生了变化的时间是{taskInfo.PPTKeyFrame},所以在这些时间段附近应该发生了授课内容得变化,授课阶段结果尽量参考这些时间节点(PPT与字幕有一定的延时)。"; : $"授课PPT发生了变化的时间是{taskInfo.PPTKeyFrame},所以在这些时间段附近应该发生了授课内容得变化,授课阶段结果尽量参考这些时间节点(PPT与字幕有一定的延时)。";
var resFormat = """[{"StartTime":开始秒(number),"EndTime":结束秒(number),"Stage":阶段(string),"Theme":主题(string),"Content":内容总结(string)}]"""; var resFormat = """[{"StartTime":开始秒(number),"EndTime":结束秒(number),"Stage":阶段(string),"Theme":主题(string),"Content":内容总结(string)}]""";

View File

@ -121,7 +121,7 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx
/// <returns></returns> /// <returns></returns>
public static async Task RunTask(string task) public static async Task RunTask(string task)
{ {
var filePath = Path.Combine(task.LocalPath(), task + ".wav"); var filePath = Path.Combine(task.LocalPath(), "task.wav");
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
throw new Exception("task 音频路径未找到"); throw new Exception("task 音频路径未找到");
await TaskHandle(new WaveReader(filePath), task); await TaskHandle(new WaveReader(filePath), task);

View File

@ -55,7 +55,7 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx
/// <param name="task"></param> /// <param name="task"></param>
public static async Task Run(string task) public static async Task Run(string task)
{ {
var filePath = Path.Combine(task.LocalPath(), task + ".wav"); var filePath = Path.Combine(task.LocalPath(), "task.wav");
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
throw new Exception("task 音频路径未找到"); throw new Exception("task 音频路径未找到");

View File

@ -92,6 +92,31 @@ namespace VideoAnalysisCore.Common
/// </summary> /// </summary>
public static string FrameName = "frame_"; public static string FrameName = "frame_";
/// <summary>
/// 删除 AI分析任务的缓存文件
/// </summary>
/// <param name="taskId"></param>
/// <returns></returns>
public static bool DeleteTaskFile(long? taskId)
{
if(taskId is null || taskId == 0) return false;
var path = taskId.ToString().LocalPath();
if (!string.IsNullOrEmpty(path) && Directory.Exists(path))
{
try
{
Directory.Delete(path, true);
Console.WriteLine($"已删除缓存文件: {taskId}");
}
catch (Exception ex)
{
Console.WriteLine($"删除缓存文件 {taskId} 时出错: {ex.Message}");
}
}
else return false;
return true;
}
/// <summary> /// <summary>
/// 对象转化为JSON字符串 /// 对象转化为JSON字符串
/// </summary> /// </summary>

View File

@ -13,6 +13,7 @@ using VideoAnalysisCore.Model;
using VideoAnalysisCore.Model.Enum; using VideoAnalysisCore.Model.Enum;
using AlibabaCloud.SDK.Vod20170321; using AlibabaCloud.SDK.Vod20170321;
using UserCenter.Model.Enum; using UserCenter.Model.Enum;
using System.Security.Policy;
namespace VideoAnalysisCore.Common namespace VideoAnalysisCore.Common
{ {
@ -90,12 +91,16 @@ namespace VideoAnalysisCore.Common
public static DownloadConfiguration Opt { get; set; } = default!; public static DownloadConfiguration Opt { get; set; } = default!;
public static int DownloadSpeed { get; set; } = default!; public static int DownloadSpeed { get; set; } = default!;
private readonly Repository<VideoTask> videoTaskDB; private readonly Repository<VideoTask> videoTaskDB;
private readonly Repository<NodePackageInfo> packageInfoTaskDB;
private readonly Client vodClient; private readonly Client vodClient;
readonly string taskVideoName = "task.mp4";
readonly string taskPPTVideoName = "ppt.mp4";
public DownloadFile(Repository<VideoTask> videoTaskDB, Client vodClient) public DownloadFile(Repository<VideoTask> videoTaskDB, Client vodClient, Repository<NodePackageInfo> nackageInfoTaskDB)
{ {
this.videoTaskDB = videoTaskDB; this.videoTaskDB = videoTaskDB;
this.vodClient = vodClient; this.vodClient = vodClient;
this.packageInfoTaskDB = nackageInfoTaskDB;
} }
// 根据 Content-Type 映射文件后缀 // 根据 Content-Type 映射文件后缀
@ -157,7 +162,7 @@ namespace VideoAnalysisCore.Common
if (!Directory.Exists(AppCommon.TaskCachedFile)) Directory.CreateDirectory(AppCommon.TaskCachedFile); if (!Directory.Exists(AppCommon.TaskCachedFile)) Directory.CreateDirectory(AppCommon.TaskCachedFile);
var localPath = task.LocalPath(); var localPath = task.LocalPath();
var outputPath = Path.Combine(localPath, task + fileExtension); var outputPath = Path.Combine(localPath, taskVideoName);
if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath); if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath);
await videoTaskDB await videoTaskDB
@ -166,38 +171,52 @@ namespace VideoAnalysisCore.Common
.Where(it => it.Id == long.Parse(task)) .Where(it => it.Id == long.Parse(task))
.ExecuteCommandAsync(); .ExecuteCommandAsync();
//下载PPT视频 //下载PPT视频
if (!string.IsNullOrEmpty(taskInfo.PPTVideoCode)) if (string.IsNullOrEmpty(taskInfo.PPTVideoUrl)&&
!string.IsNullOrEmpty(taskInfo.PPTVideoCode))
{ {
try taskInfo.PPTVideoUrl = await packageInfoTaskDB.AsQueryable()
{ .Where(s => s.VideoCode == taskInfo.PPTVideoCode)
var url = string.Empty; .Select(s => s.VideoUrl)
if (taskInfo.PPTVideoCode.Contains("http")) .FirstAsync();
url = taskInfo.PPTVideoCode; if (!string.IsNullOrEmpty(taskInfo.PPTVideoUrl))
else await videoTaskDB.AsUpdateable(taskInfo)
{ .UpdateColumns(it => new { it.PPTVideoUrl })
var videoInfo = await vodClient.GetPlayInfoAsync(new AlibabaCloud.SDK.Vod20170321.Models.GetPlayInfoRequest() .ExecuteCommandAsync();
{
VideoId = taskInfo.PPTVideoCode,
Formats = "mp4",
OutputType = "cdn",
AuthTimeout = 3600 * 24 * 12,
});
if (videoInfo is null || videoInfo.StatusCode != 200 && !videoInfo.Body.PlayInfoList.PlayInfo.Any())
throw new Exception($"{DateTime.Now} 视频订阅=>获取阿里云视频信息失败 VideoCode {taskInfo.TagId} StatusCode {videoInfo?.StatusCode}");
url = videoInfo.Body.PlayInfoList.PlayInfo.First().PlayURL;
} }
await Download(url, localPath, "ppt.mp4", if (!string.IsNullOrEmpty(taskInfo.PPTVideoUrl))
{
await Download(taskInfo.PPTVideoUrl, localPath, taskPPTVideoName,
(s, e) => RedisExpand.SetTaskProgress(task, "PPT->" + Math.Round(e.ProgressPercentage, 1) (s, e) => RedisExpand.SetTaskProgress(task, "PPT->" + Math.Round(e.ProgressPercentage, 1)
)); ));
} //try
catch //{
{ // var url = string.Empty;
throw; // if (taskInfo.PPTVideoCode.Contains("http"))
} // url = taskInfo.PPTVideoCode;
// else
// {
// var videoInfo = await vodClient.GetPlayInfoAsync(new AlibabaCloud.SDK.Vod20170321.Models.GetPlayInfoRequest()
// {
// VideoId = taskInfo.PPTVideoCode,
// Formats = "mp4",
// OutputType = "cdn",
// AuthTimeout = 3600 * 24 * 12,
// });
// if (videoInfo is null || videoInfo.StatusCode != 200 && !videoInfo.Body.PlayInfoList.PlayInfo.Any())
// throw new Exception($"{DateTime.Now} 视频订阅=>获取阿里云视频信息失败 VideoCode {taskInfo.TagId} StatusCode {videoInfo?.StatusCode}");
// url = videoInfo.Body.PlayInfoList.PlayInfo.First().PlayURL;
// }
//}
//catch
//{
// throw;
//}
} }
try try
{//下载原视频 {
await Download(fileUrl, localPath, task + fileExtension, //下载原视频
await Download(fileUrl, localPath, taskVideoName,
(s, e) => RedisExpand.SetTaskProgress(task, Math.Round(e.ProgressPercentage,1) (s, e) => RedisExpand.SetTaskProgress(task, Math.Round(e.ProgressPercentage,1)
)); ));
} }

View File

@ -104,6 +104,7 @@ namespace VideoAnalysisCore.Controllers
nodePackages.Add(np); nodePackages.Add(np);
if (videoIdArr.Contains(s.VideoCode)) continue; if (videoIdArr.Contains(s.VideoCode)) continue;
var pptCode = sPPT != null ? sPPT.VideoCode : string.Empty; var pptCode = sPPT != null ? sPPT.VideoCode : string.Empty;
var pptUrl = sPPT != null ? sPPT.VideoUrl : string.Empty;
videos.Add(new VideoTask() videos.Add(new VideoTask()
{ {
Id = YitIdHelper.NextId(), Id = YitIdHelper.NextId(),
@ -115,6 +116,7 @@ namespace VideoAnalysisCore.Controllers
TagId = s.VideoCode, TagId = s.VideoCode,
MediaUrl = s.VideoUrl, MediaUrl = s.VideoUrl,
PPTVideoCode = pptCode, PPTVideoCode = pptCode,
PPTVideoUrl = pptUrl,
VideoType = s.CourseType VideoType = s.CourseType
}); });
} }

View File

@ -51,21 +51,7 @@ namespace VideoAnalysisCore.Job
// 遍历查询结果,删除缓存文件 // 遍历查询结果,删除缓存文件
foreach (var task in completedTasks) foreach (var task in completedTasks)
{ ExpandFunction.DeleteTaskFile(task?.Id);
var path = task.Id.ToString().LocalPath();
if (!string.IsNullOrEmpty(path) && Directory.Exists(path))
{
try
{
Directory.Delete(path, true);
Console.WriteLine($"已删除缓存文件: {task.LocalMediaPath}");
}
catch (Exception ex)
{
Console.WriteLine($"删除缓存文件 {task.Id} 时出错: {ex.Message}");
}
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -79,6 +79,11 @@ namespace VideoAnalysisCore.Model
[SugarColumn(Length = 255, ColumnDataType = "varchar", IsNullable = true)] [SugarColumn(Length = 255, ColumnDataType = "varchar", IsNullable = true)]
public string? PPTVideoCode { get; set; } public string? PPTVideoCode { get; set; }
/// <summary> /// <summary>
/// 授课视频对应PPT视频ID
/// </summary>
[SugarColumn(Length = 255, ColumnDataType = "varchar", IsNullable = true)]
public string? PPTVideoUrl { get; set; }
/// <summary>
/// 授课视频对应PPT视频关键帧 /// 授课视频对应PPT视频关键帧
/// </summary> /// </summary>
[SugarColumn(ColumnDataType = "longtext",IsNullable = true)] [SugarColumn(ColumnDataType = "longtext",IsNullable = true)]