@@ -24,7 +24,7 @@ | |||
<PackageReference Include="DotNetty.Handlers" Version="0.6.0" /> | |||
<PackageReference Include="DotNetty.Transport.Libuv" 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.Hosting.Abstractions" Version="2.2.0" /> | |||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" /> | |||
@@ -26,6 +26,9 @@ | |||
<target name="JT1078TcpMessageHandlersHex" xsi:type="File" | |||
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}"/> | |||
<target name="console" xsi:type="ColoredConsole" | |||
useDefaultRowHighlightingRules="false" | |||
layout="${date:format=yyyyMMddHHmmss} ${callsite} ${level} ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}"> | |||
@@ -38,6 +41,7 @@ | |||
</targets> | |||
<rules> | |||
<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="JT1078TcpMessageHandlersHex" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpMessageHandlersHex"/> | |||
</rules> |
@@ -25,6 +25,9 @@ | |||
layout="${date:format=yyyyMMddHHmmss},${message}"/> | |||
<target name="JT1078TcpMessageHandlersHex" xsi:type="File" | |||
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}"/> | |||
<target name="console" xsi:type="ColoredConsole" | |||
useDefaultRowHighlightingRules="false" | |||
@@ -38,6 +41,7 @@ | |||
</targets> | |||
<rules> | |||
<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="JT1078TcpMessageHandlersHex" minlevel="Debug" maxlevel="Fatal" writeTo="JT1078TcpMessageHandlersHex,console"/> | |||
</rules> |
@@ -61,7 +61,7 @@ namespace JT1078.DotNetty.TestHosting | |||
StartInfo = | |||
{ | |||
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, | |||
CreateNoWindow = true | |||
} | |||
@@ -1,6 +1,7 @@ | |||
using DotNetty.Buffers; | |||
using JT1078.DotNetty.Core.Interfaces; | |||
using JT1078.DotNetty.Core.Metadata; | |||
using JT1078.DotNetty.TestHosting.JT1078WSFlv; | |||
using JT1078.Protocol; | |||
using Microsoft.Extensions.Logging; | |||
using Newtonsoft.Json; | |||
@@ -15,9 +16,12 @@ namespace JT1078.DotNetty.TestHosting.Handlers | |||
{ | |||
private readonly ILogger logger; | |||
private readonly ILogger hexLogger; | |||
private readonly JT1078WSFlvDataService jT1078WSFlvDataService; | |||
public JT1078TcpMessageHandlers( | |||
JT1078WSFlvDataService jT1078WSFlvDataServic, | |||
ILoggerFactory loggerFactory) | |||
{ | |||
this.jT1078WSFlvDataService = jT1078WSFlvDataServic; | |||
logger = loggerFactory.CreateLogger("JT1078TcpMessageHandlers"); | |||
hexLogger = loggerFactory.CreateLogger("JT1078TcpMessageHandlersHex"); | |||
} | |||
@@ -26,6 +30,11 @@ namespace JT1078.DotNetty.TestHosting.Handlers | |||
{ | |||
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)}"); | |||
var mergePackage = JT1078Serializer.Merge(request.Package); | |||
if (mergePackage != null) | |||
{ | |||
jT1078WSFlvDataService.JT1078Packages.Add(mergePackage); | |||
} | |||
return Task.FromResult<JT1078Response>(default); | |||
} | |||
} | |||
@@ -18,12 +18,20 @@ | |||
<PackageReference Include="NLog.Extensions.Logging" Version="1.5.1" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\JT1078.DotNetty.Http\JT1078.DotNetty.Http.csproj" /> | |||
<ProjectReference Include="..\JT1078.DotNetty.Tcp\JT1078.DotNetty.Tcp.csproj" /> | |||
<ProjectReference Include="..\JT1078.DotNetty.Udp\JT1078.DotNetty.Udp.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Reference Include="JT1078.Flv"> | |||
<HintPath>dll\JT1078.Flv.dll</HintPath> | |||
</Reference> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Update="appsettings.json"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
@@ -52,6 +60,12 @@ | |||
<None Update="HTTPFLV\flv.min.js"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</None> | |||
<None Update="JT1078WSFlv\flv.min.js"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</None> | |||
<None Update="JT1078WSFlv\index.html"> | |||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | |||
</None> | |||
</ItemGroup> | |||
</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.Threading; | |||
using System.Threading.Tasks; | |||
using JT1078.DotNetty.TestHosting.JT1078WSFlv; | |||
namespace JT1078.DotNetty.TestHosting | |||
{ | |||
@@ -55,18 +56,19 @@ namespace JT1078.DotNetty.TestHosting | |||
}) | |||
.ConfigureServices((hostContext, services) => | |||
{ | |||
services.AddSingleton<JT1078WSFlvDataService>(); | |||
services.AddSingleton<ILoggerFactory, LoggerFactory>(); | |||
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); | |||
services.AddJT1078Core(hostContext.Configuration) | |||
// .AddJT1078TcpHost() | |||
// .Replace<JT1078TcpMessageHandlers>() | |||
// .Builder() | |||
// .AddJT1078UdpHost() | |||
// .Replace<JT1078UdpMessageHandlers>() | |||
// .Builder() | |||
.AddJT1078TcpHost() | |||
.Replace<JT1078TcpMessageHandlers>() | |||
.Builder() | |||
//.AddJT1078UdpHost() | |||
//.Replace<JT1078UdpMessageHandlers>() | |||
// .Builder() | |||
.AddJT1078HttpHost() | |||
//.UseHttpMiddleware<CustomHttpMiddleware>() | |||
.Builder() | |||
//.Builder() | |||
; | |||
//使用ffmpeg工具 | |||
//1.success | |||
@@ -77,7 +79,9 @@ namespace JT1078.DotNetty.TestHosting | |||
//services.AddHostedService<FFMPEGWSFLVPHostedService>(); | |||
//4.success | |||
//http://127.0.0.1:5001/HLS/hls.html | |||
services.AddHostedService<FFMPEGHLSHostedService>(); | |||
//services.AddHostedService<FFMPEGHLSHostedService>(); | |||
services.AddHostedService<JT1078WSFlvHostedService>(); | |||
}); | |||
await serverHostBuilder.RunConsoleAsync(); | |||
} | |||
@@ -22,7 +22,7 @@ namespace JT1078.DotNetty.TestHosting | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
class FFMPEGWSFLVPHostedService : IHostedService,IDisposable | |||
class FFMPEGWSFLVHostedService : IHostedService,IDisposable | |||
{ | |||
private readonly Process process; | |||
private readonly NamedPipeServerStream pipeServerOut; | |||
@@ -33,7 +33,7 @@ namespace JT1078.DotNetty.TestHosting | |||
/// </summary> | |||
private byte[] flvFirstPackage; | |||
private ConcurrentDictionary<string,byte> exists = new ConcurrentDictionary<string, byte>(); | |||
public FFMPEGWSFLVPHostedService( | |||
public FFMPEGWSFLVHostedService( | |||
JT1078HttpSessionManager jT1078HttpSessionManager) | |||
{ | |||
pipeServerOut = new NamedPipeServerStream(PipeNameOut, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous,102400,102400); |