parent
972fba9959
commit
7ef238e4e2
|
|
@ -0,0 +1,172 @@
|
|||
{
|
||||
"Env": [
|
||||
{
|
||||
"Name": "10楼刀片机",
|
||||
"ServerList": [],
|
||||
"LinuxServerList": [
|
||||
{
|
||||
"UserName": "heyang",
|
||||
"Pwd": "9718CB3C9A0760CA326767D677ADEC1C",
|
||||
"Host": "10.127.127.107",
|
||||
"NickName": "10楼刀片机",
|
||||
"IIsFireUrl": null,
|
||||
"DockerFireUrl": "",
|
||||
"WindowsServiceFireUrl": null,
|
||||
"LinuxServiceFireUrl": null
|
||||
}
|
||||
],
|
||||
"IgnoreList": [
|
||||
"ffmpeg.exe"
|
||||
],
|
||||
"WindowsBackUpIgnoreList": []
|
||||
},
|
||||
{
|
||||
"Name": "阿里云_代理",
|
||||
"ServerList": [],
|
||||
"LinuxServerList": [
|
||||
{
|
||||
"UserName": "heyang",
|
||||
"Pwd": "AAC53130AF118B652BCED77C39B959F9",
|
||||
"Host": "10.127.127.77:10022",
|
||||
"NickName": "",
|
||||
"IIsFireUrl": null,
|
||||
"DockerFireUrl": "",
|
||||
"WindowsServiceFireUrl": null,
|
||||
"LinuxServiceFireUrl": null
|
||||
}
|
||||
],
|
||||
"IgnoreList": [],
|
||||
"WindowsBackUpIgnoreList": []
|
||||
}
|
||||
],
|
||||
"IIsConfig": {
|
||||
"SdkType": null,
|
||||
"WebSiteName": "",
|
||||
"LastEnvName": null,
|
||||
"EnvPairList": [
|
||||
{
|
||||
"EnvName": "10楼刀片机",
|
||||
"ConfigName": "",
|
||||
"LinuxEnvParam": null,
|
||||
"DockerPort": null,
|
||||
"DockerEnvName": null,
|
||||
"DockerVolume": null,
|
||||
"DockerOther": null
|
||||
},
|
||||
{
|
||||
"EnvName": "阿里云_代理",
|
||||
"ConfigName": "",
|
||||
"LinuxEnvParam": null,
|
||||
"DockerPort": null,
|
||||
"DockerEnvName": null,
|
||||
"DockerVolume": null,
|
||||
"DockerOther": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"WindowsServiveConfig": {
|
||||
"ServiceName": "",
|
||||
"SdkType": null,
|
||||
"LastEnvName": null,
|
||||
"EnvPairList": [
|
||||
{
|
||||
"EnvName": "10楼刀片机",
|
||||
"ConfigName": "",
|
||||
"LinuxEnvParam": null,
|
||||
"DockerPort": null,
|
||||
"DockerEnvName": null,
|
||||
"DockerVolume": null,
|
||||
"DockerOther": null
|
||||
},
|
||||
{
|
||||
"EnvName": "阿里云_代理",
|
||||
"ConfigName": "",
|
||||
"LinuxEnvParam": null,
|
||||
"DockerPort": null,
|
||||
"DockerEnvName": null,
|
||||
"DockerVolume": null,
|
||||
"DockerOther": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"LinuxServiveConfig": {
|
||||
"ServiceName": "",
|
||||
"EnvParam": "",
|
||||
"LastEnvName": null,
|
||||
"EnvPairList": [
|
||||
{
|
||||
"EnvName": "10楼刀片机",
|
||||
"ConfigName": "",
|
||||
"LinuxEnvParam": null,
|
||||
"DockerPort": null,
|
||||
"DockerEnvName": null,
|
||||
"DockerVolume": null,
|
||||
"DockerOther": null
|
||||
},
|
||||
{
|
||||
"EnvName": "阿里云_代理",
|
||||
"ConfigName": "",
|
||||
"LinuxEnvParam": null,
|
||||
"DockerPort": null,
|
||||
"DockerEnvName": null,
|
||||
"DockerVolume": null,
|
||||
"DockerOther": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"DockerConfig": {
|
||||
"Prot": "9040",
|
||||
"AspNetCoreEnv": "",
|
||||
"LastEnvName": "阿里云_代理",
|
||||
"RemoveDaysFromPublished": "10",
|
||||
"WorkDir": "/home/heyang/",
|
||||
"Volume": "/home/hy/VideoAnalysis/AICore:/app/AICore/_Static;/home/hy/VideoAnalysis/TaskCachedFile:/app/TaskCachedFile",
|
||||
"Other": "-e va_args=\"\" --name videoanalysis",
|
||||
"EnvPairList": [
|
||||
{
|
||||
"EnvName": "10楼刀片机",
|
||||
"ConfigName": null,
|
||||
"LinuxEnvParam": null,
|
||||
"DockerPort": "9040",
|
||||
"DockerEnvName": "",
|
||||
"DockerVolume": "/home/hy/VideoAnalysis/AICore:/app/AICore/_Static;/home/hy/VideoAnalysis/TaskCachedFile:/app/TaskCachedFile",
|
||||
"DockerOther": "-e va_args=\"\""
|
||||
},
|
||||
{
|
||||
"EnvName": "阿里云_代理",
|
||||
"ConfigName": null,
|
||||
"LinuxEnvParam": null,
|
||||
"DockerPort": "9040",
|
||||
"DockerEnvName": "",
|
||||
"DockerVolume": "/home/hy/VideoAnalysis/AICore:/app/AICore/_Static;/home/hy/VideoAnalysis/TaskCachedFile:/app/TaskCachedFile",
|
||||
"DockerOther": "-e va_args=\"\" --name videoanalysis"
|
||||
}
|
||||
]
|
||||
},
|
||||
"DockerImageConfig": {
|
||||
"BaseHttpProxy": "",
|
||||
"BaseImage": "",
|
||||
"BaseImageCredential": {
|
||||
"UserName": "",
|
||||
"Password": ""
|
||||
},
|
||||
"TargetImage": "",
|
||||
"TargetHttpProxy": "",
|
||||
"TargetTags": [
|
||||
""
|
||||
],
|
||||
"TargetImageCredential": {
|
||||
"UserName": "",
|
||||
"Password": ""
|
||||
},
|
||||
"ImageFormat": "Docker",
|
||||
"Entrypoint": [
|
||||
""
|
||||
],
|
||||
"Cmd": [
|
||||
""
|
||||
],
|
||||
"IgnoreList": [],
|
||||
"SkipExistingImages": false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,299 @@
|
|||
|
||||
using VideoAnalysisCore.Common;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Reflection;
|
||||
using MapsterMapper;
|
||||
using Mapster;
|
||||
using VideoAnalysisCore.AICore.SherpaOnnx;
|
||||
using UserCenter.Model.Enum;
|
||||
using VideoAnalysisCore.AICore.GPT.ChatGPT;
|
||||
using VideoAnalysisCore.AICore.GPT;
|
||||
using System.Text.Json;
|
||||
using VideoAnalysisCore.Model.Enum;
|
||||
using Yitter.IdGenerator;
|
||||
using VideoAnalysisCore.Model;
|
||||
using VideoAnalysisCore.Model.Dto;
|
||||
using Learn.VideoAnalysis.API.Controllers.Dto;
|
||||
|
||||
namespace Learn.VideoAnalysis.API.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Route("[controller]/[action]")]
|
||||
public class ApiController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<ApiController> _logger;
|
||||
private readonly IMapper mp;
|
||||
private readonly Repository<VideoTask> videoTaskDB;
|
||||
private readonly Repository<VideoKonwPoint> videoKonwDB;
|
||||
private readonly IBserGPT chatGPT;
|
||||
public ApiController(ILogger<ApiController> logger, Repository<VideoTask> videoTaskDB,
|
||||
IMapper mp, IBserGPT chatGPT, Repository<VideoKonwPoint> videoKonwDB)
|
||||
{
|
||||
_logger = logger;
|
||||
this.videoTaskDB = videoTaskDB;
|
||||
this.mp = mp;
|
||||
this.chatGPT = chatGPT;
|
||||
this.videoKonwDB = videoKonwDB;
|
||||
}
|
||||
|
||||
private string GetClientIpAddress()
|
||||
{
|
||||
// 检查 X-Forwarded-For 请求头
|
||||
if (HttpContext.Request.Headers.ContainsKey("X-Forwarded-For")
|
||||
&& !string.IsNullOrEmpty(HttpContext.Request.Headers["X-Forwarded-For"]))
|
||||
return HttpContext.Request.Headers["X-Forwarded-For"].ToString();
|
||||
if (HttpContext.Connection.RemoteIpAddress != null)
|
||||
return HttpContext.Connection.RemoteIpAddress.ToString();
|
||||
throw new Exception("未能获取到客户端ip地址");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 语音识别
|
||||
/// </summary>
|
||||
/// <param name="url">文件流</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet(Name = "AudioRecognitionUrl")]
|
||||
public async Task<IActionResult> AudioRecognitionUrl(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
using HttpClient client = new HttpClient();
|
||||
// 发送GET请求获取网络文件流
|
||||
using var networkStream = await client.GetStreamAsync(url);
|
||||
var res = await SenseVoice.RunTask(networkStream);
|
||||
return Ok(res);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return BadRequest(ex.Message);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 语音识别
|
||||
/// </summary>
|
||||
/// <param name="file">文件流</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost(Name = "AudioRecognition")]
|
||||
public async Task<IActionResult> AudioRecognition(IFormFile file)
|
||||
{
|
||||
using var s = file.OpenReadStream();
|
||||
var res = await SenseVoice.RunTask(s);
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取FTS_Data str
|
||||
/// </summary>
|
||||
/// <param name="path">路径</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet(Name = "fts_data")]
|
||||
public async Task<IActionResult> FTS_Data(string path = "itn_subject_sx.fst")
|
||||
{
|
||||
var hotwords = JsonSerializer
|
||||
.Deserialize<HotwordMode[]>(System.IO.File.ReadAllText(Path.Combine(AppCommon.AIModelFile, "Hotwords.json")));
|
||||
var res = new List<string>(100);
|
||||
foreach (var element in hotwords.OrderByDescending(s => s.key.Count()))
|
||||
foreach (var e in element.v)
|
||||
res.Add($"""("{e}", "{element.key}")""");
|
||||
var pyFile = System.IO.File.ReadAllText(Path.Combine(AppCommon.AIModelFile, "sherpa-onnx-fst.py"));
|
||||
var resStr = pyFile
|
||||
.Replace("(fts_data)", "[" + string.Join(',', res) + "]")
|
||||
.Replace("(path)", path);
|
||||
return Ok(resStr);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 重新开始执行GPT分析<para>taskId/tagId二选一</para>
|
||||
/// </summary>
|
||||
/// <param name="taskId"></param>
|
||||
/// <param name="tagId">自定义id</param>
|
||||
/// <param name="subject">切换任务所属学科 null忽略</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet(Name = "ReStart")]
|
||||
public async Task<IActionResult> ReStart(long taskId, string? tagId, SubjectEnum? subject)
|
||||
{
|
||||
var task = await videoTaskDB.AsQueryable()
|
||||
.WhereIF(taskId != 0, s => s.Id == taskId)
|
||||
.WhereIF(!string.IsNullOrEmpty(tagId), s => s.TagId == tagId)
|
||||
.FirstAsync();
|
||||
if (task is null)
|
||||
return BadRequest("未能找到对应任务");
|
||||
if (subject is not null)
|
||||
{
|
||||
task.Subject = subject;
|
||||
await videoTaskDB.UpdateAsync(task);
|
||||
}
|
||||
//重新开始执行GPT分析
|
||||
RedisExpand.InsertChannel(RedisChannelEnum.ChatModelAnalysis
|
||||
, task.Id);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 插入队列
|
||||
/// </summary>
|
||||
/// <param name="enum"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost(Name = "TestInsertChannel")]
|
||||
public IActionResult TestInsertChannel(int @enum = 1, string msg = "1")
|
||||
{
|
||||
RedisExpand.InsertChannel(@enum.ToEnum<RedisChannelEnum>().Value
|
||||
, msg);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 视频处理
|
||||
/// </summary>
|
||||
/// <param name="req">请求体</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost(Name = "VideoAnalysis")]
|
||||
public async Task<IActionResult> VideoAnalysis(VideoAnalysisReq req)
|
||||
{
|
||||
if (!ModelState.IsValid) return BadRequest(ModelState);
|
||||
|
||||
if (await videoTaskDB.IsAnyAsync(s => s.TagId == req.TagId))
|
||||
return BadRequest("重复添加");
|
||||
// 自动映射属性到哈希
|
||||
var task = new VideoTask()
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
ComeFrom = GetClientIpAddress(),
|
||||
MediaUrl = req.MediaUrl,
|
||||
ApiToken = req.ApiToken,
|
||||
Type = req.Type,
|
||||
Subject = req.Subject,
|
||||
Tag = req.Tag,
|
||||
TagId = req.TagId,
|
||||
MediaName = req.Name
|
||||
};
|
||||
//入库
|
||||
var hashEntries = task.GetType()
|
||||
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
||||
.ToDictionary(s => s.Name, s => s.GetValue(task));
|
||||
await videoTaskDB.InsertAsync(task);
|
||||
RedisExpand.Redis.HMSet(RedisExpandKey.Task(task.Id), hashEntries);
|
||||
RedisExpand.Redis.LPush(RedisExpandKey.ChannelKey, task.Id);
|
||||
return Ok(task.Id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// 获取视频知识点片段<para>taskId/tagId二选一</para>
|
||||
///// </summary>
|
||||
///// <param name="taskId"></param>
|
||||
///// <param name="tagId">自定义id</param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet(Name = "TaskKnowInfo")]
|
||||
//public async Task<IActionResult> TaskKnowInfo(long taskId, string? tagId)
|
||||
//{
|
||||
// if (taskId == 0 && string.IsNullOrEmpty(tagId))
|
||||
// return BadRequest();
|
||||
// var task = await videoTaskDB.AsQueryable()
|
||||
// .WhereIF(taskId != 0, s => s.Id == taskId)
|
||||
// .WhereIF(!string.IsNullOrEmpty(tagId), s => s.TagId == tagId)
|
||||
// .FirstAsync();
|
||||
// if (task is null)
|
||||
// return BadRequest("无效任务");
|
||||
|
||||
// var konwArr = await videoKonwDB.AsQueryable()
|
||||
// .Where(s => s.VideoTaskId == task.Id)
|
||||
// .ToArrayAsync();
|
||||
// if (konwArr is null || konwArr.Length == 0)
|
||||
// return BadRequest("无效任务");
|
||||
// return Ok(new TaskKnowRes()
|
||||
// {
|
||||
// TagId = task.TagId,
|
||||
// Status = task.LastEnum,
|
||||
// VideoTaskId = task.Id,
|
||||
// KnowBlockArr = konwArr
|
||||
// .GroupBy(s => s.StartTime)
|
||||
// .Select(s => new TaskKnowBlock()
|
||||
// {
|
||||
// Id = s.First().Id,
|
||||
// Content = s.First().Content,
|
||||
// StartTime = s.First().StartTime,
|
||||
// EndTime = s.First().EndTime,
|
||||
// Theme = s.First().Theme,
|
||||
// Know = s.Select(x => new TaskKnowInfo()
|
||||
// {
|
||||
// Id = x.Id,
|
||||
// KnowPoint = x.KnowPoint,
|
||||
// KnowPointId = x.KnowPointId
|
||||
// }).ToArray()
|
||||
// }).ToArray()
|
||||
// });
|
||||
//}
|
||||
///// <summary>
|
||||
///// 获取视频信息<para>taskId/tagId二选一</para>
|
||||
///// </summary>
|
||||
///// <param name="taskId"></param>
|
||||
///// <param name="tagId">自定义id</param>
|
||||
///// <returns></returns>
|
||||
//[HttpGet(Name = "TaskInfo")]
|
||||
//public async Task<IActionResult> TaskInfo(long taskId, string? tagId)
|
||||
//{
|
||||
// if (taskId == 0 && string.IsNullOrEmpty(tagId))
|
||||
// return BadRequest();
|
||||
// var task = await videoTaskDB.AsQueryable()
|
||||
// .WhereIF(taskId != 0, s => s.Id == taskId)
|
||||
// .WhereIF(!string.IsNullOrEmpty(tagId), s => s.TagId == tagId)
|
||||
// .FirstAsync();
|
||||
// if (task is null)
|
||||
// return BadRequest();
|
||||
// var taskData = task.ChatAnalysis.Adapt<TaskInfoRes>();
|
||||
// if (taskData is null)
|
||||
// return BadRequest();
|
||||
// taskData.Status = task.LastEnum;
|
||||
// if (task.LastEnum != RedisChannelEnum.EndTask)
|
||||
// return BadRequest(taskData);
|
||||
// if (taskData != null && taskData.TimeBase != null)
|
||||
// taskData.TimeBase = MergeTimeBases(taskData.TimeBase);
|
||||
// return Ok(taskData);
|
||||
//}
|
||||
|
||||
|
||||
//[NonAction]
|
||||
//private static List<TimeBase> MergeTimeBases(IEnumerable<TimeBase> timeBases)
|
||||
//{
|
||||
// if (timeBases == null || timeBases.Count() == 0)
|
||||
// {
|
||||
// return new List<TimeBase>();
|
||||
// }
|
||||
// var mergedList = new List<TimeBase>();
|
||||
// // 初始化合并段
|
||||
// var current = timeBases.First();
|
||||
// current.Content = string.Empty;
|
||||
// foreach (var next in timeBases)
|
||||
// {
|
||||
// // 如果类型相同,则扩展时间段
|
||||
// if (current.TimeBaseType == next.TimeBaseType)
|
||||
// current.End = Math.Max(current.End, next.End);
|
||||
// else
|
||||
// {
|
||||
// // 类型不同,将当前时间段加入结果列表,并开始新时间段
|
||||
// mergedList.Add(current);
|
||||
// current = next;
|
||||
// current.Content = string.Empty;
|
||||
// }
|
||||
// }
|
||||
// // 添加最后的时间段
|
||||
// mergedList.Add(current);
|
||||
// return mergedList;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
using SqlSugar;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using UserCenter.Model.Enum;
|
||||
using VideoAnalysisCore.AICore.GPT.Dto;
|
||||
using VideoAnalysisCore.Model.Enum;
|
||||
|
||||
namespace Learn.VideoAnalysis.API.Controllers.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 视频列表项
|
||||
/// </summary>
|
||||
public class StructurePageContentAnalyzeItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 录播内容编号
|
||||
/// </summary>
|
||||
public long StructurePageContentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 素材ID
|
||||
/// </summary>
|
||||
public long MaterialId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 视频编码
|
||||
/// </summary>
|
||||
public string VideoCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 视频文件名称
|
||||
/// </summary>
|
||||
public string VideoName { get; set; }
|
||||
/// <summary>
|
||||
/// 内容类型
|
||||
/// </summary>
|
||||
public AttachmentsInfoType AttachmentsInfoType { get; set; }
|
||||
}
|
||||
public class NodePackageReq
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 录播结构目录节点编号
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "目录节点编号是必填项")]
|
||||
public long NodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 科目类型
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "科目类型是必填项")]
|
||||
public SubjectEnum SubjectType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 任务类型
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "任务类型是必填项")]
|
||||
public TaskTypeEnum TaskType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 视频列表
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "文件数量是必填项")]
|
||||
public List<StructurePageContentAnalyzeItem> AnalyzeItems { get; set; }
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 视频处理 请求
|
||||
/// </summary>
|
||||
public class NodeMonitoringReq
|
||||
{
|
||||
/// <summary>
|
||||
/// 媒体路径
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "文件节点ID是必填项")]
|
||||
public long NodeId { get; set; }
|
||||
/// <summary>
|
||||
/// 任务类型
|
||||
/// </summary>
|
||||
public TaskTypeEnum? Type { get; set; }
|
||||
/// <summary>
|
||||
/// 学科类型
|
||||
/// </summary>
|
||||
public SubjectEnum? Subject { get; set; }
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 视频处理 请求
|
||||
/// </summary>
|
||||
public class VideoAnalysisReq
|
||||
{
|
||||
/// <summary>
|
||||
/// 媒体路径
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "资源URL是必填项")]
|
||||
public string MediaUrl { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 资源名称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "资源名称是必要的")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// ApiKey
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "接口Token是必填项")]
|
||||
public string ApiToken { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 内容所属学科
|
||||
/// </summary>
|
||||
public SubjectEnum? Subject { get; set; }
|
||||
/// <summary>
|
||||
/// 任务类型
|
||||
/// </summary>
|
||||
public TaskTypeEnum? Type { get; set; }
|
||||
/// <summary>
|
||||
/// 自定义值 任务完成后附带通知
|
||||
/// </summary>
|
||||
public string Tag { get; set; } = string.Empty;
|
||||
/// <summary>
|
||||
/// 自定义Id可用于任务完成之后的查询
|
||||
/// </summary>
|
||||
public string? TagId { get; set; }
|
||||
/// <summary>
|
||||
///回调Api地址
|
||||
/// </summary>
|
||||
//[Required(ErrorMessage = "回调Api地址是必填项")]
|
||||
//[Url(ErrorMessage = "请输入有效的 URL")]
|
||||
//public string CallBackUrl { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
public class TextValue
|
||||
{
|
||||
public TextValue(float v)
|
||||
{
|
||||
var s = TimeSpan.FromSeconds((double)v);
|
||||
var td = new[] { s.Hours, s.Minutes, s.Seconds };
|
||||
Text = string.Join(':', td.Where(s => s > 0));
|
||||
Value = v;
|
||||
}
|
||||
public TextValue(string t, object v)
|
||||
{
|
||||
Text = t;
|
||||
Value = v;
|
||||
}
|
||||
public TextValue()
|
||||
{
|
||||
|
||||
}
|
||||
public string Text { get; set; }
|
||||
public object Value { get; set; }
|
||||
}
|
||||
public class TaskKnowInfo
|
||||
{
|
||||
/// <summary>
|
||||
///视频片段知识点 id
|
||||
/// </summary>
|
||||
public long Id { get; set; }
|
||||
/// <summary>
|
||||
/// 知识点
|
||||
/// </summary>
|
||||
public string KnowPoint { get; set; }
|
||||
/// <summary>
|
||||
/// 知识点ID
|
||||
/// </summary>
|
||||
public string KnowPointId { get; set; }
|
||||
|
||||
}
|
||||
public class TaskKnowBlock
|
||||
{
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 开始时间
|
||||
/// </summary>
|
||||
public float? StartTime { get; set; }
|
||||
/// <summary>
|
||||
/// 结束时间
|
||||
/// </summary>
|
||||
public float? EndTime { get; set; }
|
||||
/// <summary>
|
||||
/// 持续时间
|
||||
/// </summary>
|
||||
[SugarColumn(IsIgnore = true)]
|
||||
public float? KeepTime => (EndTime ?? 0) - StartTime ?? 0;
|
||||
/// <summary>
|
||||
/// 主题
|
||||
/// </summary>
|
||||
public string? Theme { get; set; }
|
||||
/// <summary>
|
||||
/// 内容总结
|
||||
/// </summary>
|
||||
public string? Content { get; set; }
|
||||
/// <summary>
|
||||
/// 知识点列表
|
||||
/// </summary>
|
||||
public TaskKnowInfo[] Know { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 视频片段知识点结果
|
||||
/// </summary>
|
||||
public class TaskKnowRes
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义Id [任务视频自定义id]
|
||||
/// <see cref="VideoTask.TagId"/>
|
||||
/// </summary>
|
||||
public string? TagId { get; set; }
|
||||
/// <summary>
|
||||
/// 任务当前执行状态
|
||||
/// </summary>
|
||||
public RedisChannelEnum Status { get; set; }
|
||||
/// <summary>
|
||||
/// 视频任务id
|
||||
/// </summary>
|
||||
public long VideoTaskId { get; set; }
|
||||
/// <summary>
|
||||
/// 视频知识快
|
||||
/// </summary>
|
||||
public TaskKnowBlock[] KnowBlockArr { get; set; }
|
||||
|
||||
}
|
||||
public class TaskInfoRes : TaskRes
|
||||
{
|
||||
public TaskInfoRes()
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 任务当前执行状态
|
||||
/// </summary>
|
||||
public RedisChannelEnum Status { get; set; }
|
||||
///// <summary>
|
||||
///// 时间轴状态枚举
|
||||
///// </summary>
|
||||
//public Dictionary<int, string> TimeTypeEnum =>
|
||||
// Enum.GetValues(typeof(TimeBaseTypeEnum))
|
||||
// .Cast<TimeBaseTypeEnum>()
|
||||
// .ToDictionary(x => (int)x, x => x.ToString());
|
||||
|
||||
///// <summary>
|
||||
///// 时间轴合计
|
||||
///// </summary>
|
||||
//public Dictionary<TimeBaseTypeEnum, TextValue>? TimeBaseTotal =>
|
||||
// TimeBase?.GroupBy(s => s.TimeBaseType??TimeBaseTypeEnum.教师讲授)?
|
||||
// .ToDictionary(s => s.Key, s => new TextValue(s.Sum(x => x.End - x.Start)));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
|
||||
using VideoAnalysisCore.Common;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Reflection;
|
||||
using MapsterMapper;
|
||||
using Mapster;
|
||||
using VideoAnalysisCore.AICore.SherpaOnnx;
|
||||
using UserCenter.Model.Enum;
|
||||
using VideoAnalysisCore.AICore.GPT.ChatGPT;
|
||||
using VideoAnalysisCore.AICore.GPT;
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using VideoAnalysisCore.Model.Enum;
|
||||
using FFmpeg.NET.Services;
|
||||
using Yitter.IdGenerator;
|
||||
using VideoAnalysisCore.AICore.GPT.Dto;
|
||||
using VideoAnalysisCore.Model;
|
||||
using Learn.VideoAnalysis.API.Controllers.Dto;
|
||||
|
||||
namespace Learn.VideoAnalysis.API.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// 蓝鲸字库接口
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Route("LJZK/[action]")]
|
||||
public class LJZK_Controller : ControllerBase
|
||||
{
|
||||
private readonly ILogger<LJZK_Controller> _logger;
|
||||
private readonly IMapper mp;
|
||||
private readonly Repository<NodeSubscription> nodesubscriptionDB;
|
||||
private readonly Repository<VideoTask> videoTaskDB;
|
||||
private readonly Repository<VideoKonwPoint> videoKonwPointDB;
|
||||
private readonly Repository<NodePackageInfo> nodePackageInfoDB;
|
||||
public LJZK_Controller(ILogger<LJZK_Controller> logger,
|
||||
IMapper mp, Repository<NodeSubscription> nodesubscriptionDB,
|
||||
Repository<VideoTask> videoTaskDB = null, Repository<VideoKonwPoint> videoKonwPointDB = null
|
||||
, Repository<NodePackageInfo> nodePackageInfoDB = null)
|
||||
{
|
||||
_logger = logger;
|
||||
this.mp = mp;
|
||||
this.nodesubscriptionDB = nodesubscriptionDB;
|
||||
this.videoTaskDB = videoTaskDB;
|
||||
this.videoKonwPointDB = videoKonwPointDB;
|
||||
this.nodePackageInfoDB = nodePackageInfoDB;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 蓝鲸智库_添加文件节点监控
|
||||
/// </summary>
|
||||
/// <param name="req">请求体</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost(Name = "NodeSubscription")]
|
||||
public async Task<IActionResult> NodeSubscription(NodeMonitoringReq req)
|
||||
{
|
||||
if (req is null || req.NodeId == 0)
|
||||
return BadRequest("无效的提交数据");
|
||||
if (nodesubscriptionDB.IsAny(s => s.NodeId == req.NodeId))
|
||||
return BadRequest("重复添加了节点监控任务" + req.NodeId);
|
||||
var res = await nodesubscriptionDB.InsertReturnEntityAsync(new NodeSubscription()
|
||||
{
|
||||
NodeId = req.NodeId,
|
||||
TaskType = req.Type ?? default,
|
||||
Subject = req.Subject ?? default,
|
||||
|
||||
});
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 蓝鲸智库_文件包订阅
|
||||
/// </summary>
|
||||
/// <param name="req">请求体</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost(Name = "NodePackage")]
|
||||
public async Task<IActionResult> NodePackage(NodePackageReq req)
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now} 文件包订阅请求 req=" + JsonSerializer.Serialize(req));
|
||||
if (req.AnalyzeItems is null || req.AnalyzeItems.Count() == 0)
|
||||
return BadRequest("无效视频列表数据");
|
||||
var videos = new List<VideoTask>(req.AnalyzeItems.Count);
|
||||
var nodePackages = new List<NodePackageInfo>(req.AnalyzeItems.Count);
|
||||
var videoIdArr = videoTaskDB.AsQueryable().Select(v => v.TagId).Distinct().ToArray();
|
||||
foreach (var s in req.AnalyzeItems)
|
||||
{
|
||||
var np = new NodePackageInfo()
|
||||
{
|
||||
VideoCode = s.VideoCode,
|
||||
AttachmentsInfoType = s.AttachmentsInfoType,
|
||||
MaterialId = s.MaterialId,
|
||||
StructurePageContentId = s.StructurePageContentId,
|
||||
VideoName = s.VideoName,
|
||||
NodeId = req.NodeId,
|
||||
TaskType = req.TaskType,
|
||||
SubjectType = req.SubjectType,
|
||||
};
|
||||
nodePackages.Add(np);
|
||||
if (videoIdArr.Contains(s.VideoCode))
|
||||
continue;
|
||||
videos.Add(new VideoTask()
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
ComeFrom = "127.0.0.1",
|
||||
ApiToken = "",
|
||||
Type = req.TaskType,
|
||||
Subject = req.SubjectType,
|
||||
TagId = s.VideoCode,
|
||||
MediaUrl = string.Empty,
|
||||
MediaName = s.VideoName
|
||||
});
|
||||
}
|
||||
await nodePackageInfoDB.InsertRangeAsync(nodePackages);
|
||||
await videoTaskDB.InsertRangeAsync(videos);
|
||||
if (videos is null || videos.Count == 0)
|
||||
return Ok();
|
||||
var ids = videos.Select(s => s.Id).ToArray();
|
||||
RedisExpand.JoinQueue(ids);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取任务类型
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet(Name = "TaskTypList")]
|
||||
public IActionResult TaskType()
|
||||
{
|
||||
Type type = typeof(TaskTypeEnum);
|
||||
return Ok(Enum.GetValues(type).Cast<object>()
|
||||
.Select(s => new { Text = s.ToString(), Value = (int)s }));
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取学科类型
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet(Name = "SubjectList")]
|
||||
public IActionResult Subject()
|
||||
{
|
||||
Type type = typeof(SubjectEnum);
|
||||
return Ok(Enum.GetValues(type).Cast<object>()
|
||||
.Select(s => new { Text = s.ToString(), Value = (int)s }));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取视频知识点片段<para>taskId/tagId二选一</para>
|
||||
/// </summary>
|
||||
/// <param name="taskId"></param>
|
||||
/// <param name="tagId">自定义id</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet(Name = "TaskKnowInfo")]
|
||||
public async Task<IActionResult> TaskKnowInfo(long taskId, string? tagId)
|
||||
{
|
||||
if (taskId == 0 && string.IsNullOrEmpty(tagId))
|
||||
return BadRequest();
|
||||
var task = await videoTaskDB.AsQueryable()
|
||||
.WhereIF(taskId != 0, s => s.Id == taskId)
|
||||
.WhereIF(!string.IsNullOrEmpty(tagId), s => s.TagId == tagId)
|
||||
.FirstAsync();
|
||||
if (task is null)
|
||||
return BadRequest("无效任务");
|
||||
|
||||
var konwArr = await videoKonwPointDB.AsQueryable()
|
||||
.Where(s => s.VideoTaskId == task.Id)
|
||||
.ToArrayAsync();
|
||||
if (konwArr is null || konwArr.Length == 0)
|
||||
return BadRequest("无效任务");
|
||||
return Ok(new TaskKnowRes()
|
||||
{
|
||||
TagId = task.TagId,
|
||||
Status = task.LastEnum,
|
||||
VideoTaskId = task.Id,
|
||||
KnowBlockArr = konwArr
|
||||
.GroupBy(s => s.StartTime)
|
||||
.Select(s => new TaskKnowBlock()
|
||||
{
|
||||
Id = s.First().Id,
|
||||
Content = s.First().Content,
|
||||
StartTime = s.First().StartTime,
|
||||
EndTime = s.First().EndTime,
|
||||
Theme = s.First().Theme,
|
||||
Know = s.Select(x => new TaskKnowInfo()
|
||||
{
|
||||
Id = x.Id,
|
||||
KnowPoint = x.KnowPoint,
|
||||
KnowPointId = x.KnowPointId
|
||||
}).ToArray()
|
||||
}).ToArray()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
||||
|
||||
WORKDIR /app
|
||||
EXPOSE 9040
|
||||
COPY . .
|
||||
#设置时间为中国上海 环境为开发环境
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
# 给我们要传的参数一个初始值
|
||||
ENV va_args=
|
||||
|
||||
|
||||
ENV ASPNETCORE_URLS=http://+:9040
|
||||
|
||||
ENTRYPOINT dotnet Learn.VideoAnalysis.API.dll $va_args
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
using Coravel;
|
||||
using Coravel.Scheduling.Schedule;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VideoAnalysisCore.Job;
|
||||
|
||||
namespace Learn.VideoAnalysis.API.Expand
|
||||
{
|
||||
public static class CoravelExpand
|
||||
{
|
||||
public static void AddCoravel(this IServiceCollection service)
|
||||
{
|
||||
|
||||
Console.WriteLine($"{DateTime.Now}=>初始化 Coravel");
|
||||
service.AddScheduler();
|
||||
service.AddTransient<NodeSubscriptionJob>();
|
||||
service.AddTransient<TaskFileClearJob>();
|
||||
service.AddTransient<NodePackageJob>();
|
||||
}
|
||||
public static void UseCoravelExpand(this IApplicationBuilder provider)
|
||||
{
|
||||
provider.ApplicationServices.UseScheduler(scheduler =>
|
||||
{
|
||||
//每5分钟执行一次 未处理视频扫描
|
||||
scheduler.Schedule<NodeSubscriptionJob>().EveryFiveMinutes();
|
||||
//文件包分析
|
||||
scheduler.Schedule<NodePackageJob>().EveryThirtyMinutes(); //每30分钟执行一次
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Dockerfile" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Dockerfile">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mapster.DependencyInjection" Version="1.0.2-pre01" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\VideoAnalysisCore\VideoAnalysisCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="AntDeploy.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="appsettings.Production.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
@Learn.VideoAnalysis.API_HostAddress = http://localhost:5245
|
||||
|
||||
GET {{Learn.VideoAnalysis.API_HostAddress}}/weatherforecast/
|
||||
Accept: application/json
|
||||
|
||||
###
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
|
||||
using Learn.VideoAnalysis.API.Expand;
|
||||
using Mapster;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
||||
using VideoAnalysisCore.Common;
|
||||
using VideoAnalysisCore.Common.Expand;
|
||||
|
||||
namespace Learn.VideoAnalysis.API
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen(c =>
|
||||
{
|
||||
var file = Path.Combine(AppContext.BaseDirectory, "Learn.VideoAnalysis.API.xml"); // xml文档绝对路径
|
||||
c.IncludeXmlComments(file, true); // true : 显示控制器层注释
|
||||
c.OrderActionsBy(o => o.RelativePath); // 对action的名称进行排序,如果有多个,就可以看见效果了。
|
||||
});
|
||||
|
||||
|
||||
builder.Services.AddMapster();
|
||||
|
||||
//初始化 插件
|
||||
builder.Configuration.AddAppConfig(args);
|
||||
|
||||
builder.Services.AddSqlSugarExpand();
|
||||
builder.Services.AddRedisExpand();
|
||||
builder.Services.AddCoravel();
|
||||
builder.Services.AddCorsExpand();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddControllersWithViews(options =>
|
||||
{
|
||||
options.Filters.Add(typeof(ExceptionFilter));
|
||||
});
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
AppCommon.Services = app.Services;
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
//自定义 应用
|
||||
app.UseCorsExpand();
|
||||
app.UseSqlSugarExpand();
|
||||
app.UseCoravelExpand();
|
||||
|
||||
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"http:5238": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "http://localhost:5238",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Error",
|
||||
"Microsoft.AspNetCore": "Error"
|
||||
}
|
||||
},
|
||||
"AppConfig": {
|
||||
"TaskSetting": {
|
||||
"DownloadSpeed": 8,
|
||||
"IS_Server": true //接收任务?
|
||||
},
|
||||
"Subsystem": {
|
||||
"蓝鲸智库": {
|
||||
"APIUrl": "https://zyapi.23544.com",
|
||||
"Token": ""
|
||||
}
|
||||
},
|
||||
"Redis": {
|
||||
"ConnectionString": "redis-external.23544.com:16379,password=poiuyt)(*&^%,defaultDatabase=3"
|
||||
},
|
||||
"FFmpeg": {
|
||||
" TimeSlice": 600
|
||||
},
|
||||
"DB": {
|
||||
//"ConnectionString": "AllowLoadLocalInfile=true;Server=10.255.255.3;Port=3306;Database=learn.videoanalysis;User ID=marking;Password=qwe123!@#;CharSet=utf8mb4;pooling=true;SslMode=None",
|
||||
"ConnectionString": "AllowLoadLocalInfile=true;Server=rm-2vc20nd3d11g0oh6g2o.rwlb.cn-chengdu.rds.aliyuncs.com;User ID=marking;Password=poiuytPOIUYT098765)(*&^%;Port=3306;Database=learn.videoanalysis;CharSet=utf8mb4;pooling=true;SslMode=None",
|
||||
"SqlType": "MySql",
|
||||
"UpdateTable": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Warning",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"AppConfig": {
|
||||
"ID": 1, //程序唯一值
|
||||
"TaskSetting": {
|
||||
"DownloadSpeed": 2,
|
||||
"IS_Server": true //接收任务
|
||||
},
|
||||
"Admin": {
|
||||
"Account": "admin",
|
||||
"Password": "q1w2e3!@#"
|
||||
},
|
||||
"Subsystem": {
|
||||
"蓝鲸智库": {
|
||||
"APIUrl": "http://192.168.2.117:6400",
|
||||
"Token": ""
|
||||
}
|
||||
},
|
||||
"Redis": {
|
||||
"ConnectionString": "127.0.0.1:6379,password=Woshiren123,defaultDatabase=10"
|
||||
},
|
||||
"Whisper": {
|
||||
"ModelName": "ggml-small.bin"
|
||||
},
|
||||
"FFmpeg": {
|
||||
" TimeSlice": 600
|
||||
},
|
||||
"ChatGpt": {
|
||||
"KIMI": {
|
||||
"Host": "https://api.moonshot.cn",
|
||||
"ApiKey": "sk-8BvvhESZIkgUbiaaJhglPxFa4o2X9H3xEv9lXELrWWwGxHWY"
|
||||
},
|
||||
"ChatGpt": {
|
||||
"Host": "https://api.g4f.icu/",
|
||||
//"Host": "https://api.oaibest.com/",
|
||||
"ApiKey": "sk-D15tBln31N7dI9Fi7lds7OySFv5tOEK7DMNsG5rY2E6DCr4s"
|
||||
},
|
||||
"DeepSeek": {
|
||||
"Host": "https://api.deepseek.com/chat/completions",
|
||||
"ApiKey": "sk-88d3d2bc3dae4d50854b2569b281cf76"
|
||||
},
|
||||
"aliyun": {
|
||||
"Host": "https://dashscope.aliyuncs.com/compatible-mode/",
|
||||
"ApiKey": "sk-1742c2bf7b9846ae835de598dc6c427b"
|
||||
}
|
||||
},
|
||||
"DB": {
|
||||
"ConnectionString": "AllowLoadLocalInfile=true;Server=192.168.2.9;User ID=root;Password=qwe123!@#;Port=3306;Database=learn.videoanalysis;CharSet=utf8mb4;pooling=true;SslMode=None",
|
||||
"SqlType": "MySql",
|
||||
"UpdateTable": false
|
||||
},
|
||||
"AlibabaCloudVod": {
|
||||
"AccessKeyId": "LTAI5tDC6p9h747B7FHbgwkH",
|
||||
"AccessKeySecret": "vRKgmbp1LB05LaGOjh3ZrZxbHSLYLF",
|
||||
"EndPoint": "vod.cn-shanghai.aliyuncs.com" //上传节点
|
||||
},
|
||||
"OtherDBArr": [
|
||||
{
|
||||
"ConfigId": 1001, //ResourceBank
|
||||
"ConnectionString": "Server=47.109.35.116;Database=ResourceBank;UID=live;Password=Woshiren^&*();MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;",
|
||||
"SqlType": "SqlServer"
|
||||
},
|
||||
{
|
||||
"ConfigId": 1002, //App.public.live
|
||||
"ConnectionString": "Server=47.109.35.116;Database=App.public.live;UID=live;Password=Woshiren^&*();MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;",
|
||||
"SqlType": "SqlServer"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Learn.VideoAnalysis", "Vide
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VideoAnalysisCore", "VideoAnalysisCore\VideoAnalysisCore.csproj", "{69F4243A-B22E-431B-8F0B-ECD8729B8665}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Learn.VideoAnalysis.API", "Learn.VideoAnalysis.API\Learn.VideoAnalysis.API.csproj", "{D31BA4AB-73FC-47B1-A10A-34FD5E921F4A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -21,6 +23,10 @@ Global
|
|||
{69F4243A-B22E-431B-8F0B-ECD8729B8665}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{69F4243A-B22E-431B-8F0B-ECD8729B8665}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{69F4243A-B22E-431B-8F0B-ECD8729B8665}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D31BA4AB-73FC-47B1-A10A-34FD5E921F4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D31BA4AB-73FC-47B1-A10A-34FD5E921F4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D31BA4AB-73FC-47B1-A10A-34FD5E921F4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D31BA4AB-73FC-47B1-A10A-34FD5E921F4A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"ServerList": [],
|
||||
"LinuxServerList": [
|
||||
{
|
||||
"UserName": "hy",
|
||||
"UserName": "heyang",
|
||||
"Pwd": "9718CB3C9A0760CA326767D677ADEC1C",
|
||||
"Host": "10.127.127.107",
|
||||
"NickName": "10楼刀片机",
|
||||
|
|
@ -117,11 +117,11 @@
|
|||
"DockerConfig": {
|
||||
"Prot": "9040",
|
||||
"AspNetCoreEnv": "",
|
||||
"LastEnvName": "阿里云_代理",
|
||||
"LastEnvName": "10楼刀片机",
|
||||
"RemoveDaysFromPublished": "10",
|
||||
"WorkDir": "/home/heyang/",
|
||||
"Volume": "/home/hy/VideoAnalysis/AICore:/app/AICore/_Static;/home/hy/VideoAnalysis/TaskCachedFile:/app/TaskCachedFile",
|
||||
"Other": "-e va_args=\"NoTask\" --name videoanalysis",
|
||||
"Other": "-e va_args=\"\"",
|
||||
"EnvPairList": [
|
||||
{
|
||||
"EnvName": "10楼刀片机",
|
||||
|
|
@ -130,7 +130,7 @@
|
|||
"DockerPort": "9040",
|
||||
"DockerEnvName": "",
|
||||
"DockerVolume": "/home/hy/VideoAnalysis/AICore:/app/AICore/_Static;/home/hy/VideoAnalysis/TaskCachedFile:/app/TaskCachedFile",
|
||||
"DockerOther": "-e va_args=\"NoTask1\""
|
||||
"DockerOther": "-e va_args=\"\""
|
||||
},
|
||||
{
|
||||
"EnvName": "阿里云_代理",
|
||||
|
|
@ -139,7 +139,7 @@
|
|||
"DockerPort": "9040",
|
||||
"DockerEnvName": "",
|
||||
"DockerVolume": "/home/hy/VideoAnalysis/AICore:/app/AICore/_Static;/home/hy/VideoAnalysis/TaskCachedFile:/app/TaskCachedFile",
|
||||
"DockerOther": "-e va_args=\"NoTask\" --name videoanalysis"
|
||||
"DockerOther": "-e va_args=\"IS_Server\" --name videoanalysis"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@namespace VideoAnalysisRazor.Layouts
|
||||
@using static AntDesign.IconType
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
<AntDesign.ProLayout.BasicLayout
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using UserCenter.Model.Enum;
|
|||
using VideoAnalysisCore.Common;
|
||||
using VideoAnalysisCore.Model.Enum;
|
||||
using VideoAnalysisCore.Model;
|
||||
using Learn.VideoAnalysis.API.Expand;
|
||||
|
||||
|
||||
namespace Learn.VideoAnalysis.Components.Pages
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using UserCenter.Model.Enum;
|
|||
using VideoAnalysisCore.Common;
|
||||
using VideoAnalysisCore.Model.Enum;
|
||||
using VideoAnalysisCore.Model;
|
||||
using Learn.VideoAnalysis.API.Expand;
|
||||
|
||||
|
||||
namespace Learn.VideoAnalysis.Components.Pages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using AntDesign;
|
||||
using AntDesign.TableModels;
|
||||
using FFmpeg.NET.Services;
|
||||
using Learn.VideoAnalysis.API.Expand;
|
||||
using Learn.VideoAnalysis.Controllers.Dto;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ using VideoAnalysisCore.Model.Enum;
|
|||
using VideoAnalysisCore.Model;
|
||||
using VideoAnalysisCore.Model.Dto;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Learn.VideoAnalysis.Components.Pages
|
||||
{
|
||||
|
|
@ -29,6 +30,7 @@ namespace Learn.VideoAnalysis.Components.Pages
|
|||
[Inject] private ConfirmService ComfirmService { get; set; } = default!;
|
||||
[Inject] private IHttpContextAccessor HttpContext { get; set; } = default!;
|
||||
[Inject] private Repository<VideoTask> taskDB { get; set; } = default!;
|
||||
[Inject] private Repository<VideoKonwPoint> videoKonwPointDB { get; set; } = default!;
|
||||
[Inject] private IJSRuntime JSRuntime { get; set; } = default!;
|
||||
|
||||
private VideoTask nowTask { get; set; } = default!;
|
||||
|
|
@ -57,7 +59,7 @@ namespace Learn.VideoAnalysis.Components.Pages
|
|||
}
|
||||
public string getF(VideoKnowRes segment)
|
||||
{
|
||||
var sf = ((int)((segment.StartTime ?? 0) / 60)).ToString().PadLeft(2,'0');
|
||||
var sf = ((int)((segment.StartTime ?? 0) / 60)).ToString().PadLeft(2, '0');
|
||||
var sm = ((int)((segment.StartTime ?? 0) % 60)).ToString().PadLeft(2, '0');
|
||||
return $"{sf}:{sm}";
|
||||
//var ef = ((int)((segment.EndTime ?? 0) / 60)).ToString().PadLeft(2, '0');
|
||||
|
|
@ -73,13 +75,27 @@ namespace Learn.VideoAnalysis.Components.Pages
|
|||
return;
|
||||
long taskId = this.taskId.Value;
|
||||
nowTask = await taskDB.GetFirstAsync(s => s.Id == taskId);
|
||||
if(nowTask is null)
|
||||
if (nowTask is null)
|
||||
return;
|
||||
captionsArr = RedisExpand.Redis.HMGet<SenseVoiceRes[]>(RedisExpandKey.Task(taskId), "Captions").FirstOrDefault();
|
||||
videoKnows = RedisExpand.Redis.HMGet<VideoKnowRes[]>(RedisExpandKey.Task(taskId), "VideoKnows").FirstOrDefault();
|
||||
videoPath = AppCommon.GetVideoPath(nowTask.Id.ToString());
|
||||
captionsArr = JsonSerializer.Deserialize<SenseVoiceRes[]>(nowTask.Captions);
|
||||
RedisExpand.Redis.HMGet<SenseVoiceRes[]>(RedisExpandKey.Task(taskId), "Captions").FirstOrDefault();
|
||||
|
||||
await JSRuntime.InvokeVoidAsync("setDB", captionsArr,videoKnows, videoPath);
|
||||
var konwArr = await videoKonwPointDB.AsQueryable()
|
||||
.Where(s => s.VideoTaskId == nowTask.Id)
|
||||
.ToArrayAsync();
|
||||
|
||||
videoKnows = konwArr
|
||||
.GroupBy(s => s.StartTime)
|
||||
.Select(s => new VideoKnowRes()
|
||||
{
|
||||
Content = s.First().Content,
|
||||
StartTime = s.First().StartTime,
|
||||
EndTime = s.First().EndTime,
|
||||
Theme = s.First().Theme,
|
||||
KnowPoint = string.Join(',', s.Select(x => x.KnowPoint))
|
||||
}).ToArray();
|
||||
videoPath = AppCommon.GetVideoPath(nowTask.Id.ToString());
|
||||
await JSRuntime.InvokeVoidAsync("setDB", captionsArr, videoKnows, videoPath);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
|
||||
FROM harbor.w.23544.com:8843/marking/learnvideo-net8.0:v0.1 AS base
|
||||
|
||||
|
||||
WORKDIR /app
|
||||
|
|
@ -9,14 +9,10 @@ COPY . .
|
|||
#设置时间为中国上海 环境为开发环境
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
# 更新 apt 源
|
||||
COPY sources.list /etc/apt/sources.list
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y ffmpeg
|
||||
|
||||
# 给我们要传的参数一个初始值
|
||||
ENV va_args=
|
||||
|
||||
|
||||
ENV ASPNETCORE_URLS=http://+:9040
|
||||
|
||||
ENTRYPOINT dotnet Learn.VideoAnalysis.dll $va_args
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Coravel;
|
||||
using Coravel.Scheduling.Schedule;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -12,7 +13,6 @@ namespace Learn.VideoAnalysis.Expand
|
|||
{
|
||||
public static class CoravelExpand
|
||||
{
|
||||
public static int MyProperty { get; set; }
|
||||
public static void AddCoravel(this IServiceCollection service)
|
||||
{
|
||||
|
||||
|
|
@ -22,15 +22,11 @@ namespace Learn.VideoAnalysis.Expand
|
|||
service.AddTransient<TaskFileClearJob>();
|
||||
service.AddTransient<NodePackageJob>();
|
||||
}
|
||||
public static void UseCoravelExpand(this IServiceProvider provider)
|
||||
public static void UseCoravelExpand(this IApplicationBuilder provider)
|
||||
{
|
||||
provider.UseScheduler(scheduler =>
|
||||
provider.ApplicationServices.UseScheduler(scheduler =>
|
||||
{
|
||||
//每5分钟执行一次 未处理视频扫描
|
||||
scheduler.Schedule<NodeSubscriptionJob>().EveryFiveMinutes();
|
||||
//文件包分析
|
||||
scheduler.Schedule<NodePackageJob>().EveryThirtyMinutes(); //每30分钟执行一次
|
||||
//任务缓存清理
|
||||
//任务缓存清理
|
||||
// scheduler.Schedule<TaskFileClearJob>().HourlyAt(10);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
using SqlSugar;
|
||||
using AntDesign;
|
||||
using AntDesign.TableModels;
|
||||
|
||||
namespace Learn.VideoAnalysis.API.Expand
|
||||
{
|
||||
public static class SearchExpand
|
||||
{
|
||||
|
||||
/// <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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,10 +32,11 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\VideoAnalysisCore\VideoAnalysisCore.csproj" />
|
||||
<PackageReference Include="AlibabaCloud.SDK.Vod20170321" Version="3.6.1" />
|
||||
<PackageReference Include="AntDesign.ProLayout" Version="0.20.3" />
|
||||
<PackageReference Include="Mapster.DependencyInjection" Version="1.0.2-pre01" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.5" />
|
||||
<PackageReference Include="AntDesign.Extensions.Localization" Version="0.20.2.1" />
|
||||
<PackageReference Include="AntDesign.Extensions.Localization" Version="0.20.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using VideoAnalysisCore.Common;
|
||||
using Learn.VideoAnalysis.Components;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using AntDesign.ProLayout;
|
||||
using VideoAnalysisCore.AICore.SherpaOnnx;
|
||||
using Mapster;
|
||||
using VideoAnalysisCore.AICore.GPT;
|
||||
|
|
@ -10,6 +9,7 @@ using VideoAnalysisCore.AICore.GPT.ChatGPT;
|
|||
using Microsoft.Extensions.FileProviders;
|
||||
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using VideoAnalysisCore.Common.Expand;
|
||||
using Learn.VideoAnalysis.Expand;
|
||||
|
||||
|
||||
|
|
@ -88,9 +88,6 @@ namespace Learn.VideoAnalysis
|
|||
builder.Services.AddMapster();
|
||||
builder.Services.AddCorsExpand();
|
||||
|
||||
|
||||
builder.Services.Configure<ProSettings>(builder.Configuration.GetSection("ProSettings"));
|
||||
|
||||
builder.Services.AddHttpClient();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
builder.Services.AddSingleton<ChatGPTClient>();
|
||||
|
|
@ -128,11 +125,11 @@ namespace Learn.VideoAnalysis
|
|||
|
||||
app.MapControllers();
|
||||
|
||||
app.UseCorsExpand();
|
||||
|
||||
//×Ô¶¨Òå Ó¦ÓÃ
|
||||
SqlSugarExpand.InitDB();
|
||||
app.Services.UseCoravelExpand();
|
||||
app.UseCorsExpand();
|
||||
app.UseSqlSugarExpand();
|
||||
app.UseCoravelExpand();
|
||||
|
||||
app.Run();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
"AppConfig": {
|
||||
"TaskSetting": {
|
||||
"DownloadSpeed": 8,
|
||||
"ProcessingTasks": true //接收任务?
|
||||
"IS_Server": false //接收任务?
|
||||
},
|
||||
"Subsystem": {
|
||||
"蓝鲸智库": {
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
}
|
||||
},
|
||||
"Redis": {
|
||||
"ConnectionString": "172.28.0.1,password=qwe123!@#,defaultDatabase=3"
|
||||
"ConnectionString": "redis-external.23544.com:16379,password=poiuyt)(*&^%,defaultDatabase=3"
|
||||
},
|
||||
"FFmpeg": {
|
||||
" TimeSlice": 600
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
"ID": 1, //程序唯一值
|
||||
"TaskSetting": {
|
||||
"DownloadSpeed": 2,
|
||||
"ProcessingTasks": true,//接收任务?
|
||||
"IS_Server": false //接收任务
|
||||
},
|
||||
"Admin": {
|
||||
"Account": "admin",
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ using Newtonsoft.Json.Linq;
|
|||
using System.Net.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Json;
|
||||
using AntDesign;
|
||||
using OneOf.Types;
|
||||
using System.Net;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ using Newtonsoft.Json.Linq;
|
|||
using System.Net.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Json;
|
||||
using AntDesign;
|
||||
using OneOf.Types;
|
||||
using System.Net;
|
||||
using VideoAnalysisCore.AICore.GPT.KIMI;
|
||||
using System.Threading;
|
||||
|
|
|
|||
|
|
@ -112,18 +112,6 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
VideoKnowRes[] questionRes;
|
||||
while (true)
|
||||
{
|
||||
// var postMessages =
|
||||
//$"你的任务是分析视频字幕内容并提取出中国高考考试试题方法点,然后分析出<知识块>,来帮助学生快速了解视频字幕的内容" +
|
||||
//$"通过阅读并理解字幕内容.然后识别出{subject}学科中属于{fileNameInfoRes.授课章节}章节相关的方法点以及对应的时间段。" +
|
||||
//$"关联合并知识内容相似的知识点来合并为<知识块>。" +
|
||||
//$"分配空余未使用的时间段到内容相近的<知识块>时间区间来获取更加详细的上下文,但是请避免<知识块>之间时间重合。" +
|
||||
//$"从提取出的<知识块>内容称来匹配我提供的知识点,来作为片段的知识点(请确保匹配的知识点是用户提供的,否则片段知识点值为空字符串)。" +
|
||||
//$"提供的方法点名称({knows})。 格式 (方法点Id|方法点名称) 如果一个<知识块>出现多个知识点那么知识点Id与知识点名称都用逗号','分割。" +
|
||||
//$"这是输入的视频字幕并且是包含时间戳的视频字幕的固定格式文本。" +
|
||||
////$"字幕格式(说话人:开始秒:结束秒:内容|下一段字幕).以下是包含时间的视频字幕文本。字幕列表 {captions.Captions}。" +
|
||||
//$"字幕格式(开始秒:结束秒:内容|下一段字幕).以下是包含时间的视频字幕文本。字幕列表 {captions.Captions}。" +
|
||||
//$"最后请检查某些<知识块>之间的过渡是否自然,如果<知识块>时长超过500秒则考虑拆封为两个更加贴切的<知识块>.或者<知识块>时长小于30秒则考虑合并<知识块>到相邻的<知识块>)。" +
|
||||
//$"输出内容只返回json格式({resFormat})";
|
||||
|
||||
var resFormat = """[{"StartTime":开始秒(number),"Theme":主题(string),"Content":内容总结(string)}]""";
|
||||
var postMessages =
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.Reflection;
|
||||
using FreeRedis;
|
||||
using VideoAnalysisCore.Model.Dto;
|
||||
using AntDesign;
|
||||
using SqlSugar.IOC;
|
||||
using VideoAnalysisCore.AICore.GPT.Dto;
|
||||
using VideoAnalysisCore.AICore.GPT;
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ using Newtonsoft.Json.Linq;
|
|||
using System.Net.Http;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Json;
|
||||
using AntDesign;
|
||||
using OneOf.Types;
|
||||
using System.Net;
|
||||
using Azure;
|
||||
using System.Reflection.PortableExecutable;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
using AntDesign;
|
||||
using AntDesign.TableModels;
|
||||
using FreeRedis;
|
||||
using FreeRedis;
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
using SqlSugar;
|
||||
using SqlSugar.IOC;
|
||||
|
|
@ -155,43 +153,6 @@ namespace VideoAnalysisCore.Common
|
|||
);
|
||||
}
|
||||
/// <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>
|
||||
|
|
|
|||
|
|
@ -68,9 +68,10 @@ namespace VideoAnalysisCore.Common
|
|||
/// </summary>
|
||||
public int DownloadSpeed { get; set; }
|
||||
/// <summary>
|
||||
/// 是否接收任务
|
||||
/// 是服务端
|
||||
/// <para>不执行任务,不回调接口</para>
|
||||
/// </summary>
|
||||
public bool ProcessingTasks { get; set; }
|
||||
public bool IS_Server { get; set; }
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using AntDesign;
|
||||
using Downloader;
|
||||
using Downloader;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using SqlSugar;
|
||||
using SqlSugar.IOC;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -20,23 +19,21 @@ namespace VideoAnalysisCore.Common
|
|||
|
||||
public async Task OnExceptionAsync(ExceptionContext context)
|
||||
{
|
||||
// 创建一个包含错误信息的对象
|
||||
var errorObject = new
|
||||
{
|
||||
// 创建一个包含错误信息的对象
|
||||
var errorObject = new
|
||||
{
|
||||
ErrorMessage = context.Exception.Message,
|
||||
StackTrace = context.Exception.StackTrace,
|
||||
};
|
||||
// 将错误对象序列化为JSON格式
|
||||
var json = JsonSerializer.Serialize(errorObject);
|
||||
ErrorMessage = context.Exception.Message,
|
||||
StackTrace = context.Exception.StackTrace,
|
||||
};
|
||||
// 将错误对象序列化为JSON格式
|
||||
var json = JsonSerializer.Serialize(errorObject);
|
||||
|
||||
// 设置响应内容类型为JSON
|
||||
context.HttpContext.Response.ContentType = "application/json";
|
||||
// 设置状态码
|
||||
context.HttpContext.Response.StatusCode = 500;
|
||||
// 将JSON数据写入响应体
|
||||
await context.HttpContext.Response.WriteAsync(json);
|
||||
}
|
||||
// 设置响应内容类型为JSON
|
||||
context.HttpContext.Response.ContentType = "application/json";
|
||||
// 设置状态码
|
||||
context.HttpContext.Response.StatusCode = 500;
|
||||
// 将JSON数据写入响应体
|
||||
await context.HttpContext.Response.WriteAsync(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
using Coravel;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using VideoAnalysisCore.Common;
|
||||
using VideoAnalysisCore.Job;
|
||||
|
||||
namespace Learn.VideoAnalysis.Expand
|
||||
namespace VideoAnalysisCore.Common.Expand
|
||||
{
|
||||
public static class AppConfigExpand
|
||||
{
|
||||
public static void AddAppConfig(this ConfigurationManager cm, string[] args)
|
||||
public static void AddAppConfig(this IConfigurationManager cm, string[] args)
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now}=>初始化 AppConfig");
|
||||
cm.GetSection("AppConfig").Bind(AppCommon.Config);
|
||||
var argList= args.ToList();
|
||||
var argList = args.ToList();
|
||||
var eArgs = Environment.GetEnvironmentVariable("va_args");
|
||||
if (!string.IsNullOrEmpty(eArgs))
|
||||
argList.AddRange(eArgs.Split(","));
|
||||
|
|
@ -21,8 +22,8 @@ namespace Learn.VideoAnalysis.Expand
|
|||
Console.WriteLine(string.Join(',', args));
|
||||
Console.WriteLine("===========================================");
|
||||
|
||||
if (args.Contains("NoTask"))
|
||||
AppCommon.Config.TaskSetting.ProcessingTasks = false;
|
||||
if (args.Contains("IS_Server"))
|
||||
AppCommon.Config.TaskSetting.IS_Server = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Learn.VideoAnalysis.Expand
|
||||
namespace VideoAnalysisCore.Common.Expand
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// 跨域
|
||||
/// </summary>
|
||||
public static class CorsExpand
|
||||
{
|
||||
|
|
@ -14,7 +14,7 @@ namespace Learn.VideoAnalysis.Expand
|
|||
/// <param name="services"></param>
|
||||
public static void AddCorsExpand(this IServiceCollection services)
|
||||
{
|
||||
services.AddCors(c =>
|
||||
CorsServiceCollectionExtensions.AddCors(services,c =>
|
||||
{
|
||||
c.AddPolicy("All", policy =>
|
||||
{
|
||||
|
|
@ -26,7 +26,7 @@ namespace Learn.VideoAnalysis.Expand
|
|||
/// 使用跨域
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
public static void UseCorsExpand(this WebApplication app)
|
||||
public static void UseCorsExpand(this IApplicationBuilder app)
|
||||
{
|
||||
app.UseCors("All");
|
||||
// 获取配置文件中的允许跨域的地址
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MySqlConnector;
|
||||
using SqlSugar;
|
||||
|
|
@ -13,7 +14,7 @@ using System.Xml.Linq;
|
|||
using VideoAnalysisCore.Common;
|
||||
using Yitter.IdGenerator;
|
||||
|
||||
namespace Learn.VideoAnalysis.Expand
|
||||
namespace VideoAnalysisCore.Common.Expand
|
||||
{
|
||||
public static class SqlSugarExpand
|
||||
{
|
||||
|
|
@ -21,7 +22,7 @@ namespace Learn.VideoAnalysis.Expand
|
|||
public static void AddSqlSugarExpand(this IServiceCollection services)
|
||||
{
|
||||
|
||||
services.AddHttpContextAccessor();
|
||||
HttpServiceCollectionExtensions.AddHttpContextAccessor(services);
|
||||
Console.WriteLine($"{DateTime.Now}=>初始化 YitId雪花ID");
|
||||
var options = new IdGeneratorOptions(ushort.Parse(AppCommon.Config.ID));
|
||||
YitIdHelper.SetIdGenerator(options);
|
||||
|
|
@ -102,7 +103,7 @@ namespace Learn.VideoAnalysis.Expand
|
|||
|
||||
#endregion
|
||||
}
|
||||
public static void InitDB()
|
||||
public static void UseSqlSugarExpand(this IApplicationBuilder app)
|
||||
{
|
||||
ShowSQL = false;
|
||||
var builder = new MySqlConnectionStringBuilder(AppCommon.Config.DB.ConnectionString);
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VideoAnalysisCore.Common.Expand
|
||||
{
|
||||
public static class StartUpExpand
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
using AntDesign;
|
||||
using FreeRedis;
|
||||
using FreeRedis;
|
||||
using FreeRedis.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json.Schema;
|
||||
|
|
@ -276,8 +275,11 @@ namespace VideoAnalysisCore.Common
|
|||
/// </summary>
|
||||
public static async Task ReceivingTaskAsync()
|
||||
{
|
||||
if (!AppCommon.Config.TaskSetting.ProcessingTasks)//是否接收任务
|
||||
if (AppCommon.Config.TaskSetting.IS_Server)
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now} =>服务端不接收任务");
|
||||
return;
|
||||
}
|
||||
var oldTask = await Redis.GetAsync(RedisExpandKey.IDTask);
|
||||
if (!string.IsNullOrEmpty(oldTask))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,11 +40,10 @@ namespace VideoAnalysisCore.Job
|
|||
}
|
||||
public async Task Invoke()
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now} Invoke=>文件包任务");
|
||||
|
||||
Console.WriteLine($"{DateTime.Now} 执行=>文件包任务");
|
||||
var taskArr = await nodePackageInfoDB.AsQueryable()
|
||||
.Where(s => s.SuccessTime == null)
|
||||
.ToArrayAsync();
|
||||
.Where(s => s.SuccessTime == null)
|
||||
.ToArrayAsync();
|
||||
var videoIdArr = await videoTaskDB.AsQueryable()
|
||||
.Where(s => s.EndTime != null)
|
||||
.Select(s => s.TagId)
|
||||
|
|
@ -58,7 +57,7 @@ namespace VideoAnalysisCore.Job
|
|||
item.SuccessTime = DateTime.Now;
|
||||
}
|
||||
}
|
||||
Console.WriteLine($"{DateTime.Now} Invoke=>文件包任务 已完成任务回调 数量{postData.Count}");
|
||||
Console.WriteLine($"{DateTime.Now} 执行=>文件包任务 已完成任务回调 数量{postData.Count}");
|
||||
if (postData.Count() == 0)
|
||||
return;
|
||||
var responseMessage = await new HttpClient()
|
||||
|
|
@ -66,7 +65,7 @@ namespace VideoAnalysisCore.Job
|
|||
if (responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
var res = await responseMessage.Content.ReadAsStringAsync();
|
||||
Console.WriteLine($"{DateTime.Now} Invoke=>文件包任务 回调结果 {res}");
|
||||
Console.WriteLine($"{DateTime.Now} 执行=>文件包任务 回调结果 {res}");
|
||||
|
||||
await nodePackageInfoDB.AsUpdateable(postData)
|
||||
.UpdateColumns(it => new { it.SuccessTime })
|
||||
|
|
@ -75,7 +74,7 @@ namespace VideoAnalysisCore.Job
|
|||
else
|
||||
{
|
||||
var res = await responseMessage.Content.ReadAsStringAsync();
|
||||
Console.WriteLine($"{DateTime.Now} Invoke=>文件包任务 回调失败!!! {responseMessage.StatusCode} {res}");
|
||||
Console.WriteLine($"{DateTime.Now} 执行=>文件包任务 回调失败!!! {responseMessage.StatusCode} {res}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ namespace VideoAnalysisCore.Job
|
|||
}
|
||||
public async Task Invoke()
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now} Invoke=>{this.GetType().FullName}");
|
||||
Console.WriteLine($"{DateTime.Now} 执行=>文件节点订阅");
|
||||
|
||||
|
||||
var videoIdArr = videotaskDB.AsQueryable().Select(v => v.TagId).Distinct().ToArray();
|
||||
var tasks = await nodesubscriptionDB.GetListAsync(s => s.Enable && s.Subject ==SubjectEnum.数学);
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace VideoAnalysisCore.Job
|
|||
}
|
||||
public async Task Invoke()
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now} Invoke=>{this.GetType().FullName}");
|
||||
Console.WriteLine($"{DateTime.Now} 执行=>{this.GetType().FullName}");
|
||||
|
||||
DeleteOldCompletedTaskCaches();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using AntDesign;
|
||||
using VideoAnalysisCore.AICore.GPT.Dto;
|
||||
using VideoAnalysisCore.AICore.GPT.Dto;
|
||||
using VideoAnalysisCore.Model.Enum;
|
||||
|
||||
namespace VideoAnalysisCore.Model.Dto
|
||||
|
|
|
|||
|
|
@ -9,19 +9,19 @@ namespace VideoAnalysisCore.Model.Enum
|
|||
{
|
||||
public enum AttachmentsInfoType
|
||||
{
|
||||
[Description("默认")]
|
||||
None = 0,
|
||||
[Description("常规课程")]
|
||||
RegularClasses = 1,
|
||||
None = 0,
|
||||
[Description("教研")]
|
||||
TeachingResearch = 2,
|
||||
TeachingResearch = 1,
|
||||
[Description("PPT")]
|
||||
PPT = 3,
|
||||
PPT = 2,
|
||||
[Description("复习")]
|
||||
Review = 4,
|
||||
Review = 3,
|
||||
[Description("活动")]
|
||||
Activities = 5,
|
||||
Activities = 4,
|
||||
[Description("班会")]
|
||||
Meeting = 6,
|
||||
Meeting = 5,
|
||||
[Description("行为分析")]
|
||||
Behavior = 6,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using AntDesign;
|
||||
using SqlSugar;
|
||||
using SqlSugar;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using AntDesign;
|
||||
using SqlSugar;
|
||||
using SqlSugar;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@
|
|||
<PackageReference Include="FreeRedis" Version="1.3.2" />
|
||||
<PackageReference Include="Downloader" Version="3.2.1" />
|
||||
<PackageReference Include="Mapster" Version="7.4.1-pre01" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cors" Version="2.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
|
|
@ -73,7 +75,6 @@
|
|||
<PackageReference Include="Whisper.net" Version="1.5.0" />
|
||||
<PackageReference Include="Whisper.net.Runtime" Version="1.5.0" />
|
||||
<PackageReference Include="xFFmpeg.NET" Version="6.0.0" />
|
||||
<PackageReference Include="AntDesign.ProLayout" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
Loading…
Reference in New Issue