C# ffmpeg简单帮助类

需要ffmpeg文件下载方式

可跳转到:C#使用ffmpeg对画面进行旋转

更多命令可参考:https://www.cnblogs.com/zlp520/p/4241088.html

视频添加水印命令参考自:https://www.cnblogs.com/1175429393wljblog/p/11601817.html

该帮助类加入了,截图、获取视频宽高参数、加水印、视频旋转等基本功能。

//添加水印
ffmpeg -i "D:\VideoText\video.mp4" -i "D:\VideoText\water.png" -filter_complex overlay=10:10 "D:\VideoText\videoWater.mp4"
  1 public class ffmpegHepler
  2     {
  3         //ffmpeg执行文件的路径
  4         private static string ffmpeg = System.AppDomain.CurrentDomain.BaseDirectory + "ffmpeg\\ffmpeg.exe";
  5         private static int? width;    //视频宽度
  6         private static int? height;   //视频高度
  7 
  8         #region 属性访问
  9         /// <summary>
 10         /// 获取宽度
 11         /// </summary>
 12         /// <returns></returns>
 13         public static int? GetWidth()
 14         {
 15             return width;
 16         }
 17         /// <summary>
 18         /// 获取高度
 19         /// </summary>
 20         /// <returns></returns>
 21         public static int? GetHeight()
 22         {
 23             return height;
 24         }
 25         #endregion 
 26 
 27         #region 从视频画面中截取一帧画面为图片
 28         /// <summary>
 29         /// 从视频画面中截取一帧画面为图片
 30         /// </summary>
 31         /// <param name="VideoName">视频文件,绝对路径</param>
 32         /// <param name="Width">图片的宽:620</param>
 33         /// <param name="Height">图片的长:360</param>
 34         /// <param name="CutTimeFrame">开始截取的时间如:"1"【单位秒】</param>
 35         /// <param name="PicPath">截图文件的保存路径【含文件名及后缀名】</param>
 36         /// <param name="SleepTime">线程挂起等待时间,单位毫秒【默认值是7000】</param>
 37         /// <returns>截图成功返回截图路径,失败返回空</returns>
 38         public static string GetPicFromVideo(string VideoName, int Width,int Height, string CutTimeFrame,string PicPath,int SleepTime)
 39         {
 40             //获取视频长宽尺寸
 41             GetMovWidthAndHeight(VideoName);
 42             if (!string.IsNullOrWhiteSpace(width.ToString()))   //说明获取到了视频的长宽参数
 43             {
 44                 int resultWidht;
 45                 int resultHeight;
 46                 DealWidthAndHeight(int.Parse(width.ToString()), int.Parse(height.ToString()), Width, Height, out resultWidht, out resultHeight);
 47 
 48                 System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(ffmpeg);
 49                 startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
 50                 startInfo.Arguments = " -i " + VideoName
 51                                     + " -y -f image2 -ss " + CutTimeFrame
 52                                     + " -t 0.001 -s " + resultWidht.ToString() + "*" + resultHeight.ToString()
 53                                     + " " + PicPath;  //設定程式執行參數
 54                 try
 55                 {
 56                     System.Diagnostics.Process.Start(startInfo);
 57                     Thread.Sleep(SleepTime);//线程挂起,等待ffmpeg截图完毕
 58                 }
 59                 catch (Exception e)
 60                 {
 61                     return e.Message;
 62                 }
 63 
 64                 //返回视频图片完整路径
 65                 if (System.IO.File.Exists(PicPath))
 66                     return PicPath;
 67                 return "";
 68             }
 69             else
 70                 return "";
 71         }
 72         #endregion
 73 
 74         #region 获取视频的帧宽度和帧高度
 75         /// <summary>
 76         /// 获取视频的帧宽度和帧高度
 77         /// </summary>
 78         /// <param name="videoFilePath">mov文件的路径</param>
 79         /// <returns>null表示获取宽度或高度失败</returns>
 80         public static void GetMovWidthAndHeight(string videoFilePath)
 81         {
 82             width = null;
 83             height = null;
 84             try
 85             {
 86                 //判断文件是否存在
 87                 if (File.Exists(videoFilePath))
 88                 {
 89                     string output;
 90                     string error;
 91                     //执行命令
 92                     ExecuteCommand("\"" + ffmpeg + "\"" + " -i " + "\"" + videoFilePath + "\"", out output, out error);
 93 
 94                     if (!string.IsNullOrEmpty(error))
 95                     {
 96                         width = null;
 97                         height = null;
 98                     
 99                         //通过正则表达式获取信息里面的宽度信息
100                         Regex regex = new Regex("(\\d{2,4})x(\\d{2,4})", RegexOptions.Compiled);
101                         Match m = regex.Match(error);
102                         if (m.Success)
103                         {
104                             width = int.Parse(m.Groups[1].Value);
105                             height = int.Parse(m.Groups[2].Value);
106                         }
107                     }
108                 }
109             }
110             catch (Exception)
111             {}
112         }
113         #endregion 
114 
115         #region  处理图片宽高比例截图问题
116         /// <summary>
117         /// 处理图片宽高比例截图问题
118         /// </summary>
119         /// <param name="videoWidht">304</param>
120         /// <param name="videoHeight">640</param>
121         /// <param name="imgWidth">640</param>
122         /// <param name="imgHeight">360</param>
123         /// <param name="width">最终处理的图片宽</param>
124         /// <param name="height">最终处理的图片高</param>
125         private static void DealWidthAndHeight(int videoWidht,int videoHeight,int imgWidth,int imgHeight,out int width, out int height)
126         {
127             if (videoWidht < videoHeight)  //说明是竖屏拍摄
128             {
129                 if (imgWidth > videoWidht)
130                     width = videoWidht;
131                 else
132                     width = imgWidth;
133                 height = videoHeight;
134             }
135             else                           //说明是横屏拍摄
136             {
137                 if (imgHeight > videoHeight)
138                     height = videoHeight;
139                 else
140                     height = imgHeight;
141                 width = videoWidht;
142             }
143         }
144         #endregion
145 
146         #region 视频旋转
147         /// <summary>
148         /// 视频旋转
149         /// </summary>
150         /// <param name="videoFilePath">视频绝对路径</param>
151         /// <param name="dealVideFilePath">视频旋转后保存路径</param>
152         /// <param name="flag">1=顺时针旋转90度  2=逆时针旋转90度</param>
153         /// <returns>true  成功  false  失败</returns>
154         public static bool VideoRotate(string videoFilePath,string dealVideFilePath,string flag)
155         {
156             //ffmpeg -i success.mp4 -metadata:s:v rotate="90" -codec copy output_success.mp4
157             string output;
158             string error;
159             //执行命令
160             ExecuteCommand("\"" + ffmpeg + "\"" + " -y -i " + "\"" + videoFilePath + "\"" + " -vf transpose=" + flag + " -acodec copy " + "\"" + dealVideFilePath + "\"", out output, out error);
161             if (File.Exists(dealVideFilePath))
162                 return true;
163             else
164                 return false;
165         }
166         #endregion
167 
168         #region 给视频添加水印
169         /// <summary>
170         /// 给视频添加水印
171         /// </summary>
172         /// <param name="videoFilePath">原视频位置</param>
173         /// <param name="dealVideFilePath">处理后的视频位置</param>
174         /// <param name="waterPicPath">水印图片</param>
175         /// <param name="location">水印距离视频的左上角坐标比如: 10:10</param>
176         /// <returns></returns>
177         public static bool VideoWaterMark(string videoFilePath, string dealVideFilePath,string waterPicPath,string location)
178         {
179             //ffmpeg -i success.mp4 -metadata:s:v rotate="90" -codec copy output_success.mp4
180             string output;
181             string error;
182             //执行命令
183             ExecuteCommand("\"" + ffmpeg + "\"" + " -i " + "\"" + videoFilePath + "\"" + " -i " + "\"" + waterPicPath + "\"" + " -filter_complex overlay=" + location + " \"" + dealVideFilePath + "\"", out output, out error);
184             if (File.Exists(dealVideFilePath))
185                 return true;
186             else
187                 return false;
188         }
189         #endregion
190 
191         #region 让ffmpeg执行一条命令
192         /// <summary>
193         /// 让ffmpeg执行一条command命令
194         /// </summary>
195         /// <param name="command">需要执行的Command</param>
196         /// <param name="output">输出</param>
197         /// <param name="error">错误</param>
198         private static void ExecuteCommand(string command, out string output, out string error)
199         {
200             try
201             {
202                 //创建一个进程
203                 Process pc = new Process();
204                 pc.StartInfo.FileName = command;
205                 pc.StartInfo.UseShellExecute = false;
206                 pc.StartInfo.RedirectStandardOutput = true;
207                 pc.StartInfo.RedirectStandardError = true;
208                 pc.StartInfo.CreateNoWindow = true;
209 
210                 //启动进程
211                 pc.Start();
212 
213                 //准备读出输出流和错误流
214                 string outputData = string.Empty;
215                 string errorData = string.Empty;
216                 pc.BeginOutputReadLine();
217                 pc.BeginErrorReadLine();
218 
219                 pc.OutputDataReceived += (ss, ee) =>
220                 {
221                     outputData += ee.Data;
222                 };
223 
224                 pc.ErrorDataReceived += (ss, ee) =>
225                 {
226                     errorData += ee.Data;
227                 };
228 
229                 //等待退出
230                 pc.WaitForExit();
231 
232                 //关闭进程
233                 pc.Close();
234 
235                 //返回流结果
236                 output = outputData;
237                 error = errorData;
238             }
239             catch (Exception ex)
240             {
241                 output = null;
242                 error = null;
243             }
244         }
245         #endregion
246     }