Learn.VideoAnalysis/VideoAnalysisCore/Controllers/ApiController.cs

323 lines
11 KiB
C#

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 Microsoft.AspNetCore.Http;
using VideoAnalysisCore.Model.Dto;
using VideoAnalysisCore.Controllers.Dto;
using VideoAnalysisCore.Common.Expand;
namespace VideoAnalysisCore.Controllers
{
[ApiController]
[Route("[controller]/[action]")]
public class ApiController : ControllerBase
{
private readonly IMapper mp;
private readonly Repository<VideoTask> videoTaskDB;
private readonly Repository<VideoKonwPoint> videoKonwDB;
public ApiController(Repository<VideoTask> videoTaskDB,
IMapper mp, Repository<VideoKonwPoint> videoKonwDB)
{
this.videoTaskDB = videoTaskDB;
this.mp = mp;
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地址");
}
#if DEBUG
/// <summary>
/// 初始化主库表
/// </summary>
/// <param name="url">文件流</param>
/// <returns></returns>
[HttpGet(Name = "InitDbTable")]
public IActionResult InitDbTable()
{
var b = AppCommon.Config.DB.UpdateTable;
AppCommon.Config.DB.UpdateTable= true;
SqlSugarExpand.InitDbTable();
AppCommon.Config.DB.UpdateTable = b;
return Ok();
}
#endif
/// <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,
PPTVideoCode = req.PPTVideoCode,
VideoType=req.VideoType
};
//入库
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;
//}
}
}