网站首页 网站源码
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");
}
}
上述代码是一个 C# 类 VideoPretreatment
的实现,主要用于处理视频的预处理任务。它使用了 HttpClient
来与一个视频处理服务进行交互,执行视频切片和查询任务状态的功能。以下是代码的主要功能和结构的详细解释:
public VideoPretreatment(
HttpClient httpClient,
ILogger<VideoPretreatment> logger,
IConfiguration configuration,
UpyunOperator upyunOperator
)
SliceAsync
public async Task SliceAsync(string source, string name)
source
: 视频源的 URL。name
: 切片后视频的名称。PretreatmentArgument
对象,包含服务名称、通知 URL、源视频和任务列表。HttpRequestMessage
创建一个 POST 请求,目标是 pretreatment
接口。FormUrlEncodedContent
设置请求的内容,包括服务、通知 URL、源视频和任务信息。SignatureAsync
方法为请求添加签名(可能是为了安全性)。httpClient.SendAsync
发送请求。QueryTaskResultAsync
方法查询任务的处理结果。QueryTaskResultAsync
public async Task QueryTaskResultAsync(string taskId)
taskId
,要查询的任务 ID。HttpRequestMessage
创建一个 GET 请求,目标是 status
接口,包含服务名称和任务 ID。SignatureAsync
方法为请求添加签名。null
,记录警告。这个类的主要功能是与视频处理服务进行交互,执行视频切片操作,并能够查询任务的处理状态。它通过异步方法实现了非阻塞的操作,适合在高并发环境中使用。代码中还包含了错误处理和日志记录,以便于调试和监控。