You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

121 line
6.0 KiB

  1. using JT1078.Gateway.Sessions;
  2. using Microsoft.Extensions.Hosting;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using System.Linq;
  8. using Microsoft.Extensions.Logging;
  9. using Microsoft.Extensions.Caching.Memory;
  10. using JT1078.Protocol;
  11. using System.Text.Json;
  12. using JT1078.Protocol.H264;
  13. using System.Collections.Concurrent;
  14. using JT1078.FMp4;
  15. using JT1078.Protocol.Extensions;
  16. using System.IO;
  17. namespace JT1078.Gateway.TestNormalHosting.Services
  18. {
  19. public class JT1078FMp4NormalMsgHostedService : BackgroundService
  20. {
  21. private JT1078HttpSessionManager HttpSessionManager;
  22. private FMp4Encoder FM4Encoder;
  23. private ILogger Logger;
  24. private IMemoryCache memoryCache;
  25. private const string ikey = "IFMp4KEY";
  26. private MessageDispatchDataService messageDispatchDataService;
  27. private ConcurrentDictionary<string, List<H264NALU>> avFrameDict;
  28. private H264Decoder H264Decoder;
  29. List<JT1078Package> SegmentPackages = new List<JT1078Package>();// 一段包 以I帧为界 IPPPP , IPPPP 一组
  30. public JT1078FMp4NormalMsgHostedService(
  31. MessageDispatchDataService messageDispatchDataService,
  32. IMemoryCache memoryCache,
  33. ILoggerFactory loggerFactory,
  34. FMp4Encoder fM4Encoder,
  35. H264Decoder h264Decoder,
  36. JT1078HttpSessionManager httpSessionManager)
  37. {
  38. Logger = loggerFactory.CreateLogger<JT1078FMp4NormalMsgHostedService>();
  39. HttpSessionManager = httpSessionManager;
  40. FM4Encoder = fM4Encoder;
  41. H264Decoder= h264Decoder;
  42. this.memoryCache = memoryCache;
  43. this.messageDispatchDataService = messageDispatchDataService;
  44. //todo:定时清理
  45. avFrameDict = new ConcurrentDictionary<string, List<H264NALU>>();
  46. }
  47. protected async override Task ExecuteAsync(CancellationToken stoppingToken)
  48. {
  49. while (!stoppingToken.IsCancellationRequested)
  50. {
  51. var data = await messageDispatchDataService.FMp4Channel.Reader.ReadAsync();
  52. try
  53. {
  54. if (Logger.IsEnabled(LogLevel.Debug))
  55. {
  56. Logger.LogDebug(JsonSerializer.Serialize(HttpSessionManager.GetAll()));
  57. Logger.LogDebug($"{data.SIM},{data.SN},{data.LogicChannelNumber},{data.Label3.DataType.ToString()},{data.Label3.SubpackageType.ToString()},{data.Bodies.ToHexString()}");
  58. }
  59. if (data.Label3.DataType == Protocol.Enums.JT1078DataType.视频I帧)
  60. {
  61. if (SegmentPackages.Count>0)
  62. {
  63. //判断是否首帧
  64. //Logger.LogDebug($"时间1:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff")}");
  65. var httpSessions = HttpSessionManager.GetAllBySimAndChannelNo(data.SIM.TrimStart('0'), data.LogicChannelNumber);
  66. var firstHttpSessions = httpSessions.Where(w => !w.FirstSend && (w.RTPVideoType == Metadata.RTPVideoType.Http_FMp4 || w.RTPVideoType == Metadata.RTPVideoType.Ws_FMp4)).ToList();
  67. var otherHttpSessions = httpSessions.Where(w => w.FirstSend && (w.RTPVideoType == Metadata.RTPVideoType.Http_FMp4 || w.RTPVideoType == Metadata.RTPVideoType.Ws_FMp4)).ToList();
  68. if (firstHttpSessions.Count > 0)
  69. {
  70. //唯一
  71. var ftyp = FM4Encoder.FtypBox();
  72. var package1 = SegmentPackages[0];
  73. var nalus1 = H264Decoder.ParseNALU(package1);
  74. var moov = FM4Encoder.MoovBox(
  75. nalus1.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.SPS),
  76. nalus1.FirstOrDefault(f => f.NALUHeader.NalUnitType == NalUnitType.PPS));
  77. //首帧
  78. var styp = FM4Encoder.StypBox();
  79. var firstVideo = FM4Encoder.OtherVideoBox(SegmentPackages);
  80. foreach (var session in firstHttpSessions)
  81. {
  82. HttpSessionManager.SendAVData(session, ftyp.Concat(moov).Concat(styp).Concat(firstVideo).ToArray(), true);
  83. SegmentPackages.Clear();//发送完成后清理
  84. }
  85. }
  86. if (otherHttpSessions.Count > 0)
  87. {
  88. //非首帧
  89. var styp = FM4Encoder.StypBox();
  90. var otherVideo = FM4Encoder.OtherVideoBox(SegmentPackages);
  91. foreach (var session in otherHttpSessions)
  92. {
  93. HttpSessionManager.SendAVData(session, styp.Concat(otherVideo).ToArray(), false);
  94. SegmentPackages.Clear();//发送完成后清理
  95. }
  96. }
  97. }
  98. if (SegmentPackages.Count==0)
  99. SegmentPackages.Add(data);
  100. }
  101. else {
  102. if (SegmentPackages.Count!=0) {
  103. SegmentPackages.Add(data);
  104. }
  105. }
  106. }
  107. catch (Exception ex)
  108. {
  109. Logger.LogError(ex, $"{data.SIM},{data.SN},{data.LogicChannelNumber},{data.Label3.DataType.ToString()},{data.Label3.SubpackageType.ToString()},{data.Bodies.ToHexString()}");
  110. }
  111. }
  112. await Task.CompletedTask;
  113. }
  114. }
  115. }