网站首页 网站源码
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Nodes;
using Dpz.Core.Infrastructure;
using Dpz.Core.Public.ViewModel;
using Dpz.Core.Public.ViewModel.Response;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Dpz.Core.Service.ObjectStorage.Services.Impl;
public class VideoCloudService : IVideoCloudService
{
private readonly HttpClient _httpClient;
private readonly ILogger<VideoCloudService> _logger;
private readonly UpyunOperator _upyunOperator;
public VideoCloudService(
HttpClient httpClient,
IConfiguration configuration,
ILogger<VideoCloudService> logger
)
{
_httpClient = httpClient;
_logger = logger;
var upyunOperator = configuration.GetSection("upyun").Get<UpyunOperator>();
_upyunOperator =
upyunOperator
?? throw new BusinessException("configuration error,need upyun config node.");
}
public async Task<ResponseResult<string?>> VideoScreenshotAsync(
string pathToFile,
TimeSpan time
)
{
var result = new ResponseResult<string?>();
if (string.IsNullOrEmpty(pathToFile))
throw new ArgumentNullException(nameof(pathToFile));
var parentPath = pathToFile[..pathToFile.LastIndexOf('/')];
var request = new HttpRequestMessage(HttpMethod.Post, $"{_upyunOperator.Bucket}/snapshot");
await request.SignatureAsync(_upyunOperator);
request.Content = JsonContent.Create(
new
{
source = pathToFile,
save_as = $"{parentPath}/video.webp",
point = $"{time.TotalHours:00}:{time.Minutes:00}:{time.Seconds:00}",
format = "webp",
}
);
try
{
var response = await _httpClient.SendAsync(request);
int? statusCode = (int)response.StatusCode;
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
#if DEBUG
Console.WriteLine(json);
#endif
var root = JsonNode.Parse(json);
statusCode = root?["status_code"]?.GetValue<int>();
if (statusCode == 200)
{
var savePath = root?["save_as"]?.GetValue<string>();
if (string.IsNullOrEmpty(savePath))
return result.FailResult("没有获取到缩略图地址");
return result.SuccessResult(_upyunOperator.Host + savePath);
}
}
return result.FailResult($"设置缩略图失败,响应码:{statusCode}");
}
catch (Exception e)
{
_logger.LogError(e, "screenshot fail");
return result.FailResult($"截图失败:{e.Message}");
}
}
public async Task<ResponseResult<VideoMetaDataResponse?>> GetVideoMetaAsync(string pathToFile)
{
var result = new ResponseResult<VideoMetaDataResponse?>();
if (string.IsNullOrEmpty(pathToFile))
throw new ArgumentNullException(nameof(pathToFile));
var request = new HttpRequestMessage(
HttpMethod.Post,
$"{_upyunOperator.Bucket}/m3u8er/get_meta"
);
await request.SignatureAsync(_upyunOperator);
request.Content = JsonContent.Create(new { m3u8 = pathToFile });
try
{
var response = await _httpClient.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
_logger.LogError(
"get video meta fail,response status code:{StatusCode}",
response.StatusCode
);
return result.FailResult($"获取视频元数据失败,响应状态码:{response.StatusCode}");
}
var json = await response.Content.ReadAsStringAsync();
var root = JsonNode.Parse(json);
var data = root?["meta"]?.Deserialize(
typeof(VideoMetaDataResponse),
new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }
);
if (data is not VideoMetaDataResponse meta)
{
return result.FailResult("获取视频元数据失败");
}
return result.SuccessResult(meta);
}
catch (Exception e)
{
_logger.LogError(e, "get video meta fail");
return result.FailResult($"获取视频元数据失败:{e.Message}");
}
}
}
上述代码定义了一个名为 VideoCloudService
的类,它实现了 IVideoCloudService
接口,主要用于与云视频服务进行交互。该类的功能主要包括视频截图和获取视频元数据。以下是对代码的详细解释:
HttpClient
、IConfiguration
和 ILogger<VideoCloudService>
作为参数。这些依赖项通过依赖注入提供。upyun
节点的配置,并将其映射到 UpyunOperator
对象。如果配置不存在,则抛出 BusinessException
。pathToFile
:视频文件的路径。time
:指定生成缩略图的时间点。pathToFile
是否为空,若为空则抛出 ArgumentNullException
。SignatureAsync
方法对请求进行签名(假设这是一个自定义扩展方法)。pathToFile
:视频文件的路径。pathToFile
是否为空,若为空则抛出 ArgumentNullException
。SignatureAsync
方法对请求进行签名。VideoCloudService
类提供了与云视频服务交互的功能,主要包括生成视频缩略图和获取视频元数据。它通过 HTTP 请求与云服务进行通信,并处理响应和错误,确保在出现问题时能够记录日志并返回适当的错误信息。