@@ -0,0 +1,33 @@ | |||||
<Project> | |||||
<PropertyGroup> | |||||
<TargetFramework>net6.0</TargetFramework> | |||||
<LangVersion>10.0</LangVersion> | |||||
<Copyright>Copyright 2019.</Copyright> | |||||
<Authors>SmallChi(Koike)</Authors> | |||||
<RepositoryUrl>https://github.com/SmallChi/JT1078Gateway</RepositoryUrl> | |||||
<PackageProjectUrl>https://github.com/SmallChi/JT1078Gateway</PackageProjectUrl> | |||||
<licenseUrl>https://github.com/SmallChi/JT1078Gateway/blob/master/LICENSE</licenseUrl> | |||||
<license>https://github.com/SmallChi/JT1078Gateway/blob/master/LICENSE</license> | |||||
<Version>1.0.0-preview3</Version> | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | |||||
<AnalysisLevel>latest</AnalysisLevel> | |||||
<EnableNETAnalyzers>true</EnableNETAnalyzers> | |||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild> | |||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> | |||||
<PackageReadmeFile>README.md</PackageReadmeFile> | |||||
<PublishRepositoryUrl>true</PublishRepositoryUrl> | |||||
<DebugSymbols>true</DebugSymbols> | |||||
<DebugType>embedded</DebugType> | |||||
</PropertyGroup> | |||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'"> | |||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild> | |||||
<Deterministic>true</Deterministic> | |||||
<EmbedUntrackedSources>true</EmbedUntrackedSources> | |||||
</PropertyGroup> | |||||
<ItemGroup> | |||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All"/> | |||||
</ItemGroup> | |||||
</Project> |
@@ -1,24 +1,12 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | <Project Sdk="Microsoft.NET.Sdk"> | ||||
<Import Project="..\Version.props" /> | |||||
<Import Project="..\Info.props" /> | |||||
<PropertyGroup> | <PropertyGroup> | ||||
<TargetFrameworks>netstandard2.1;net5.0;</TargetFrameworks> | |||||
<LangVersion>9.0</LangVersion> | |||||
<Copyright>Copyright 2019.</Copyright> | |||||
<Authors>SmallChi(Koike)</Authors> | |||||
<PackageId>JT1078.Gateway.Abstractions</PackageId> | <PackageId>JT1078.Gateway.Abstractions</PackageId> | ||||
<Product>JT1078.Gateway.Abstractions</Product> | <Product>JT1078.Gateway.Abstractions</Product> | ||||
<Description>基于JT1078Gateway的抽象库</Description> | <Description>基于JT1078Gateway的抽象库</Description> | ||||
<PackageReleaseNotes>基于JT1078Gateway的抽象库</PackageReleaseNotes> | <PackageReleaseNotes>基于JT1078Gateway的抽象库</PackageReleaseNotes> | ||||
<RepositoryUrl>https://github.com/SmallChi/JT1078Gateway</RepositoryUrl> | |||||
<PackageProjectUrl>https://github.com/SmallChi/JT1078Gateway</PackageProjectUrl> | |||||
<licenseUrl>https://github.com/SmallChi/JT1078Gateway/blob/master/LICENSE</licenseUrl> | |||||
<license>https://github.com/SmallChi/JT1078Gateway/blob/master/LICENSE</license> | |||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> | |||||
<SignAssembly>false</SignAssembly> | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | |||||
<Version>$(JT1078PackageVersion)</Version> | |||||
<DocumentationFile>JT1078.Gateway.Abstractions.xml</DocumentationFile> | <DocumentationFile>JT1078.Gateway.Abstractions.xml</DocumentationFile> | ||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -27,10 +15,11 @@ | |||||
<Compile Remove="IJT1078PackageProducer.cs" /> | <Compile Remove="IJT1078PackageProducer.cs" /> | ||||
<Compile Remove="IJT1078QueueGatewayBuilder.cs" /> | <Compile Remove="IJT1078QueueGatewayBuilder.cs" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | |||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | |||||
<None Include="..\..\README.md" Pack="true" PackagePath="" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="JT1078" Version="1.1.1-preview1" /> | <PackageReference Include="JT1078" Version="1.1.1-preview1" /> | ||||
@@ -1,7 +1,7 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk.Web"> | <Project Sdk="Microsoft.NET.Sdk.Web"> | ||||
<PropertyGroup> | <PropertyGroup> | ||||
<TargetFramework>net5.0</TargetFramework> | |||||
<TargetFramework>net6.0</TargetFramework> | |||||
<IsPackable>true</IsPackable> | <IsPackable>true</IsPackable> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
@@ -1,32 +1,21 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | <Project Sdk="Microsoft.NET.Sdk"> | ||||
<Import Project="..\Version.props" /> | |||||
<Import Project="..\Info.props" /> | |||||
<PropertyGroup> | <PropertyGroup> | ||||
<TargetFrameworks>netstandard2.1;net5.0;</TargetFrameworks> | |||||
<LangVersion>9.0</LangVersion> | |||||
<Copyright>Copyright 2019.</Copyright> | |||||
<Authors>SmallChi(Koike)</Authors> | |||||
<PackageId>JT1078.Gateway.InMemoryMQ</PackageId> | <PackageId>JT1078.Gateway.InMemoryMQ</PackageId> | ||||
<Product>JT1078.Gateway.InMemoryMQ</Product> | <Product>JT1078.Gateway.InMemoryMQ</Product> | ||||
<Description>基于JT1078Gateway实现的内存队列</Description> | <Description>基于JT1078Gateway实现的内存队列</Description> | ||||
<PackageReleaseNotes>基于JT1078Gateway实现的内存队列</PackageReleaseNotes> | <PackageReleaseNotes>基于JT1078Gateway实现的内存队列</PackageReleaseNotes> | ||||
<RepositoryUrl>https://github.com/SmallChi/JT1078Gateway</RepositoryUrl> | |||||
<PackageProjectUrl>https://github.com/SmallChi/JT1078Gateway</PackageProjectUrl> | |||||
<licenseUrl>https://github.com/SmallChi/JT1078Gateway/blob/master/LICENSE</licenseUrl> | |||||
<license>https://github.com/SmallChi/JT1078Gateway/blob/master/LICENSE</license> | |||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> | |||||
<SignAssembly>false</SignAssembly> | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | |||||
<Version>$(JT1078PackageVersion)</Version> | |||||
<DocumentationFile>JT1078.Gateway.InMemoryMQ.xml</DocumentationFile> | <DocumentationFile>JT1078.Gateway.InMemoryMQ.xml</DocumentationFile> | ||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="System.Threading.Channels" Version="5.0.0" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | |||||
<PackageReference Include="System.Threading.Channels" Version="6.0.0" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | |||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | |||||
<None Include="..\..\README.md" Pack="true" PackagePath="" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | <ItemGroup> | ||||
<ProjectReference Include="..\JT1078.Gateway.Abstractions\JT1078.Gateway.Abstractions.csproj" /> | <ProjectReference Include="..\JT1078.Gateway.Abstractions\JT1078.Gateway.Abstractions.csproj" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
@@ -1,19 +1,19 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | <Project Sdk="Microsoft.NET.Sdk"> | ||||
<PropertyGroup> | <PropertyGroup> | ||||
<TargetFramework>net5.0</TargetFramework> | |||||
<TargetFramework>net6.0</TargetFramework> | |||||
<IsPackable>false</IsPackable> | <IsPackable>false</IsPackable> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" /> | |||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> | |||||
<PackageReference Include="xunit" Version="2.4.1" /> | <PackageReference Include="xunit" Version="2.4.1" /> | ||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"> | <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3"> | ||||
<PrivateAssets>all</PrivateAssets> | <PrivateAssets>all</PrivateAssets> | ||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||
</PackageReference> | </PackageReference> | ||||
<PackageReference Include="coverlet.collector" Version="1.3.0"> | |||||
<PackageReference Include="coverlet.collector" Version="3.1.0"> | |||||
<PrivateAssets>all</PrivateAssets> | <PrivateAssets>all</PrivateAssets> | ||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||
</PackageReference> | </PackageReference> | ||||
@@ -6,11 +6,11 @@ | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" /> | |||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.2" /> | |||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="6.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" /> | |||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="6.0.0" /> | |||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.7.4" /> | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
@@ -17,20 +17,19 @@ using System.IO; | |||||
namespace JT1078.Gateway.TestNormalHosting.Services | namespace JT1078.Gateway.TestNormalHosting.Services | ||||
{ | { | ||||
public class JT1078FMp4NormalMsgHostedService : BackgroundService | |||||
public class JT1078FMp4NormalMsgHostedService : IHostedService | |||||
{ | { | ||||
private JT1078HttpSessionManager HttpSessionManager; | private JT1078HttpSessionManager HttpSessionManager; | ||||
private FMp4Encoder FM4Encoder; | private FMp4Encoder FM4Encoder; | ||||
private ILogger Logger; | private ILogger Logger; | ||||
private IMemoryCache memoryCache; | |||||
private const string ikey = "IFMp4KEY"; | private const string ikey = "IFMp4KEY"; | ||||
private MessageDispatchDataService messageDispatchDataService; | private MessageDispatchDataService messageDispatchDataService; | ||||
private ConcurrentDictionary<string, List<H264NALU>> avFrameDict; | |||||
private ConcurrentDictionary<string, FMp4AVContext> avFrameDict; | |||||
private H264Decoder H264Decoder; | private H264Decoder H264Decoder; | ||||
List<JT1078Package> SegmentPackages = new List<JT1078Package>();// 一段包 以I帧为界 IPPPP , IPPPP 一组 | |||||
List<NalUnitType> NaluFilter; | |||||
BlockingCollection<(string SIM, byte ChannelNo,byte[]FirstBuffer, byte[] OtherBuffer)> FMp4Blocking; | |||||
public JT1078FMp4NormalMsgHostedService( | public JT1078FMp4NormalMsgHostedService( | ||||
MessageDispatchDataService messageDispatchDataService, | MessageDispatchDataService messageDispatchDataService, | ||||
IMemoryCache memoryCache, | |||||
ILoggerFactory loggerFactory, | ILoggerFactory loggerFactory, | ||||
FMp4Encoder fM4Encoder, | FMp4Encoder fM4Encoder, | ||||
H264Decoder h264Decoder, | H264Decoder h264Decoder, | ||||
@@ -40,81 +39,149 @@ namespace JT1078.Gateway.TestNormalHosting.Services | |||||
HttpSessionManager = httpSessionManager; | HttpSessionManager = httpSessionManager; | ||||
FM4Encoder = fM4Encoder; | FM4Encoder = fM4Encoder; | ||||
H264Decoder= h264Decoder; | H264Decoder= h264Decoder; | ||||
this.memoryCache = memoryCache; | |||||
this.messageDispatchDataService = messageDispatchDataService; | this.messageDispatchDataService = messageDispatchDataService; | ||||
//todo:定时清理 | |||||
avFrameDict = new ConcurrentDictionary<string, List<H264NALU>>(); | |||||
avFrameDict = new ConcurrentDictionary<string, FMp4AVContext>(); | |||||
FMp4Blocking=new BlockingCollection<(string SIM, byte ChannelNo, byte[] FirstBuffer, byte[] OtherBuffer)>(); | |||||
NaluFilter = new List<NalUnitType>(); | |||||
NaluFilter.Add(NalUnitType.SEI); | |||||
NaluFilter.Add(NalUnitType.PPS); | |||||
NaluFilter.Add(NalUnitType.SPS); | |||||
NaluFilter.Add(NalUnitType.AUD); | |||||
} | } | ||||
protected async override Task ExecuteAsync(CancellationToken stoppingToken) | |||||
public Task StartAsync(CancellationToken cancellationToken) | |||||
{ | { | ||||
while (!stoppingToken.IsCancellationRequested) | |||||
{ | |||||
var data = await messageDispatchDataService.FMp4Channel.Reader.ReadAsync(); | |||||
try | |||||
Task.Run(async () => { | |||||
while (!cancellationToken.IsCancellationRequested) | |||||
{ | { | ||||
if (Logger.IsEnabled(LogLevel.Debug)) | |||||
{ | |||||
Logger.LogDebug(JsonSerializer.Serialize(HttpSessionManager.GetAll())); | |||||
Logger.LogDebug($"{data.SIM},{data.SN},{data.LogicChannelNumber},{data.Label3.DataType.ToString()},{data.Label3.SubpackageType.ToString()},{data.Bodies.ToHexString()}"); | |||||
} | |||||
if (data.Label3.DataType == Protocol.Enums.JT1078DataType.视频I帧) | |||||
var data = await messageDispatchDataService.FMp4Channel.Reader.ReadAsync(); | |||||
try | |||||
{ | { | ||||
if (SegmentPackages.Count>0) | |||||
if (Logger.IsEnabled(LogLevel.Debug)) | |||||
{ | { | ||||
//判断是否首帧 | |||||
//Logger.LogDebug($"时间1:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff")}"); | |||||
var httpSessions = HttpSessionManager.GetAllBySimAndChannelNo(data.SIM.TrimStart('0'), data.LogicChannelNumber); | |||||
var firstHttpSessions = httpSessions.Where(w => !w.FirstSend && (w.RTPVideoType == Metadata.RTPVideoType.Http_FMp4 || w.RTPVideoType == Metadata.RTPVideoType.Ws_FMp4)).ToList(); | |||||
var otherHttpSessions = httpSessions.Where(w => w.FirstSend && (w.RTPVideoType == Metadata.RTPVideoType.Http_FMp4 || w.RTPVideoType == Metadata.RTPVideoType.Ws_FMp4)).ToList(); | |||||
if (firstHttpSessions.Count > 0) | |||||
Logger.LogDebug(JsonSerializer.Serialize(HttpSessionManager.GetAll())); | |||||
Logger.LogDebug($"{data.SIM},{data.SN},{data.LogicChannelNumber},{data.Label3.DataType.ToString()},{data.Label3.SubpackageType.ToString()},{data.Bodies.ToHexString()}"); | |||||
} | |||||
List<H264NALU> h264NALUs = H264Decoder.ParseNALU(data); | |||||
if (h264NALUs!=null && h264NALUs.Count>0) | |||||
{ | |||||
if(!avFrameDict.TryGetValue(data.GetKey(),out FMp4AVContext cacheFrame)) | |||||
{ | |||||
cacheFrame=new FMp4AVContext(); | |||||
avFrameDict.TryAdd(data.GetKey(), cacheFrame); | |||||
} | |||||
foreach(var nalu in h264NALUs) | |||||
{ | { | ||||
//唯一 | |||||
var ftyp = FM4Encoder.FtypBox(); | |||||
var package1 = SegmentPackages[0]; | |||||
var nalus1 = H264Decoder.ParseNALU(package1); | |||||
var moov = FM4Encoder.MoovBox( | |||||
nalus1.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.SPS), | |||||
nalus1.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.PPS)); | |||||
//首帧 | |||||
var styp = FM4Encoder.StypBox(); | |||||
var firstVideo = FM4Encoder.OtherVideoBox(SegmentPackages); | |||||
foreach (var session in firstHttpSessions) | |||||
if (NaluFilter.Contains(nalu.NALUHeader.NalUnitType)) | |||||
{ | { | ||||
HttpSessionManager.SendAVData(session, ftyp.Concat(moov).Concat(styp).Concat(firstVideo).ToArray(), true); | |||||
SegmentPackages.Clear();//发送完成后清理 | |||||
if (nalu.NALUHeader.NalUnitType== NalUnitType.SPS) | |||||
{ | |||||
cacheFrame.SPSNalu=nalu; | |||||
} | |||||
else if (nalu.NALUHeader.NalUnitType== NalUnitType.PPS) | |||||
{ | |||||
cacheFrame.PPSNalu=nalu; | |||||
} | |||||
} | |||||
else | |||||
{ | |||||
cacheFrame.NALUs.Add(nalu); | |||||
} | } | ||||
} | } | ||||
if (otherHttpSessions.Count > 0) | |||||
if (cacheFrame.NALUs.Count>1) | |||||
{ | { | ||||
//非首帧 | |||||
var styp = FM4Encoder.StypBox(); | |||||
var otherVideo = FM4Encoder.OtherVideoBox(SegmentPackages); | |||||
foreach (var session in otherHttpSessions) | |||||
if (cacheFrame.FirstCacheBuffer==null) | |||||
{ | { | ||||
HttpSessionManager.SendAVData(session, styp.Concat(otherVideo).ToArray(), false); | |||||
SegmentPackages.Clear();//发送完成后清理 | |||||
cacheFrame.FirstCacheBuffer=FM4Encoder.FirstVideoBox(cacheFrame.SPSNalu, cacheFrame.PPSNalu); | |||||
} | } | ||||
List<H264NALU> tmp = new List<H264NALU>(); | |||||
int i = 0; | |||||
foreach (var item in cacheFrame.NALUs) | |||||
{ | |||||
if (item.NALUHeader.KeyFrame) | |||||
{ | |||||
if (tmp.Count>0) | |||||
{ | |||||
FMp4Blocking.Add((data.SIM, data.LogicChannelNumber, cacheFrame.FirstCacheBuffer, FM4Encoder.OtherVideoBox(tmp))); | |||||
i+=tmp.Count; | |||||
tmp.Clear(); | |||||
} | |||||
tmp.Add(item); | |||||
i+=tmp.Count; | |||||
FMp4Blocking.Add((data.SIM, data.LogicChannelNumber, cacheFrame.FirstCacheBuffer, FM4Encoder.OtherVideoBox(tmp))); | |||||
tmp.Clear(); | |||||
cacheFrame.PrevPrimaryNalu = item; | |||||
continue; | |||||
} | |||||
if (cacheFrame.PrevPrimaryNalu!=null) //第一帧I帧 | |||||
{ | |||||
if (tmp.Count>1) | |||||
{ | |||||
FMp4Blocking.Add((data.SIM, data.LogicChannelNumber, cacheFrame.FirstCacheBuffer, FM4Encoder.OtherVideoBox(tmp))); | |||||
i+=tmp.Count; | |||||
tmp.Clear(); | |||||
} | |||||
tmp.Add(item); | |||||
} | |||||
} | |||||
cacheFrame.NALUs.RemoveRange(0, i); | |||||
} | } | ||||
} | } | ||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
Logger.LogError(ex, $"{data.SIM},{data.SN},{data.LogicChannelNumber},{data.Label3.DataType.ToString()},{data.Label3.SubpackageType.ToString()},{data.Bodies.ToHexString()}"); | |||||
} | |||||
if (SegmentPackages.Count==0) | |||||
SegmentPackages.Add(data); | |||||
} | |||||
}); | |||||
Task.Run(() => { | |||||
try | |||||
{ | |||||
foreach(var item in FMp4Blocking.GetConsumingEnumerable(cancellationToken)) | |||||
{ | |||||
var httpSessions = HttpSessionManager.GetAllBySimAndChannelNo(item.SIM.TrimStart('0'), item.ChannelNo); | |||||
var firstHttpSessions = httpSessions.Where(w => !w.FirstSend && (w.RTPVideoType == Metadata.RTPVideoType.Http_FMp4 || w.RTPVideoType == Metadata.RTPVideoType.Ws_FMp4)).ToList(); | |||||
var otherHttpSessions = httpSessions.Where(w => w.FirstSend && (w.RTPVideoType == Metadata.RTPVideoType.Http_FMp4 || w.RTPVideoType == Metadata.RTPVideoType.Ws_FMp4)).ToList(); | |||||
if (firstHttpSessions.Count > 0) | |||||
{ | |||||
//首帧 | |||||
foreach (var session in firstHttpSessions) | |||||
{ | |||||
HttpSessionManager.SendAVData(session, item.FirstBuffer, true); | |||||
HttpSessionManager.SendAVData(session, item.OtherBuffer, false); | |||||
} | |||||
} | |||||
if (otherHttpSessions.Count > 0) | |||||
{ | |||||
//非首帧 | |||||
foreach (var session in otherHttpSessions) | |||||
{ | |||||
HttpSessionManager.SendAVData(session, item.OtherBuffer, false); | |||||
} | |||||
} | |||||
} | } | ||||
else { | |||||
if (SegmentPackages.Count!=0) { | |||||
SegmentPackages.Add(data); | |||||
} | |||||
} | |||||
} | } | ||||
catch (Exception ex) | catch (Exception ex) | ||||
{ | { | ||||
Logger.LogError(ex, $"{data.SIM},{data.SN},{data.LogicChannelNumber},{data.Label3.DataType.ToString()},{data.Label3.SubpackageType.ToString()},{data.Bodies.ToHexString()}"); | |||||
} | } | ||||
} | |||||
await Task.CompletedTask; | |||||
}); | |||||
return Task.CompletedTask; | |||||
} | |||||
public Task StopAsync(CancellationToken cancellationToken) | |||||
{ | |||||
return Task.CompletedTask; | |||||
} | |||||
public class FMp4AVContext | |||||
{ | |||||
public byte[] FirstCacheBuffer { get; set; } | |||||
public H264NALU PrevPrimaryNalu { get; set; } | |||||
public H264NALU SPSNalu { get; set; } | |||||
public H264NALU PPSNalu { get; set; } | |||||
public List<H264NALU> NALUs { get; set; } = new List<H264NALU>(); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -33,16 +33,17 @@ namespace JT1078.Gateway.TestNormalHosting.Services | |||||
var merge = JT1078.Protocol.JT1078Serializer.Merge(package); | var merge = JT1078.Protocol.JT1078Serializer.Merge(package); | ||||
if (merge != null) | if (merge != null) | ||||
{ | { | ||||
Parallel.Invoke( | |||||
async() => { | |||||
await messageDispatchDataService.FMp4Channel.Writer.WriteAsync(merge, stoppingToken); | |||||
}, | |||||
async () => { | |||||
await messageDispatchDataService.FlvChannel.Writer.WriteAsync(merge, stoppingToken); | |||||
}, | |||||
async () => { | |||||
await messageDispatchDataService.HlsChannel.Writer.WriteAsync(merge, stoppingToken); | |||||
}); | |||||
await messageDispatchDataService.FMp4Channel.Writer.WriteAsync(merge, stoppingToken); | |||||
//Parallel.Invoke( | |||||
// async() => { | |||||
// await messageDispatchDataService.FMp4Channel.Writer.WriteAsync(merge, stoppingToken); | |||||
// }, | |||||
// async () => { | |||||
// await messageDispatchDataService.FlvChannel.Writer.WriteAsync(merge, stoppingToken); | |||||
// }, | |||||
// async () => { | |||||
// await messageDispatchDataService.HlsChannel.Writer.WriteAsync(merge, stoppingToken); | |||||
// }); | |||||
} | } | ||||
}); | }); | ||||
return Task.CompletedTask; | return Task.CompletedTask; | ||||
@@ -1,7 +1,7 @@ | |||||
| | ||||
Microsoft Visual Studio Solution File, Format Version 12.00 | Microsoft Visual Studio Solution File, Format Version 12.00 | ||||
# Visual Studio Version 16 | |||||
VisualStudioVersion = 16.0.29418.71 | |||||
# Visual Studio Version 17 | |||||
VisualStudioVersion = 17.0.32002.185 | |||||
MinimumVisualStudioVersion = 10.0.40219.1 | MinimumVisualStudioVersion = 10.0.40219.1 | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Gateway.Test", "JT1078.Gateway.Tests\JT1078.Gateway.Test\JT1078.Gateway.Test.csproj", "{DAC80A8E-4172-451F-910D-9032BF8640F9}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Gateway.Test", "JT1078.Gateway.Tests\JT1078.Gateway.Test\JT1078.Gateway.Test.csproj", "{DAC80A8E-4172-451F-910D-9032BF8640F9}" | ||||
EndProject | EndProject | ||||
@@ -17,6 +17,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Gateway", "JT1078.Ga | |||||
EndProject | EndProject | ||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Gateway.InMemoryMQ", "JT1078.Gateway.InMemoryMQ\JT1078.Gateway.InMemoryMQ.csproj", "{011934D6-BEE7-4CDA-9F67-4D6D7D672D6C}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Gateway.InMemoryMQ", "JT1078.Gateway.InMemoryMQ\JT1078.Gateway.InMemoryMQ.csproj", "{011934D6-BEE7-4CDA-9F67-4D6D7D672D6C}" | ||||
EndProject | EndProject | ||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6631FE91-3525-4A84-937B-781C73B343C9}" | |||||
ProjectSection(SolutionItems) = preProject | |||||
Info.props = Info.props | |||||
EndProjectSection | |||||
EndProject | |||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
Debug|Any CPU = Debug|Any CPU | Debug|Any CPU = Debug|Any CPU | ||||
@@ -1,24 +1,12 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | <Project Sdk="Microsoft.NET.Sdk"> | ||||
<Import Project="..\Version.props" /> | |||||
<Import Project="..\Info.props" /> | |||||
<PropertyGroup> | <PropertyGroup> | ||||
<TargetFrameworks>net6.0;</TargetFrameworks> | |||||
<LangVersion>9.0</LangVersion> | |||||
<Copyright>Copyright 2019.</Copyright> | |||||
<Authors>SmallChi(Koike)</Authors> | |||||
<PackageId>JT1078.Gateway</PackageId> | <PackageId>JT1078.Gateway</PackageId> | ||||
<Product>JT1078.Gateway</Product> | <Product>JT1078.Gateway</Product> | ||||
<Description>基于Pipeline实现的JT1078Gateway库</Description> | <Description>基于Pipeline实现的JT1078Gateway库</Description> | ||||
<PackageReleaseNotes>基于Pipeline实现的JT1078Gateway库</PackageReleaseNotes> | <PackageReleaseNotes>基于Pipeline实现的JT1078Gateway库</PackageReleaseNotes> | ||||
<RepositoryUrl>https://github.com/SmallChi/JT1078Gateway</RepositoryUrl> | |||||
<PackageProjectUrl>https://github.com/SmallChi/JT1078Gateway</PackageProjectUrl> | |||||
<licenseUrl>https://github.com/SmallChi/JT1078Gateway/blob/master/LICENSE</licenseUrl> | |||||
<license>https://github.com/SmallChi/JT1078Gateway/blob/master/LICENSE</license> | |||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild> | |||||
<SignAssembly>false</SignAssembly> | |||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance> | |||||
<Version>$(JT1078PackageVersion)</Version> | |||||
<DocumentationFile>JT1078.Gateway.xml</DocumentationFile> | <DocumentationFile>JT1078.Gateway.xml</DocumentationFile> | ||||
<PackageLicenseFile>LICENSE</PackageLicenseFile> | |||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<Compile Remove="Codecs\**" /> | <Compile Remove="Codecs\**" /> | ||||
@@ -39,16 +27,17 @@ | |||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<PackageReference Include="JT1078.Hls" Version="1.2.0-preview1" /> | |||||
<PackageReference Include="JT1078.FMp4" Version="1.2.0-preview1" /> | |||||
<PackageReference Include="JT1078.Flv" Version="1.2.0-preview1" /> | |||||
<PackageReference Include="JT1078.Hls" Version="1.2.0-preview2" /> | |||||
<PackageReference Include="JT1078.FMp4" Version="1.2.0-preview2" /> | |||||
<PackageReference Include="JT1078.Flv" Version="1.2.0-preview2" /> | |||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" /> | <PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" /> | ||||
<PackageReference Include="System.IO.Pipelines" Version="6.0.1" /> | <PackageReference Include="System.IO.Pipelines" Version="6.0.1" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | |||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | |||||
<None Include="..\..\LICENSE" Pack="true" PackagePath="" /> | |||||
<None Include="..\..\README.md" Pack="true" PackagePath="" /> | |||||
</ItemGroup> | |||||
<ItemGroup> | <ItemGroup> | ||||
<ProjectReference Include="..\JT1078.Gateway.Abstractions\JT1078.Gateway.Abstractions.csproj" /> | <ProjectReference Include="..\JT1078.Gateway.Abstractions\JT1078.Gateway.Abstractions.csproj" /> | ||||