using System.Net.Http.Json;
using System.Text.Json.Nodes;
using Dpz.Core.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Dpz.Core.Service.ObjectStorage.VideoHandle;
public class VideoPretreatment(
HttpClient httpClient,
ILogger<VideoPretreatment> logger,
IConfiguration configuration,
UpyunOperator upyunOperator
)
{
public async Task SliceAsync(string source, string name)
{
var argument = new PretreatmentArgument
{
Service = upyunOperator.Bucket ?? throw new InvalidConfigurationException(),
NotifyUrl = configuration["NotifyUrl"] ?? throw new InvalidConfigurationException(),
Source = source,
Tasks =
[
new PretreatmentTask
{
Type = "video",
AvOpts = [new 切片(5), new 视频分辨率()],
SaveAs = $"/Video/{name}/1080p.m3u8",
},
],
};
var request = new HttpRequestMessage(HttpMethod.Post, "pretreatment");
request.Content = new FormUrlEncodedContent([
new KeyValuePair<string, string>("service", argument.Service),
new KeyValuePair<string, string>("notify_url", argument.NotifyUrl),
new KeyValuePair<string, string>("source", argument.Source),
new KeyValuePair<string, string>("tasks", argument.TasksBase64String()),
new KeyValuePair<string, string>("Accept", argument.Accept),
]);
await request.SignatureAsync(upyunOperator);
var response = await httpClient.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
logger.LogError("pretreatment fail,status code:{StatusCode}", response.StatusCode);
throw new BusinessException(
$"pretreatment fail,response status code:{response.StatusCode}"
);
}
var taskIds = await response.Content.ReadFromJsonAsync<List<string>>();
if (taskIds == null || taskIds.Count == 0)
{
logger.LogWarning("pretreatment fail,task ids is empty");
return;
}
await QueryTaskResultAsync(taskIds[0]);
}
public async Task QueryTaskResultAsync(string taskId)
{
var request = new HttpRequestMessage(
HttpMethod.Get,
$"status?service={upyunOperator.Bucket}&task_ids={taskId}"
);
await request.SignatureAsync(upyunOperator);
var response = await httpClient.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
logger.LogError("query task result fail,status code:{StatusCode}", response.StatusCode);
throw new BusinessException(
$"query task result fail,response status code:{response.StatusCode}"
);
}
var json = await response.Content.ReadAsStringAsync();
var root = JsonNode.Parse(json);
var status = root?["tasks"]?[taskId]?.GetValue<decimal?>();
if (status == null)
{
logger.LogWarning("query task result fail,task status is null,data :{Data}", json);
}
if (status is null or < 100)
{
logger.LogInformation("task is processing : {Process}%", status ?? 0);
await Task.Delay(TimeSpan.FromSeconds(3));
await QueryTaskResultAsync(taskId);
return;
}
logger.LogInformation("task is processed");
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
这是一个用于视频预处理的服务类,主要功能是将视频文件进行切片处理并查询处理状态。让我详细解释一下各个部分:
类的整体结构
public class VideoPretreatment(
HttpClient httpClient,
ILogger<VideoPretreatment> logger,
IConfiguration configuration,
UpyunOperator upyunOperator
)
这是一个使用了 C# 12 主构造函数语法的类,通过依赖注入接收四个依赖项:
HttpClient:用于发送HTTP请求ILogger:用于记录日志IConfiguration:用于读取配置UpyunOperator:又拍云操作器,用于云存储相关操作
主要方法分析
1. SliceAsync 方法
这是视频切片的主要方法:
public async Task SliceAsync(string source, string name)
功能流程:
构建请求参数:创建一个
PretreatmentArgument对象,包含:- 服务名称(从upyunOperator获取)
- 回调通知URL
- 源文件路径
- 处理任务配置(视频切片,5秒一片,保存为1080p.m3u8格式)
发送HTTP请求:
- 使用POST方法调用"pretreatment"接口
- 将参数以表单形式提交
- 对请求进行签名(通过
SignatureAsync扩展方法)
处理响应:
- 检查响应状态码
- 解析返回的任务ID列表
- 调用查询方法监控任务状态
2. QueryTaskResultAsync 方法
这是查询任务处理状态的递归方法:
public async Task QueryTaskResultAsync(string taskId)
功能流程:
- 发送查询请求:使用GET方法查询指定任务的状态
- 解析响应:从JSON响应中提取任务状态进度
- 状态判断:
- 如果状态为null:记录警告日志
- 如果进度小于100%:等待3秒后递归调用自身继续查询
- 如果进度达到100%:任务完成,记录信息日志
关键特性
- 异步处理:所有方法都是异步的,使用
async/await模式 - 错误处理:包含完整的错误处理和日志记录
- 递归查询:使用递归方式轮询任务状态,直到完成
- 配置驱动:通过配置文件获取关键参数
- 签名认证:对HTTP请求进行签名,确保安全性
使用场景
这个类主要用于视频处理服务,特别是:
- 将长视频切片成HLS格式(m3u8)
- 转换视频分辨率
- 异步监控视频处理进度
- 集成又拍云存储服务
整体来说,这是一个设计良好的视频预处理服务类,具有完整的错误处理、日志记录和异步处理能力。
AI 正在分析代码…
评论加载中...