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
 using System;
1
 using System;
2
 using System.Collections.Generic;
2
 using System.Collections.Generic;
3
 using System.Diagnostics;
3
 using System.Diagnostics;
4
+using System.IO;
4
 using System.Linq;
5
 using System.Linq;
5
 using System.Text;
6
 using System.Text;
6
 using VisioForge.Shared.NAudio.CoreAudioApi;
7
 using VisioForge.Shared.NAudio.CoreAudioApi;
16
     public class FFMpeg
17
     public class FFMpeg
17
     {
18
     {
18
         Process myProcess = null;
19
         Process myProcess = null;
19
-
20
         /// <summary>
20
         /// <summary>
21
-        /// 录屏
21
+        /// ffmpeg输出日志文件地址  每个文件2MB左右
22
+        /// </summary>
23
+        string LogPath = "";
24
+        /// <summary>
25
+        /// 录制屏幕
22
         /// </summary>
26
         /// </summary>
23
         /// <param name="PathName">文件存储路径</param>
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
             Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
31
             Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
27
             Debug.WriteLine(KillProcessArray.Length.ToString());
32
             Debug.WriteLine(KillProcessArray.Length.ToString());
30
                 KillProcess.Kill();
35
                 KillProcess.Kill();
31
             }
36
             }
32
             myProcess = new Process();
37
             myProcess = new Process();
38
+            LogPath = CreateffmpegLog();
33
             string MicrophoneName = GetMicrophone();
39
             string MicrophoneName = GetMicrophone();
34
             myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe");   //ffmpeg.exe的绝对路径
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
             else
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
             myProcess.StartInfo.UseShellExecute = false;           //不使用操作系统外壳程序启动
112
             myProcess.StartInfo.UseShellExecute = false;           //不使用操作系统外壳程序启动
45
             myProcess.StartInfo.RedirectStandardError = true;      //重定向标准错误输出
113
             myProcess.StartInfo.RedirectStandardError = true;      //重定向标准错误输出
46
             myProcess.StartInfo.CreateNoWindow = true;             //不显示程序窗口
114
             myProcess.StartInfo.CreateNoWindow = true;             //不显示程序窗口
47
             myProcess.StartInfo.RedirectStandardInput = true;    //用于模拟该进程控制台的输入
115
             myProcess.StartInfo.RedirectStandardInput = true;    //用于模拟该进程控制台的输入
116
+            //外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
48
             myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);
117
             myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);
49
-            myProcess.Start();
50
-            myProcess.BeginErrorReadLine();
118
+            myProcess.Start();                //启动线程
119
+            myProcess.BeginErrorReadLine();   //开始异步读取
51
         }
120
         }
121
+
52
         /// <summary>
122
         /// <summary>
53
         /// 停止录制
123
         /// 停止录制
54
         /// </summary>
124
         /// </summary>
58
             if (myProcess == null)
128
             if (myProcess == null)
59
                 return;
129
                 return;
60
             myProcess.StandardInput.WriteLine("q");//在这个进程的控制台中模拟输入q,用于暂停录制
130
             myProcess.StandardInput.WriteLine("q");//在这个进程的控制台中模拟输入q,用于暂停录制
61
-            myProcess.Close();
62
-            myProcess.Dispose();
131
+            myProcess.Close();//关闭进程
132
+            myProcess.Dispose();//释放资源
63
             myProcess = null;
133
             myProcess = null;
64
             //myProcess.Kill();
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
         /// <summary>
137
         /// <summary>
78
         /// 合成视频
138
         /// 合成视频
79
         /// </summary>
139
         /// </summary>
80
-        /// <param name="ImageListPath">图片列表位置 命名为1.png</param>
140
+        /// <param name="ImageListPath">图片列表位置 命名为1.png 2.png</param>
81
         /// <param name="Mp3Path">MP3音频位置</param>
141
         /// <param name="Mp3Path">MP3音频位置</param>
82
         /// <param name="VideoSavePath">视频保存位置</param>
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
             Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
149
             Process[] KillProcessArray = Process.GetProcessesByName("ffmpeg");
87
             Debug.WriteLine(KillProcessArray.Length.ToString());
150
             Debug.WriteLine(KillProcessArray.Length.ToString());
89
             {
152
             {
90
                 KillProcess.Kill();
153
                 KillProcess.Kill();
91
             }
154
             }
92
-            Process myProcess = new Process();
155
+            myProcess = new Process();
156
+            LogPath=CreateffmpegLog();
93
             this.myProcess.StartInfo.FileName = FileToolsCommon.GetFileAbsolutePath(@"/ffmpeg/bin/ffmpeg.exe");   //ffmpeg.exe的绝对路径
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
             //外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
189
             //外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
102
             myProcess.ErrorDataReceived += new DataReceivedEventHandler(Output);
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
         //private void P_ErrorDataReceived(object sender, DataReceivedEventArgs e)
284
         //private void P_ErrorDataReceived(object sender, DataReceivedEventArgs e)
114
         //    using (StreamWriter fs = new StreamWriter("E:\\项目\\测试\\Wpf测试\\bin\\Debug\\ffmpeg\\log.txt", true))
287
         //    using (StreamWriter fs = new StreamWriter("E:\\项目\\测试\\Wpf测试\\bin\\Debug\\ffmpeg\\log.txt", true))
115
         //    {
288
         //    {
116
         //        fs.WriteLine(e.Data);
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
     <startup> 
3
     <startup> 
4
         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
4
         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
5
     </startup>
5
     </startup>
6
- <appSettings>
6
+  <appSettings>
7
     <!--图片压缩等级-->
7
     <!--图片压缩等级-->
8
     <add key="ImageCompressionLevel" value="30" />
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
   </appSettings>
13
   </appSettings>
10
 </configuration>
14
 </configuration>

Loading…
Cancel
Save