最近做一个上传视频并且截取缩略图的功能,百度了一下好像都是上传视频之后使用ffmpeg进行截图,自己尝试了一下,很方便
原帖:http://blog.csdn.net/mqplw/article/details/43675093
ffmpeg官方下载地址:http://ffmpeg.zeranoe.com/builds/
前台
<body>
<form id="form1" runat="server">
<div>
<asp:FileUpload ID="filupMV" runat="server" />
</div>
<div>
<asp:Button ID="btnUp" runat="server" Text="上传" onclick="btnUp_Click" />
</div>
</form>
</body>
后台
protected void btnUp_Click(object sender, EventArgs e)
{
FileUpload upload = filupMV;
string paramVirtualPath = "/upload";
string paramDirectory = "mv";
string paramOriginalDirectory = DateTime.Now.ToString("yyyyMMdd");
string paramThumbnailDirectory = "img";
string paramFileName = DateTime.Now.ToString("yyyyMM") + Guid.NewGuid().ToString().Substring(24, 12).ToUpper();
string returnTxt=UploadAndThumbnail(upload, paramVirtualPath, paramDirectory, paramOriginalDirectory, paramThumbnailDirectory,paramFileName);
Response.Write(returnTxt);
}
#region 上传文件并生成缩略图
/// <summary>
/// 上传文件并生成缩略图
/// </summary>
/// <param name="paramFileUpload">上传控件</param>
/// <param name="paramVirtualPath">上传目标虚拟路径</param>
/// <param name="paramDirectory">用户自定义创建文件夹</param>
/// <param name="paramOriginalDirectory">存放原始文件夹</param>
/// <param name="paramThumbnailDirectory">存放缩略图文件夹</param>
private string UploadAndThumbnail(FileUpload paramFileUpload, string paramVirtualPath, string paramDirectory, string paramOriginalDirectory, string paramThumbnailDirectory,string paramFileName)
{
string returnValue = string.Empty;//返回值
string imgType;//文件类型
string fullFileName = paramFileUpload.PostedFile.FileName; //上传文件名
imgType = fullFileName.Substring(fullFileName.LastIndexOf(".") + 1).ToLower();//文件类型
string UserPath = Server.MapPath(paramVirtualPath).ToString() + "\\" + paramDirectory;//存放文件目录
//如果文件夹不存在则创建
if (!Directory.Exists(UserPath))
{
Directory.CreateDirectory(UserPath);
}
string originalImagePath = UserPath + "\\" + paramOriginalDirectory;//原始路径
if (!Directory.Exists(originalImagePath))
{
Directory.CreateDirectory(originalImagePath);
}
//缩略图路径
string thumbnailPath = UserPath + "\\" + paramThumbnailDirectory;
if (!Directory.Exists(thumbnailPath))
{
Directory.CreateDirectory(thumbnailPath);
}
// 获取上传视频的文件名
string fileName = paramFileName;
// *.avi *.rmvb *.rm *.asf *.divx *.mpg *.mpeg *.mpe *.wmv *.mp4 *.mkv *.vob(常见视频后缀名)
if (imgType == "flv" || imgType == "mp4" || imgType == "avi" || imgType == "rmvb" || imgType == "rm" || imgType == "asf" || imgType == "divx" || imgType == "mpg" || imgType == "mpeg" || imgType == "mpe" || imgType == "wmv" || imgType == "mkv")
{
try
{
string mvFile = originalImagePath + "\\" + fileName + "." + imgType;
string imgFile = thumbnailPath + "\\" + fileName +".jpg";
//string ffmpeg = Server.MapPath("ffmpeg.exe");
//ffmpeg.exe所在目录
string ffmpeg = Server.MapPath("\\ffmpeg-20170620-ae6f6d4-win64-static\\ffmpeg-20170620-ae6f6d4-win64-static\\bin");
paramFileUpload.PostedFile.SaveAs(mvFile);
VideoConverToImg.ConverToImg(ffmpeg, mvFile, imgFile);
returnValue = "上传成功";
}
catch (Exception ex)
{
returnValue = "由于网络原因,上传文件错误 " + ex.Message;
}
}
else
{
returnValue = "你选择的文件格式错误!";
}
return returnValue;
}
#endregion
单独建了一个类,调用ffmpeg.exe
public class VideoConverToImg
{
/// <summary>
/// 从视频中截取img格式图片
/// </summary>
/// <param name="applicationPath">ffmpeg.exe文件路径</param>
/// <param name="fileNamePath">视频文件路径(带文件名)</param>
/// <param name="targetImgNamePath">生成img图片路径(带文件名)</param>
public static void ConverToImg(string applicationPath, string fileNamePath, string targetImgNamePath)
{
//string c = applicationPath + @"\ffmpeg.exe -i" + fileNamePath + targetImgNamePath+"-ss 00:00:05 -r 1 -vframes 1 -an -vcodec mjpeg " ;
string c = applicationPath + @"\ffmpeg.exe -ss 00:00:05 -i" + " " + fileNamePath + " " + targetImgNamePath + " " + "-r 1 -vframes 1 -an -vcodec mjpeg ";//速度快
Cmd(c);
//-i:设定输入文件名
//-r:设定帧 此处设为1帧
//-f:设定输出格式
//-ss 从指定时间截图
//-vcodec:设定影像解码器,没有输入时为文件原来相同的解码器
//-vframes 设置转换多少桢(frame)的视频
//-an 不处理声音
}
/// <summary>
/// 程序中调用CMD.exe程序,并且不显示命令行窗口界面
/// </summary>
/// <param name="c">执行的cmd命令</param>
private static void Cmd(string c)
{
try
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.CreateNoWindow = true; //不显示程序窗口
process.StartInfo.FileName = "cmd.exe";//要执行的程序名称
process.StartInfo.UseShellExecute = false;
//process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
process.StartInfo.RedirectStandardInput = true; //可能接受来自调用程序的输入信息
process.Start();//启动程序
process.StandardInput.WriteLine(c);
process.StandardInput.AutoFlush = true;
process.StandardInput.WriteLine("exit");
}
catch { }
}
}
以上试用与本地上传的情况,在实际使用中,可以选择直接部署在文件服务器。若不直接部署在服务器上则要使用跨域上传,则需要使用异步。因为截图会有一定的时间差,所以需要先上传视频,本地截图,再上传图片
//线程池异步上传 在上传方法内调用,imgName为带后缀图片名
ThreadPool.QueueUserWorkItem(TestMethod, imgName);
//线程上传
public void TestMethod(object data)
{
string imgFile = Server.MapPath("/upload/"+data.ToString()).ToString() ;
FileManager FileMgr = new FileManager("", "flv");
//检查文件是否已生成
while (! System.IO.File.Exists(imgFile))
{
Thread.Sleep(1000);
}
System.IO.Stream str = System.IO.File.OpenRead(imgFile);
//跨域上传
if (FileMgr.UploadFile(str, data.ToString()))
{
//删除本地图片时需要先释放资源
str.Dispose();
System.IO.File.Delete(imgFile);
}
}