完善视频播放

pull/5/head
刘鑫 4 months ago
parent 21a29230bb
commit 1a572fbb36
  1. 5
      WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs
  2. 8
      WeiCloud.Fusion/AlarmService/AlarmService.API/Program.cs
  3. 11
      WeiCloud.Fusion/AlarmService/AlarmService.API/appsettings.json
  4. 16
      WeiCloud.Fusion/Common.SharedService/Common.Shared.API/Common.Shared.API.csproj
  5. 15
      WeiCloud.Fusion/Common.SharedService/Common.Shared.API/Infrastructure/AutoMapperProfile.cs
  6. 31
      WeiCloud.Fusion/Common.SharedService/Common.Shared.API/Infrastructure/ConfigureAutofac.cs
  7. 57
      WeiCloud.Fusion/Common.SharedService/Common.Shared.API/NLog.config
  8. 114
      WeiCloud.Fusion/Common.SharedService/Common.Shared.API/Program.cs
  9. 19
      WeiCloud.Fusion/Common.SharedService/Common.Shared.API/Startup.cs
  10. 71
      WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/DaHApiResult.cs
  11. 2
      WeiCloud.Fusion/Common.SharedService/Common.Shared.DomainService/DaHTokenService/ITokenProviderService.cs
  12. 29
      WeiCloud.Fusion/Common.SharedService/Common.Shared.DomainService/DaHTokenService/TokenProviderService.cs
  13. 2
      WeiCloud.Fusion/Common.SharedService/Common.Shared.DomainService/MqttClient/IMqttClientService.cs
  14. 2
      WeiCloud.Fusion/Common.SharedService/Common.Shared.DomainService/MqttClient/MQTTClient.cs
  15. 2
      WeiCloud.Fusion/Common.SharedService/Common.Shared.DomainService/MqttClient/MqttClientListService.cs
  16. 2
      WeiCloud.Fusion/Common.SharedService/Common.Shared.DomainService/MqttClient/MqttClientService.cs
  17. 2
      WeiCloud.Fusion/VideoService/Video.API/Controllers/DaHua/VideoManageController.cs
  18. 3
      WeiCloud.Fusion/VideoService/Video.API/Program.cs
  19. 4
      WeiCloud.Fusion/VideoService/Video.API/Video.API.csproj
  20. 7
      WeiCloud.Fusion/VideoService/Video.API/appsettings.json
  21. 44
      WeiCloud.Fusion/VideoService/Video.Application/RequestDto/DahuaVideoQueryDto.cs
  22. 22
      WeiCloud.Fusion/VideoService/Video.Application/ResponeDto/DahuaVideoResDto.cs
  23. 11
      WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/DahuaGeneralCtlService.cs
  24. 2
      WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/IDahuaGeneralCtlService.cs
  25. 2
      WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/IRootVideoPlaybackService.cs
  26. 2
      WeiCloud.Fusion/VideoService/Video.DomainService/Dahvision/RootVideoPlaybackService.cs

@ -1,11 +1,12 @@
using Alarm.Application.RequestDto; using Alarm.Application.RequestDto;
using Alarm.Application.ResponeDto; using Alarm.Application.ResponeDto;
using Common.Shared.Application.DaHua; using Common.Shared.Application.DaHua;
using Common.Shared.DomainService.MqttClient; using Common.Shared.DomainService;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security; using Org.BouncyCastle.Security;
using System;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text.Json; using System.Text.Json;
@ -234,7 +235,7 @@ namespace Alarm.DomainService.DahAlarm
}; };
} }
if (!(body.Success && string.Equals(body.Code, "0", StringComparison.OrdinalIgnoreCase))) if (!(body.Success && string.Equals((string?)body.Code, "0", StringComparison.OrdinalIgnoreCase)))
{ {
return new DaHApiResult<object> return new DaHApiResult<object>
{ {

@ -1,7 +1,7 @@
using AlarmService.API.Infrastructure; using AlarmService.API.Infrastructure;
using Autofac; using Autofac;
using Autofac.Extensions.DependencyInjection; using Autofac.Extensions.DependencyInjection;
using Common.Shared.DomainService.MqttClient; using Common.Shared.DomainService;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using NLog; using NLog;
using NLog.Extensions.Logging; using NLog.Extensions.Logging;
@ -43,6 +43,12 @@ namespace AlarmService.API
#endregion Cors #endregion Cors
#region 注册大华token 服务
builder.Services.AddSingleton<ITokenProviderService, TokenProviderService>();
#endregion 注册大华token 服务
#region SwaggerUI #region SwaggerUI
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();

@ -16,5 +16,14 @@
"ClientId": "datasource_points_AXYJPT_v4", "ClientId": "datasource_points_AXYJPT_v4",
"ApiUrl": "http://v4.weienergy.cn/datastream" "ApiUrl": "http://v4.weienergy.cn/datastream"
}, },
"AllowedHosts": "*" "AllowedHosts": "*",
//
"DahuaAuth": {
"Host": "demo.weienergy.cn:15214",
"ClientId": "taiyanggong",
"ClientSecret": "6d6c78f8-3d4c-4e76-ab6b-827942a7b725",
"Username": "system",
"Password": "Admin123"
}
} }

@ -4,10 +4,26 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Controllers\" /> <Folder Include="Controllers\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="8.4.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="NLog" Version="6.0.3" />
<PackageReference Include="NLog.Extensions.Logging" Version="6.0.3" />
<PackageReference Include="NLog.Web.AspNetCore" Version="6.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="9.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="9.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\WeiCloud.Utils\WeiCloud.Utils.csproj" />
<ProjectReference Include="..\Common.Shared.DomainService\Common.Shared.DomainService.csproj" />
</ItemGroup>
</Project> </Project>

@ -0,0 +1,15 @@
namespace Video.API.Infrastructure
{
/// <summary>
/// 配置AutoMapper
/// </summary>
public class AutoMapperProfile
{
/// <summary>
/// 构造函数
/// </summary>
public AutoMapperProfile()
{
}
}
}

@ -0,0 +1,31 @@
using Autofac;
using System.Reflection;
namespace Common.Shared.API.Infrastructure
{
/// <summary>
/// autofac
/// </summary>
public class ConfigureAutofac : Autofac.Module
{
/// <summary>
///
/// </summary>
/// <param name="builder"></param>
protected override void Load(ContainerBuilder builder)
{
//Assembly assemblysServices1 = Assembly.Load("WeiCloud.Core");
//builder.RegisterAssemblyTypes(assemblysServices1).Where(t => t.Namespace != "" && t.Namespace != null && t.Name.EndsWith("Service") && t.Namespace.StartsWith("WeiCloud.Core"))
// .AsImplementedInterfaces()
// .InstancePerLifetimeScope().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
var assemblysServices = Assembly.Load("Common.Shared.DomainService");
builder.RegisterAssemblyTypes(assemblysServices)
.Where(x => x.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
// builder.RegisterType(typeof(GrainFactory)).PropertiesAutowired().InstancePerLifetimeScope();
}
}
}

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
throwExceptions="false"
internalLogLevel="Warn" internalLogFile="nlog-internal.log">
<!-- optional, add some variables
https://github.com/nlog/NLog/wiki/Configuration-file#variables
-->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!--<variable name="myvar" value="myvalue"/>-->
<variable name="year" value="${date:format=yyyy}"/>
<variable name="year_month" value="${date:format=yyyy-MM}"/>
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets async="true">
<!--
add your targets here
See https://github.com/nlog/NLog/wiki/Targets for possible targets.
See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers.
-->
<!--
Write events to a file with the date in the filename.
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
-->
<target xsi:type="AsyncWrapper" name="MyLogger">
<target xsi:type="File"
layout="${longdate},${uppercase:${level}},${message}"
fileName="${basedir}/Log/${level}/${year}/${year_month}/${shortdate}.log" encoding="utf-8" />
</target>
<target xsi:type="Null" name="blackhole" />
</targets>
<rules>
<!-- add your logging rules here -->
<!--
Write all events with minimal level of Debug (So Debug, Info, Warn, Error and Fatal, but not Trace) to "f"
<logger name="*" minlevel="Debug" writeTo="f" />
-->
<!--跳过Microsoft的系统日志-->
<logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
<logger name="*" minlevel="Debug" writeTo="MyLogger" final="true"/>
<logger name="Microsoft.*" minlevel="Warn" writeTo="MyLogger" final="true"/>
</rules>
</nlog>

@ -1,27 +1,123 @@
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Common.Shared.API.Infrastructure;
using Microsoft.OpenApi.Models;
using NLog;
using NLog.Extensions.Logging;
using NLog.Web;
using System.Reflection;
namespace Common.Shared.API namespace Common.Shared.API
{ {
public class Program public class Program
{ {
public static void Main(string[] args) public static void Main(string[] args)
{ {
var builder = WebApplication.CreateBuilder(args); var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Debug("init main");
try
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpContextAccessor();
builder.Services.AddHttpClient();
builder.Services.AddControllers();
builder.Services.AddSingleton(builder.Configuration);
#region Cors
builder.Services.AddCors(options =>
{
options.AddPolicy("_myAllowSpecificOrigins",
builder =>
{
builder.AllowAnyOrigin() //允许所有源访问本API(开发环境设置)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.SetIsOriginAllowed((h) => true);//为Signalr新添加的配置
});
});
#endregion Cors
#region SwaggerUI
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1.0", new OpenApiInfo
{
Version = "v1.0",
Title = "WeiCloud.IoT",//左侧大标题名称
Description = "安消一体化平台",
Contact = new OpenApiContact
{
Name = "hi7t",
Email = "",
Url = null
}
});
//c.OperationFilter<AddProjectHeaderParameter>();
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath, true);
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
});
#endregion SwaggerUI
builder.Services.AddLogging(m => { m.AddNLog(); });
// Add services to the container. #region Autofac
builder.Services.AddControllers(); builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new ConfigureAutofac());
});
var app = builder.Build(); #endregion Autofac
// Configure the HTTP request pipeline. // 设置全局默认请求体大小限制
builder.WebHost.ConfigureKestrel(options =>
{
options.Limits.MaxRequestBodySize = 200 * 1024 * 1024; // 默认 200MB
});
app.UseHttpsRedirection(); var app = builder.Build();
app.UseAuthorization(); if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1.0/swagger.json", "WeiCloud.IoT-v1.0");
});
}
app.UseHttpsRedirection();
app.MapControllers(); app.UseAuthorization();
app.Run(); app.MapControllers();
// 创建 Startup 实例
var startup = new Startup(builder.Configuration);
startup.Configure(app, app.Environment, builder.Configuration);
app.Run();
}
catch (Exception exception)
{
// NLog: catch setup errors
logger.Error(exception, "Stopped program because of exception");
throw;
}
finally
{
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
NLog.LogManager.Shutdown();
}
} }
} }
} }

@ -0,0 +1,19 @@
using WeiCloud.Utils.Common;
namespace Common.Shared.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IConfiguration configuration)
{
ServiceLocator.Instance = app.ApplicationServices;
}
}
}

@ -1,4 +1,6 @@
using System.Text.Json.Serialization; using System.Text.Json;
using System.Text.Json.Serialization;
using System.Globalization;
namespace Common.Shared.Application.DaHua namespace Common.Shared.Application.DaHua
{ {
@ -9,10 +11,73 @@ namespace Common.Shared.Application.DaHua
public class DaHApiResult<T> public class DaHApiResult<T>
{ {
[JsonPropertyName("code")] [JsonPropertyName("code")]
public string Code { get; set; } [JsonConverter(typeof(FlexibleStringConverter))]
public string? Code { get; set; }
// errMsg 和 desc 都可能出现,做一个统一的“Message”来使用
[JsonPropertyName("errMsg")] [JsonPropertyName("errMsg")]
public string Msg { get; set; } public string? Msg { get; set; }
[JsonPropertyName("desc")]
public string? Desc { get; set; }
[JsonIgnore]
public string? Message => !string.IsNullOrWhiteSpace(Msg) ? Msg : Desc;
[JsonPropertyName("data")]
public T? Data { get; set; }
[JsonPropertyName("success")]
public bool Success { get; set; }
}
public sealed class FlexibleStringConverter : JsonConverter<string?>
{
public override string? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
switch (reader.TokenType)
{
case JsonTokenType.String:
return reader.GetString();
case JsonTokenType.Number:
// 先尽量按整数,再按 decimal,最后兜底 double
if (reader.TryGetInt64(out long i))
return i.ToString(CultureInfo.InvariantCulture);
if (reader.TryGetDecimal(out decimal m))
return m.ToString(CultureInfo.InvariantCulture);
double d = reader.GetDouble();
return d.ToString(CultureInfo.InvariantCulture);
case JsonTokenType.True:
return "true";
case JsonTokenType.False:
return "false";
case JsonTokenType.Null:
return null;
default:
throw new JsonException($"Unsupported token for string: {reader.TokenType}");
}
}
public override void Write(Utf8JsonWriter writer, string? value, JsonSerializerOptions options)
{
if (value is null) { writer.WriteNullValue(); return; }
writer.WriteStringValue(value);
}
}
public class DaHApiDescResult<T>
{
[JsonPropertyName("code")]
public int Code { get; set; } // 修改为 int 类型
[JsonPropertyName("desc")] // 修改为 "desc" 而不是 "errMsg"
public string Desc { get; set; }
[JsonPropertyName("data")] [JsonPropertyName("data")]
public T Data { get; set; } public T Data { get; set; }

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Common.Shared.DomainService.DaHToken namespace Common.Shared.DomainService
{ {
public interface ITokenProviderService public interface ITokenProviderService
{ {

@ -6,9 +6,8 @@ using Org.BouncyCastle.Security;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text.Json; using System.Text.Json;
using static System.Net.WebRequestMethods;
namespace Common.Shared.DomainService.DaHToken namespace Common.Shared.DomainService
{ {
/// <summary> /// <summary>
/// 获取大华icc平台的token服务 /// 获取大华icc平台的token服务
@ -27,7 +26,7 @@ namespace Common.Shared.DomainService.DaHToken
/// <summary> /// <summary>
/// 开发测试的时候,忽略证书 /// 开发测试的时候,忽略证书
/// </summary> /// </summary>
private static readonly HttpClient _http = new HttpClient(new HttpClientHandler private static readonly HttpClient _http = new(new HttpClientHandler
{ {
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
}); });
@ -77,9 +76,9 @@ namespace Common.Shared.DomainService.DaHToken
RefreshToken = refreshToken.Replace("Bearer ", string.Empty) RefreshToken = refreshToken.Replace("Bearer ", string.Empty)
}; };
var result = await this.RefreshToken(dto); var result = await RefreshToken(dto);
if (result?.Data != null) if (result?.Data != null && result.Data.AccessToken != "" && result.Data.AccessToken != null)
{ {
refreshed = new TokenEntry refreshed = new TokenEntry
{ {
@ -132,7 +131,7 @@ namespace Common.Shared.DomainService.DaHToken
TokenEntry refreshed = new() TokenEntry refreshed = new()
{ {
AccessToken = string.Concat(loginResult!.Data.TokenType, " ", loginResult.Data.AccessToken), AccessToken = loginResult.Data.AccessToken,
ExpireAt = DateTimeOffset.UtcNow.AddSeconds(120) ExpireAt = DateTimeOffset.UtcNow.AddSeconds(120)
}; };
return refreshed; return refreshed;
@ -293,7 +292,7 @@ namespace Common.Shared.DomainService.DaHToken
#region RES加密 #region RES加密
private static String EncryptByPublicKey(String context, String publicKey) private static string EncryptByPublicKey(string context, string publicKey)
{ {
RSACryptoServiceProvider rsa = new(); RSACryptoServiceProvider rsa = new();
@ -316,14 +315,14 @@ namespace Common.Shared.DomainService.DaHToken
{ {
switch (node.Name) switch (node.Name)
{ {
case "Modulus": parameters.Modulus = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "Modulus": parameters.Modulus = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "Exponent": parameters.Exponent = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "Exponent": parameters.Exponent = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "P": parameters.P = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "P": parameters.P = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "Q": parameters.Q = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "Q": parameters.Q = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "DP": parameters.DP = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "DP": parameters.DP = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "DQ": parameters.DQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "DQ": parameters.DQ = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "InverseQ": parameters.InverseQ = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "InverseQ": parameters.InverseQ = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "D": parameters.D = (string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText)); break; case "D": parameters.D = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
} }
} }
} }

@ -1,6 +1,6 @@
using MQTTnet.Client; using MQTTnet.Client;
namespace Common.Shared.DomainService.MqttClient namespace Common.Shared.DomainService
{ {
public interface IMqttClientService public interface IMqttClientService
{ {

@ -4,7 +4,7 @@ using MQTTnet.Client;
using MQTTnet.Protocol; using MQTTnet.Protocol;
using WeiCloud.Core.BaseModels; using WeiCloud.Core.BaseModels;
namespace Common.Shared.DomainService.MqttClient namespace Common.Shared.DomainService
{ {
public class MQTTClient public class MQTTClient
{ {

@ -7,7 +7,7 @@ using System.Collections.Concurrent;
using System.Text; using System.Text;
using WeiCloud.Utils.Common; using WeiCloud.Utils.Common;
namespace Common.Shared.DomainService.MqttClient namespace Common.Shared.DomainService
{ {
public class MqttClientListService public class MqttClientListService
{ {

@ -2,7 +2,7 @@
using MQTTnet; using MQTTnet;
using MQTTnet.Client; using MQTTnet.Client;
namespace Common.Shared.DomainService.MqttClient namespace Common.Shared.DomainService
{ {
public class MqttClientService : IMqttClientService public class MqttClientService : IMqttClientService
{ {

@ -71,7 +71,7 @@ namespace Video.API.Controllers.DaHua
/// <param name="dto"></param> /// <param name="dto"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("rtspstart/dh")] [HttpPost("rtspstart/dh")]
public async Task<ApiResult<UrlDataDto>> RtspStartVideoUrl(StreamReqDto dto) public async Task<ApiResult<UrlDataDto>> RtspStartVideoUrl(StreamRtspReqDto dto)
{ {
return await _rootVideoPlaybackService.RtspStartVideoUrl(dto); return await _rootVideoPlaybackService.RtspStartVideoUrl(dto);
} }

@ -1,12 +1,11 @@
using Autofac; using Autofac;
using Autofac.Extensions.DependencyInjection; using Autofac.Extensions.DependencyInjection;
using Common.Shared.DomainService.DaHToken; using Common.Shared.DomainService;
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
using NLog; using NLog;
using NLog.Extensions.Logging; using NLog.Extensions.Logging;
using NLog.Web; using NLog.Web;
using Quartz; using Quartz;
using Quartz.Simpl;
using System.Reflection; using System.Reflection;
using Video.API.Infrastructure; using Video.API.Infrastructure;
using Video.Application; using Video.Application;

@ -28,8 +28,4 @@
<ProjectReference Include="..\Video.DomainService\Video.DomainService.csproj" /> <ProjectReference Include="..\Video.DomainService\Video.DomainService.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="HostService\" />
</ItemGroup>
</Project> </Project>

@ -26,6 +26,11 @@
// //
"DahuaAuth": { "DahuaAuth": {
"Host": "demo.weienergy.cn:15214", "Host": "demo.weienergy.cn:15214",
"ClientId": "taiyanggong" "ClientId": "taiyanggong",
"ClientSecret": "6d6c78f8-3d4c-4e76-ab6b-827942a7b725",
"Username": "system",
"Password": "Admin123"
} }
} }

@ -79,8 +79,8 @@ namespace Video.Application
/// <summary> /// <summary>
/// 回放开始时间,格式:"yyyy-M-d HH:mm:ss" /// 回放开始时间,格式:"yyyy-M-d HH:mm:ss"
/// </summary> /// </summary>
[JsonPropertyName("beginTime")] [JsonPropertyName("startTime")]
public string BeginTime { get; set; } public string startTime { get; set; }
/// <summary> /// <summary>
/// 回放结束时间,格式:"yyyy-M-d HH:mm:ss" /// 回放结束时间,格式:"yyyy-M-d HH:mm:ss"
@ -230,24 +230,54 @@ namespace Video.Application
/// </summary> /// </summary>
[JsonPropertyName("type")] [JsonPropertyName("type")]
public string? Type { get; set; } public string? Type { get; set; }
}
/// <summary>
/// 实时 流播放请求响应包装类
/// </summary>
public class StreamReqDto
{
/// <summary> /// <summary>
/// rtsp专用,有datatype没有type,有type没有datatype /// 请求数据
/// </summary> /// </summary>
[JsonPropertyName("dataType")] [JsonPropertyName("data")]
public string? DataType { get; set; } public StreamRequestData Data { get; set; }
} }
/// <summary> /// <summary>
/// 实时 流播放请求响应包装类 /// 实时 流播放请求响应包装类
/// </summary> /// </summary>
public class StreamReqDto public class StreamRtspReqDto
{ {
/// <summary> /// <summary>
/// 请求数据 /// 请求数据
/// </summary> /// </summary>
[JsonPropertyName("data")] [JsonPropertyName("data")]
public StreamRequestData Data { get; set; } public StreamRtspRequestData Data { get; set; }
}
/// <summary>
/// 实时流播放请求数据实体
/// </summary>
public class StreamRtspRequestData
{
/// <summary>
/// 通道编码
/// </summary>
[JsonPropertyName("channelId")]
public string ChannelId { get; set; }
/// <summary>
/// 码流类型:1-主码流,2-子码流
/// </summary>
[JsonPropertyName("streamType")]
public string StreamType { get; set; }
/// <summary>
/// rtsp专用,有datatype没有type,有type没有datatype
/// </summary>
[JsonPropertyName("dataType")]
public string? DataType { get; set; }
} }
/// <summary> /// <summary>

@ -370,5 +370,27 @@ namespace Video.Application
/// </summary> /// </summary>
[JsonPropertyName("trackId")] [JsonPropertyName("trackId")]
public string TrackId { get; set; } // 可为null public string TrackId { get; set; } // 可为null
// 添加JSON中存在的新属性
[JsonPropertyName("urlList")]
public object UrlList { get; set; } // 可为null
[JsonPropertyName("stream")]
public object Stream { get; set; } // 可为null
[JsonPropertyName("innerIp")]
public string InnerIp { get; set; } // 新增IP属性
[JsonPropertyName("compress")]
public bool? Compress { get; set; } // 压缩标识
[JsonPropertyName("reachable")]
public object Reachable { get; set; } // 可为null
[JsonPropertyName("wssDirect")]
public int? WssDirect { get; set; } // 新增数值属性
[JsonPropertyName("netFlag")]
public string NetFlag { get; set; } // 网络标识
} }
} }

@ -1,11 +1,8 @@
using Common.Shared.Application.DaHua; using Common.Shared.Application.DaHua;
using Common.Shared.DomainService.DaHToken; using Common.Shared.DomainService;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Security.Cryptography;
using System.Text.Json; using System.Text.Json;
using Video.Application; using Video.Application;
@ -321,7 +318,7 @@ namespace Video.DomainService
var clientId = _configuration["DahuaAuth:ClientId"]; var clientId = _configuration["DahuaAuth:ClientId"];
var token = await _tokenProviderService.GetTokenAsync(clientId!); var token = await _tokenProviderService.GetTokenAsync(clientId!);
var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/video/stream/record"; var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/admin/API/SS/Playback/StartPlaybackByTime";
using var req = new HttpRequestMessage(HttpMethod.Post, url) using var req = new HttpRequestMessage(HttpMethod.Post, url)
{ {
@ -362,7 +359,7 @@ namespace Video.DomainService
/// <param name="dto"></param> /// <param name="dto"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="NotImplementedException"></exception> /// <exception cref="NotImplementedException"></exception>
public async Task<DaHApiResult<UrlDataDto>> RtspStartVideoUrl(StreamReqDto dto) public async Task<DaHApiResult<UrlDataDto>> RtspStartVideoUrl(StreamRtspReqDto dto)
{ {
if (dto == null || dto.Data == null) if (dto == null || dto.Data == null)
{ {
@ -393,7 +390,7 @@ namespace Video.DomainService
} }
var result = JsonSerializer.Deserialize<DaHApiResult<UrlDataDto>>(body); var result = JsonSerializer.Deserialize<DaHApiResult<UrlDataDto>>(body);
if (result == null || !result.Success || result.Code != "0") if (result == null || !result.Success || result.Code != "100")
{ {
_logger.LogWarning("实时流请求业务失败: {Body}", body); _logger.LogWarning("实时流请求业务失败: {Body}", body);
return new DaHApiResult<UrlDataDto> { Success = false, Code = "1010", Msg = "实时流请求失败" }; return new DaHApiResult<UrlDataDto> { Success = false, Code = "1010", Msg = "实时流请求失败" };

@ -49,7 +49,7 @@ namespace Video.DomainService
/// </summary> /// </summary>
/// <param name="dto"></param> /// <param name="dto"></param>
/// <returns></returns> /// <returns></returns>
Task<DaHApiResult<UrlDataDto>> RtspStartVideoUrl(StreamReqDto dto); Task<DaHApiResult<UrlDataDto>> RtspStartVideoUrl(StreamRtspReqDto dto);
/// <summary> /// <summary>
/// 注销认证信息 /// 注销认证信息

@ -25,7 +25,7 @@ namespace Video.DomainService
/// </summary> /// </summary>
/// <param name="dto"></param> /// <param name="dto"></param>
/// <returns></returns> /// <returns></returns>
Task<ApiResult<UrlDataDto>> RtspStartVideoUrl(StreamReqDto dto); Task<ApiResult<UrlDataDto>> RtspStartVideoUrl(StreamRtspReqDto dto);
/// <summary> /// <summary>
/// rtsp录像回放 /// rtsp录像回放

@ -121,7 +121,7 @@ namespace Video.DomainService
/// <param name="dto"></param> /// <param name="dto"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="NotImplementedException"></exception> /// <exception cref="NotImplementedException"></exception>
public async Task<ApiResult<UrlDataDto>> RtspStartVideoUrl(StreamReqDto dto) public async Task<ApiResult<UrlDataDto>> RtspStartVideoUrl(StreamRtspReqDto dto)
{ {
ApiResult<UrlDataDto> result = new ApiResult<UrlDataDto>() { Code = 200, Msg = "接口调用成功" }; ApiResult<UrlDataDto> result = new ApiResult<UrlDataDto>() { Code = 200, Msg = "接口调用成功" };
var urlReult = await _dahuaGeneralCtlService.RtspStartVideoUrl(dto); var urlReult = await _dahuaGeneralCtlService.RtspStartVideoUrl(dto);

Loading…
Cancel
Save