上传视频并截取缩略图

来源:互联网 发布:c语言编写游戏 编辑:程序博客网 时间:2024/05/21 18:39

最近做一个上传视频并且截取缩略图的功能,百度了一下好像都是上传视频之后使用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);            }        }