using FreeRedis; using FreeRedis.Internal; using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; using NetTaste; using Newtonsoft.Json.Schema; using SqlSugar.IOC; using System; using System.Security.Cryptography; using System.Text.Json; using System.Threading.Channels; using System.Threading.Tasks; using System.Collections.Concurrent; using System.Xml.Linq; using UserCenter.Model.Enum; using VideoAnalysisCore.AICore.FFMPGE; using VideoAnalysisCore.AICore.GPT; using VideoAnalysisCore.AICore.GPT.Dto; //using VideoAnalysisCore.AICore.FFMPGE; using VideoAnalysisCore.AICore.SherpaOnnx; using VideoAnalysisCore.AICore.Whisper; using VideoAnalysisCore.Model; using VideoAnalysisCore.Model.Dto; using VideoAnalysisCore.Model.Enum; namespace VideoAnalysisCore.Common { /// /// redis key /// public static class RedisExpandKey { /// /// 基础key /// public const string BaseKey = "VideoAnalysis:"; /// /// 基础Channel key /// public const string ChannelKey = BaseKey + "TaskChannel"; /// /// TidySlide 工作流 Channel key /// public const string TidySlideChannelKey = BaseKey + "TidySlideTaskChannel"; /// /// 下载文件 /// public const string DownloadFile = ChannelKey + "DownloadFile"; /// /// 分离音频 /// public const string SeparateAudio = ChannelKey + "SeparateAudio"; /// /// 解析字幕 /// public const string ParsingCaptions = ChannelKey + "ParsingCaptions"; /// /// 解析说话人 /// public const string ParsingSpeaker = ChannelKey + "ParsingSpeaker"; /// /// Chat模型分析 /// public const string ChatModelAnalysis = ChannelKey + "ChatModelAnalysis"; /// /// 任务数组 /// public const string TaskArr = BaseKey + "TaskArr"; /// /// 任务日志缓存 /// public static string TaskLog => BaseKey + "TaskLog:" + AppCommon.Config.ID; /// /// 任务对象地址 /// public static string Task(object taskId) => BaseKey + "Info:" + taskId; public static string IDTask => BaseKey + "Services:" + AppCommon.Config.ID; /// /// 在线设备Key集合 (已弃用,直接扫描 Heartbeat) /// // public static string OnlineDevices => BaseKey + "OnlineDevices"; /// /// 设备心跳Key前缀 (VideoAnalysis:Heartbeat:{DeviceId}) /// public static string DeviceHeartbeat(string deviceId) => BaseKey + "Heartbeat:" + deviceId; public static string TaskGPT(object taskId) => BaseKey + "GPTCached:" + taskId; /// /// 初始化 redis /// 需要在初始化配置文件时候调用 /// public static void AddTaskSubscribe(this IServiceCollection service) { Console.WriteLine($"{DateTime.Now}=>初始化 Redis任务队列"); service.AddSingleton(); } /// /// redis连接拓展(包含消息队列任务) /// /// public static void AddRedisExpand(this IServiceCollection service) { Console.WriteLine($"{DateTime.Now}=>初始化 Redis"); var redis = new RedisClient(AppCommon.Config.Redis.ConnectionString); redis.Serialize = obj => JsonSerializer.Serialize(obj); redis.Deserialize = (json, type) => JsonSerializer.Deserialize(json, type); service.AddSingleton(redis); service.AddSingleton(); service.AddVideoSliceWorkflow(); service.AddTidySlideWorkflow(); // 注册心跳 Job // service.AddTransient(); // 迁移到 CoravelExpand 中统一管理 // service.AddTransient(); // service.AddTransient(); } } public class RedisInit { public RedisInit(IServiceProvider serviceProvider) { serviceProvider.GetService(); serviceProvider.GetService(); // serviceProvider.GetService().InitChannel(); // 已废弃,由各工作流自行初始化 } } /// /// redis拓展 /// public class RedisManager { public static bool StopTask { get; set; } = false; public static Dictionary> SubscribeList = new Dictionary>(); /// /// 正在后台运行的任务集合 /// public static ConcurrentDictionary RunningTasks = new ConcurrentDictionary(); private static CancellationTokenSource? _cts; private static Task? _workerTask; public RedisClient Redis { get; set; } public Repository videoTaskDB { get; set; } public Repository taskLogDB { get; set; } public RedisManager(RedisClient redis, Repository videoTaskDB, Repository taskLogDB) { Redis = redis; this.videoTaskDB = videoTaskDB; this.taskLogDB = taskLogDB; } /// /// 缓存GPT任务缓存 /// /// public void SetTaskGPTCached(object taskId, string time, object? data) { Redis.Set(RedisExpandKey.TaskGPT(taskId) + ":" + time, data, timeoutSeconds: 3600 * 24); } /// /// 加入到消费队列 /// /// public void JoinQueue(params long[] taskIds) { //事务 if (taskIds is null || taskIds.Length == 0) return; using (var tran = Redis.Multi()) { foreach (var item in taskIds) tran.LPush(RedisExpandKey.ChannelKey, item); tran.Exec(); } } // AddTaskLog 已迁移至 WorkflowBase /// /// 获取任务进度 /// /// /// 工作流名称(可选) public string GetTaskProgress(object taskId, string workflowName = "VideoSliceWorkflow") { var fieldName = workflowName == "VideoSliceWorkflow" ? "Progress" : $"Progress:{workflowName}"; return Redis.HMGet(RedisExpandKey.Task(taskId), fieldName)[0] ?? ""; } // 注意:SetTaskProgress, TaskEnd, SetTaskErrorMessage, ClearTaskError, SetTaskError // 已迁移至 WorkflowBase,此处移除或标记为已废弃 } }