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.
 
 
 

124 lines
4.7 KiB

  1. using DotNetty.Buffers;
  2. using DotNetty.Codecs.Http.WebSockets;
  3. using JT1078.DotNetty.Core.Session;
  4. using Microsoft.Extensions.Hosting;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. using JT1078.Protocol;
  13. using System.Collections.Concurrent;
  14. using JT1078.Protocol.Enums;
  15. using System.Diagnostics;
  16. using System.IO.Pipes;
  17. using Newtonsoft.Json;
  18. namespace JT1078.DotNetty.TestHosting
  19. {
  20. /// <summary>
  21. ///
  22. /// </summary>
  23. class FFMPEGWSFLVPHostedService :BackgroundService
  24. {
  25. private readonly Process process;
  26. private readonly NamedPipeServerStream pipeServerOut;
  27. private const string PipeNameOut = "demo2serverout";
  28. private readonly JT1078WebSocketSessionManager jT1078WebSocketSessionManager;
  29. /// <summary>
  30. /// 需要缓存flv的第一包数据,当新用户进来先推送第一包的数据
  31. /// </summary>
  32. private byte[] flvFirstPackage;
  33. private ConcurrentDictionary<string,byte> exists = new ConcurrentDictionary<string, byte>();
  34. public FFMPEGWSFLVPHostedService(
  35. JT1078WebSocketSessionManager jT1078WebSocketSessionManager)
  36. {
  37. pipeServerOut = new NamedPipeServerStream(PipeNameOut, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous,102400,102400);
  38. process = new Process
  39. {
  40. StartInfo =
  41. {
  42. FileName = @"C:\ffmpeg\bin\ffmpeg.exe",
  43. Arguments = $@"-f dshow -i video={HardwareCamera.CameraName} -c copy -f flv -vcodec h264 -y \\.\pipe\{PipeNameOut}",
  44. UseShellExecute = false,
  45. CreateNoWindow = true,
  46. }
  47. };
  48. this.jT1078WebSocketSessionManager = jT1078WebSocketSessionManager;
  49. }
  50. public override void Dispose()
  51. {
  52. try
  53. {
  54. process.Close();
  55. pipeServerOut.Flush();
  56. }
  57. catch
  58. {
  59. }
  60. process.Dispose();
  61. pipeServerOut.Dispose();
  62. base.Dispose();
  63. }
  64. protected override Task ExecuteAsync(CancellationToken stoppingToken)
  65. {
  66. process.Start();
  67. Task.Run(() =>
  68. {
  69. while (true)
  70. {
  71. try
  72. {
  73. Console.WriteLine("IsConnected>>>" + pipeServerOut.IsConnected);
  74. if (pipeServerOut.IsConnected)
  75. {
  76. if (pipeServerOut.CanRead)
  77. {
  78. Span<byte> v1 = new byte[2048];
  79. var length = pipeServerOut.Read(v1);
  80. var realValue = v1.Slice(0, length).ToArray();
  81. if (realValue.Length <= 0) continue;
  82. if (flvFirstPackage == null)
  83. {
  84. flvFirstPackage = realValue;
  85. }
  86. if (jT1078WebSocketSessionManager.GetAll().Count() > 0)
  87. {
  88. foreach (var session in jT1078WebSocketSessionManager.GetAll())
  89. {
  90. if (!exists.ContainsKey(session.Channel.Id.AsShortText()))
  91. {
  92. session.Channel.WriteAndFlushAsync(new BinaryWebSocketFrame(Unpooled.WrappedBuffer(flvFirstPackage)));
  93. exists.TryAdd(session.Channel.Id.AsShortText(), 0);
  94. }
  95. session.Channel.WriteAndFlushAsync(new BinaryWebSocketFrame(Unpooled.WrappedBuffer(realValue)));
  96. }
  97. }
  98. }
  99. }
  100. else
  101. {
  102. if (!pipeServerOut.IsConnected)
  103. {
  104. Console.WriteLine("WaitForConnection Star...");
  105. pipeServerOut.WaitForConnectionAsync();
  106. Console.WriteLine("WaitForConnection End...");
  107. }
  108. }
  109. }
  110. catch (Exception ex)
  111. {
  112. Console.WriteLine(ex);
  113. }
  114. }
  115. });
  116. return Task.CompletedTask;
  117. }
  118. }
  119. }