using FreeRedis; using Microsoft.Extensions.DependencyInjection; using SqlSugar.IOC; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using VideoAnalysisCore.AICore.FFMPGE; using VideoAnalysisCore.AICore.GPT; using VideoAnalysisCore.AICore.SherpaOnnx; using VideoAnalysisCore.AICore.Whisper; using VideoAnalysisCore.Common.Expand; using VideoAnalysisCore.Model; using VideoAnalysisCore.Model.Enum; namespace VideoAnalysisCore.Common { /// /// AI视频切片工作流 /// public static class VideoSliceWorkflowExpand { public static void AddVideoSliceWorkflow(this IServiceCollection services) { if (AppCommon.Config.Workflow.Default.Enabled) { Console.WriteLine($"{DateTime.Now}=>初始化 AI切片工作流"); services.AddSingleton(); services.AddSingleton(); } } } public class VideoSliceWorkflowInit { private readonly VideoSliceWorkflowManager _manager; private readonly IServiceProvider _serviceProvider; private readonly FFMPGEHandle _ffmpeg; private readonly SenseVoice _senseVoice; private readonly RedisManager _redisManager; public VideoSliceWorkflowInit(VideoSliceWorkflowManager manager, IServiceProvider serviceProvider, FFMPGEHandle ffmpeg, SenseVoice senseVoice, RedisManager redisManager) { _manager = manager; _serviceProvider = serviceProvider; _ffmpeg = ffmpeg; _senseVoice = senseVoice; _redisManager = redisManager; Init(); _manager.InitChannel(); } public void Init() { var SubscribeList = _manager.SubscribeList; SubscribeList.Add(RedisChannelEnum.排队中, async (task) => await Task.CompletedTask); SubscribeList.Add(RedisChannelEnum.下载文件, async (task) => { using var scope = _serviceProvider.CreateScope(); var downloadService = scope.ServiceProvider.GetService(); if (downloadService is null) throw new Exception("DownloadFile 未注入"); await downloadService.RunTask(task); }); SubscribeList.Add(RedisChannelEnum.分离音频, _ffmpeg.RunAsync); SubscribeList.Add(RedisChannelEnum.解析字幕, _senseVoice.RunTask); SubscribeList.Add(RedisChannelEnum.AI课程类型, async (task) => { using var scope = _serviceProvider.CreateScope(); var service = scope.ServiceProvider.GetService(); if (service is null) throw new Exception("IBserGPT 未注入"); await service.GetVideoType(task); }); SubscribeList.Add(RedisChannelEnum.AI模型分析, async (task) => { using var scope = _serviceProvider.CreateScope(); var service = scope.ServiceProvider.GetService(); if (service is null) throw new Exception("IBserGPT 未注入"); await service.GetKnow(task); }); SubscribeList.Add(RedisChannelEnum.AI分析试题, async (task) => { using var scope = _serviceProvider.CreateScope(); var service = scope.ServiceProvider.GetService(); if (service is null) throw new Exception("IBserGPT 未注入"); await service.GetVideoQuestion(task); }); SubscribeList.Add(RedisChannelEnum.结束任务, _redisManager.TaskEnd); } } public class VideoSliceWorkflowManager : WorkflowBase { public VideoSliceWorkflowManager(RedisClient redis, RedisManager redisManager) : base(redis, redisManager) { } protected override string ChannelKey => RedisExpandKey.ChannelKey; protected override int Concurrency => AppCommon.Config.Workflow.Default.Concurrency; protected override async Task HandleSpecialFlowAsync(RedisChannelEnum currentStep, RedisChannelEnum nextStep, string taskId) { // 4. 特殊分流:解析字幕完成后,后续步骤转后台并行处理 if (currentStep == RedisChannelEnum.解析字幕) { await DispatchBackgroundFlow(nextStep, taskId, taskId); throw new WorkflowFlowSwitchException(); // 抛出异常以中断当前流程(基类捕获) } await Task.CompletedTask; } } }