230 lines
8.5 KiB
C#
230 lines
8.5 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;
|
|
|
|
namespace Learn.VideoAnalysis.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 IBserGPT chatGPT;
|
|
public ApiController(ILogger<ApiController> logger, Repository<VideoTask> videoTaskDB,
|
|
IMapper mp, IBserGPT chatGPT)
|
|
{
|
|
_logger = logger;
|
|
this.videoTaskDB = videoTaskDB;
|
|
this.mp = mp;
|
|
this.chatGPT = chatGPT;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
[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;
|
|
}
|
|
|
|
/// <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>
|
|
/// 获取视频信息<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);
|
|
}
|
|
|
|
/// <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()
|
|
{
|
|
ComeFrom = GetClientIpAddress(),
|
|
MediaUrl = req.MediaUrl,
|
|
ApiToken = req.ApiToken,
|
|
Type = req.Type,
|
|
Subject = req.Subject,
|
|
Tag = req.Tag,
|
|
TagId = req.TagId,
|
|
MediaName = req.Name
|
|
};
|
|
//入库
|
|
task.Id = await videoTaskDB.InsertReturnBigIdentityAsync(task);
|
|
var hashEntries = task.GetType()
|
|
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
|
.ToDictionary(s => s.Name, s => s.GetValue(task));
|
|
RedisExpand.Redis.HMSet(RedisExpandKey.Task(task.Id), hashEntries);
|
|
RedisExpand.Redis.LPush(RedisExpandKey.ChannelKey, task.Id);
|
|
return Ok(task.Id);
|
|
}
|
|
}
|
|
}
|