diff --git a/WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/RequestDto/DahuaVideoQueryDto.cs b/WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/RequestDto/DahuaVideoQueryDto.cs
index d042e23..cbf4a22 100644
--- a/WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/RequestDto/DahuaVideoQueryDto.cs
+++ b/WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/RequestDto/DahuaVideoQueryDto.cs
@@ -59,6 +59,11 @@ namespace Common.Shared.Application.DaHua
public class PlaybackReqDto
{
public PlaybackItem Data { get; set; }
+
+ ///
+ /// 如果多个icc平台的话,决定是哪个平台的回放
+ ///
+ public string? IpAddress { get; set; }
}
///
@@ -109,6 +114,11 @@ namespace Common.Shared.Application.DaHua
public class RtspPlayBackReqDto
{
public RtspPlaybackItem Data { get; set; }
+
+ ///
+ /// 如果多个icc平台的话,决定是哪个平台的回放
+ ///
+ public string? IpAddress { get; set; }
}
///
@@ -258,6 +268,11 @@ namespace Common.Shared.Application.DaHua
///
[JsonPropertyName("data")]
public StreamRequestData Data { get; set; }
+
+ ///
+ /// 如果多个icc平台的话,决定是哪个平台的回放
+ ///
+ public string? IpAddress { get; set; }
}
///
@@ -270,6 +285,11 @@ namespace Common.Shared.Application.DaHua
///
[JsonPropertyName("data")]
public StreamRtspRequestData Data { get; set; }
+
+ ///
+ /// 如果多个icc平台的话,决定是哪个平台的回放
+ ///
+ public string? IpAddress { get; set; }
}
///
@@ -398,5 +418,10 @@ namespace Common.Shared.Application.DaHua
///
[JsonPropertyName("recordType")]
public required string RecordType { get; set; }
+
+ ///
+ /// 如果多个icc平台的话,决定是哪个平台的回放
+ ///
+ public string? IpAddress { get; set; }
}
}
\ No newline at end of file
diff --git a/WeiCloud.Fusion/VideoService/Video.API/Program.cs b/WeiCloud.Fusion/VideoService/Video.API/Program.cs
index e58b492..f91072e 100644
--- a/WeiCloud.Fusion/VideoService/Video.API/Program.cs
+++ b/WeiCloud.Fusion/VideoService/Video.API/Program.cs
@@ -1,5 +1,6 @@
using Autofac;
using Autofac.Extensions.DependencyInjection;
+using Common.Shared.Application.DaHua;
using Common.Shared.DomainService;
using Microsoft.OpenApi.Models;
using NLog;
diff --git a/WeiCloud.Fusion/VideoService/Video.API/appsettings.json b/WeiCloud.Fusion/VideoService/Video.API/appsettings.json
index 2485a3e..5c7aa11 100644
--- a/WeiCloud.Fusion/VideoService/Video.API/appsettings.json
+++ b/WeiCloud.Fusion/VideoService/Video.API/appsettings.json
@@ -22,19 +22,29 @@
"RedisConnection": "v4.weienergy.cn:6380,allowadmin=true,password=Zrhredis#2019,defaultDatabase=10",
"DBConnection": "server=v4.weienergy.cn;uid=root;pwd=Zrhdb#2019;port=3307;database=WeiCloudDB.Cap;default command timeout=100;CharSet=utf8;SslMode=None;allowPublicKeyRetrieval=true"
},
+
"VideoOpen": "1", //0表示部署视频对接,1表示不对接
//大华摄像头的配置
"DahuaAuth": {
"Host": "demo.weienergy.cn:15214",
"ClientId": "taiyanggong",
- "RealRootHost": "192.168.21.18:9100", //RTSP实时播放的icc地址
- "RealReplaceHost": "demo.weienergy.cn:15210", //rtps试试播放的替换地址
- "TimeRootHost": "192.168.21.18:9320", //RTSP历史回放的icc地址
- "TimeReplaceHost": "demo.weienergy.cn:15211", //rtps历史回放的替换地址
-
"ClientSecret": "6d6c78f8-3d4c-4e76-ab6b-827942a7b725",
-
"Username": "system",
- "Password": "Admin123"
+ "Password": "Admin123",
+ "Real": {
+ "DefaultRoot": "192.168.21.18:9100",
+ "DefaultReplace": "demo.weienergy.cn:15210",
+ "Overrides": {
+ "192.168.21.20:9100": "demo.weienergy.cn:15210",
+ "10.20.30.40:9100": "demo.weienergy.cn:15210"
+ }
+ },
+ "Time": {
+ "DefaultRoot": "192.168.21.18:9320",
+ "DefaultReplace": "demo.weienergy.cn:15211",
+ "Overrides": {
+ "192.168.21.20:9320": "demo.weienergy.cn:15211"
+ }
+ }
}
}
\ No newline at end of file
diff --git a/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs b/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs
index 482f21a..e234798 100644
--- a/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs
+++ b/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs
@@ -4,6 +4,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Net.Http.Json;
using System.Text.Json;
+using Video.DomainService.Dahvision;
namespace Video.DomainService
{
@@ -48,15 +49,18 @@ namespace Video.DomainService
try
{
- // 2) Token:优先入参,其次缓存/获取(建议返回完整的 "Bearer xxx")
var clientId = _configuration["DahuaAuth:ClientId"];
var token = await _tokenProviderService.GetTokenAsync(clientId!);
- if (_tokenProviderService.IsTokenValid(token))
+ if (!_tokenProviderService.IsTokenValid(token))
{
_logger.LogWarning("hls等录像回放:token无效");
return new DaHApiResult { Success = false, Code = "1009", Msg = "token无效" };
}
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/video/stream/record";
+ if (dto.IpAddress != null)
+ {
+ url = $"https://{dto.IpAddress}/evo-apigw/admin/API/video/stream/record";
+ }
// 3) 构造请求(把 dto 放进 Body),并用 SendAsync 发送,才能带上头
using var req = new HttpRequestMessage(HttpMethod.Post, url)
@@ -80,7 +84,12 @@ namespace Video.DomainService
_logger.LogWarning("录像请求业务失败: {Body}", body);
return new DaHApiResult { Success = false, Code = "1008", Msg = "录像请求失败" };
}
- result.Data!.Url = result.Data.Url + "?token=" + token;
+ result.Data!.Url = UrlHostReplacer.ReplaceHost(
+ result.Data.Url,
+ dto.IpAddress,
+ _configuration,
+ "Time"
+ ) + "?token=" + result.Data.Token;
return result;
}
catch (Exception ex)
@@ -107,13 +116,16 @@ namespace Video.DomainService
var clientId = _configuration["DahuaAuth:ClientId"];
var token = await _tokenProviderService.GetTokenAsync(clientId!);
- if (_tokenProviderService.IsTokenValid(token))
+ if (!_tokenProviderService.IsTokenValid(token))
{
_logger.LogWarning("查询普通录像信息列表:token无效");
return new DaHApiResult { Success = false, Code = "1009", Msg = "token无效" };
}
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/SS/Record/QueryRecords";
-
+ if (dto.IpAddress != null)
+ {
+ url = $"https://{dto.IpAddress}/evo-apigw/admin/API/SS/Record/QueryRecords";
+ }
using var req = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = JsonContent.Create(dto) // 关键:把 dto 放进请求体
@@ -164,7 +176,7 @@ namespace Video.DomainService
var clientId = _configuration["DahuaAuth:ClientId"];
var token = await _tokenProviderService.GetTokenAsync(clientId!);
- if (_tokenProviderService.IsTokenValid(token))
+ if (!_tokenProviderService.IsTokenValid(token))
{
_logger.LogWarning("通道分页查询失败:token无效");
return new DaHApiResult { Success = false, Code = "1009", Msg = "token无效" };
@@ -225,7 +237,7 @@ namespace Video.DomainService
// 2) Token:优先用入参;否则走缓存/获取(建议返回已带前缀的 "Bearer xxx")
var clientId = _configuration["DahuaAuth:ClientId"];
var token = await _tokenProviderService.GetTokenAsync(clientId!);
- if (_tokenProviderService.IsTokenValid(token))
+ if (!_tokenProviderService.IsTokenValid(token))
{
_logger.LogWarning(" HLS实时流请求失败:token无效");
return new DaHApiResult { Success = false, Code = "1009", Msg = "token无效" };
@@ -233,6 +245,11 @@ namespace Video.DomainService
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/video/stream/realtime";
+ if (dto.IpAddress != null)
+ {
+ url = $"https://{dto.IpAddress}/evo-apigw/admin/API/video/stream/realtime";
+ }
+
// 3) 用 HttpRequestMessage 发送,才能带上自定义头
using var req = new HttpRequestMessage(HttpMethod.Post, url)
{
@@ -255,7 +272,12 @@ namespace Video.DomainService
_logger.LogWarning("实时流请求业务失败: {Body}", body);
return new DaHApiResult { Success = false, Code = "1010", Msg = "实时流请求失败" };
}
- result.Data!.Url = result.Data.Url + "?token=" + token;
+ result.Data!.Url = UrlHostReplacer.ReplaceHost(
+ result.Data.Url,
+ dto.IpAddress,
+ _configuration,
+ "Real"
+ ) + "?token=" + result.Data.Token;
return result;
}
catch (Exception ex)
@@ -335,13 +357,17 @@ namespace Video.DomainService
// 先用缓存里的 token,不足5分钟过期再刷新(按你之前的口径来)
var clientId = _configuration["DahuaAuth:ClientId"];
var token = await _tokenProviderService.GetTokenAsync(clientId!);
- if (_tokenProviderService.IsTokenValid(token))
+ if (!_tokenProviderService.IsTokenValid(token))
{
_logger.LogWarning("rtsp录像回放:token无效");
return new DaHApiResult { Success = false, Code = "1009", Msg = "token无效" };
}
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/SS/Playback/StartPlaybackByTime";
+ if (dto.IpAddress != null)
+ {
+ url = $"https://{dto.IpAddress}/evo-apigw/admin/API/SS/Playback/StartPlaybackByTime";
+ }
using var req = new HttpRequestMessage(HttpMethod.Post, url)
{
@@ -366,7 +392,12 @@ namespace Video.DomainService
_logger.LogWarning("录像请求业务失败: {Body}", body);
return new DaHApiResult { Success = false, Code = "1008", Msg = "录像请求失败" };
}
- result.Data!.Url = result.Data.Url.Replace(_configuration["DahuaAuth:TimeRootHost"], _configuration["DahuaAuth:TimeReplaceHost"]) + "?token=" + result.Data.Token;
+ result.Data!.Url = UrlHostReplacer.ReplaceHost(
+ result.Data.Url,
+ dto.IpAddress,
+ _configuration,
+ "Time"
+ ) + "?token=" + result.Data.Token;
return result;
}
catch (Exception ex)
@@ -393,13 +424,17 @@ namespace Video.DomainService
var clientId = _configuration["DahuaAuth:ClientId"];
var token = await _tokenProviderService.GetTokenAsync(clientId!);
- if (_tokenProviderService.IsTokenValid(token))
+ if (!_tokenProviderService.IsTokenValid(token))
{
_logger.LogWarning("rtsp实时预览接口方式:token无效");
return new DaHApiResult { Success = false, Code = "1009", Msg = "token无效" };
}
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/MTS/Video/StartVideo";
+ if (dto.IpAddress != null)
+ {
+ url = $"https://{dto.IpAddress}/evo-apigw/admin/API/MTS/Video/StartVideo";
+ }
using var req = new HttpRequestMessage(HttpMethod.Post, url)
{
@@ -424,7 +459,12 @@ namespace Video.DomainService
_logger.LogWarning("实时流请求业务失败: {Body}", body);
return new DaHApiResult { Success = false, Code = "1010", Msg = "实时流请求失败" };
}
- result.Data!.Url = result.Data.Url.Replace(_configuration["DahuaAuth:RealRootHost"], _configuration["DahuaAuth:RealReplaceHost"]) + "?token=" + result.Data!.Token;
+ result.Data!.Url = UrlHostReplacer.ReplaceHost(
+ result.Data.Url,
+ dto.IpAddress,
+ _configuration,
+ "Real"
+ ) + "?token=" + result.Data.Token;
return result;
}
catch (Exception ex)
@@ -444,13 +484,18 @@ namespace Video.DomainService
{
var clientId = _configuration["DahuaAuth:ClientId"];
var token = await _tokenProviderService.GetTokenAsync(clientId!);
- if (_tokenProviderService.IsTokenValid(token))
+ if (!_tokenProviderService.IsTokenValid(token))
{
_logger.LogWarning("下载:token无效");
return "下载地址无效";
}
- return _configuration["DahuaAuth:Host"] + $"/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}";
+ 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}";
}
}
}
\ No newline at end of file
diff --git a/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/UrlHostReplacer.cs b/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/UrlHostReplacer.cs
new file mode 100644
index 0000000..1d4e020
--- /dev/null
+++ b/WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/UrlHostReplacer.cs
@@ -0,0 +1,26 @@
+using Microsoft.Extensions.Configuration;
+
+namespace Video.DomainService.Dahvision
+{
+ public static class UrlHostReplacer
+ {
+ public static string ReplaceHost(string url, string? ipAddress, IConfiguration config, string sectionName)
+ {
+ var section = config.GetSection($"DahuaAuth:{sectionName}");
+ var defaultRoot = section["DefaultRoot"]!;
+ var defaultReplace = section["DefaultReplace"]!;
+
+ // 1) 确定 fromHost
+ var fromHost = string.IsNullOrWhiteSpace(ipAddress) ? defaultRoot : ipAddress;
+
+ // 2) 尝试在 Overrides 找对应的 value
+ var overrides = section.GetSection("Overrides").Get>() ?? new();
+ var toHost = overrides.TryGetValue(fromHost, out var mapped)
+ ? mapped
+ : defaultReplace;
+
+ // 3) 字符串替换
+ return url.Replace(fromHost, toHost, StringComparison.OrdinalIgnoreCase);
+ }
+ }
+}
\ No newline at end of file