Learn.VideoAnalysis/VideoAnalysisCore/Common/AppCommon.cs

416 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AntDesign;
using AntDesign.TableModels;
using FreeRedis;
using Microsoft.Extensions.DependencyModel;
using SqlSugar;
using SqlSugar.IOC;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using UserCenter.Model.Interface;
using VideoAnalysisCore.AICore.SherpaOnnx;
using VideoAnalysisCore.Enum;
using VideoAnalysisCore.Interface;
using VideoAnalysisCore.Model.Dto;
using Whisper.net;
using static System.Runtime.InteropServices.JavaScript.JSType;
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;
public static readonly IEnumerable<Type> KnowsType;
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
.Where(u => u.GetInterfaces().Contains(typeof(IDB)));
KnowsType = assembliesType
.Where(u =>u.GetInterfaces().Contains(typeof(IKnowsDB)));
}
catch
{
throw;
}
//.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>
/// <param name="tid"></param>
/// <returns></returns>
public static string GetVideoPath(string tid) => $"./video/{tid}/{tid}.mp4";
}
/// <summary>
/// 拓展函数
/// </summary>
public static class ExpandFunction
{
static Dictionary<string, string> FormulaData = new Dictionary<string, string>()
{
{ "阿尔法","α"},
{ "贝塔","β"},
{ "伽马","γ"},
{ "德尔塔","Δ"},
{ "派","π"},
{ "西格马","∑"},
{ "欧米伽","Ω"},
{ "普西","Ψ"},
};
static string FormulaDataKey = string.Join("|", FormulaData.Keys);
/// <summary>
/// 处理数学公式
/// </summary>
/// <param name="f"></param>
/// <returns></returns>
public static string HandleFormula(string f)
{
if (string.IsNullOrEmpty(f))
return f;
return Regex.Replace(f, FormulaDataKey,
match =>
FormulaData[match.Value]
);
}
/// <summary>
/// 转换 ant 查询枚举 到 sqlsuger枚举
/// </summary>
/// <param name="filterOperator">ant 查询枚举</param>
/// <returns></returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public static ConditionalType ConvertToConditionalType(TableFilterCompareOperator filterOperator)
{
return filterOperator switch
{
TableFilterCompareOperator.Equals => ConditionalType.Equal,
TableFilterCompareOperator.Contains => ConditionalType.Like,
TableFilterCompareOperator.StartsWith => ConditionalType.LikeLeft,
TableFilterCompareOperator.EndsWith => ConditionalType.LikeRight,
TableFilterCompareOperator.GreaterThan => ConditionalType.GreaterThan,
TableFilterCompareOperator.LessThan => ConditionalType.LessThan,
TableFilterCompareOperator.GreaterThanOrEquals => ConditionalType.GreaterThanOrEqual,
TableFilterCompareOperator.LessThanOrEquals => ConditionalType.LessThanOrEqual,
TableFilterCompareOperator.Condition => ConditionalType.In,
TableFilterCompareOperator.NotEquals => ConditionalType.NoEqual,
TableFilterCompareOperator.IsNull => ConditionalType.IsNullOrEmpty,
TableFilterCompareOperator.IsNotNull => ConditionalType.IsNot,
TableFilterCompareOperator.NotContains => ConditionalType.NoLike,
TableFilterCompareOperator.TheSameDateWith => ConditionalType.EqualNull,
TableFilterCompareOperator.Between => ConditionalType.Range,
_ => throw new ArgumentOutOfRangeException(nameof(filterOperator), filterOperator, "未知的枚举类型!")
};
}
public static List<IConditionalModel> ToSqlSugerWhere(this QueryModel qm )
{
return qm.FilterModel.SelectMany(s => s.Filters.Select(x => new ConditionalModel()
{
FieldName = s.FieldName,
ConditionalType = ConvertToConditionalType( x.FilterCompareOperator),
FieldValue = x.Value.GetType().IsEnum?((int)x.Value).ToString() : x.Value.ToString(),
} as IConditionalModel)).ToList();
}
/// <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<SenseVoiceRes[]>(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 is null || !speakerArr.Any()
? 0
:speakerArr.GroupBy(s=>s.SpeakerIndex).Select(s => (s.Key,s.Sum(x=>x.Total)))
.OrderByDescending(s=>s.Item2).First().Key;
var teacherSpeaking = 0f;
var studentSpeaking = 0f;
var results = new Dictionary<SenseVoiceRes, List<int>>();
if (speakerArr is null || speakerArr.Count() == 0)
{
var ss = new List<int> { 1 };
results = captionsArr.ToDictionary(s => s, s=> ss);
}
else
{
foreach (var segment in captionsArr)
{
var spList = new List<int>();
foreach (var speakerRes in speakerArr)
{
if (speakerRes.Start > segment.End)
break;
if (segment.Start <= speakerRes.End
&& segment.End >= speakerRes.Start)
{
if (speakerRes.SpeakerIndex == techerId)
teacherSpeaking += speakerRes.Total;
else
studentSpeaking += speakerRes.Total;
spList.Add(speakerRes.SpeakerIndex);
}
}
var sp = spList.Distinct().ToList();
if (sp.Count > 0)
results.Add(segment, sp);
}
}
//拼接 提示词字幕源
var stringBuilder = new StringBuilder();
foreach (var item in results)
{
stringBuilder.Append(item.Value.First());
stringBuilder.Append(":");
stringBuilder.Append(item.Key.Start);
stringBuilder.Append(":");
stringBuilder.Append(item.Key.End);
stringBuilder.Append(":");
stringBuilder.Append(item.Key.Text);
stringBuilder.Append("|");
}
return new TotalCaptionsDto
{
StudentSpeaking = (decimal)studentSpeaking,
TeacherSpeaking = (decimal)teacherSpeaking,
Captions = stringBuilder.ToString(),
TimeBase = results.Select(s=>new TimeBase()
{
Start = s.Key.Start,
End = s.Key.End,
Content = s.Key.Text,
TimeBaseType = 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
{
try
{
if (data is null || string.IsNullOrEmpty(data?.ToString()))
return null;
return System.Enum.Parse<T>(data.ToString());
}
catch (Exception)
{
return null;
}
}
/// <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 GptConfig
{
/// <summary>
/// 请求 公开的服务地址
/// </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 GptConfig ChatGpt { get; set; } = new GptConfig();
public GptConfig KIMI { get; set; } = new GptConfig();
}
/// <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>
/// 管理界面Admin账号
/// </summary>
public class AdminConfig
{
/// <summary>
/// 账号
/// </summary>
public string Account { get; set; } = string.Empty;
/// <summary>
/// 密码
/// </summary>
public string Password { 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>
/// 程序ID
/// </summary>
public string ID { get; set; } = string.Empty;
/// <summary>
/// Admin
/// </summary>
public AdminConfig Admin { get; set; } = new AdminConfig();
/// <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();
/// <summary>
/// 知识点数据库
/// </summary>
public DBConfig KnowsDB { get; set; } = new DBConfig();
}
}