Learn.VideoAnalysis/VideoAnalysisCore/Common/DownloadFile.cs

95 lines
3.8 KiB
C#

using System;
using System.IO;
using System.Threading.Tasks;
namespace VideoAnalysisCore.Common
{
/// <summary>
///
/// </summary>
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", // 默认二进制文件
};
}
/// <summary>
/// 使用 HttpClient 下载任务的资源文件到本地
/// </summary>
/// <param name="task"></param>
/// <returns></returns>
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;
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 (totalBytes.HasValue && count % 3 == 0)
{
var progress = (double)totalBytesRead / totalBytes.Value * 100;
Console.WriteLine($"{DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}=> {task} 下载进度: {progress:F2}%");
}
}
//加入下一队列
RedisExpand.InsertChannel(Enum.RedisChannelEnum.SeparateAudio, task);
}
}
}