using System; using System.IO; using System.Threading.Tasks; namespace VideoAnalysisCore.Common { /// /// /// public class DownloadFile { // 根据 Content-Type 映射文件后缀 static string GetExtensionFromContentType(HttpResponseMessage res) { var contentType = res.Content.Headers.ContentType?.MediaType; return contentType switch { "application/pdf" => ".pdf", "image/jpeg" => ".jpg", "image/png" => ".png", "application/zip" => ".zip", "text/html" => ".html", "audio/wav" => ".wav", "audio/mp4" => ".mp4", "audio/mp3" => ".mp3", // 根据需要添加其他 Content-Type 映射 _ => ".mp4", // 默认二进制文件 }; } /// /// 使用 HttpClient 下载任务的资源文件到本地 /// /// /// public static async Task RunTask(string task) { //获取资源文件 地址 var fileUrl = RedisExpand.Redis.HMGet(RedisExpandKey.Task(task), "MediaUrl") .FirstOrDefault(); if (string.IsNullOrEmpty(fileUrl)) throw new Exception($"任务id[{task}] 资源地址无效 {fileUrl}"); using HttpClient client = new HttpClient(); // 发送 GET 请求以下载文件 var response = await client.GetAsync(fileUrl, HttpCompletionOption.ResponseHeadersRead); // 确保响应是成功的 response.EnsureSuccessStatusCode(); // 尝试从 URL 中获取文件后缀 string fileExtension = Path.GetExtension(new Uri(fileUrl).AbsolutePath); //否则 获取 从Content-Type 获取文件后缀 if (string.IsNullOrEmpty(fileExtension)) fileExtension = GetExtensionFromContentType(response); //创建下载文件缓存路径 if (!Directory.Exists(AppCommon.TaskCachedFile)) Directory.CreateDirectory(AppCommon.TaskCachedFile); // 获取文件大小 var totalBytes = response.Content.Headers.ContentLength; if (!totalBytes.HasValue) throw new Exception(task+" 未能获取到下载文件的 ContentLength "); var localPath = task.LocalPath(); var outputPath = Path.Combine(localPath, task + fileExtension); if (!Directory.Exists(localPath)) Directory.CreateDirectory(localPath); //同步到redis RedisExpand.Redis.HSet(RedisExpandKey.Task(task), "LocalMediaPath", outputPath); // 打开本地文件流以写入文件 using var fs = new FileStream(outputPath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None); // 读取响应内容流 using var contentStream = await response.Content.ReadAsStreamAsync(); var buffer = new byte[512 * 1024]; // 512KB 缓冲区 long totalBytesRead = 0; var count = 0; int bytesRead; while ((bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length)) > 0) { count++; await fs.WriteAsync(buffer, 0, bytesRead); totalBytesRead += bytesRead; // 计算下载进度 if (count % 30 == 0) { var progress = (double)totalBytesRead / totalBytes.Value * 100; RedisExpand.SetTaskProgress(task, progress); } } //加入下一队列 RedisExpand.InsertChannel(Enum.RedisChannelEnum.SeparateAudio, task); } } }