using FreeRedis; using Microsoft.Extensions.DependencyModel; using SqlSugar; using SqlSugar.IOC; using System.Reflection; using System.Runtime.Loader; using System.Text; using System.Threading.Tasks; using VideoAnalysisCore.AICore.SherpaOnnx; using VideoAnalysisCore.Enum; using VideoAnalysisCore.Model.Dto; using Whisper.net; namespace VideoAnalysisCore.Common { /// /// 程序 公共变量 /// public static class AppCommon { /// /// 应用有效程序集 /// public static readonly IEnumerable Assemblies; /// /// 主库数据库表类型 /// public static readonly IEnumerable DbMatserType; static AppCommon() { try { Assemblies = ExpandFunction.GetAssemblies(); var assembliesType = Assemblies.Where(s => s.FullName.Contains("VideoAnalysis")).SelectMany(s => s.ExportedTypes .Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsDefined(typeof(SugarTable), false))); DbMatserType = assembliesType; } catch { } //.Where(u => !u.IsDefined(typeof(SplitTableAttribute), false)) //.Where(u => !typeof(Model.DataCenterYH.IDataCenterYHModel).IsAssignableFrom(u)) //.Where(u => !u.IsSubclassOf(typeof(YQ_BaseEntity))); } /// /// 程序配置 /// public static AppConfig Config = new AppConfig(); /// /// ServiceProvider /// public static IServiceProvider? Services; /// /// 文件下载路径 /// public static string TaskCachedFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskCachedFile"); /// /// 模型地址 /// public static string AIModelFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AICore", "_Static"); } /// /// 拓展函数 /// public static class ExpandFunction { /// /// 获取应用有效程序集 /// /// IEnumerable public static List GetAssemblies() { // 获取当前解决方案的所有程序集 var assembliesStr = DependencyContext.Default.RuntimeLibraries .Where(u => !u.Name.StartsWith(nameof(Microsoft)) && !u.Name.StartsWith(nameof(System)) && !u.Name.StartsWith("netstandard") && (u.Type == "project")); var assemblies = assembliesStr.Select(a => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(a.Name))).ToList(); var assemblies1 = Assembly.GetEntryAssembly().GetReferencedAssemblies().Where(x => x.Name.StartsWith("App.") || x.Name.StartsWith("UserCenter.")) .Select(a => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(a.Name))).ToList(); foreach (var item in assemblies1) { if (!assemblies.Contains(item)) assemblies.Add(item); } return assemblies; } /// /// 获取Task处理后的 说话人字幕 /// public static TotalCaptionsDto GetSpeakerCaptions(string task) { var captionsArr = RedisExpand.Redis.HMGet(RedisExpandKey.Task(task), "Captions").FirstOrDefault(); var speakerArr = RedisExpand.Redis.HMGet(RedisExpandKey.Task(task), "Speaker").FirstOrDefault(); if (captionsArr is null || captionsArr.Length == 0 || speakerArr is null || speakerArr.Length == 0) throw new Exception("音频解析数据异常"); // 教师说话人Id var techerId = speakerArr.GroupBy(s=>s.SpeakerIndex).Select(s => (s.Key,s.Sum(x=>x.Total))) .OrderByDescending(s=>s.Item2).First().Key; var teacherSpeaking = 0m; var studentSpeaking = 0m; var results = new Dictionary>(); foreach (var segment in captionsArr) { var spList = new List(); foreach (var speakerRes in speakerArr) { if ((double)speakerRes.Start > segment.End.TotalSeconds) break; if (segment.Start.TotalSeconds <= (double)speakerRes.End && segment.End.TotalSeconds >= (double)speakerRes.Start) { if (speakerRes.SpeakerIndex == techerId) teacherSpeaking += speakerRes.Total; else studentSpeaking += speakerRes.Total; spList.Add(speakerRes.SpeakerIndex); break; } } results.Add(segment, spList); } //拼接 提示词字幕源 var stringBuilder = new StringBuilder(); foreach (var item in results) stringBuilder.Append($"{item.Value.First()}:{item.Key.Start.TotalSeconds}:{item.Key.End.TotalSeconds}:{item.Key.Text},"); //todo 分析上课时间段情况 分析 独立学习 小组合作 随堂练习等情况 return new TotalCaptionsDto { StudentSpeaking = studentSpeaking, TeacherSpeaking = teacherSpeaking, Captions = stringBuilder.ToString(), TimeBase = results.Select(s=>new TimeBase() { Start = s.Key.Start.TotalSeconds, End = s.Key.End.TotalSeconds, Type = s.Value.Count == 1 && s.Value.First() == techerId ? TimeBaseTypeEnum.教师讲授 : TimeBaseTypeEnum.互动交流 }) }; } /// /// 转化枚举 /// /// /// public static T? ToEnum(this object data) where T : struct, System.Enum { if (data is null || string.IsNullOrEmpty(data?.ToString())) return null; return System.Enum.Parse(data.ToString()); } /// /// 转化本地缓存目录 /// /// 任务id /// public static string LocalPath(this string taskId) { return Path.Combine(AppCommon.TaskCachedFile, taskId); } } /// /// ffmpeg配置 /// public class KIMIConfig { /// /// kimi请求 公开的服务地址 /// public string Host { get; set; } = string.Empty; /// /// api的密钥 /// public string ApiKey { get; set; } = string.Empty; } /// /// 文本模型 配置 /// public class ChatGptConfig { /// /// KIMI /// /// public KIMIConfig KIMI { get; set; } = new KIMIConfig(); } /// /// ffmpeg配置 /// public class FFmpegConfig { /// /// 音频切片时间段 /// 0不切片 /// public int TimeSlice { get; set; } = 0; } /// /// Whisper配置 /// public class WhisperConfig { /// /// 模型名称 /// public string ModelName { get; set; } = string.Empty; } /// /// redis配置 /// public class RedisConfig { /// /// redis连接字符串 /// public string ConnectionString { get; set; } = string.Empty; } public class DBConfig { /// /// 主库链接 /// public string ConnectionString { get; set; }=string.Empty; /// /// 数据库类型 /// public IocDbType SqlType { get; set; } /// /// 启动时更新表结构 /// public bool UpdateTable { get; set; } } /// /// 应用程序配置 /// public class AppConfig { /// /// redis /// public RedisConfig Redis { get; set; } = new RedisConfig(); /// /// Whisper AI /// public WhisperConfig Whisper { get; set; } = new WhisperConfig(); /// /// FFmpeg /// public FFmpegConfig FFmpeg { get; set; } = new FFmpegConfig(); /// /// ChatGpt /// public ChatGptConfig ChatGpt { get; set; } = new ChatGptConfig(); /// /// 数据库配置 /// public DBConfig DB { get; set; } = new DBConfig(); } }