@@ -24,7 +24,7 @@ | |||||
<PackageReference Include="DotNetty.Handlers" Version="0.6.0" /> | <PackageReference Include="DotNetty.Handlers" Version="0.6.0" /> | ||||
<PackageReference Include="DotNetty.Transport.Libuv" Version="0.6.0" /> | <PackageReference Include="DotNetty.Transport.Libuv" Version="0.6.0" /> | ||||
<PackageReference Include="DotNetty.Codecs" Version="0.6.0" /> | <PackageReference Include="DotNetty.Codecs" Version="0.6.0" /> | ||||
<PackageReference Include="JT1078" Version="1.0.0" /> | |||||
<PackageReference Include="JT1078" Version="1.0.1" /> | |||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" /> | <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" /> | ||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="2.2.0" /> | <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="2.2.0" /> | ||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" /> | <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" /> | ||||
@@ -26,6 +26,9 @@ | |||||
<target name="JT1078TcpMessageHandlersHex" xsi:type="File" | <target name="JT1078TcpMessageHandlersHex" xsi:type="File" | ||||
fileName="${Directory}/JT1078TcpMessageHandlersHex/${shortdate}.log" | fileName="${Directory}/JT1078TcpMessageHandlersHex/${shortdate}.log" | ||||
layout="${date:format=yyyyMMddHHmmss},${message}"/> | layout="${date:format=yyyyMMddHHmmss},${message}"/> | ||||
<target name="JT1078TcpConnectionHandler" xsi:type="File" | |||||
fileName="${Directory}/JT1078TcpConnectionHandler/${shortdate}.log" | |||||
layout="${date:format=yyyyMMddHHmmss},${message}"/> | |||||
<target name="console" xsi:type="ColoredConsole" | <target name="console" xsi:type="ColoredConsole" | ||||
useDefaultRowHighlightingRules="false" | useDefaultRowHighlightingRules="false" | ||||
layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level} ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}"> | layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level} ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}"> | ||||
@@ -38,6 +41,7 @@ | |||||
</targets> | </targets> | ||||
<rules> | <rules> | ||||
<logger name="*" minlevel="Error" maxlevel="Fatal" writeTo="all"/> | <logger name="*" minlevel="Error" maxlevel="Fatal" writeTo="all"/> | ||||
<logger name="JT1078.DotNetty.Tcp.Handlers.JT1078TcpConnectionHandler" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpConnectionHandler,console"/> | |||||
<logger name="JT1078TcpMessageHandlers" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpMessageHandlers"/> | <logger name="JT1078TcpMessageHandlers" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpMessageHandlers"/> | ||||
<logger name="JT1078TcpMessageHandlersHex" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpMessageHandlersHex"/> | <logger name="JT1078TcpMessageHandlersHex" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpMessageHandlersHex"/> | ||||
</rules> | </rules> |
@@ -25,6 +25,9 @@ | |||||
layout="${date:format=yyyyMMddHHmmss},${message}"/> | layout="${date:format=yyyyMMddHHmmss},${message}"/> | ||||
<target name="JT1078TcpMessageHandlersHex" xsi:type="File" | <target name="JT1078TcpMessageHandlersHex" xsi:type="File" | ||||
fileName="${Directory}/JT1078TcpMessageHandlersHex/${shortdate}.log" | fileName="${Directory}/JT1078TcpMessageHandlersHex/${shortdate}.log" | ||||
layout="${date:format=yyyyMMddHHmmss},${message}"/> | |||||
<target name="JT1078TcpConnectionHandler" xsi:type="File" | |||||
fileName="${Directory}/JT1078TcpConnectionHandler/${shortdate}.log" | |||||
layout="${date:format=yyyyMMddHHmmss},${message}"/> | layout="${date:format=yyyyMMddHHmmss},${message}"/> | ||||
<target name="console" xsi:type="ColoredConsole" | <target name="console" xsi:type="ColoredConsole" | ||||
useDefaultRowHighlightingRules="false" | useDefaultRowHighlightingRules="false" | ||||
@@ -38,6 +41,7 @@ | |||||
</targets> | </targets> | ||||
<rules> | <rules> | ||||
<logger name="*" minlevel="Debug" maxlevel="Fatal" writeTo="all,console"/> | <logger name="*" minlevel="Debug" maxlevel="Fatal" writeTo="all,console"/> | ||||
<logger name="JT1078.DotNetty.Tcp.Handlers.JT1078TcpConnectionHandler" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpConnectionHandler,console"/> | |||||
<logger name="JT1078TcpMessageHandlers" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpMessageHandlers,console"/> | <logger name="JT1078TcpMessageHandlers" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpMessageHandlers,console"/> | ||||
<logger name="JT1078TcpMessageHandlersHex" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpMessageHandlersHex,console"/> | <logger name="JT1078TcpMessageHandlersHex" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpMessageHandlersHex,console"/> | ||||
</rules> | </rules> |
@@ -61,7 +61,7 @@ namespace JT1078.DotNetty.TestHosting | |||||
StartInfo = | StartInfo = | ||||
{ | { | ||||
FileName = @"C:\ffmpeg\bin\ffmpeg.exe", | FileName = @"C:\ffmpeg\bin\ffmpeg.exe", | ||||
Arguments = $@"-f dshow -i video={HardwareCamera.CameraName} -vcodec h264 -hls_wrap 20 -start_number 0 -hls_list_size 10 -f hls {filePath} -segment_time 10", | |||||
Arguments = $@"-f dshow -i video={HardwareCamera.CameraName} -vcodec h264 -hls_wrap 10 -start_number 0 -hls_list_size 10 -f hls {filePath} -segment_time 10", | |||||
UseShellExecute = false, | UseShellExecute = false, | ||||
CreateNoWindow = true | CreateNoWindow = true | ||||
} | } | ||||
@@ -1,6 +1,7 @@ | |||||
using DotNetty.Buffers; | using DotNetty.Buffers; | ||||
using JT1078.DotNetty.Core.Interfaces; | using JT1078.DotNetty.Core.Interfaces; | ||||
using JT1078.DotNetty.Core.Metadata; | using JT1078.DotNetty.Core.Metadata; | ||||
using JT1078.DotNetty.TestHosting.JT1078WSFlv; | |||||
using JT1078.Protocol; | using JT1078.Protocol; | ||||
using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
@@ -15,9 +16,12 @@ namespace JT1078.DotNetty.TestHosting.Handlers | |||||
{ | { | ||||
private readonly ILogger logger; | private readonly ILogger logger; | ||||
private readonly ILogger hexLogger; | private readonly ILogger hexLogger; | ||||
private readonly JT1078WSFlvDataService jT1078WSFlvDataService; | |||||
public JT1078TcpMessageHandlers( | public JT1078TcpMessageHandlers( | ||||
JT1078WSFlvDataService jT1078WSFlvDataServic, | |||||
ILoggerFactory loggerFactory) | ILoggerFactory loggerFactory) | ||||
{ | { | ||||
this.jT1078WSFlvDataService = jT1078WSFlvDataServic; | |||||
logger = loggerFactory.CreateLogger("JT1078TcpMessageHandlers"); | logger = loggerFactory.CreateLogger("JT1078TcpMessageHandlers"); | ||||
hexLogger = loggerFactory.CreateLogger("JT1078TcpMessageHandlersHex"); | hexLogger = loggerFactory.CreateLogger("JT1078TcpMessageHandlersHex"); | ||||
} | } | ||||
@@ -26,6 +30,11 @@ namespace JT1078.DotNetty.TestHosting.Handlers | |||||
{ | { | ||||
logger.LogInformation(JsonConvert.SerializeObject(request.Package)); | logger.LogInformation(JsonConvert.SerializeObject(request.Package)); | ||||
hexLogger.LogInformation($"{request.Package.SIM},{request.Package.SN},{request.Package.LogicChannelNumber},{request.Package.Label3.DataType.ToString()},{request.Package.Label3.SubpackageType.ToString()},{ByteBufferUtil.HexDump(request.Src)}"); | hexLogger.LogInformation($"{request.Package.SIM},{request.Package.SN},{request.Package.LogicChannelNumber},{request.Package.Label3.DataType.ToString()},{request.Package.Label3.SubpackageType.ToString()},{ByteBufferUtil.HexDump(request.Src)}"); | ||||
var mergePackage = JT1078Serializer.Merge(request.Package); | |||||
if (mergePackage != null) | |||||
{ | |||||
jT1078WSFlvDataService.JT1078Packages.Add(mergePackage); | |||||
} | |||||
return Task.FromResult<JT1078Response>(default); | return Task.FromResult<JT1078Response>(default); | ||||
} | } | ||||
} | } | ||||
@@ -18,12 +18,20 @@ | |||||
<PackageReference Include="NLog.Extensions.Logging" Version="1.5.1" /> | <PackageReference Include="NLog.Extensions.Logging" Version="1.5.1" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | <ItemGroup> | ||||
<ProjectReference Include="..\JT1078.DotNetty.Http\JT1078.DotNetty.Http.csproj" /> | <ProjectReference Include="..\JT1078.DotNetty.Http\JT1078.DotNetty.Http.csproj" /> | ||||
<ProjectReference Include="..\JT1078.DotNetty.Tcp\JT1078.DotNetty.Tcp.csproj" /> | <ProjectReference Include="..\JT1078.DotNetty.Tcp\JT1078.DotNetty.Tcp.csproj" /> | ||||
<ProjectReference Include="..\JT1078.DotNetty.Udp\JT1078.DotNetty.Udp.csproj" /> | <ProjectReference Include="..\JT1078.DotNetty.Udp\JT1078.DotNetty.Udp.csproj" /> | ||||
</ItemGroup> | </ItemGroup> | ||||
<ItemGroup> | |||||
<Reference Include="JT1078.Flv"> | |||||
<HintPath>dll\JT1078.Flv.dll</HintPath> | |||||
</Reference> | |||||
</ItemGroup> | |||||
<ItemGroup> | <ItemGroup> | ||||
<None Update="appsettings.json"> | <None Update="appsettings.json"> | ||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | <CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||||
@@ -52,6 +60,12 @@ | |||||
<None Update="HTTPFLV\flv.min.js"> | <None Update="HTTPFLV\flv.min.js"> | ||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | <CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||||
</None> | </None> | ||||
<None Update="JT1078WSFlv\flv.min.js"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
<None Update="JT1078WSFlv\index.html"> | |||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||||
</None> | |||||
</ItemGroup> | </ItemGroup> | ||||
</Project> | </Project> |
@@ -0,0 +1,17 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Text; | |||||
using System.Collections.Concurrent; | |||||
using JT1078.Protocol; | |||||
namespace JT1078.DotNetty.TestHosting.JT1078WSFlv | |||||
{ | |||||
public class JT1078WSFlvDataService | |||||
{ | |||||
public JT1078WSFlvDataService() | |||||
{ | |||||
JT1078Packages = new BlockingCollection<JT1078Package>(); | |||||
} | |||||
public BlockingCollection<JT1078Package> JT1078Packages { get; set; } | |||||
} | |||||
} |
@@ -0,0 +1,86 @@ | |||||
using DotNetty.Buffers; | |||||
using DotNetty.Codecs.Http.WebSockets; | |||||
using JT1078.DotNetty.Core.Session; | |||||
using JT1078.DotNetty.Core.Extensions; | |||||
using Microsoft.Extensions.Hosting; | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.IO; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading; | |||||
using System.Threading.Tasks; | |||||
using JT1078.Protocol; | |||||
using System.Collections.Concurrent; | |||||
using JT1078.Protocol.Enums; | |||||
using System.Diagnostics; | |||||
using System.IO.Pipes; | |||||
using Newtonsoft.Json; | |||||
using JT1078.DotNetty.TestHosting.JT1078WSFlv; | |||||
using JT1078.Flv; | |||||
using JT1078.Flv.H264; | |||||
using Microsoft.Extensions.Logging; | |||||
namespace JT1078.DotNetty.TestHosting | |||||
{ | |||||
/// <summary> | |||||
/// | |||||
/// </summary> | |||||
class JT1078WSFlvHostedService : IHostedService | |||||
{ | |||||
private readonly JT1078HttpSessionManager jT1078HttpSessionManager; | |||||
private ConcurrentDictionary<string, byte> exists = new ConcurrentDictionary<string, byte>(); | |||||
private readonly JT1078WSFlvDataService jT1078WSFlvDataService; | |||||
private readonly FlvEncoder FlvEncoder = new FlvEncoder(); | |||||
private readonly ILogger logger; | |||||
public JT1078WSFlvHostedService( | |||||
ILoggerFactory loggerFactory, | |||||
JT1078WSFlvDataService jT1078WSFlvDataServic, | |||||
JT1078HttpSessionManager jT1078HttpSessionManager) | |||||
{ | |||||
logger = loggerFactory.CreateLogger("JT1078WSFlvHostedService"); | |||||
this.jT1078WSFlvDataService = jT1078WSFlvDataServic; | |||||
this.jT1078HttpSessionManager = jT1078HttpSessionManager; | |||||
} | |||||
public Task StartAsync(CancellationToken cancellationToken) | |||||
{ | |||||
Task.Run(() => | |||||
{ | |||||
try | |||||
{ | |||||
foreach (var item in jT1078WSFlvDataService.JT1078Packages.GetConsumingEnumerable()) | |||||
{ | |||||
var flv3 = FlvEncoder.CreateFlvFrame(item); | |||||
if (flv3 == null) continue; | |||||
if (jT1078HttpSessionManager.GetAll().Count() > 0) | |||||
{ | |||||
foreach (var session in jT1078HttpSessionManager.GetAll()) | |||||
{ | |||||
if (!exists.ContainsKey(session.Channel.Id.AsShortText())) | |||||
{ | |||||
exists.TryAdd(session.Channel.Id.AsShortText(), 0); | |||||
string key = item.GetKey(); | |||||
session.SendBinaryWebSocketAsync(FlvEncoder.GetFirstFlvFrame(key, flv3)); | |||||
} | |||||
session.SendBinaryWebSocketAsync(flv3); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
Console.WriteLine(ex); | |||||
} | |||||
}); | |||||
return Task.CompletedTask; | |||||
} | |||||
public Task StopAsync(CancellationToken cancellationToken) | |||||
{ | |||||
return Task.CompletedTask; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,26 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> | |||||
<head> | |||||
<meta charset="utf-8" /> | |||||
<title></title> | |||||
<script src="flv.min.js"></script> | |||||
</head> | |||||
<body> | |||||
<video muted="muted" webkit-playsinline="true" autoplay="true" id="player"></video> | |||||
<script> | |||||
if (flvjs.isSupported()) { | |||||
var player = document.getElementById('player'); | |||||
var flvPlayer = flvjs.createPlayer({ | |||||
type: 'flv', | |||||
isLive: true, | |||||
url: "ws://127.0.0.1:1818/jt1078live?token=" + Math.floor((Math.random() * 1000000) + 1) | |||||
}); | |||||
flvPlayer.attachMediaElement(player); | |||||
flvPlayer.load(); | |||||
flvPlayer.play(); | |||||
} | |||||
</script> | |||||
</body> | |||||
</html> |
@@ -17,6 +17,7 @@ using System.Collections.Generic; | |||||
using System.Diagnostics; | using System.Diagnostics; | ||||
using System.Threading; | using System.Threading; | ||||
using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
using JT1078.DotNetty.TestHosting.JT1078WSFlv; | |||||
namespace JT1078.DotNetty.TestHosting | namespace JT1078.DotNetty.TestHosting | ||||
{ | { | ||||
@@ -55,18 +56,19 @@ namespace JT1078.DotNetty.TestHosting | |||||
}) | }) | ||||
.ConfigureServices((hostContext, services) => | .ConfigureServices((hostContext, services) => | ||||
{ | { | ||||
services.AddSingleton<JT1078WSFlvDataService>(); | |||||
services.AddSingleton<ILoggerFactory, LoggerFactory>(); | services.AddSingleton<ILoggerFactory, LoggerFactory>(); | ||||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | ||||
services.AddJT1078Core(hostContext.Configuration) | services.AddJT1078Core(hostContext.Configuration) | ||||
// .AddJT1078TcpHost() | |||||
// .Replace<JT1078TcpMessageHandlers>() | |||||
// .Builder() | |||||
// .AddJT1078UdpHost() | |||||
// .Replace<JT1078UdpMessageHandlers>() | |||||
// .Builder() | |||||
.AddJT1078TcpHost() | |||||
.Replace<JT1078TcpMessageHandlers>() | |||||
.Builder() | |||||
//.AddJT1078UdpHost() | |||||
//.Replace<JT1078UdpMessageHandlers>() | |||||
// .Builder() | |||||
.AddJT1078HttpHost() | .AddJT1078HttpHost() | ||||
//.UseHttpMiddleware<CustomHttpMiddleware>() | //.UseHttpMiddleware<CustomHttpMiddleware>() | ||||
.Builder() | |||||
//.Builder() | |||||
; | ; | ||||
//使用ffmpeg工具 | //使用ffmpeg工具 | ||||
//1.success | //1.success | ||||
@@ -77,7 +79,9 @@ namespace JT1078.DotNetty.TestHosting | |||||
//services.AddHostedService<FFMPEGWSFLVPHostedService>(); | //services.AddHostedService<FFMPEGWSFLVPHostedService>(); | ||||
//4.success | //4.success | ||||
//http://127.0.0.1:5001/HLS/hls.html | //http://127.0.0.1:5001/HLS/hls.html | ||||
services.AddHostedService<FFMPEGHLSHostedService>(); | |||||
//services.AddHostedService<FFMPEGHLSHostedService>(); | |||||
services.AddHostedService<JT1078WSFlvHostedService>(); | |||||
}); | }); | ||||
await serverHostBuilder.RunConsoleAsync(); | await serverHostBuilder.RunConsoleAsync(); | ||||
} | } | ||||
@@ -22,7 +22,7 @@ namespace JT1078.DotNetty.TestHosting | |||||
/// <summary> | /// <summary> | ||||
/// | /// | ||||
/// </summary> | /// </summary> | ||||
class FFMPEGWSFLVPHostedService : IHostedService,IDisposable | |||||
class FFMPEGWSFLVHostedService : IHostedService,IDisposable | |||||
{ | { | ||||
private readonly Process process; | private readonly Process process; | ||||
private readonly NamedPipeServerStream pipeServerOut; | private readonly NamedPipeServerStream pipeServerOut; | ||||
@@ -33,7 +33,7 @@ namespace JT1078.DotNetty.TestHosting | |||||
/// </summary> | /// </summary> | ||||
private byte[] flvFirstPackage; | private byte[] flvFirstPackage; | ||||
private ConcurrentDictionary<string,byte> exists = new ConcurrentDictionary<string, byte>(); | private ConcurrentDictionary<string,byte> exists = new ConcurrentDictionary<string, byte>(); | ||||
public FFMPEGWSFLVPHostedService( | |||||
public FFMPEGWSFLVHostedService( | |||||
JT1078HttpSessionManager jT1078HttpSessionManager) | JT1078HttpSessionManager jT1078HttpSessionManager) | ||||
{ | { | ||||
pipeServerOut = new NamedPipeServerStream(PipeNameOut, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous,102400,102400); | pipeServerOut = new NamedPipeServerStream(PipeNameOut, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous,102400,102400); |