95 lines
3.8 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|