|
|
@@ -1,22 +1,19 @@ |
|
|
|
using JT1078.Gateway.Abstractions; |
|
|
|
using JT1078.Gateway.Sessions; |
|
|
|
using JT1078.Flv; |
|
|
|
using JT1078.Gateway.Sessions; |
|
|
|
using Microsoft.Extensions.Hosting; |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Text; |
|
|
|
using System.Threading; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using System.Linq; |
|
|
|
using Microsoft.Extensions.Logging; |
|
|
|
using JT1078.Flv.Extensions; |
|
|
|
using Microsoft.Extensions.Caching.Memory; |
|
|
|
using JT1078.Protocol; |
|
|
|
using System.Text.Json; |
|
|
|
using System.Text.Json.Serialization; |
|
|
|
using JT1078.FMp4; |
|
|
|
using JT1078.Protocol.H264; |
|
|
|
using System.Collections.Concurrent; |
|
|
|
using JT1078.FMp4; |
|
|
|
using JT1078.Protocol.Extensions; |
|
|
|
using System.IO; |
|
|
|
|
|
|
|
namespace JT1078.Gateway.TestNormalHosting.Services |
|
|
|
{ |
|
|
@@ -24,7 +21,6 @@ namespace JT1078.Gateway.TestNormalHosting.Services |
|
|
|
{ |
|
|
|
private JT1078HttpSessionManager HttpSessionManager; |
|
|
|
private FMp4Encoder FM4Encoder; |
|
|
|
private readonly H264Decoder H264Decoder; |
|
|
|
private ILogger Logger; |
|
|
|
private IMemoryCache memoryCache; |
|
|
|
private const string ikey = "IFMp4KEY"; |
|
|
@@ -35,14 +31,12 @@ namespace JT1078.Gateway.TestNormalHosting.Services |
|
|
|
MessageDispatchDataService messageDispatchDataService, |
|
|
|
IMemoryCache memoryCache, |
|
|
|
ILoggerFactory loggerFactory, |
|
|
|
H264Decoder h264Decoder, |
|
|
|
FMp4Encoder fM4Encoder, |
|
|
|
JT1078HttpSessionManager httpSessionManager) |
|
|
|
{ |
|
|
|
Logger = loggerFactory.CreateLogger<JT1078FMp4NormalMsgHostedService>(); |
|
|
|
HttpSessionManager = httpSessionManager; |
|
|
|
FM4Encoder = fM4Encoder; |
|
|
|
H264Decoder = h264Decoder; |
|
|
|
this.memoryCache = memoryCache; |
|
|
|
this.messageDispatchDataService = messageDispatchDataService; |
|
|
|
avFrameDict = new ConcurrentDictionary<string, List<H264NALU>>(); |
|
|
@@ -51,10 +45,10 @@ namespace JT1078.Gateway.TestNormalHosting.Services |
|
|
|
{ |
|
|
|
while (!stoppingToken.IsCancellationRequested) |
|
|
|
{ |
|
|
|
var data = await messageDispatchDataService.FlvChannel.Reader.ReadAsync(); |
|
|
|
var data = await messageDispatchDataService.FMp4Channel.Reader.ReadAsync(); |
|
|
|
|
|
|
|
try |
|
|
|
{ |
|
|
|
var nalus = H264Decoder.ParseNALU(data); |
|
|
|
if (Logger.IsEnabled(LogLevel.Debug)) |
|
|
|
{ |
|
|
|
Logger.LogDebug(JsonSerializer.Serialize(HttpSessionManager.GetAll())); |
|
|
@@ -63,9 +57,7 @@ namespace JT1078.Gateway.TestNormalHosting.Services |
|
|
|
string key = $"{data.GetKey()}_{ikey}"; |
|
|
|
if (data.Label3.DataType == Protocol.Enums.JT1078DataType.视频I帧) |
|
|
|
{ |
|
|
|
var moov = FM4Encoder.EncoderMoovBox(nalus.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.SPS), |
|
|
|
nalus.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.PPS)); |
|
|
|
memoryCache.Set(key, moov); |
|
|
|
memoryCache.Set(key, data); |
|
|
|
} |
|
|
|
var httpSessions = HttpSessionManager.GetAllBySimAndChannelNo(data.SIM.TrimStart('0'), data.LogicChannelNumber); |
|
|
|
var firstHttpSessions = httpSessions.Where(w => !w.FirstSend).ToList(); |
|
|
@@ -73,14 +65,19 @@ namespace JT1078.Gateway.TestNormalHosting.Services |
|
|
|
{ |
|
|
|
try |
|
|
|
{ |
|
|
|
var flvVideoBuffer = FM4Encoder.EncoderFtypBox(); |
|
|
|
memoryCache.TryGetValue(key, out byte[] moovBuffer); |
|
|
|
foreach (var session in firstHttpSessions) |
|
|
|
if (memoryCache.TryGetValue(key, out JT1078Package idata)) |
|
|
|
{ |
|
|
|
HttpSessionManager.SendAVData(session, flvVideoBuffer, true); |
|
|
|
if (moovBuffer != null) |
|
|
|
try |
|
|
|
{ |
|
|
|
foreach (var session in firstHttpSessions) |
|
|
|
{ |
|
|
|
var fmp4VideoBuffer = FM4Encoder.EncoderVideo(idata, session.FMp4EncoderInfo, true); |
|
|
|
HttpSessionManager.SendAVData(session, fmp4VideoBuffer, true); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
|
{ |
|
|
|
HttpSessionManager.SendAVData(session, moovBuffer, false); |
|
|
|
Logger.LogError(ex, $"{data.SIM},{true},{data.SN},{data.LogicChannelNumber},{data.Label3.DataType.ToString()},{data.Label3.SubpackageType.ToString()},{data.Bodies.ToHexString()}"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@@ -94,34 +91,10 @@ namespace JT1078.Gateway.TestNormalHosting.Services |
|
|
|
{ |
|
|
|
try |
|
|
|
{ |
|
|
|
if(!avFrameDict.TryGetValue(key, out List<H264NALU> frames)) |
|
|
|
foreach (var session in otherHttpSessions) |
|
|
|
{ |
|
|
|
frames = new List<H264NALU>(); |
|
|
|
avFrameDict.TryAdd(key, frames); |
|
|
|
} |
|
|
|
foreach (var nalu in nalus) |
|
|
|
{ |
|
|
|
if (nalu.Slice) |
|
|
|
{ |
|
|
|
//H264 NALU slice first_mb_in_slice |
|
|
|
frames.Add(nalu); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if (nalus.Count > 0) |
|
|
|
{ |
|
|
|
var otherBuffer = FM4Encoder.EncoderOtherVideoBox(frames); |
|
|
|
foreach (var session in otherHttpSessions) |
|
|
|
{ |
|
|
|
if (otherBuffer != null) |
|
|
|
{ |
|
|
|
HttpSessionManager.SendAVData(session, otherBuffer, false); |
|
|
|
} |
|
|
|
} |
|
|
|
frames.Clear(); |
|
|
|
} |
|
|
|
frames.Add(nalu); |
|
|
|
} |
|
|
|
var fmp4VideoBuffer = FM4Encoder.EncoderVideo(data, session.FMp4EncoderInfo, false); |
|
|
|
HttpSessionManager.SendAVData(session, fmp4VideoBuffer, false); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception ex) |
|
|
@@ -134,6 +107,7 @@ namespace JT1078.Gateway.TestNormalHosting.Services |
|
|
|
{ |
|
|
|
Logger.LogError(ex, $"{data.SIM},{data.SN},{data.LogicChannelNumber},{data.Label3.DataType.ToString()},{data.Label3.SubpackageType.ToString()},{data.Bodies.ToHexString()}"); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
await Task.CompletedTask; |
|
|
|
} |
|
|
|