Learn.VideoAnalysis/VideoAnalysisCore/Common/AppCommon.cs

282 lines
9.4 KiB
C#

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
{
/// <summary>
/// 程序 公共变量
/// </summary>
public static class AppCommon
{
/// <summary>
/// 应用有效程序集
/// </summary>
public static readonly IEnumerable<Assembly> Assemblies;
/// <summary>
/// 主库数据库表类型
/// </summary>
public static readonly IEnumerable<Type> 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)));
}
/// <summary>
/// 程序配置
/// </summary>
public static AppConfig Config = new AppConfig();
/// <summary>
/// ServiceProvider
/// </summary>
public static IServiceProvider? Services;
/// <summary>
/// 文件下载路径
/// </summary>
public static string TaskCachedFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskCachedFile");
/// <summary>
/// 模型地址
/// </summary>
public static string AIModelFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AICore", "_Static");
}
/// <summary>
/// 拓展函数
/// </summary>
public static class ExpandFunction
{
/// <summary>
/// 获取应用有效程序集
/// </summary>
/// <returns>IEnumerable</returns>
public static List<Assembly> 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;
}
/// <summary>
/// 获取Task处理后的 说话人字幕
/// </summary>
public static TotalCaptionsDto GetSpeakerCaptions(string task)
{
var captionsArr = RedisExpand.Redis.HMGet<SegmentData[]>(RedisExpandKey.Task(task), "Captions").FirstOrDefault();
var speakerArr = RedisExpand.Redis.HMGet<OfflineSpeakerRes[]>(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<SegmentData, List<int>>();
foreach (var segment in captionsArr)
{
var spList = new List<int>();
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.
})
};
}
/// <summary>
/// 转化枚举
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static T? ToEnum<T>(this object data) where T : struct, System.Enum
{
if (data is null || string.IsNullOrEmpty(data?.ToString()))
return null;
return System.Enum.Parse<T>(data.ToString());
}
/// <summary>
/// 转化本地缓存目录
/// </summary>
/// <param name="taskId">任务id</param>
/// <returns></returns>
public static string LocalPath(this string taskId)
{
return Path.Combine(AppCommon.TaskCachedFile, taskId);
}
}
/// <summary>
/// ffmpeg配置
/// </summary>
public class KIMIConfig
{
/// <summary>
/// kimi请求 公开的服务地址
/// </summary>
public string Host { get; set; } = string.Empty;
/// <summary>
/// api的密钥
/// </summary>
public string ApiKey { get; set; } = string.Empty;
}
/// <summary>
/// 文本模型 配置
/// </summary>
public class ChatGptConfig
{
/// <summary>
/// KIMI
/// <para></para>
/// </summary>
public KIMIConfig KIMI { get; set; } = new KIMIConfig();
}
/// <summary>
/// ffmpeg配置
/// </summary>
public class FFmpegConfig
{
/// <summary>
/// 音频切片时间段
/// <para>0不切片</para>
/// </summary>
public int TimeSlice { get; set; } = 0;
}
/// <summary>
/// Whisper配置
/// </summary>
public class WhisperConfig
{
/// <summary>
/// 模型名称
/// </summary>
public string ModelName { get; set; } = string.Empty;
}
/// <summary>
/// redis配置
/// </summary>
public class RedisConfig
{
/// <summary>
/// redis连接字符串
/// </summary>
public string ConnectionString { get; set; } = string.Empty;
}
public class DBConfig
{
/// <summary>
/// 主库链接
/// </summary>
public string ConnectionString { get; set; }=string.Empty;
/// <summary>
/// 数据库类型
/// </summary>
public IocDbType SqlType { get; set; }
/// <summary>
/// 启动时更新表结构
/// </summary>
public bool UpdateTable { get; set; }
}
/// <summary>
/// 应用程序配置
/// </summary>
public class AppConfig
{
/// <summary>
/// redis
/// </summary>
public RedisConfig Redis { get; set; } = new RedisConfig();
/// <summary>
/// Whisper AI
/// </summary>
public WhisperConfig Whisper { get; set; } = new WhisperConfig();
/// <summary>
/// FFmpeg
/// </summary>
public FFmpegConfig FFmpeg { get; set; } = new FFmpegConfig();
/// <summary>
/// ChatGpt
/// </summary>
public ChatGptConfig ChatGpt { get; set; } = new ChatGptConfig();
/// <summary>
/// 数据库配置
/// </summary>
public DBConfig DB { get; set; } = new DBConfig();
}
}