From 6ec31f5e78a1ebb91ad00520cf5c014665163374 Mon Sep 17 00:00:00 2001 From: waterliu99 Date: Wed, 28 Jul 2021 15:23:37 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9B=86=E6=88=90mp4=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Program.cs | 4 +- .../JT1078FMp4NormalMsgHostedService.cs | 70 ++++++------------- .../wwwroot/fmp4_demo/index.html | 3 +- src/JT1078.Gateway.sln | 12 ++++ src/JT1078.Gateway/JT1078.Gateway.csproj | 2 +- src/JT1078.Gateway/JT1078.Gateway.xml | 5 ++ .../Metadata/JT1078HttpContext.cs | 7 +- 7 files changed, 50 insertions(+), 53 deletions(-) diff --git a/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/Program.cs b/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/Program.cs index f74782a..0399646 100644 --- a/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/Program.cs +++ b/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/Program.cs @@ -42,14 +42,14 @@ namespace JT1078.Gateway.TestNormalHosting //hls视频解码器 services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); //添加hls依赖项 services.AddHlsGateway(hostContext.Configuration); services.Configure(hostContext.Configuration.GetSection("M3U8Option")); var m3u8Option = services.BuildServiceProvider().GetRequiredService>().Value; services.AddSingleton(m3u8Option); + services.AddSingleton(); + //使用内存队列实现会话通知 services.AddJT1078Gateway(hostContext.Configuration) .AddTcp() diff --git a/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/Services/JT1078FMp4NormalMsgHostedService.cs b/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/Services/JT1078FMp4NormalMsgHostedService.cs index a68f836..9ad8395 100644 --- a/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/Services/JT1078FMp4NormalMsgHostedService.cs +++ b/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/Services/JT1078FMp4NormalMsgHostedService.cs @@ -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(); HttpSessionManager = httpSessionManager; FM4Encoder = fM4Encoder; - H264Decoder = h264Decoder; this.memoryCache = memoryCache; this.messageDispatchDataService = messageDispatchDataService; avFrameDict = new ConcurrentDictionary>(); @@ -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 frames)) + foreach (var session in otherHttpSessions) { - frames = new List(); - 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; } diff --git a/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/wwwroot/fmp4_demo/index.html b/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/wwwroot/fmp4_demo/index.html index 6d0c1e4..1b65ae8 100644 --- a/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/wwwroot/fmp4_demo/index.html +++ b/src/JT1078.Gateway.Tests/JT1078.Gateway.TestNormalHosting/wwwroot/fmp4_demo/index.html @@ -168,7 +168,8 @@ // source_buffer.mode = 'segments'; source_buffer.addEventListener("updateend", loadPacket); - ws = new WebSocket("ws://127.0.0.1:15555/live.mp4?sim=12345678901&channel=3&token=123456"); //创建WebSocket连接 + ws = new WebSocket("ws://127.0.0.1:15555/live.mp4?sim=1901305037&channel=1&token=123456"); //创建WebSocket连接 + ws.binaryType = 'arraybuffer'; ws.onmessage = function (e) { //当客户端收到服务端发来的消息时,触发onmessage事件,参数e.data包含server传递过来的数据 console.log(e.data); diff --git a/src/JT1078.Gateway.sln b/src/JT1078.Gateway.sln index 4cf5778..02e6763 100644 --- a/src/JT1078.Gateway.sln +++ b/src/JT1078.Gateway.sln @@ -17,6 +17,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Gateway", "JT1078.Ga EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Gateway.InMemoryMQ", "JT1078.Gateway.InMemoryMQ\JT1078.Gateway.InMemoryMQ.csproj", "{011934D6-BEE7-4CDA-9F67-4D6D7D672D6C}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.FMp4", "..\..\JT1078\src\JT1078.FMp4\JT1078.FMp4.csproj", "{FDE3681A-46D2-451A-91A0-E5F63E80737F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JT1078.Protocol", "..\..\JT1078\src\JT1078.Protocol\JT1078.Protocol.csproj", "{D8714E62-5ECB-4886-8A97-11F215F8D60F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -47,6 +51,14 @@ Global {011934D6-BEE7-4CDA-9F67-4D6D7D672D6C}.Debug|Any CPU.Build.0 = Debug|Any CPU {011934D6-BEE7-4CDA-9F67-4D6D7D672D6C}.Release|Any CPU.ActiveCfg = Release|Any CPU {011934D6-BEE7-4CDA-9F67-4D6D7D672D6C}.Release|Any CPU.Build.0 = Release|Any CPU + {FDE3681A-46D2-451A-91A0-E5F63E80737F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FDE3681A-46D2-451A-91A0-E5F63E80737F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FDE3681A-46D2-451A-91A0-E5F63E80737F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FDE3681A-46D2-451A-91A0-E5F63E80737F}.Release|Any CPU.Build.0 = Release|Any CPU + {D8714E62-5ECB-4886-8A97-11F215F8D60F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8714E62-5ECB-4886-8A97-11F215F8D60F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8714E62-5ECB-4886-8A97-11F215F8D60F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8714E62-5ECB-4886-8A97-11F215F8D60F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/JT1078.Gateway/JT1078.Gateway.csproj b/src/JT1078.Gateway/JT1078.Gateway.csproj index 3a31ae5..68dc127 100644 --- a/src/JT1078.Gateway/JT1078.Gateway.csproj +++ b/src/JT1078.Gateway/JT1078.Gateway.csproj @@ -39,9 +39,9 @@ + - diff --git a/src/JT1078.Gateway/JT1078.Gateway.xml b/src/JT1078.Gateway/JT1078.Gateway.xml index 611ad76..fcc5020 100644 --- a/src/JT1078.Gateway/JT1078.Gateway.xml +++ b/src/JT1078.Gateway/JT1078.Gateway.xml @@ -195,6 +195,11 @@ 会话Id + + + FMp4编码信息 + + http上下文 diff --git a/src/JT1078.Gateway/Metadata/JT1078HttpContext.cs b/src/JT1078.Gateway/Metadata/JT1078HttpContext.cs index 7e190fb..eb4d597 100644 --- a/src/JT1078.Gateway/Metadata/JT1078HttpContext.cs +++ b/src/JT1078.Gateway/Metadata/JT1078HttpContext.cs @@ -1,4 +1,5 @@ -using System; +using JT1078.FMp4; +using System; using System.Collections.Generic; using System.Net; using System.Net.WebSockets; @@ -18,6 +19,10 @@ namespace JT1078.Gateway.Metadata /// public string SessionId { get; } /// + /// FMp4编码信息 + /// + public FMp4EncoderInfo FMp4EncoderInfo { get; set; } = new FMp4EncoderInfo(); + /// /// http上下文 /// [JsonIgnore]