|
|
|
|
|
using Common.Shared.Application.DaHua;
|
|
|
|
|
|
using Common.Shared.DomainService;
|
|
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
|
using NPOI.XWPF.UserModel;
|
|
|
|
|
|
using System.Net.Http.Json;
|
|
|
|
|
|
using System.Text.Json;
|
|
|
|
|
|
using Video.DomainService.Dahvision;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Video.DomainService
|
|
|
|
|
|
{
|
|
|
|
|
|
public class DahuaGeneralCtlService : IDahuaGeneralCtlService
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly ILogger<DahuaGeneralCtlService> _logger;
|
|
|
|
|
|
private readonly IConfiguration _configuration;
|
|
|
|
|
|
private readonly ITokenProviderService _tokenProviderService;
|
|
|
|
|
|
// private readonly HttpClient _http;
|
|
|
|
|
|
|
|
|
|
|
|
public DahuaGeneralCtlService(ILogger<DahuaGeneralCtlService> logger, IConfiguration configuration, ITokenProviderService tokenProviderService, HttpClient http)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger = logger;
|
|
|
|
|
|
_configuration = configuration;
|
|
|
|
|
|
_tokenProviderService = tokenProviderService;
|
|
|
|
|
|
|
|
|
|
|
|
// _http = http;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 开发测试的时候,忽略证书
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private static readonly HttpClient _http = new HttpClient(new HttpClientHandler
|
|
|
|
|
|
{
|
|
|
|
|
|
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// hls等录像回放
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
public async Task<DaHApiResult<UrlDataDto>> RecordVideoUrl(PlaybackReqDto dto, string? ipaddress)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1) 参数校验 + 早退
|
|
|
|
|
|
if (dto == null || string.IsNullOrWhiteSpace(dto.Data.ChannelId))
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("录像请求失败:通道ID不能为空");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1007", Msg = "通道ID不能为空" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
var clientId = _configuration["DahuaAuth:ClientId"];
|
|
|
|
|
|
var token = await _tokenProviderService.GetTokenAsync(clientId!);
|
|
|
|
|
|
if (!_tokenProviderService.IsTokenValid(token))
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("hls等录像回放:token无效");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1009", Msg = "token无效" };
|
|
|
|
|
|
}
|
|
|
|
|
|
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/video/stream/record";
|
|
|
|
|
|
if (ipaddress != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
url = $"https://{ipaddress}/evo-apigw/admin/API/video/stream/record";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3) 构造请求(把 dto 放进 Body),并用 SendAsync 发送,才能带上头
|
|
|
|
|
|
using var req = new HttpRequestMessage(HttpMethod.Post, url)
|
|
|
|
|
|
{
|
|
|
|
|
|
Content = JsonContent.Create(dto.Data) // 关键:别再丢 body 了
|
|
|
|
|
|
};
|
|
|
|
|
|
req.Headers.TryAddWithoutValidation("Authorization", token);
|
|
|
|
|
|
|
|
|
|
|
|
using var resp = await _http.SendAsync(req);
|
|
|
|
|
|
var body = await resp.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
|
|
|
|
if (!resp.IsSuccessStatusCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("录像请求 HTTP 失败: {Status}, Body: {Body}", (int)resp.StatusCode, body);
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1008", Msg = $"HTTP错误 {(int)resp.StatusCode}" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var result = JsonSerializer.Deserialize<DaHApiResult<UrlDataDto>>(body);
|
|
|
|
|
|
if (result == null || !result.Success)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("录像请求业务失败: {Body}", body);
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1008", Msg = "录像请求失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
result.Data!.Url = UrlHostReplacer.ReplaceHost(
|
|
|
|
|
|
result.Data.Url,
|
|
|
|
|
|
ipaddress,
|
|
|
|
|
|
_configuration,
|
|
|
|
|
|
"Time"
|
|
|
|
|
|
) + "?token=" + result.Data.Token;
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "大华录像请求出错");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1008", Msg = "录像请求失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 查询普通录像信息列表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
public async Task<DaHApiResult<RecordsResDto>> QueryRecords(PlaybackReqDto dto)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 0) 参数校验 + 早退(按需增加更多必填校验)
|
|
|
|
|
|
if (dto == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("查询录像信息失败:请求参数不能为空");
|
|
|
|
|
|
return new DaHApiResult<RecordsResDto> { Success = false, Code = "1009", Msg = "请求参数不能为空" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var clientId = _configuration["DahuaAuth:ClientId"];
|
|
|
|
|
|
var token = await _tokenProviderService.GetTokenAsync(clientId!);
|
|
|
|
|
|
if (!_tokenProviderService.IsTokenValid(token))
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("查询普通录像信息列表:token无效");
|
|
|
|
|
|
return new DaHApiResult<RecordsResDto> { Success = false, Code = "1009", Msg = "token无效" };
|
|
|
|
|
|
}
|
|
|
|
|
|
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/SS/Record/QueryRecords";
|
|
|
|
|
|
|
|
|
|
|
|
using var req = new HttpRequestMessage(HttpMethod.Post, url)
|
|
|
|
|
|
{
|
|
|
|
|
|
Content = JsonContent.Create(dto.Data) // 关键:把 dto 放进请求体
|
|
|
|
|
|
};
|
|
|
|
|
|
req.Headers.TryAddWithoutValidation("Authorization", token);
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
using var resp = await _http.SendAsync(req); // 关键:用 SendAsync 发送 req,才能带上头
|
|
|
|
|
|
var body = await resp.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
|
|
|
|
if (!resp.IsSuccessStatusCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("查询录像信息 HTTP 失败: {Status}, Body: {Body}", (int)resp.StatusCode, body);
|
|
|
|
|
|
return new DaHApiResult<RecordsResDto> { Success = false, Code = "1008", Msg = $"HTTP错误 {(int)resp.StatusCode}" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var result = JsonSerializer.Deserialize<DaHApiResult<RecordsResDto>>(body);
|
|
|
|
|
|
if (result == null || !result.Success)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("查询录像信息业务失败: {Body}", body);
|
|
|
|
|
|
return new DaHApiResult<RecordsResDto> { Success = false, Code = "1008", Msg = "查询录像信息失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "查询大华录像信息出错");
|
|
|
|
|
|
return new DaHApiResult<RecordsResDto> { Success = false, Code = "1008", Msg = "查询录像信息失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设备通道分页查询
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="ArgumentNullException"></exception>
|
|
|
|
|
|
/// <exception cref="InvalidOperationException"></exception>
|
|
|
|
|
|
public async Task<DaHApiResult<PageInfoDto>> GetChannelPageList(ChannelPageReqDto dto)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (dto == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("通道分页查询失败:请求参数不能为空");
|
|
|
|
|
|
return new DaHApiResult<PageInfoDto> { Success = false, Code = "1009", Msg = "请求参数不能为空" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var clientId = _configuration["DahuaAuth:ClientId"];
|
|
|
|
|
|
var token = await _tokenProviderService.GetTokenAsync(clientId!);
|
|
|
|
|
|
if (!_tokenProviderService.IsTokenValid(token))
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("通道分页查询失败:token无效");
|
|
|
|
|
|
return new DaHApiResult<PageInfoDto> { Success = false, Code = "1009", Msg = "token无效" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/evo-brm/1.2.0/device/channel/subsystem/page";
|
|
|
|
|
|
|
|
|
|
|
|
using var req = new HttpRequestMessage(HttpMethod.Post, url)
|
|
|
|
|
|
{
|
|
|
|
|
|
Content = JsonContent.Create(dto) // 关键:把 dto 放进请求体
|
|
|
|
|
|
};
|
|
|
|
|
|
req.Headers.TryAddWithoutValidation("Authorization", token);
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
using var resp = await _http.SendAsync(req); // 关键:用 SendAsync 发送 req
|
|
|
|
|
|
var body = await resp.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
|
|
|
|
if (!resp.IsSuccessStatusCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("通道分页查询 HTTP 失败: {Status}, Body: {Body}", (int)resp.StatusCode, body);
|
|
|
|
|
|
return new DaHApiResult<PageInfoDto> { Success = false, Code = "1007", Msg = $"HTTP错误 {(int)resp.StatusCode}" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var result = JsonSerializer.Deserialize<DaHApiResult<PageInfoDto>>(body);
|
|
|
|
|
|
if (result == null || !result.Success)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("通道分页查询业务失败: {Body}", body);
|
|
|
|
|
|
return new DaHApiResult<PageInfoDto> { Success = false, Code = "1007", Msg = $"通道分页查询失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "获取大华设备通道分页查询出错");
|
|
|
|
|
|
return new DaHApiResult<PageInfoDto> { Success = false, Code = "1007", Msg = "获取大华设备通道分页查询失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// HLS、FLV、RTMP实时预览接口方式
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
public async Task<DaHApiResult<UrlDataDto>> RealtimeStreamUrl(StreamReqDto dto, string? ipaddress)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1) 参数校验 + 早退
|
|
|
|
|
|
if (dto == null || dto.Data == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("实时流请求失败:请求参数不能为空");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1009", Msg = "请求参数不能为空" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// 2) Token:优先用入参;否则走缓存/获取(建议返回已带前缀的 "Bearer xxx")
|
|
|
|
|
|
var clientId = _configuration["DahuaAuth:ClientId"];
|
|
|
|
|
|
var token = await _tokenProviderService.GetTokenAsync(clientId!);
|
|
|
|
|
|
if (!_tokenProviderService.IsTokenValid(token))
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning(" HLS实时流请求失败:token无效");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1009", Msg = "token无效" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/video/stream/realtime";
|
|
|
|
|
|
|
|
|
|
|
|
if (ipaddress != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
url = $"https://{ipaddress}/evo-apigw/admin/API/video/stream/realtime";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 3) 用 HttpRequestMessage 发送,才能带上自定义头
|
|
|
|
|
|
using var req = new HttpRequestMessage(HttpMethod.Post, url)
|
|
|
|
|
|
{
|
|
|
|
|
|
Content = JsonContent.Create(dto.Data) // 等价 PostAsJsonAsync,但不会丢头
|
|
|
|
|
|
};
|
|
|
|
|
|
req.Headers.TryAddWithoutValidation("Authorization", token);
|
|
|
|
|
|
|
|
|
|
|
|
using var resp = await _http.SendAsync(req);
|
|
|
|
|
|
var body = await resp.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
|
|
|
|
if (!resp.IsSuccessStatusCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("实时流请求 HTTP 失败: {Status}, Body: {Body}", (int)resp.StatusCode, body);
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1010", Msg = $"HTTP错误 {(int)resp.StatusCode}" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var result = JsonSerializer.Deserialize<DaHApiResult<UrlDataDto>>(body);
|
|
|
|
|
|
if (result == null || !result.Success)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("实时流请求业务失败: {Body}", body);
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1010", Msg = "实时流请求失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
result.Data!.Url = UrlHostReplacer.ReplaceHost(
|
|
|
|
|
|
result.Data.Url,
|
|
|
|
|
|
ipaddress,
|
|
|
|
|
|
_configuration,
|
|
|
|
|
|
"Real"
|
|
|
|
|
|
) + "?token=" + result.Data.Token;
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "大华实时流请求出错");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1010", Msg = "实时流请求失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 注销登录
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="authorization"></param>
|
|
|
|
|
|
/// <param name="openId"></param>
|
|
|
|
|
|
/// <param name="userClient"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
public async Task<DaHApiResult<object>> Logout(string authorization, string? openId, int? userClient)
|
|
|
|
|
|
{
|
|
|
|
|
|
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/evo-oauth/1.0.0/oauth/logout";
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
using var req = new HttpRequestMessage(HttpMethod.Get, url);
|
|
|
|
|
|
req.Headers.TryAddWithoutValidation("Authorization", authorization);
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(openId))
|
|
|
|
|
|
{
|
|
|
|
|
|
req.Headers.Add("openId", openId);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (userClient != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
req.Headers.Add("User-Client", userClient.ToString());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
using var resp = await _http.SendAsync(req);
|
|
|
|
|
|
resp.EnsureSuccessStatusCode();
|
|
|
|
|
|
|
|
|
|
|
|
var result = await resp.Content.ReadFromJsonAsync<DaHApiResult<object>>();
|
|
|
|
|
|
|
|
|
|
|
|
if (!result.Success || result.Code != "0")
|
|
|
|
|
|
{
|
|
|
|
|
|
result.Success = false;
|
|
|
|
|
|
result.Code = "1011";
|
|
|
|
|
|
result.Msg = "注销登录失败";
|
|
|
|
|
|
_logger.LogWarning("注销登录失败,返回结果:{Result}", result);
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "大华注销登录出错");
|
|
|
|
|
|
return new DaHApiResult<object>
|
|
|
|
|
|
{
|
|
|
|
|
|
Success = false,
|
|
|
|
|
|
Code = "1011",
|
|
|
|
|
|
Msg = "注销登录失败"
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// rtsp录像回放
|
|
|
|
|
|
/// (播放命令:ffplay -rtsp_transport tcp -i "rtsp://demo.weienergy.cn:15210/dss/monitor/param/cameraid=1000021%24104%26substream=1?token=430")强制走tcp
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
public async Task<DaHApiResult<UrlDataDto>> RtspPlaybackByTime(RtspPlayBackReqDto dto, string? ipaddress)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 参数校验 + 早退
|
|
|
|
|
|
if (dto == null || string.IsNullOrWhiteSpace(dto.Data.ChannelId))
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("录像请求失败:通道ID不能为空");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1007", Msg = "通道ID不能为空" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 先用缓存里的 token,不足5分钟过期再刷新(按你之前的口径来)
|
|
|
|
|
|
var clientId = _configuration["DahuaAuth:ClientId"];
|
|
|
|
|
|
var token = await _tokenProviderService.GetTokenAsync(clientId!);
|
|
|
|
|
|
if (!_tokenProviderService.IsTokenValid(token))
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("rtsp录像回放:token无效");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1009", Msg = "token无效" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/SS/Playback/StartPlaybackByTime";
|
|
|
|
|
|
if (ipaddress != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
url = $"https://{ipaddress}/evo-apigw/admin/API/SS/Playback/StartPlaybackByTime";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
using var req = new HttpRequestMessage(HttpMethod.Post, url)
|
|
|
|
|
|
{
|
|
|
|
|
|
Content = JsonContent.Create(dto) // 关键:把 dto 放进请求体
|
|
|
|
|
|
};
|
|
|
|
|
|
req.Headers.TryAddWithoutValidation("Authorization", token);
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
using var resp = await _http.SendAsync(req); // 关键:用 SendAsync 发送 req
|
|
|
|
|
|
var body = await resp.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
|
|
|
|
if (!resp.IsSuccessStatusCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("录像请求 HTTP 失败: {Status}, Body: {Body}", (int)resp.StatusCode, body);
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1008", Msg = $"HTTP错误 {(int)resp.StatusCode}" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var result = JsonSerializer.Deserialize<DaHApiResult<UrlDataDto>>(body);
|
|
|
|
|
|
if (result == null || !result.Success)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("录像请求业务失败: {Body}", body);
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1008", Msg = "录像请求失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
result.Data!.Url = UrlHostReplacer.ReplaceHost(
|
|
|
|
|
|
result.Data.Url,
|
|
|
|
|
|
ipaddress,
|
|
|
|
|
|
_configuration,
|
|
|
|
|
|
"Time"
|
|
|
|
|
|
) + "?token=" + result.Data.Token;
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, "录像请求异常");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1008", Msg = "录像请求失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// rtsp实时预览接口方式
|
|
|
|
|
|
/// (播放命令:ffplay -rtsp_transport tcp -i "rtsp://demo.weienergy.cn:15210/dss/monitor/param/cameraid=1000021%24104%26substream=1?token=68")强制走tcp
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
public async Task<DaHApiResult<UrlDataDto>> RtspStartVideoUrl(StreamRtspReqDto dto, string? ipaddress)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (dto == null || dto.Data == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("实时流请求失败:请求参数不能为空");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1005", Msg = "请求参数不能为空" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var clientId = _configuration["DahuaAuth:ClientId"];
|
|
|
|
|
|
var token = await _tokenProviderService.GetTokenAsync(clientId!);
|
|
|
|
|
|
_logger.LogWarning($"我的token: {token}");
|
|
|
|
|
|
if (!_tokenProviderService.IsTokenValid(token))
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("rtsp实时预览接口方式:token无效");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1009", Msg = "token无效" };
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/MTS/Video/StartVideo";
|
|
|
|
|
|
if (ipaddress != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
url = $"https://{ipaddress}/evo-apigw/admin/API/MTS/Video/StartVideo";
|
|
|
|
|
|
}
|
|
|
|
|
|
_logger.LogWarning($"我的url: {url}");
|
|
|
|
|
|
using var req = new HttpRequestMessage(HttpMethod.Post, url)
|
|
|
|
|
|
{
|
|
|
|
|
|
Content = JsonContent.Create(dto) // 等价于 PostAsJsonAsync,但和 req 绑定
|
|
|
|
|
|
};
|
|
|
|
|
|
req.Headers.TryAddWithoutValidation("Authorization", token);
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
using var resp = await _http.SendAsync(req); // 关键:用 SendAsync 发 req
|
|
|
|
|
|
var body = await resp.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
|
|
|
|
if (!resp.IsSuccessStatusCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("实时流请求 HTTP 失败: {Status}, Body: {Body}", (int)resp.StatusCode, body);
|
|
|
|
|
|
_logger.LogWarning($"{resp.StatusCode}: {body}");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1014", Msg = $"HTTP错误 {(int)resp.StatusCode}" };
|
|
|
|
|
|
}
|
|
|
|
|
|
_logger.LogWarning($"大华实时流请求返回body{body}");
|
|
|
|
|
|
var result = JsonSerializer.Deserialize<DaHApiResult<UrlDataDto>>(body);
|
|
|
|
|
|
if (result == null || !result.Success)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("实时流请求业务反序列化失败: {Body}", body);
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1013", Msg = "实时流请求业务反序列化失败" };
|
|
|
|
|
|
}
|
|
|
|
|
|
result.Data!.Url = UrlHostReplacer.ReplaceHost(
|
|
|
|
|
|
result.Data.Url,
|
|
|
|
|
|
ipaddress,
|
|
|
|
|
|
_configuration,
|
|
|
|
|
|
"Real"
|
|
|
|
|
|
) + "?token=" + result.Data.Token;
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, $"大华实时流请求出错{ex.Message}");
|
|
|
|
|
|
_logger.LogWarning($"{ex.Message}");
|
|
|
|
|
|
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1012", Msg = $"实时流请求失败{ex.Message}" };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 下载
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="dto"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
public async Task<string> Download(DownloadReqDto dto)
|
|
|
|
|
|
{
|
|
|
|
|
|
var clientId = _configuration["DahuaAuth:ClientId"];
|
|
|
|
|
|
var token = await _tokenProviderService.GetTokenAsync(clientId!);
|
|
|
|
|
|
if (!_tokenProviderService.IsTokenValid(token))
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogWarning("下载:token无效");
|
|
|
|
|
|
return "下载地址无效";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var url = _configuration["DahuaAuth:Host"];
|
|
|
|
|
|
if (dto.IpAddress != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
url = dto.IpAddress;
|
|
|
|
|
|
}
|
|
|
|
|
|
return url + $"/evo-apigw/evo-httpnode/vod/cam/download.mp4?vcuid={dto.Vcuid}&subtype={dto.Subtype}&starttime={dto.StartTime}endtime={dto.EndTime}&videoType={dto.VideoType}&token={token}&recordType={dto.RecordType}";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|