Browse Source

zhao:1增加录音方法,2增加视频格式

tags/录制修改前
耀 4 years ago
parent
commit
a956170188
2 changed files with 217 additions and 39 deletions
  1. 212
    38
      Common/system/FFMpeg.cs
  2. 5
    1
      XHWK.WKTool/App.config

+ 212
- 38
Common/system/FFMpeg.cs View File

@@ -1,6 +1,7 @@
1 1
 using System;
2 2
 using System.Collections.Generic;
3 3
 using System.Diagnostics;
4
+using System.IO;
4 5
 using System.Linq;
5 6
 using System.Text;
6 7
 using VisioForge.Shared.NAudio.CoreAudioApi;
@@ -16,12 +17,16 @@ namespace Common.system
16 17
     public class FFMpeg
17 18
     {
18 19
         Process myProcess = null;
19
-
20 20
         /// <summary>
21
-        /// 录屏
21
+        /// ffmpeg输出日志文件地址  每个文件2MB左右
22
+        /// </summary>
23
+        string LogPath = "";
24
+        /// <summary>
25
+        /// 录制屏幕
22 26
         /// </summary>
23 27
         /// <param name="PathName">文件存储路径</param>
24
-        public void RunFFmpeg(string PathName)
28
+        /// <param name="VideoType">视频类型</param>
29
+        public void StartRecordingVideo(string PathName, string VideoType)
25 30
         {
26 31
             Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
27 32
             Debug.WriteLine(KillProcessArray.Length.ToString());
@@ -30,25 +35,90 @@ namespace Common.system
30 35
                 KillProcess.Kill();
31 36
             }
32 37
             myProcess = new Process();
38
+            LogPath = CreateffmpegLog();
33 39
             string MicrophoneName = GetMicrophone();
34 40
             myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe");   //ffmpeg.exe的绝对路径
35
-            if(string.IsNullOrWhiteSpace(MicrophoneName))
41
+            switch (VideoType.ToUpper())
36 42
             {
37
-                myProcess.StartInfo.Arguments = "-f dshow -i video=\"screen-capture-recorder\" -f dshow -i audio=\"virtual-audio-capturer\" -vcodec libx264 -acodec libmp3lame -r 15 -crf 22 -f avi " + PathName;  //ffmpeg的参数
43
+                case "MP4":
44
+                    if (string.IsNullOrWhiteSpace(MicrophoneName))
45
+                    {
46
+                        myProcess.StartInfo.Arguments = "-f dshow -i video=\"screen-capture-recorder\" -f dshow -i audio=\"virtual-audio-capturer\" -vcodec libx264 -acodec libmp3lame -r 15 -crf 22 -f avi " + PathName;  //ffmpeg的参数
47
+                    }
48
+                    else
49
+                    {
50
+                        myProcess.StartInfo.Arguments = "-f dshow -i audio=\"virtual-audio-capturer\" -f dshow -i audio=\"" +
51
+                            MicrophoneName + "\" -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f dshow -i video=\"screen-capture-recorder\" -pix_fmt yuv420p -vcodec h264 -preset:v ultrafast -tune:v zerolatency -acodec aac -ar 44100 -ac 2 " + PathName;  //ffmpeg的参数
52
+                    }
53
+                    break;
54
+                case "AVI":
55
+                case "FLV":
56
+                    if (string.IsNullOrWhiteSpace(MicrophoneName))
57
+                    {
58
+                        myProcess.StartInfo.Arguments = "-f dshow -i video=\"screen-capture-recorder\" -f dshow -i audio=\"virtual-audio-capturer\" -vcodec libx264 -acodec libmp3lame -r 15 -crf 22 -f "+ VideoType.ToLower() + " " + PathName;  //ffmpeg的参数
59
+                    }
60
+                    else
61
+                    {
62
+                        myProcess.StartInfo.Arguments = "-f dshow -i audio=\"virtual-audio-capturer\" -f dshow -i audio=\"" +
63
+                            MicrophoneName + "\" -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f dshow -i video=\"screen-capture-recorder\" -pix_fmt yuv420p -vcodec h264 -preset:v ultrafast -tune:v zerolatency -acodec aac -ar 44100 -ac 2 -f " + VideoType.ToLower() + " " + PathName;  //ffmpeg的参数
64
+                    }
65
+                    break;
66
+                default:
67
+                    if (string.IsNullOrWhiteSpace(MicrophoneName))
68
+                    {
69
+                        myProcess.StartInfo.Arguments = "-f dshow -i video=\"screen-capture-recorder\" -f dshow -i audio=\"virtual-audio-capturer\" -vcodec libx264 -acodec libmp3lame -r 15 -crf 22 -f avi " + PathName;  //ffmpeg的参数
70
+                    }
71
+                    else
72
+                    {
73
+                        myProcess.StartInfo.Arguments = "-f dshow -i audio=\"virtual-audio-capturer\" -f dshow -i audio=\"" +
74
+                            MicrophoneName + "\" -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f dshow -i video=\"screen-capture-recorder\" -pix_fmt yuv420p -vcodec h264 -preset:v ultrafast -tune:v zerolatency -acodec aac -ar 44100 -ac 2 " + PathName;  //ffmpeg的参数
75
+                    }
76
+                    break;
77
+            }
78
+            myProcess.StartInfo.UseShellExecute = false;           //不使用操作系统外壳程序启动
79
+            myProcess.StartInfo.RedirectStandardError = true;      //重定向标准错误输出
80
+            myProcess.StartInfo.CreateNoWindow = true;             //不显示程序窗口
81
+            myProcess.StartInfo.RedirectStandardInput = true;      //用于模拟该进程控制台的输入
82
+            myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);
83
+            myProcess.Start();
84
+            myProcess.BeginErrorReadLine();
85
+        }
86
+
87
+        /// <summary>
88
+        /// 录制音频
89
+        /// </summary>
90
+        /// <param name="Mp3Path">MP3音频位置</param>
91
+        private void StartRecordingAudio(string Mp3Path)
92
+        {
93
+            Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
94
+            Debug.WriteLine(KillProcessArray.Length.ToString());
95
+            foreach (var KillProcess in KillProcessArray)
96
+            {
97
+                KillProcess.Kill();
98
+            }
99
+            myProcess = new Process();
100
+            LogPath = CreateffmpegLog();
101
+            this.myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe");   //ffmpeg.exe的绝对路径
102
+            string MicrophoneName = GetMicrophone();
103
+            if (string.IsNullOrWhiteSpace(MicrophoneName))
104
+            {
105
+                myProcess.StartInfo.Arguments = "-f dshow -i audio=\"virtual-audio-capturer\" " + Mp3Path;
38 106
             }
39 107
             else
40 108
             {
41
-                myProcess.StartInfo.Arguments = "-f dshow -i audio=\"virtual-audio-capturer\" -f dshow -i audio=\"" + MicrophoneName + "\" -filter_complex amix=inputs=2:duration=first:dropout_transition=2 -f dshow -i video=\"screen-capture-recorder\" -pix_fmt yuv420p -vcodec h264 -preset:v ultrafast -tune:v zerolatency -acodec aac -ar 44100 -ac 2 -f avi " + PathName;  //ffmpeg的参数
42
-
109
+                myProcess.StartInfo.Arguments = "-f dshow -i audio=\"virtual-audio-capturer\"  -f dshow -i audio=\"" +
110
+                        MicrophoneName + "\" -filter_complex amix=inputs=2:duration=first:dropout_transition=2 " + Mp3Path;
43 111
             }
44 112
             myProcess.StartInfo.UseShellExecute = false;           //不使用操作系统外壳程序启动
45 113
             myProcess.StartInfo.RedirectStandardError = true;      //重定向标准错误输出
46 114
             myProcess.StartInfo.CreateNoWindow = true;             //不显示程序窗口
47 115
             myProcess.StartInfo.RedirectStandardInput = true;    //用于模拟该进程控制台的输入
116
+            //外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
48 117
             myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);
49
-            myProcess.Start();
50
-            myProcess.BeginErrorReadLine();
118
+            myProcess.Start();                //启动线程
119
+            myProcess.BeginErrorReadLine();   //开始异步读取
51 120
         }
121
+
52 122
         /// <summary>
53 123
         /// 停止录制
54 124
         /// </summary>
@@ -58,30 +128,23 @@ namespace Common.system
58 128
             if (myProcess == null)
59 129
                 return;
60 130
             myProcess.StandardInput.WriteLine("q");//在这个进程的控制台中模拟输入q,用于暂停录制
61
-            myProcess.Close();
62
-            myProcess.Dispose();
131
+            myProcess.Close();//关闭进程
132
+            myProcess.Dispose();//释放资源
63 133
             myProcess = null;
64 134
             //myProcess.Kill();
65 135
         }
66
-        /// <summary>
67
-        /// 输出结果
68
-        /// </summary>
69
-        /// <param name="sendProcess"></param>
70
-        /// <param name="output"></param>
71
-        private void Output(object sendProcess, DataReceivedEventArgs output)
72
-        {
73
-            if (!String.IsNullOrEmpty(output.Data))
74
-                Debug.WriteLine(output.Data.ToString());
75
-        }
76 136
 
77 137
         /// <summary>
78 138
         /// 合成视频
79 139
         /// </summary>
80
-        /// <param name="ImageListPath">图片列表位置 命名为1.png</param>
140
+        /// <param name="ImageListPath">图片列表位置 命名为1.png 2.png</param>
81 141
         /// <param name="Mp3Path">MP3音频位置</param>
82 142
         /// <param name="VideoSavePath">视频保存位置</param>
83
-        /// <param name="frequency">每秒帧率</param>
84
-        private void SynthesisVideo(string ImageListPath,string Mp3Path,string VideoSavePath,int frequency)
143
+        /// <param name="Frequency">每秒帧率</param>
144
+        /// <param name="VideoWidth">视频宽度</param>
145
+        /// <param name="VideoHeight">视频高度</param>
146
+        /// <param name="VideoType">视频类型  MP4 FLV AVI</param>
147
+        private void SynthesisVideo(string ImageListPath, string Mp3Path, string VideoSavePath, int Frequency, int VideoWidth, int VideoHeight, string VideoType)
85 148
         {
86 149
             Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
87 150
             Debug.WriteLine(KillProcessArray.Length.ToString());
@@ -89,23 +152,133 @@ namespace Common.system
89 152
             {
90 153
                 KillProcess.Kill();
91 154
             }
92
-            Process myProcess = new Process();
155
+            myProcess = new Process();
156
+            LogPath=CreateffmpegLog();
93 157
             this.myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe");   //ffmpeg.exe的绝对路径
94
-            myProcess.StartInfo.Arguments = @"-y -r "+ frequency + " -i " +
95
-                ImageListPath + @"%d.png -i " +
96
-                Mp3Path + @" -s 800x800 -vcodec mpeg4 " +
97
-                VideoSavePath;
98
-            myProcess.StartInfo.UseShellExecute = false;
99
-            myProcess.StartInfo.RedirectStandardError = true;
100
-            myProcess.StartInfo.CreateNoWindow = true;
158
+            switch (VideoType.ToUpper())
159
+            {
160
+                case "MP4":
161
+                    myProcess.StartInfo.Arguments = @"-y -r " + Frequency + " -i " +
162
+                        ImageListPath + @"%d.png -i " +
163
+                        Mp3Path + @" -s " + VideoWidth + "x" + VideoHeight + " -vcodec mpeg4 " +
164
+                        VideoSavePath;
165
+                    break;
166
+                case "AVI":
167
+                    myProcess.StartInfo.Arguments = @"-y -r " + Frequency + " -i " +
168
+                        ImageListPath + @"%d.png -i " +
169
+                        Mp3Path + @" -s " + VideoWidth + "x" + VideoHeight + " -f AVI " +
170
+                        VideoSavePath;
171
+                    break;
172
+                case "FLV":
173
+                    myProcess.StartInfo.Arguments = @"-y -r " + Frequency + " -i " +
174
+                        ImageListPath + @"%d.png -i " +
175
+                        Mp3Path + @" -s " + VideoWidth + "x" + VideoHeight + " -f FLV " +
176
+                        VideoSavePath;
177
+                    break;
178
+                default:
179
+                    myProcess.StartInfo.Arguments = @"-y -r " + Frequency + " -i " +
180
+                        ImageListPath + @"%d.png -i " +
181
+                        Mp3Path + @" -s " + VideoWidth + "x" + VideoHeight + " -vcodec mpeg4 " +
182
+                        VideoSavePath;
183
+                    break;
184
+            }
185
+            myProcess.StartInfo.UseShellExecute = false;           //不使用操作系统外壳程序启动
186
+            myProcess.StartInfo.RedirectStandardError = true;      //重定向标准错误输出
187
+            myProcess.StartInfo.CreateNoWindow = true;             //不显示程序窗口
188
+            myProcess.StartInfo.RedirectStandardInput = true;      //用于模拟该进程控制台的输入
101 189
             //外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
102 190
             myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);
103
-            //p.ErrorDataReceived += new DataReceivedEventHandler((s, message) => { Console.WriteLine(message.Data); });
104
-            myProcess.Start();//启动线程
105
-            myProcess.BeginErrorReadLine();//开始异步读取
106
-            myProcess.WaitForExit();//阻塞等待进程结束
107
-            myProcess.Close();//关闭进程
108
-            myProcess.Dispose();//释放资源
191
+            myProcess.Start();                 //启动线程
192
+            myProcess.BeginErrorReadLine();    //开始异步读取
193
+            myProcess.WaitForExit();           //阻塞等待进程结束
194
+            myProcess.Close();                 //关闭进程
195
+            myProcess.Dispose();               //释放资源
196
+            //生成视频后删除图片保存列表
197
+            FileToolsCommon.DeleteDirectory(ImageListPath);
198
+            
199
+        }
200
+        
201
+        /// <summary>
202
+        /// 生成缩略图
203
+        /// </summary>
204
+        /// <param name="VideoPath">视频地址</param>
205
+        /// <param name="ImagePath">图片地址</param>
206
+        void GenerateThumbnails(string VideoPath,string ImagePath)
207
+        {
208
+            Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
209
+            Debug.WriteLine(KillProcessArray.Length.ToString());
210
+            foreach (var KillProcess in KillProcessArray)
211
+            {
212
+                KillProcess.Kill();
213
+            }
214
+            myProcess = new Process();
215
+            LogPath = CreateffmpegLog();
216
+            this.myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe");   //ffmpeg.exe的绝对路径
217
+            //myProcess.StartInfo.Arguments = "-i \"" + VideoPath + "\" -ss 1 -vframes 1 -r 1 -ac 1 -ab 2 -s " + thubWidth + "*" + thubHeight + " -f image2 \"" + ImagePath + "\"";
218
+            myProcess.StartInfo.Arguments = "-i \"" + VideoPath + "\" -ss 1 -vframes 1 -r 1 -ac 1 -ab 2 -f image2 \"" + ImagePath + "\"";
219
+            myProcess.StartInfo.UseShellExecute = false;           //不使用操作系统外壳程序启动
220
+            myProcess.StartInfo.RedirectStandardError = true;      //重定向标准错误输出
221
+            myProcess.StartInfo.CreateNoWindow = true;             //不显示程序窗口
222
+            myProcess.StartInfo.RedirectStandardInput = true;      //用于模拟该进程控制台的输入
223
+            //外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
224
+            myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);
225
+            myProcess.Start();                 //启动线程
226
+            myProcess.BeginErrorReadLine();    //开始异步读取
227
+            myProcess.WaitForExit();           //阻塞等待进程结束
228
+            myProcess.Close();                 //关闭进程
229
+            myProcess.Dispose();               //释放资源
230
+        }
231
+
232
+        /// <summary>
233
+        /// 创建日志文件
234
+        /// </summary>
235
+        /// <returns></returns>
236
+        string CreateffmpegLog()
237
+        {
238
+            string LogFileName = DateTime.Now.ToString("yyyyMMdd");
239
+            string LogFilePath = FileToolsCommon.GetFileAbsolutePath("/Log/FFMpegLog/");
240
+            FileToolsCommon.CreateDirectory(LogFilePath);
241
+            string LogName = LogFilePath + LogFileName + ".log";
242
+            try
243
+            {
244
+                if (!FileToolsCommon.IsExistFile(LogName))
245
+                {
246
+                    FileToolsCommon.CreateFile(LogName);
247
+                    FileToolsCommon.AppendText(LogName, "\r\n****************************************************************************************************" +
248
+                        "****************************************************************************************************\r\n");
249
+                    return LogName;
250
+                }
251
+                else
252
+                {
253
+                    int num = 0;
254
+                    while (FileToolsCommon.GetFileSizeByMB(LogName) > 2)
255
+                    {
256
+                        num++;
257
+                        LogName = LogFilePath + LogFileName + "_" + num + ".log";
258
+                        FileToolsCommon.CreateFile(LogName);
259
+                    }
260
+                    FileToolsCommon.AppendText(LogName, "\r\n****************************************************************************************************" +
261
+                        "****************************************************************************************************\r\n");
262
+                    return LogName;
263
+                }
264
+            }
265
+            catch (Exception)
266
+            {
267
+                return LogName;
268
+            }
269
+        }
270
+
271
+        /// <summary>
272
+        /// 输出结果
273
+        /// </summary>
274
+        /// <param name="sendProcess"></param>
275
+        /// <param name="output"></param>
276
+        private void Output(object sendProcess, DataReceivedEventArgs output)
277
+        {
278
+            if (!String.IsNullOrEmpty(output.Data))
279
+            {
280
+                FileToolsCommon.AppendText(LogPath, output.Data);
281
+            }
109 282
         }
110 283
 
111 284
         //private void P_ErrorDataReceived(object sender, DataReceivedEventArgs e)
@@ -114,6 +287,7 @@ namespace Common.system
114 287
         //    using (StreamWriter fs = new StreamWriter("E:\\项目\\测试\\Wpf测试\\bin\\Debug\\ffmpeg\\log.txt", true))
115 288
         //    {
116 289
         //        fs.WriteLine(e.Data);
290
+        //        Debug.WriteLine(output.Data.ToString());
117 291
         //    }
118 292
         //}
119 293
 

+ 5
- 1
XHWK.WKTool/App.config View File

@@ -3,8 +3,12 @@
3 3
     <startup> 
4 4
         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
5 5
     </startup>
6
- <appSettings>
6
+  <appSettings>
7 7
     <!--图片压缩等级-->
8 8
     <add key="ImageCompressionLevel" value="30" />
9
+    <!--文件存放路径  路径\账户名\讲解名称_x.MP4-->
10
+    <add key="VideoSavePath" value="30" />
11
+    <!--视频格式 1、MP4 2、FlV 3、AVI-->
12
+    <add key="VideoType" value="1" />
9 13
   </appSettings>
10 14
 </configuration>

Loading…
Cancel
Save