using VideoAnalysisCore.Common; using Microsoft.OpenApi.Models; using VideoAnalysisCore.AICore.SherpaOnnx; using Mapster; using VideoAnalysisCore.AICore.GPT; using VideoAnalysisCore.AICore.GPT.ChatGPT; using Microsoft.Extensions.FileProviders; using VideoAnalysisCore.AICore.GPT.DeepSeek; using Microsoft.Extensions.DependencyInjection; using VideoAnalysisCore.Common.Expand; using Learn.VideoAnalysis.Expand; using Microsoft.AspNetCore.Mvc.Formatters; using System.Security.Cryptography; using System.Diagnostics; using VideoAnalysisCore.AICore.FFMPGE; using System.Text.Encodings.Web; using System.Text.Unicode; using System.Text.Json; using Microsoft.AspNetCore.Hosting.Server.Features; using Microsoft.AspNetCore.Hosting.Server; using System.IO.Compression; using System.Text; using System.Text.Json.Nodes; namespace Learn.VideoAnalysis { public class Program { public static void CleanHarFile(string inputPath, string outputPath) { try { // 1. 读取原始文件 var jsonString = File.ReadAllText(inputPath); var root = JsonNode.Parse(jsonString)!; var entries = root["log"]?["entries"]?.AsArray(); if (entries == null) return; // 过滤关键词 var blackList = new[] { "google", "gstatic", "doubleclick", "analytics", "facebook", "recaptcha" }; // 2. 逻辑清理 (从后往前) for (int i = entries.Count - 1; i >= 0; i--) { var entry = entries[i]; string url = entry?["request"]?["url"]?.GetValue().ToLower() ?? ""; string resourceType = entry?["_resourceType"]?.GetValue().ToLower() ?? ""; // 判定是否保留 (必须是 API 且 不在黑名单内) bool isApi = (resourceType == "xhr" || resourceType == "fetch"); bool isBlacklisted = blackList.Any(k => url.Contains(k)); if (!isApi || isBlacklisted) { entries.RemoveAt(i); continue; } // 3. 结构瘦身 if (entry?["_initiator"] is JsonObject initiator) { initiator.Remove("stack"); initiator.Remove("callFrames"); } // 移除所有以下划线开头的非标准扩展字段 (Chrome 专用字段) var entryObj = entry.AsObject(); var keysToRemove = entryObj.Where(kv => kv.Key.StartsWith("_")).Select(kv => kv.Key).ToList(); foreach (var key in keysToRemove) entryObj.Remove(key); } // 4. 极限压缩配置 var options = new JsonSerializerOptions { // 核心:禁用缩进,输出单行压缩格式 WriteIndented = false, // 核心:防止斜杠等字符被转义成 \u002F,保持原始字符减少长度 Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, // 忽略值为 null 的字段,进一步减小体积 DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull }; // 5. 写入文件 string compressedJson = root.ToJsonString(options); File.WriteAllText(outputPath, compressedJson); long originalSize = new FileInfo(inputPath).Length; long newSize = new FileInfo(outputPath).Length; Console.WriteLine("--- 压缩统计 ---"); Console.WriteLine($"原始大小: {originalSize / 1024.0:F2} KB"); Console.WriteLine($"压缩后大小: {newSize / 1024.0:F2} KB"); Console.WriteLine($"压缩率: {(1.0 - (double)newSize / originalSize) * 100:F2}%"); Console.WriteLine($"保留请求数: {entries.Count}"); } catch (Exception ex) { Console.WriteLine($"处理失败: {ex.Message}"); } } public static void Main(string[] args) { // 调用方法 CleanHarFile("C:\\Users\\Administrator\\Downloads\\kream.co.kr.har", "C:\\Users\\Administrator\\Downloads\\kream.co.kr.API压缩.har"); //交互式环境选择函数 AppConfigExpand.SelectEnvironment(ref args); var builder = WebApplication.CreateBuilder(args); //设置接口请求体最大100m builder.WebHost.ConfigureKestrel(serverOptions => { serverOptions.Limits.MaxRequestBodySize = 100_000_000; // 100MB }); builder.Services.AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); // 清除默认的日志提供程序 loggingBuilder.AddConsole(); // 添加控制台日志提供程序 loggingBuilder.SetMinimumLevel(LogLevel.Warning); // 设置最小日志级别为 Warning }); //绑定 appsetting 配置 builder.AddAppConfig(args); //初始化 插件 builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerExpand("AI视频分析"); builder.Services.AddPermissionAuthentication(); builder.Services.AddSqlSugarExpand(); builder.Services.AddRedisExpand(); //工作流 builder.Services.AddSimpleTexOcrClient(); builder.Services.AddDownloadFileExpand(); builder.Services.AddFFMPGEExpand(); builder.Services.AddAlibabaCloudVod(); builder.Services.AddAliyunOSS(); //语音转写 builder.Services.AddSenseVoiceExpand(); builder.Services.AddFunASRNanoExpand(); builder.Services.AddSherpaVadExpand(); //builder.Services.AddSpeakerAI(); //定时任务 builder.Services.AddCoravel(); //异常过滤器 builder.Services.AddControllersWithViews(options => { options.Filters.Add(typeof(ExceptionFilter)); }); builder.Services.AddControllers() .AddJsonOptions(options => { options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);//中文转换时不使用Unicode options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// 默认小驼峰 null 大驼峰 options.JsonSerializerOptions.PropertyNameCaseInsensitive = true; }); builder.Services.AddScoped(sp => { var httpContext = sp.GetRequiredService().HttpContext; if (httpContext != null) { return new HttpClient { BaseAddress = new Uri(httpContext.Request.Scheme + "://" + httpContext.Request.Host) }; } return new HttpClient(); }); builder.Services.AddMapster(); builder.Services.AddCorsExpand(); builder.Services.AddHttpClient(); builder.Services.AddHttpContextAccessor(); builder.Services.AddGPTService(); builder.Services.AddTaskSubscribe(); var app = builder.Build(); AppCommon.Services = app.Services; app.UseMiddleware("Swagger"); // Configure the HTTP request pipeline. app.UseSwagger(); app.UseSwaggerUI(); app.UseExceptionHandler("/Error"); //添加wwwroot 静态目录 app.UseStaticFiles(); //添加 自定义 静态目录 app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(AppCommon.TaskCachedFile), RequestPath = "/video", }); app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider(AppCommon.WebUIFile), RequestPath = "/ui", }); app.UseAntiforgery(); app.MapControllers(); //自定义 应用 app.UseCorsExpand(); app.UseSqlSugarExpand(); app.UseCoravelExpand(); app.UseServiceSystem(() => { //开启redis队列服务 _ = AppCommon.Services.GetRequiredService(); }); app.Run(); } } }