using VideoAnalysisCore.Common; using Learn.VideoAnalysis.Controllers.Dto; using Microsoft.AspNetCore.Mvc; using System.Reflection; using VideoAnalysisCore.Enum; using VideoAnalysisCore.Model; using VideoAnalysisCore.AICore.FFMPGE; using VideoAnalysisCore.Model.Dto; using VideoAnalysisCore.AICore.ChatGPT.Dto; using AntDesign; using System.Threading.Tasks; using FFmpeg.NET.Services; using MapsterMapper; using Mapster; using VideoAnalysisCore.AICore.SherpaOnnx; using System.Net; using System.Security.Policy; using System.IO; namespace Learn.VideoAnalysis.Controllers { [ApiController] [Route("[controller]/[action]")] public class ApiController : ControllerBase { private readonly ILogger _logger; private readonly IMapper mp; private readonly Repository videoTaskDB; public ApiController(ILogger logger, Repository videoTaskDB, IMapper mp) { _logger = logger; this.videoTaskDB = videoTaskDB; this.mp = mp; } 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地址"); } /// /// 语音识别 /// /// 文件流 /// [HttpGet(Name = "AudioRecognitionUrl")] public async Task 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); } } /// /// 语音识别 /// /// 文件流 /// [HttpPost(Name = "AudioRecognition")] public async Task AudioRecognition(IFormFile file) { using var s = file.OpenReadStream(); var res = await SenseVoice.RunTask(s); return Ok(res); } [NonAction] private static List MergeTimeBases(IEnumerable timeBases) { if (timeBases == null || timeBases.Count() == 0) { return new List(); } var mergedList = new List(); // 初始化合并段 var current = timeBases.First(); foreach (var next in timeBases) { // 如果类型相同,则扩展时间段 if (current.TimeBaseType == next.TimeBaseType) { current.End = Math.Max(current.End, next.End); } else { // 类型不同,将当前时间段加入结果列表,并开始新时间段 current.Content = string.Empty; mergedList.Add(current); current = next; } } // 添加最后的时间段 mergedList.Add(current); return mergedList; } /// /// 获取视频信息taskId/tagId二选一 /// /// /// 自定义id /// 是否附加字幕 /// [HttpGet(Name = "TaskInfo")] public async Task TaskInfo(long taskId,string? tagId,bool needSubtitle=false) { 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(); if (taskData is null) return BadRequest(); taskData.Status = task.LastEnum; if (task.LastEnum != RedisChannelEnum.EndTask) return BadRequest(taskData); if (!needSubtitle && taskData != null && taskData.TimeBase != null) taskData.TimeBase = MergeTimeBases(taskData.TimeBase); return Ok(taskData); } /// /// 插入队列 /// /// /// /// [HttpPost(Name = "TestInsertChannel")] public IActionResult TestInsertChannel(int @enum=1, string msg= "1") { RedisExpand.InsertChannel(@enum.ToEnum().Value , msg); return Ok(); } /// /// 视频处理 /// /// 请求体 /// [HttpPost(Name = "VideoAnalysis")] public async Task VideoAnalysis(VideoAnalysisReq req) { if (!ModelState.IsValid) return BadRequest(ModelState); // 自动映射属性到哈希 var task = new VideoTask() { ComeFrom = GetClientIpAddress(), MediaUrl = req.MediaUrl, ApiToken = req.ApiToken, Tag = req.Tag, TagId = req.TagId, }; //入库 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); } } }