parent
49dcdc9fcb
commit
8ee1db05ed
|
|
@ -49,7 +49,7 @@ video {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height: 850px;
|
height: 750px;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using VideoAnalysisCore.AICore.GPT.KIMI;
|
||||||
using VideoAnalysisCore.AICore.GPT.ChatGPT;
|
using VideoAnalysisCore.AICore.GPT.ChatGPT;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
using VideoAnalysisCore.AICore.GPT.DeepSeek;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -24,10 +25,16 @@ namespace Learn.VideoAnalysis
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddRazorComponents()
|
builder.Services.AddRazorComponents()
|
||||||
.AddInteractiveServerComponents();
|
.AddInteractiveServerComponents();
|
||||||
//.AddInteractiveWebAssemblyComponents();
|
//.AddInteractiveWebAssemblyComponents();
|
||||||
|
|
||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddHttpContextAccessor();
|
||||||
|
|
||||||
|
builder.Services.AddLogging(loggingBuilder =>
|
||||||
|
{
|
||||||
|
loggingBuilder.ClearProviders(); // 清除默认的日志提供程序
|
||||||
|
loggingBuilder.AddConsole(); // 添加控制台日志提供程序
|
||||||
|
loggingBuilder.SetMinimumLevel(LogLevel.Warning); // 设置最小日志级别为 Warning
|
||||||
|
});
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Information",
|
"Default": "Warning",
|
||||||
"Microsoft.AspNetCore": "Warning"
|
"Microsoft.AspNetCore": "Warning"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
"DB": {
|
"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",
|
"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",
|
"SqlType": "MySql",
|
||||||
"UpdateTable": true
|
"UpdateTable": false
|
||||||
},
|
},
|
||||||
"KnowsDB": {
|
"KnowsDB": {
|
||||||
"ConnectionString": "Server=47.109.35.116;Database=ResourceBank;UID=live;Password=Woshiren^&*();MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;",
|
"ConnectionString": "Server=47.109.35.116;Database=ResourceBank;UID=live;Password=Woshiren^&*();MultipleActiveResultSets=true;Encrypt=True;TrustServerCertificate=True;",
|
||||||
|
|
|
||||||
|
|
@ -140,9 +140,13 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
public async Task<(Usage u, string res, string reasoning)?> ChatSSE(ChatRequest chatReq)
|
public async Task<(Usage u, string res, string reasoning)?> ChatSSE(ChatRequest chatReq)
|
||||||
{
|
{
|
||||||
var requestBody = System.Text.Json.JsonSerializer.Serialize(chatReq);
|
var requestBody = System.Text.Json.JsonSerializer.Serialize(chatReq);
|
||||||
|
PostJsonStream:
|
||||||
var chatResp = PostJsonStream(string.Empty, requestBody);
|
var chatResp = PostJsonStream(string.Empty, requestBody);
|
||||||
if (!chatResp.IsSuccessStatusCode)
|
if (!chatResp.IsSuccessStatusCode)
|
||||||
throw new Exception("GPT请求状态异常=>"+ chatResp.StatusCode);
|
{
|
||||||
|
Console.WriteLine(DateTime.Now + "=>请求GPT服务器异常 " + chatResp?.StatusCode);
|
||||||
|
goto PostJsonStream;
|
||||||
|
}
|
||||||
using var stream = chatResp.Content.ReadAsStream();
|
using var stream = chatResp.Content.ReadAsStream();
|
||||||
using var reader = new StreamReader(stream, Encoding.UTF8);
|
using var reader = new StreamReader(stream, Encoding.UTF8);
|
||||||
string line;
|
string line;
|
||||||
|
|
@ -150,7 +154,8 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
var messageBuilder1 = new StringBuilder();
|
var messageBuilder1 = new StringBuilder();
|
||||||
var lastChat = new ChatResSSE();
|
var lastChat = new ChatResSSE();
|
||||||
var splitCount = "data:".Length;
|
var splitCount = "data:".Length;
|
||||||
var maxLoop = 60*100;
|
var maxLoop = 60*1000;
|
||||||
|
int threshold = 50;
|
||||||
while (maxLoop>0)
|
while (maxLoop>0)
|
||||||
{
|
{
|
||||||
line = reader.ReadLine();
|
line = reader.ReadLine();
|
||||||
|
|
@ -187,6 +192,12 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
messageBuilder.Append(str);
|
messageBuilder.Append(str);
|
||||||
if (!string.IsNullOrEmpty(strReasoning))
|
if (!string.IsNullOrEmpty(strReasoning))
|
||||||
messageBuilder1.Append(strReasoning);
|
messageBuilder1.Append(strReasoning);
|
||||||
|
var steamCount = messageBuilder.Length + messageBuilder1.Length;
|
||||||
|
if (steamCount> threshold)
|
||||||
|
{
|
||||||
|
threshold += threshold;
|
||||||
|
Console.WriteLine(DateTime.Now + "=>接收到流 " + steamCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -76,37 +76,61 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
.OrderBy(s=>s.Id)
|
.OrderBy(s=>s.Id)
|
||||||
.GroupBy(s=>s.Name)
|
.GroupBy(s=>s.Name)
|
||||||
.ToDictionary(s => s.First().Name, s => s.First().Id);
|
.ToDictionary(s => s.First().Name, s => s.First().Id);
|
||||||
var postMessages =
|
VideoKnowRes[] questionRes;
|
||||||
$"你的任务是分析视频字幕内容并提取出中国高考考试试题方法点,然后根据步骤分析出知识片段" +
|
while (true)
|
||||||
$"按以下步骤完成:" +
|
{
|
||||||
$"1.识别方法点:提取字幕内容中与{subject}考试属于{fileNameInfoRes.授课章节}章节相关的方法点。" +
|
var postMessages =
|
||||||
$"2.关联合并知识内容相似的知识点来合并为知识片段。如果知识片段时长超过12分钟则考虑拆封为2个更加细微贴切的知识片段" +
|
$"你的任务是分析视频字幕内容并提取出中国高考考试试题方法点,然后分析出<知识块>,来帮助学生快速了解视频字幕的内容" +
|
||||||
$"3.分配空余未使用的时间段到内容相近的知识片段时间区间来获取更加详细的上下文,但是请避免知识片段之间时间重合。" +
|
$"通过阅读并理解字幕内容.然后识别出{subject}学科中属于{fileNameInfoRes.授课章节}章节相关的方法点以及对应的时间段。" +
|
||||||
$"4.分析总结:基于提取出的知识片段内容称来匹配我提供的知识点,来作为片段的知识点(请确保匹配的知识点是我提供的,否者片段知识点值为空字符串)" +
|
$"关联合并知识内容相似的知识点来合并为<知识块>。(请注意如果<知识块>时长超过600秒则考虑拆封为两个更加贴切的<知识块>.或者<知识块>时长小于30秒则考虑合并<知识块>到相邻的<知识块>)" +
|
||||||
$"提供的方法点名称({knows})。 格式 (方法点Id|方法点名称) 如果一个知识片段出现多个知识点那么知识点Id与知识点名称都用逗号','分割" +
|
$"分配空余未使用的时间段到内容相近的<知识块>时间区间来获取更加详细的上下文,但是请避免<知识块>之间时间重合。" +
|
||||||
$"输入:包含时间戳的视频字幕文本。" +
|
$"从提取出的<知识块>内容称来匹配我提供的知识点,来作为片段的知识点(请确保匹配的知识点是用户提供的,否则片段知识点值为空字符串)。" +
|
||||||
$"以下是包含时间的视频字幕文本。" +
|
$"提供的方法点名称({knows})。 格式 (方法点Id|方法点名称) 如果一个<知识块>出现多个知识点那么知识点Id与知识点名称都用逗号','分割。" +
|
||||||
$"字幕格式(说话人:开始秒:结束秒:内容|下一段字幕).字幕列表 {captions.Captions}" +
|
$"这是输入的视频字幕并且是包含时间戳的视频字幕的固定格式文本。" +
|
||||||
|
$"字幕格式(说话人:开始秒:结束秒:内容|下一段字幕).以下是包含时间的视频字幕文本。字幕列表 {captions.Captions}。" +
|
||||||
|
$"最后请检查某些<知识块>之间的过渡是否自然。建议按时间顺序优化分段密度,增强知识点衔接。" +
|
||||||
$"输出格式({resFormat})";
|
$"输出格式({resFormat})";
|
||||||
|
|
||||||
Console.WriteLine("=>开始分析视频内容");
|
Console.WriteLine(DateTime.Now + "=>开始分析视频内容");
|
||||||
|
|
||||||
var questionRes = await ChatAsync<VideoKnowRes[]>(task, postMessages, null);
|
questionRes = await ChatAsync<VideoKnowRes[]>(task, postMessages, null);
|
||||||
|
|
||||||
if (questionRes.Length <= 3)
|
if (questionRes.Length <= 3)
|
||||||
throw new Exception("视频分段数量过低 =>" + questionRes.Length);
|
throw new Exception("视频分段数量过低 =>" + questionRes.Length);
|
||||||
|
questionRes = questionRes.OrderBy(s => s.StartTime).ToArray();
|
||||||
|
for (int i = 0; i < questionRes.Length; i++)
|
||||||
|
{
|
||||||
|
var item = questionRes[i];
|
||||||
|
if (i == questionRes.Length - 1)
|
||||||
|
item.EndTime = maxVideoTime;
|
||||||
|
else
|
||||||
|
item.EndTime = (int)(questionRes[i + 1]?.StartTime ?? 0) - 1;
|
||||||
|
}
|
||||||
|
var thems = string.Join(',', questionRes.Select(s => s.StartTime + "->" + s.Theme));
|
||||||
|
|
||||||
for (int i = 0; i < questionRes.Length; i++)
|
var checkResFormat = """{"Score":打分(number),"Evaluation":评价(string)}""";
|
||||||
{
|
var checkMessage = "我为视频的讲解内容做了一些分段,你能帮我检查下这些分段的分配合理吗?请给出你的打分(0-100,60分及格)以及评价" +
|
||||||
var item = questionRes[i];
|
$"这是我的分段 {thems}." +
|
||||||
if (i == questionRes.Length - 1)
|
$"后续的内容是包含时间戳的视频字幕的固定格式文本。" +
|
||||||
item.EndTime = maxVideoTime;
|
$"字幕格式(说话人:开始秒:结束秒:内容|下一段字幕).以下是包含时间的视频字幕文本。字幕列表 {captions.Captions}。" +
|
||||||
|
$"输出格式为json({checkResFormat})";
|
||||||
|
|
||||||
|
Console.WriteLine(DateTime.Now + "=>开始检查视频分段结果");
|
||||||
|
var checkRes = await ChatAsync <CheckMessageDto>(task, checkMessage, null);
|
||||||
|
if (checkRes != null && checkRes.Score >= 80)
|
||||||
|
break;
|
||||||
else
|
else
|
||||||
item.EndTime = (int)(questionRes[i + 1]?.StartTime ?? 0) - 1;
|
{
|
||||||
}
|
Console.WriteLine(DateTime.Now + "=>得分过低 " + checkRes?.Score );
|
||||||
|
Console.WriteLine( checkRes.Evaluation);
|
||||||
|
Console.WriteLine( );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
await videoKonwPointDB.DeleteAsync(s => s.VideoTaskId == taskId);
|
await videoKonwPointDB.DeleteAsync(s => s.VideoTaskId == taskId);
|
||||||
var data = questionRes.SelectMany(
|
var data = questionRes
|
||||||
|
.Where(s=>!string.IsNullOrEmpty(s.KnowPoint))
|
||||||
|
.SelectMany(
|
||||||
s =>
|
s =>
|
||||||
{
|
{
|
||||||
var ks = s.KnowPoint.Split(",");
|
var ks = s.KnowPoint.Split(",");
|
||||||
|
|
@ -152,7 +176,6 @@ namespace VideoAnalysisCore.AICore.GPT.DeepSeek
|
||||||
max_tokens = maxTokens,
|
max_tokens = maxTokens,
|
||||||
temperature = 0.2f,
|
temperature = 0.2f,
|
||||||
messages = messageArr
|
messages = messageArr
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
RedisExpand.SetTaskGPTReqCached(task, chatRep);
|
RedisExpand.SetTaskGPTReqCached(task, chatRep);
|
||||||
|
|
|
||||||
|
|
@ -127,10 +127,23 @@ namespace VideoAnalysisCore.AICore.GPT.Dto
|
||||||
public string? ImprovedMethods { get; set; }
|
public string? ImprovedMethods { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
|
||||||
/// 课堂AI评价结果
|
public class CheckMessageDto
|
||||||
/// </summary>
|
{
|
||||||
public class AssessmentDto
|
/// <summary>
|
||||||
|
/// 打分
|
||||||
|
/// </summary>
|
||||||
|
public decimal Score { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 评分
|
||||||
|
/// </summary>
|
||||||
|
public string Evaluation { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 课堂AI评价结果
|
||||||
|
/// </summary>
|
||||||
|
public class AssessmentDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 优秀的评价
|
/// 优秀的评价
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ namespace VideoAnalysisCore.AICore.SherpaOnnx
|
||||||
{
|
{
|
||||||
res.Add(new()
|
res.Add(new()
|
||||||
{
|
{
|
||||||
Text = ExpandFunction.HandleFormula(stream.Result.Text),
|
Text = stream.Result.Text,
|
||||||
Start = (float)Math.Round(startTime, 2, MidpointRounding.AwayFromZero),
|
Start = (float)Math.Round(startTime, 2, MidpointRounding.AwayFromZero),
|
||||||
End = (float)Math.Round(startTime + duration, 2, MidpointRounding.AwayFromZero),
|
End = (float)Math.Round(startTime + duration, 2, MidpointRounding.AwayFromZero),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ namespace VideoAnalysisCore.Common
|
||||||
if (!AppCommon.Config.DB.UpdateTable)
|
if (!AppCommon.Config.DB.UpdateTable)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"【1】初始化主库表 跳过....");
|
Console.WriteLine($"【1】初始化主库表 跳过....");
|
||||||
ShowSQL = true;
|
//ShowSQL = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Console.WriteLine($"【1】初始化主库表 执行中....");
|
Console.WriteLine($"【1】初始化主库表 执行中....");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue