Compare commits
4 Commits
f8a758ff40
...
53951aa870
| Author | SHA1 | Date |
|---|---|---|
|
|
53951aa870 | |
|
|
d948f854fb | |
|
|
eed63794b8 | |
|
|
43a59dd593 |
|
|
@ -18,7 +18,9 @@ namespace Learn.VideoAnalysis.Expand
|
|||
|
||||
Console.WriteLine($"{DateTime.Now}=>初始化 Coravel");
|
||||
service.AddScheduler();
|
||||
#if !DEBUG
|
||||
service.AddTransient<TaskFileClearJob>();
|
||||
#endif
|
||||
service.AddTransient<NodePackageJob>();
|
||||
}
|
||||
public static void UseCoravelExpand(this IApplicationBuilder provider)
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ namespace Learn.VideoAnalysis
|
|||
AppCommon.Services = app.Services;
|
||||
app.UseMiddleware<BasicAuthMiddleware>("Swagger");
|
||||
// Configure the HTTP request pipeline.
|
||||
//¿ªÆôredis¶ÓÁзþÎñ
|
||||
_ = app.Services.GetRequiredService<RedisInit>();
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ export default {
|
|||
component: () => import("@/views/welcome/runningTask.vue"),
|
||||
meta: {
|
||||
title: "进行中任务",
|
||||
showLink: true
|
||||
showLink: true,
|
||||
keepAlive:true,
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -36,7 +37,8 @@ export default {
|
|||
component: () => import("@/views/welcome/showTask.vue"),
|
||||
meta: {
|
||||
title: "预览任务",
|
||||
showLink: false
|
||||
showLink: false,
|
||||
keepAlive:true,
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -45,7 +47,8 @@ export default {
|
|||
component: () => import("@/views/welcome/errorTask.vue"),
|
||||
meta: {
|
||||
title: "错误任务",
|
||||
showLink: true
|
||||
showLink: true,
|
||||
keepAlive:true,
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ function previewTask(row: any) {
|
|||
meta: {
|
||||
title: `任务预览` + row.id.toString().slice(-4),
|
||||
dynamicLevel: 3,
|
||||
keepAlive: true,
|
||||
},
|
||||
});
|
||||
// 路由跳转
|
||||
|
|
|
|||
|
|
@ -155,9 +155,13 @@ function timeupdateVideo() {
|
|||
let subtitleI = subtitles.value.findIndex(
|
||||
(subtitle) => currentTime >= subtitle.start && currentTime <= subtitle.end
|
||||
);
|
||||
// 更新字幕 AI优化字幕
|
||||
let subtitleI1 = subtitles1.value.findLastIndex(
|
||||
(subtitle) => currentTime >= subtitle.start
|
||||
);
|
||||
if (subtitleI > -1 && currentSubtitle.value !== subtitles.value[subtitleI].text) {
|
||||
currentSubtitle.value = subtitles.value[subtitleI].text;
|
||||
currentSubtitle1.value = subtitles1.value[subtitleI]?.text || "";
|
||||
currentSubtitle1.value = subtitles1.value[subtitleI1]?.text || "";
|
||||
} else if (subtitleI == -1) {
|
||||
currentSubtitle.value = "";
|
||||
currentSubtitle1.value = "";
|
||||
|
|
|
|||
|
|
@ -62,12 +62,6 @@ namespace VideoAnalysisCore.AICore.GPT
|
|||
public float? max_tokens { get; set; } = 8000;
|
||||
public float? max_completion_tokens { get; set; } = 8000;
|
||||
/// <summary>
|
||||
/// 要使用的采样温度,介于 0 和 2 之间。较高的值(如 0.8)将使输出更加随机,而较低的值(如 0.2)将使其更加集中和确定。 我们通常建议更改此项或同时更改两者。top_p
|
||||
/// <para> 默认为 1</para>
|
||||
/// <para> <see cref="ChatRequest.top_p"/>联动</para>
|
||||
/// </summary>
|
||||
public float? temperature { get; set; } = 0.2f;
|
||||
/// <summary>
|
||||
/// 一种替代温度采样的方法,称为原子核采样, 其中,模型考虑具有top_p概率的标记的结果 质量。所以 0.1 表示仅包含前 10% 概率质量的代币 被考
|
||||
/// <para>建议与<see cref="ChatRequest.temperature"/>联动</para>
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
|||
title = title,
|
||||
max_tokens = max_tokens,
|
||||
stream = true,
|
||||
temperature = 0.2f,
|
||||
messages = messageArr
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
|||
model = model ?? ChatGPTType.Deepseek_Chat,
|
||||
max_tokens = model == ChatGPTType.Deepseek_Reasoner ? 32000 : max_tokens,
|
||||
stream = true,
|
||||
temperature = 0.2f,
|
||||
messages = messageArr
|
||||
};
|
||||
return await base.ChatAsync<T>(chatReq);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -34,9 +34,10 @@ namespace VideoAnalysisCore.AICore.GPT.Dto
|
|||
}
|
||||
public class VideoKnowPointDto
|
||||
{
|
||||
public float KnowPointWeight { get; set; }
|
||||
public string KnowPoint { get; set; }
|
||||
public string KnowPointId { get; set; }
|
||||
public float KnowSourceTime { get; set; }
|
||||
public float KnowPointWeight { get; set; }
|
||||
public string KnowSource { get; set; }
|
||||
}
|
||||
public class VideoKnowRes
|
||||
|
|
@ -65,10 +66,6 @@ namespace VideoAnalysisCore.AICore.GPT.Dto
|
|||
/// </summary>
|
||||
public virtual string? KnowPoint { get; set; }
|
||||
/// <summary>
|
||||
/// 知识点权重
|
||||
/// </summary>
|
||||
public virtual float? KnowPointWeight { get; set; }
|
||||
/// <summary>
|
||||
/// 知识点ID
|
||||
/// </summary>
|
||||
public virtual string? KnowPointId { get; set; }
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
/// <summary>
|
||||
/// 视频分析工作流1
|
||||
/// </summary>
|
||||
public class GTP_Analysis_1 : IBserGPTWorkflow
|
||||
public class GTP_Analysis_1 : IBserGPTWorkflow
|
||||
{
|
||||
private readonly GeminiGPTClient geminiClient;
|
||||
private readonly DeepSeekGPTClient deepSeekClient;
|
||||
|
|
@ -187,7 +187,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
$"字幕列表 {rCaptionArr}。" +
|
||||
$"输出格式 json字符串 对象格式{fileNameResFormat}";
|
||||
var task = taskInfo.Id.ToString();
|
||||
var fileNameInfoRes = await chatGPTClient.ChatAsync<FileNameInfo>
|
||||
var fileNameInfoRes = await geminiClient.ChatAsync<FileNameInfo>
|
||||
(task, fileNamePostMessages, "授课章节");
|
||||
taskInfo.Sections = fileNameInfoRes.授课章节;
|
||||
await videoTaskDB.AsUpdateable()
|
||||
|
|
@ -309,7 +309,7 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
await Parallel.ForAsync(0, totalCount,
|
||||
new ParallelOptions()
|
||||
#if DEBUG
|
||||
{ MaxDegreeOfParallelism = 1 },
|
||||
{ MaxDegreeOfParallelism = 4 },
|
||||
#else
|
||||
{ MaxDegreeOfParallelism = 9 },
|
||||
#endif
|
||||
|
|
@ -326,25 +326,23 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
var postMessages =
|
||||
$$"""
|
||||
# Role
|
||||
你是一位{{subject}}学科的教育专家与资深校对。你的任务是将{{sections}}内容的原始语音识别(STT)JSON 数据清洗为高质量教学文本。
|
||||
你是一位{{subject}}学科的教育专家,有着资深字幕校对经验。你的任务是将{{sections}}内容的原始语音识别(STT)JSON 数据清洗为高质量教学文本。
|
||||
# Input & Output Protocol
|
||||
输入和输出均为严格的 JSON 数组格式:`[{"t": number, "r": string}]`。
|
||||
* `t` (Time): 绝对锚点,代表时间戳。严禁修改、严禁排序、严禁删除。
|
||||
* `r` (Result): 字幕内容,仅对此字段进行清洗。
|
||||
# Processing Rules (按优先级执行)
|
||||
`t` (Time): 绝对锚点,代表时间戳。严禁修改、严禁排序、严禁删除。
|
||||
`r` (Result): 字幕内容,仅对此字段进行清洗。
|
||||
Processing Rules (按优先级执行)
|
||||
1. 结构铁律 (最高优先级):
|
||||
长度一致:输入 N 条,输出必须 N 条。
|
||||
时间锁定:输出的第 i 条 `t` 必须等于输入的第 i 条 `t`。
|
||||
原地修正:禁止跨行移动文本。即使一句话被切分在两行,也不要合并它们,只需分别修正各自行的错别字即可。
|
||||
|
||||
2. 上下文关联修正 (核心任务):
|
||||
2. 内容清洗标准:
|
||||
口语过滤:删除“那个、然后、嗯、啊、就是”等无意义填充词。若该行被清空,`r` 设为 `""`,保留对象。
|
||||
LaTeX 格式化:数学/科学公式必须转换为 LaTeX (如 `$\\frac{a}{b}$`),JSON 中反斜杠需双重转义 (`\\\\`)。
|
||||
3. 上下文关联修正 (核心任务):
|
||||
全局理解,局部修正:请阅读前后多行内容来确定当前行特定词汇的含义,解决同音错别字。
|
||||
案例:如果上一行是“求函数的”,当前行是“集值”,结合数学上下文应修正为“极值”。
|
||||
逻辑:修正依据是“上下文语义”,但修正范围仅限“当前行文本”。
|
||||
|
||||
3. 内容清洗标准:
|
||||
口语过滤:删除“那个、然后、嗯、啊、就是”等无意义填充词。若该行被清空,`r` 设为 `""`,保留对象。
|
||||
LaTeX 格式化:数学/科学公式必须转换为 LaTeX (如 `$\\frac{a}{b}$`),JSON 中反斜杠需双重转义 (`\\\\`)。
|
||||
# Task Data
|
||||
待处理数据 (共 {{cStrArr.Count()}} 条):
|
||||
{{nowCaptionStr}}
|
||||
|
|
@ -436,7 +434,13 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 作业内容检查
|
||||
/// </summary>
|
||||
/// <param name="taskInfo"></param>
|
||||
/// <param name="captions"></param>
|
||||
/// <param name="sections"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<VideoKnowRes?> DetectHomeworkAssignment(VideoTask taskInfo, TotalCaptionsDto captions, string sections)
|
||||
{
|
||||
if (captions is null || string.IsNullOrWhiteSpace(captions.Captions))
|
||||
|
|
@ -721,6 +725,8 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
throw new Exception("未能找到对应知识点=>" + sections);
|
||||
List<KnowledgeInfo>? knowledgeInfos = new List<KnowledgeInfo>();
|
||||
var kInfo = await knowledgeInfoDB.GetByIdAsync(know.Parent_Id);
|
||||
if (know.Parent_Id == 0)
|
||||
kInfo = know;
|
||||
try
|
||||
{
|
||||
knowledgeInfos = await knowledgeInfoDB.AsQueryable()
|
||||
|
|
@ -796,6 +802,10 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
Stage = s.First().Stage,
|
||||
Theme = s.First().Theme,
|
||||
VideoTaskId = taskInfo.Id,
|
||||
CourseLevel = taskInfo.CourseLevel,
|
||||
TextBookVersionId = taskInfo.TextBookVersionId,
|
||||
GradeSemester= taskInfo.GradeSemester,
|
||||
GradeId = taskInfo.GradeId,
|
||||
}).ToList();
|
||||
//尝试追加 作业布置分段
|
||||
if (homework != null && (!questionRes.Any(s => s.Stage == StageEnum.作业布置.ToString())))
|
||||
|
|
@ -846,6 +856,8 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
|||
if (know is null)
|
||||
throw new Exception("未能找到对应知识点=>" + sections);
|
||||
var kInfo = await knowledgeInfoDB.GetByIdAsync(know.Parent_Id);
|
||||
if (know.Parent_Id == 0)
|
||||
kInfo = know;
|
||||
var knowledgeInfos = await knowledgeInfoDB.AsQueryable()
|
||||
.ToChildListAsync(s => s.Parent_Id, kInfo.Parent_Id == 0 ? kInfo.Id : kInfo.Parent_Id);
|
||||
//开始分析复习课 试题
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ namespace VideoAnalysisCore.AICore.GPT.ChatGPT
|
|||
model = model,
|
||||
max_tokens = max_tokens,
|
||||
stream = true,
|
||||
temperature = 0.2f,
|
||||
messages = messageArr,
|
||||
max_completion_tokens= 12288,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using System.Text;
|
|||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using UserCenter.Model.Enum;
|
||||
using VideoAnalysisCore.Common;
|
||||
using VideoAnalysisCore.Model;
|
||||
using VideoAnalysisCore.Model.Enum;
|
||||
|
|
@ -49,7 +50,7 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx
|
|||
/// </summary>
|
||||
/// <param name="numThreads">默认6线程</param>
|
||||
/// <param name="useGPU">是否使用gpu 报错请看安装CUDA环境 <see cref="https://k2-fsa.github.io/sherpa/onnx/pretrained_models/whisper/large-v3.html#run-with-gpu-float32"/></param>
|
||||
public void Init(int numThreads = 6, bool useGPU = false, bool useHotwords = false)
|
||||
public void Init(SubjectEnum? subject = null, int numThreads = 10, bool useGPU = false, bool useHotwords = false)
|
||||
{
|
||||
Console.WriteLine("初始化 FunASRNano");
|
||||
OfflineRecognizerConfig config = new OfflineRecognizerConfig();
|
||||
|
|
@ -63,17 +64,23 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx
|
|||
//将非结构化数据(文本、图像、音频等)转换为低维稠密向量
|
||||
config.ModelConfig.FunAsrNano.EncoderAdaptor = Path.Combine(topFolder, "encoder_adaptor.int8.onnx");
|
||||
//接入的大语言模型
|
||||
config.ModelConfig.FunAsrNano.LLM = Path.Combine(topFolder, "llm.fp16.onnx");
|
||||
//config.ModelConfig.FunAsrNano.LLM = Path.Combine(topFolder ,"llm.fp16.onnx");
|
||||
config.ModelConfig.FunAsrNano.LLM = Path.Combine(topFolder, "int8-2025-12-30", "llm.int8.onnx");
|
||||
//插入预训练模型(如Transformer)的小型可训练模块 (如语音识别、情感分析)
|
||||
config.ModelConfig.FunAsrNano.Embedding = Path.Combine(topFolder, "embedding.int8.onnx");
|
||||
//分词器
|
||||
config.ModelConfig.FunAsrNano.Tokenizer = Path.Combine(topFolder, "Qwen3-0.6B");
|
||||
//提示词
|
||||
config.ModelConfig.FunAsrNano.SystemPrompt = "You are a professional video audio transcription assistant.";
|
||||
config.ModelConfig.FunAsrNano.UserPrompt = "这是一堂中国的课堂视频音频,请你帮我分析出它讲述的内容!";
|
||||
//加上学科为空的处理
|
||||
if (subject != null)
|
||||
config.ModelConfig.FunAsrNano.UserPrompt = $"这是一堂中国{subject}的课堂视频音频,请你帮我分析出它讲述的内容!";
|
||||
else
|
||||
config.ModelConfig.FunAsrNano.UserPrompt = "这是一堂中国课堂的视频音频,请你帮我分析出它讲述的内容!";
|
||||
config.ModelConfig.FunAsrNano.MaxNewTokens = 512;
|
||||
config.ModelConfig.FunAsrNano.Temperature = 1E-06f;
|
||||
config.ModelConfig.FunAsrNano.TopP = 0.8f;
|
||||
config.ModelConfig.FunAsrNano.TopP = 0.7f;
|
||||
//种子
|
||||
config.ModelConfig.FunAsrNano.Seed = 42;
|
||||
|
||||
//模型类型
|
||||
|
|
@ -81,10 +88,10 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx
|
|||
config.ModelConfig.NumThreads = numThreads;
|
||||
config.ModelConfig.Provider = "cpu";
|
||||
//需要使用GPU
|
||||
if (!useGPU)
|
||||
if (useGPU)
|
||||
config.ModelConfig.Provider = "cuda";
|
||||
#if DEBUG
|
||||
config.ModelConfig.Debug = 1;
|
||||
//config.ModelConfig.Debug = 1;
|
||||
#endif
|
||||
OR = new OfflineRecognizer(config);
|
||||
}
|
||||
|
|
@ -106,15 +113,17 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx
|
|||
/// </summary>
|
||||
/// <param name="task"></param>
|
||||
/// <returns></returns>
|
||||
public Task RunTask(string task)
|
||||
public Task RunTask(string task)
|
||||
{
|
||||
var taskInfo = serviceProvider.GetRequiredService<Repository<VideoTask>>().GetById(task);
|
||||
if(taskInfo is null)
|
||||
throw new Exception("task 未找到");
|
||||
var filePath = Path.Combine(task.LocalPath(), "task.wav");
|
||||
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath))
|
||||
throw new Exception("task 音频路径未找到");
|
||||
if (OR is null) Init();
|
||||
if (OR is null) Init(taskInfo.Subject);
|
||||
serviceProvider.GetRequiredService<SherpaVad>()
|
||||
.TaskHandle(new WaveReader(filePath), null, SoundHandle, SherpaVadVersion.ten_vad_324);
|
||||
|
||||
.TaskHandle(new WaveReader(filePath), task, SoundHandle, SherpaVadVersion.ten_vad_324);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx
|
|||
VADModelConfig.SileroVad = new SileroVadModelConfig();
|
||||
VADModelConfig.SileroVad.Model = path;
|
||||
//(阈值 / 灵敏度) 含义:判定为“语音”的置信度。取值范围通常在 0 到 1 之间。
|
||||
VADModelConfig.SileroVad.Threshold = 0.3f;
|
||||
VADModelConfig.SileroVad.Threshold = 0.25f;
|
||||
//(最小静音长度)秒。 含义:“要沉默多久,我才认为这句话说完了?”
|
||||
VADModelConfig.SileroVad.MinSilenceDuration = 0.2f;
|
||||
// (最小语音长度)秒 含义:“这段声音至少要多长,我才认为它是有效的说话?”
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ namespace VideoAnalysisCore.Common
|
|||
}
|
||||
}
|
||||
var sp = spList.Distinct().ToList();
|
||||
if (sp.Count > 0)
|
||||
if (sp.Count > 0 && !string.IsNullOrWhiteSpace(segment.Text))
|
||||
results.Add(segment, sp);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,12 +110,14 @@ namespace VideoAnalysisCore.Common
|
|||
|
||||
public FFMPGEHandle FFMPGE { get; set; }
|
||||
public SenseVoice senseVoice { get; set; }
|
||||
public FunASRNano funASRNano { get; set; }
|
||||
public RedisManager redisManager { get; set; }
|
||||
|
||||
public RedisInit(FFMPGEHandle fFMPGE, SenseVoice senseVoice, RedisManager redisManager)
|
||||
public RedisInit(FFMPGEHandle fFMPGE, SenseVoice senseVoice, RedisManager redisManager, FunASRNano funASRNano)
|
||||
{
|
||||
FFMPGE = fFMPGE;
|
||||
this.senseVoice = senseVoice;
|
||||
this.funASRNano = funASRNano;
|
||||
this.redisManager = redisManager;
|
||||
Init();
|
||||
redisManager.InitChannel();
|
||||
|
|
@ -138,6 +140,7 @@ namespace VideoAnalysisCore.Common
|
|||
});
|
||||
SubscribeList.Add(RedisChannelEnum.分离音频, FFMPGE.RunAsync);
|
||||
SubscribeList.Add(RedisChannelEnum.解析字幕, senseVoice.RunTask);
|
||||
//SubscribeList.Add(RedisChannelEnum.解析字幕, funASRNano.RunTask);
|
||||
//SubscribeList.Add(RedisChannelEnum.解析说话人,Speaker.Run);
|
||||
SubscribeList.Add(RedisChannelEnum.AI课程类型, async (task) =>
|
||||
{
|
||||
|
|
@ -430,15 +433,20 @@ namespace VideoAnalysisCore.Common
|
|||
var oldTaskCount = Redis.LLen(RedisExpandKey.IDTask);
|
||||
//重试任务并发过多可能会导致程序崩溃
|
||||
// 未能重新分析的中断任务 则单独开一个网页来处理
|
||||
if (oldTaskCount > 0 )
|
||||
if (oldTaskCount > 0)
|
||||
{
|
||||
var oldTaskArr = Redis.LRange(RedisExpandKey.IDTask, 0, oldTaskCount);
|
||||
//不自动清理未完成任务 等待执行完毕/失败后自动清理
|
||||
//Redis.LTrim(RedisExpandKey.IDTask, 1, 0);//删除 redis 列表
|
||||
//最多执行5个上次中断/或者未完成的任务
|
||||
foreach (var oldTask in oldTaskArr.Take(5))
|
||||
//获取所有未完成的任务
|
||||
var oldTaskArr = Redis.LRange(RedisExpandKey.IDTask, 0, -1);
|
||||
Console.WriteLine($"{DateTime.Now:HH:mm:ss}-------------> 发现 {oldTaskArr.Length} 个未完成任务,准备恢复...");
|
||||
|
||||
//使用信号量限制并发数(5),防止崩溃
|
||||
using var semaphore = new System.Threading.SemaphoreSlim(5);
|
||||
var retryTaskArr = new List<Task>();
|
||||
|
||||
foreach (var oldTask in oldTaskArr)
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
await semaphore.WaitAsync();
|
||||
var res = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -450,10 +458,21 @@ namespace VideoAnalysisCore.Common
|
|||
catch (Exception ex)
|
||||
{
|
||||
await SetTaskErrorMessage(long.Parse(oldTask), ex);
|
||||
throw;
|
||||
Console.WriteLine($"恢复任务 {oldTask} 失败: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
});
|
||||
retryTaskArr.Add(res);
|
||||
}
|
||||
//等待所有 重试任务完成后接收新任务
|
||||
await Task.WhenAll(retryTaskArr);
|
||||
|
||||
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + "-------------> 所有未完成任务处理完毕!");
|
||||
ReceivingTaskAsync();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -128,11 +128,23 @@ namespace VideoAnalysisCore.Controllers.Dto
|
|||
/// 用户中心的云校id
|
||||
/// </summary>
|
||||
public long? UserCenterCloudSchoolId { get; set; }
|
||||
/// <summary>
|
||||
/// 教材层次
|
||||
/// </summary>
|
||||
public CourselevelTypeEnum? CourseLevel { get; set; }
|
||||
/// <summary>
|
||||
/// 年级
|
||||
/// </summary>
|
||||
public GradeEnum? GradeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 教育阶段
|
||||
/// </summary>
|
||||
public EducationStageEnum StageId { get; set; }
|
||||
/// <summary>
|
||||
/// 年级册(上册/下册)
|
||||
/// </summary>
|
||||
public GradeSemesterEnum? GradeSemester { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 视频处理 请求
|
||||
|
|
|
|||
|
|
@ -115,6 +115,10 @@ namespace VideoAnalysisCore.Controllers
|
|||
CloudSchoolId =s.UserCenterCloudSchoolId,
|
||||
Area = s.Area,
|
||||
HostIP = s.HostIP,
|
||||
StageId = s.StageId,
|
||||
GradeId = s.GradeId,
|
||||
GradeSemester = s.GradeSemester,
|
||||
TextBookVersionId = s.TextBookVersionId,
|
||||
};
|
||||
nodePackages.Add(np);
|
||||
if (videoIdArr.Contains(s.VideoCode)) continue;
|
||||
|
|
@ -134,6 +138,10 @@ namespace VideoAnalysisCore.Controllers
|
|||
PPTVideoUrl = pptUrl,
|
||||
VideoType = s.CourseType,
|
||||
CloudSchoolId = s.UserCenterCloudSchoolId,
|
||||
TextBookVersionId = s.TextBookVersionId,
|
||||
GradeSemester =s .GradeSemester,
|
||||
CourseLevel =s.CourseLevel,
|
||||
GradeId = s.GradeId,
|
||||
});
|
||||
}
|
||||
await nodePackageInfoDB.InsertRangeAsync(nodePackages);
|
||||
|
|
|
|||
|
|
@ -153,8 +153,8 @@ namespace VideoAnalysisCore.Controllers
|
|||
public IActionResult AudioRecognition(IFormFile file)
|
||||
{
|
||||
using var s = file.OpenReadStream();
|
||||
senseVoice.RunTask(s);
|
||||
return Ok();
|
||||
var res = senseVoice.RunTask(s);
|
||||
return Ok(res);
|
||||
}
|
||||
/// <summary>
|
||||
/// 语音识别
|
||||
|
|
@ -266,7 +266,7 @@ namespace VideoAnalysisCore.Controllers
|
|||
TagId = req.TagId,
|
||||
PPTVideoCode = req.PPTVideoCode,
|
||||
PPTVideoUrl = req.PPTVideoUrl,
|
||||
VideoType = req.VideoType
|
||||
VideoType = req.VideoType,
|
||||
};
|
||||
//入库
|
||||
await baseService.InsertAsync(task);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VideoAnalysisCore.Model.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 课程层次
|
||||
/// </summary>
|
||||
public enum CourselevelTypeEnum
|
||||
{
|
||||
一层次 = 1,
|
||||
二层次 = 2,
|
||||
三层次 = 3
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace VideoAnalysisCore.Model.Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 年级层次
|
||||
/// </summary>
|
||||
public enum GradeSemesterEnum
|
||||
{
|
||||
上册 = 1,
|
||||
下册 = 2
|
||||
}
|
||||
}
|
||||
|
|
@ -83,6 +83,25 @@ namespace VideoAnalysisCore.Model
|
|||
/// </summary>
|
||||
public string Area { get; set; }
|
||||
/// <summary>
|
||||
/// 年级
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public GradeEnum? GradeId { get; set; }
|
||||
/// <summary>
|
||||
/// 教育阶段
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public EducationStageEnum StageId { get; set; }
|
||||
/// <summary>
|
||||
/// 年级册(上册/下册)
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public GradeSemesterEnum? GradeSemester { get; set; }
|
||||
/// <summary>
|
||||
/// 学科网的教材版本Id
|
||||
/// </summary>
|
||||
public long TextBookVersionId { get; set; }
|
||||
/// <summary>
|
||||
/// 请求区域
|
||||
/// <para>回调添加到Headers</para>
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -145,5 +145,26 @@ namespace VideoAnalysisCore.Model
|
|||
[SugarColumn(IsNullable = true)]
|
||||
public long? CloudSchoolId { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 教材层次
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public CourselevelTypeEnum? CourseLevel { get; set; }
|
||||
/// <summary>
|
||||
/// 年级
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public GradeEnum? GradeId { get; set; }
|
||||
/// <summary>
|
||||
/// 年级册(上册/下册)
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public GradeSemesterEnum? GradeSemester { get; set; }
|
||||
/// <summary>
|
||||
/// 学科网的教材版本Id
|
||||
/// </summary>
|
||||
public long TextBookVersionId { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ namespace VideoAnalysisCore.Model
|
|||
/// <summary>
|
||||
/// 知识点来源 视频秒,来源原因
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 500, IsNullable = true)]
|
||||
public string Content { get; set; }
|
||||
/// <summary>
|
||||
/// 课程阶段
|
||||
|
|
@ -75,5 +76,26 @@ namespace VideoAnalysisCore.Model
|
|||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public virtual string? TextbookSource { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 教材层次
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public CourselevelTypeEnum? CourseLevel { get; set; }
|
||||
/// <summary>
|
||||
/// 年级
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public GradeEnum? GradeId { get; set; }
|
||||
/// <summary>
|
||||
/// 年级册(上册/下册)
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public GradeSemesterEnum? GradeSemester { get; set; }
|
||||
/// <summary>
|
||||
/// 学科网的教材版本Id
|
||||
/// </summary>
|
||||
public long TextBookVersionId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@
|
|||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="org.k2fsa.sherpa.onnx" Version="1.12.21" />
|
||||
<PackageReference Include="org.k2fsa.sherpa.onnx" Version="1.12.22" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
|
||||
<PackageReference Include="SqlSugar.IOC" Version="2.0.0" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.205" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue