视频处理类
using System; using System.Diagnostics; using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Windows.Forms; namespace Test.Util { class VideoUtil { /// <summary> /// 功能:获取视频的时间长度 /// 作者:黄海 /// 时间:2014-11-09 /// </summary> /// <param name="vdieoFile"></param> /// <returns></returns> public static string GetLength(string vdieoFile) { var ffMpeg = Path.Combine(Application.StartupPath + "\\ffmpeg", "ffmpeg.exe"); Process mProcess = null; StreamReader srOutput = null; var outPut = ""; var filepath = vdieoFile; var param = string.Format("-i \"{0}\"", filepath); ProcessStartInfo oInfo = null; Regex re = null; Match m = null; //Get ready with ProcessStartInfo oInfo = new ProcessStartInfo(ffMpeg, param) { CreateNoWindow = true, RedirectStandardError = true, WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = false }; //ffMPEG uses StandardError for its output. // Lets start the process mProcess = Process.Start(oInfo); // Divert output srOutput = mProcess.StandardError; // Read all outPut = srOutput.ReadToEnd(); // Please donot forget to call WaitForExit() after calling SROutput.ReadToEnd mProcess.WaitForExit(); mProcess.Close(); srOutput.Close(); //get duration re = new Regex("[D|d]uration:.((\\d|:|\\.)*)"); m = re.Match(outPut); if (m.Success) { //Means the output has cantained the string "Duration" var temp = m.Groups[1].Value; var timepieces = temp.Split(':', '.'); if (timepieces.Length == 4) { // Store duration var str = new TimeSpan(0, Convert.ToInt16(timepieces[0]), Convert.ToInt16(timepieces[1]), Convert.ToInt16(timepieces[2]), Convert.ToInt16(timepieces[3])); var str2 = ""; try { str2 = str.ToString().Substring(0, str.ToString().LastIndexOf(".", StringComparison.Ordinal)); } catch (Exception) { str2 = str.ToString().Replace("{", "").Replace("}", ""); } return str2; } } else { return "00:00:00"; } return "00:00:00"; } /// <summary> /// 执行一条command命令 /// </summary> /// <param name="command">需要执行的Command</param> /// <param name="output">输出</param> /// <param name="error">错误</param> private static void ExecuteCommand(string command, out string output, out string error) { try { //创建一个进程 var pc = new Process { StartInfo = { FileName = command, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true } }; //启动进程 pc.Start(); //准备读出输出流和错误流 var outputData = string.Empty; var errorData = string.Empty; pc.BeginOutputReadLine(); pc.BeginErrorReadLine(); pc.OutputDataReceived += (ss, ee) => { outputData += ee.Data; }; pc.ErrorDataReceived += (ss, ee) => { errorData += ee.Data; }; //等待退出 pc.WaitForExit(); //关闭进程 pc.Close(); //返回流结果 output = outputData; error = errorData; } catch (Exception) { output = null; error = null; } } /// <summary> /// 获取视频的帧宽度和帧高度 /// </summary> /// <param name="videoFilePath">mov文件的路径</param> /// <param name="width"></param> /// <param name="height"></param> /// <returns>null表示获取宽度或高度失败</returns> private static void GetWidthAndHeight(string videoFilePath, out int width, out int height) { try { //判断文件是否存在 if (!File.Exists(videoFilePath)) { width = 0; height = 0; } //执行命令获取该文件的一些信息 var ffmpegPath = new FileInfo(Process.GetCurrentProcess().MainModule.FileName).DirectoryName + @"\ffmpeg\ffmpeg.exe"; string output; string error; ExecuteCommand("\"" + ffmpegPath + "\"" + " -i " + "\"" + videoFilePath + "\"", out output, out error); if (string.IsNullOrEmpty(error)) { width = 0; height = 0; } //通过正则表达式获取信息里面的宽度信息 var regex = new Regex("(\\d{2,4})x(\\d{2,4})", RegexOptions.Compiled); var m = regex.Match(error); if (m.Success) { width = int.Parse(m.Groups[1].Value); height = int.Parse(m.Groups[2].Value); } else { width = 0; height = 0; } } catch (Exception) { width = 0; height = 0; } } public static void GetImage(string videoRealPath, string imageRealPath, int width, int height) { var fi = new FileInfo(imageRealPath); if (fi.Exists) { fi.IsReadOnly = false; fi.Delete(); } fi = new FileInfo(videoRealPath); var tool = Application.StartupPath + @"\ffmpeg\ffmpeg.exe"; var command = "-i \"" + videoRealPath + "\" -ss 00:00:03 -vframes 1 -r 1 -ac 1 -ab 2 -s " + width + "*" + height + " -f image2 \"" + imageRealPath + "\""; var p = new Process { StartInfo = { FileName = tool, Arguments = command, WorkingDirectory = fi.DirectoryName, UseShellExecute = false, CreateNoWindow = false } }; p.Start(); p.WaitForExit(); p.Close(); p.Dispose(); //压缩一下PNG图 // ThumbImage.CompressPng(imageRealPath, imageRealPath); } public static void ConvertFlv(FileInfo sourceFile, FileInfo targetFile) { var strArrMencoder = new string[] { "rmvb", "rm" }; var strArrFfmpeg = new string[] { "asf", "avi", "mpg", "3gp", "mov", "mp4", "wmv", "mpeg" }; if (strArrFfmpeg.Any(var => var == sourceFile.Extension.Replace(".",""))) { ConvertFlvByFFmpeg(sourceFile.FullName, targetFile.FullName); } if (strArrMencoder.Any(var => var == "."+sourceFile.Extension.Replace(".",""))) { ConvertFlvByMencoder(sourceFile.FullName, targetFile.FullName); } } private static bool ConvertFlvByMencoder(string vFileName, string flvFile) { var fi = new FileInfo(vFileName); var tool = Application.StartupPath + "\\FFModules\\Encoder\\mencoder.exe"; var command = " " + vFileName + " -o " + flvFile + " -of lavf -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:vbitrate=200:mbd=2:mv0:trell:v4mv:cbp:last_pred=1:dia=-1:cmp=0:vb_strategy=1 -vf scale=" + 640 + ":" + 480 + " -ofps 12 -srate 22050"; var p = new System.Diagnostics.Process { StartInfo = { FileName = tool, Arguments = command, WorkingDirectory = fi.DirectoryName, UseShellExecute = false, CreateNoWindow = false } }; p.Start(); p.WaitForExit(); p.Close(); p.Dispose(); return true; } private static bool ConvertFlvByFFmpeg(string vFileName, string exportName) { var fi = new FileInfo(vFileName); var ffmpegtool = Application.StartupPath + "\\ffmpeg\\ffmpeg.exe"; var command = " -i \"" + vFileName + "\" -y -ab 32 -ar 22050 -b 800000 -s 640*480 \"" + exportName + "\""; //Flv格式 var p = new Process { StartInfo = { FileName = ffmpegtool, Arguments = command, WorkingDirectory = fi.DirectoryName, UseShellExecute = false, CreateNoWindow = false } }; p.Start(); p.WaitForExit(); p.Close(); p.Dispose(); return true; } /// <summary> /// 功能:转换视频文件为M3U8 /// 作者:黄海 /// 时间:2014-11-09 /// </summary> /// <param name="sourceFlv"></param> /// <param name="targepath"></param> /// <param name="m3U8Name"></param> /// <returns></returns> public static bool ConvertM3U8(string sourceFlv, string targepath, string m3U8Name) { var di = new DirectoryInfo(targepath); if (!di.Exists) { di.Create(); } try { //文件名称,生成M3U8文件 var fileName = Application.StartupPath + @"\ffmpeg\ffmpeg.exe"; var command = " -i " + sourceFlv + " -hls_time 15 -c:v libx264 -hls_list_size 0 -c:a aac -strict -2 -f hls " + m3U8Name + ".m3u8"; var workingDirectory = new FileInfo(sourceFlv).DirectoryName; if (workingDirectory != null) { var p = new Process { StartInfo = { FileName = fileName, Arguments = command, WorkingDirectory = workingDirectory, UseShellExecute = false, CreateNoWindow = false } }; p.Start(); p.WaitForExit(); p.Close(); p.Dispose(); } return true; } catch (Exception) { return false; } } } }
用法示例:
VideoUtil.ConvertFlv(new FileInfo( @"c:\BeforeDawn19.mp4"), new FileInfo(@"c:\111.flv")); VideoUtil.GetImage("c:\\111.flv","c:\\111.png",160,120); Console.WriteLine(VideoUtil.GetLength("c:\\111.flv")); VideoUtil.ConvertM3U8(@"c:\\111.flv", "c:\\temp", "1111"); MessageBox.Show("ok");