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");