星火微课系统客户端
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

ZVideoRecordHelper.cs 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. using System;
  2. using System.Drawing.Imaging;
  3. using System.Drawing;
  4. using System.Runtime.InteropServices;
  5. using Accord.Video;
  6. using Accord.Video.FFMPEG;
  7. namespace XHWK.WKTool.Utils
  8. {
  9. using System.Linq;
  10. public class ZVideoRecordHelper
  11. {
  12. public enum RecordState
  13. {
  14. Stop = 0,
  15. Start = 1,
  16. Pause = 2
  17. }
  18. private RecordState _state;
  19. //录制帧率
  20. //录制质量
  21. private bool _captureMouse;
  22. private VideoFileWriter _videoWriter = new VideoFileWriter(); //视频写入
  23. private ScreenCaptureStream _videoStreamer; //视频捕获
  24. public ZVideoRecordHelper(string filePath, int width, int height, int rate = 5, int quality = 8, bool captureMouse = false)
  25. {
  26. int width1 = width / 2 * 2;
  27. int height1 = height / 2 * 2;
  28. int rate1 = rate;
  29. _captureMouse = captureMouse;
  30. _state = RecordState.Pause;
  31. try
  32. {
  33. // 打开写入
  34. lock (this)
  35. {
  36. _videoWriter.Open(
  37. filePath,
  38. width1,
  39. height1,
  40. rate1,
  41. VideoCodec.MPEG4,
  42. width1 * height1 * quality
  43. );
  44. }
  45. System.Drawing.Rectangle rec = new System.Drawing.Rectangle(
  46. 0,
  47. 0,
  48. width1,
  49. height1
  50. );
  51. _videoStreamer = new ScreenCaptureStream(rec, 1000 / rate1); //帧间隔需要和帧率关联,不然录的10秒视频文件不是10s
  52. _videoStreamer.NewFrame += VideoNewFrame;
  53. _videoStreamer.Start();
  54. }
  55. catch (Exception)
  56. {
  57. // ignored
  58. }
  59. }
  60. /// <summary>
  61. /// 开始录制
  62. /// </summary>
  63. public bool StartRecordVideo()
  64. {
  65. _state = RecordState.Start;
  66. return true;
  67. }
  68. [DllImport("user32.dll")]
  69. private static extern bool GetCursorInfo(out Cursorinfo pci);
  70. [StructLayout(LayoutKind.Sequential)]
  71. private struct Point
  72. {
  73. public Int32 x;
  74. public Int32 y;
  75. }
  76. [StructLayout(LayoutKind.Sequential)]
  77. private struct Cursorinfo
  78. {
  79. public Int32 cbSize;
  80. public Int32 flags;
  81. public IntPtr hCursor;
  82. public Point ptScreenPos;
  83. }
  84. // 帧返回时绘制上鼠标
  85. private void VideoNewFrame(object sender, NewFrameEventArgs e)
  86. {
  87. if (_state == RecordState.Start)
  88. {
  89. if (_captureMouse)
  90. {
  91. var g = System.Drawing.Graphics.FromImage(e.Frame);
  92. Cursorinfo pci;
  93. pci.cbSize = Marshal.SizeOf(typeof(Cursorinfo));
  94. GetCursorInfo(out pci);
  95. try
  96. {
  97. System.Windows.Forms.Cursor cur = new System.Windows.Forms.Cursor(pci.hCursor);
  98. cur.Draw(
  99. g,
  100. new System.Drawing.Rectangle(
  101. System.Windows.Forms.Cursor.Position.X - 10,
  102. System.Windows.Forms.Cursor.Position.Y - 10,
  103. cur.Size.Width,
  104. cur.Size.Height
  105. )
  106. );
  107. }
  108. catch
  109. {
  110. // ignored
  111. } //打开任务管理器时会导致异常
  112. }
  113. _videoWriter.WriteVideoFrame(e.Frame);
  114. }
  115. }
  116. /// <summary>
  117. /// 结束录制
  118. /// </summary>
  119. public void StopRecordVideo()
  120. {
  121. _state = RecordState.Stop;
  122. // 停止
  123. _videoStreamer.Stop();
  124. //结束写入
  125. _videoWriter.Close();
  126. _videoWriter.Dispose();
  127. }
  128. /// <summary>
  129. /// 暂停录制
  130. /// </summary>
  131. public void PauseRecordVideo()
  132. {
  133. _state = RecordState.Pause;
  134. }
  135. /// <summary>
  136. /// 恢复录制
  137. /// </summary>
  138. public void ResumeRecordVideo()
  139. {
  140. _state = RecordState.Start;
  141. }
  142. /// <summary>
  143. /// 生成缩略图
  144. /// </summary>
  145. /// <param name="mp4Path"></param>
  146. /// <param name="picPath"></param>
  147. public static void GetVideoPic(string mp4Path, string picPath)
  148. {
  149. using (var video = new VideoFileReader())
  150. {
  151. video.Open(mp4Path);
  152. int frameNum = video.FrameCount > 3 ? 3 : 0;
  153. using (var bmp = video.ReadVideoFrame(frameNum))
  154. {
  155. SaveAsJpeg
  156. (
  157. bmp,
  158. picPath,
  159. 90
  160. );
  161. }
  162. video.Close();
  163. }
  164. }
  165. // 保存为jpeg格式,quality为图像质量(0-100)
  166. public static void SaveAsJpeg
  167. (
  168. Bitmap bitmap,
  169. string fileName,
  170. int quality
  171. )
  172. {
  173. var jpegEncoder = ImageCodecInfo.GetImageEncoders().First(codec => codec.FormatID == ImageFormat.Jpeg.Guid);
  174. var encoderParameters = new EncoderParameters(1);
  175. encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
  176. bitmap.Save
  177. (
  178. fileName,
  179. jpegEncoder,
  180. encoderParameters
  181. );
  182. }
  183. }
  184. }