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}");
}
}
}