mzchenwb 2013-10-21
在项目推进的过程中,力求做到前台展现和后台管理的分离,文件上传属于后台管理的功能,而关于文件的删除,名称的更改等等,都已一一解决。
接下来需要完成前台展示的功能。
目标效果是希望在前台加载页面时,自动为视频文件截取缩略图,自动获取视频文件的时长,这里用到了一个插件,ffmpeg.exe。
为此在前台的aspx.cs文件中写了两个自定义方法:
/// <param name="VideoName">视频文件pic/guiyu.mov</param> /// <param name="WidthAndHeight">图片的尺寸如:240*180</param> /// <param name="CutTimeFrame">开始截取的时间如:"1"</param> #region 从视频画面中截取一帧画面为图片 public string GetPicFromVideo(string VideoName, string WidthAndHeight, string CutTimeFrame, string PicName) { string ffmpeg = HttpContext.Current.Server.MapPath("~/Source/Scripts/ffmpeg/ffmpeg.exe"); System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(ffmpeg); startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; startInfo.Arguments = " -i " + VideoName + " -y -f image2 -ss " + CutTimeFrame + " -t 0.001 -s " + WidthAndHeight + " " + PicName; //设定程序执行的参数 try { System.Diagnostics.Process.Start(startInfo); return PicName; } catch (Exception err) { return err.Message; } } #endregion
#region 获取视频长度 /// <summary> /// /// </summary> /// <param name="ffmpegfile">ffmpeg.exe路径</param> /// <param name="sourceFile">视频文件路径</param> /// <returns></returns> public string GetVideoDuration(string sourceFile) { string ffmpegfile = HttpContext.Current.Server.MapPath("~/Source/Scripts/ffmpeg/ffmpeg.exe"); using (System.Diagnostics.Process ffmpeg = new System.Diagnostics.Process()) { String duration; String result; StreamReader errorreader; ffmpeg.StartInfo.UseShellExecute = false; ffmpeg.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; ffmpeg.StartInfo.RedirectStandardError = true; ffmpeg.StartInfo.FileName = ffmpegfile; ffmpeg.StartInfo.Arguments = "-i " + sourceFile; ffmpeg.Start(); errorreader = ffmpeg.StandardError; ffmpeg.WaitForExit(); result = errorreader.ReadToEnd(); duration = result.Substring(result.IndexOf("Duration: ") + ("Duration: ").Length, ("00:00:00").Length); return duration; } } #endregion
这样,只要在pageLoad事件中调用这两个方法,传入参数,即可为视频生成缩略图。
这里遍历视频并为视频生成视频信息没有使用数据库而是在该视频文件目录下创建XML文档。
protected void Page_Load(object sender, EventArgs e) { string mainPath = MapPath(Common.ComFunction.GetConfig("UpLoadPath")) + "Video\\Eco"; string[] Directories = Directory.GetDirectories(mainPath); List<VideoModelExtension> _list = new List<VideoModelExtension>(); for (int i = 0; i < Directories.Length; i++) { string dairs = Directories[i]; string[] n = dairs.Split('\\'); int x = n.Length - 1; string name = n[x]; string XmlConfig = dairs + "\\XMLConfig.xml";//配置文件 string AbPath = dairs + "\\" + name + ".flv"; //获取视频文件的绝对路径 string PicName = AbPath + ".jpg"; //指定缩略图文件的名称 VideoModelExtension model = new VideoModelExtension(); if (!File.Exists(XmlConfig)) { XmlDocument xmldoc = new XmlDocument(); //xml文档声明 XmlDeclaration xmldecl; xmldecl = xmldoc.CreateXmlDeclaration("1.0", "utf-8", null); xmldoc.AppendChild(xmldecl); //增加跟节点 XmlElement xmlelem = xmldoc.CreateElement("", "EcoVideo", ""); xmldoc.AppendChild(xmlelem); //获取根节点 XmlNode root = xmldoc.SelectSingleNode("EcoVideo"); //添加子节点 和属性 //名称 xmlelem = xmldoc.CreateElement("Name"); xmlelem.SetAttribute("Value", name); root.AppendChild(xmlelem); //名称 xmlelem = xmldoc.CreateElement("Directory"); xmlelem.SetAttribute("Value", name); root.AppendChild(xmlelem); ///创建日期 xmlelem = xmldoc.CreateElement("DateAdd"); xmlelem.SetAttribute("Value", DateTime.Now.ToLongDateString()); root.AppendChild(xmlelem); ///视频地址 xmlelem = xmldoc.CreateElement("Path"); xmlelem.SetAttribute("Value", name + "/" + name + ".flv"); root.AppendChild(xmlelem); ///添加评分 xmlelem = xmldoc.CreateElement("Count"); xmlelem.SetAttribute("Value", "0"); root.AppendChild(xmlelem); ///添加时长 xmlelem = xmldoc.CreateElement("Duration"); xmlelem.SetAttribute("Value", model.GetVideoDuration(AbPath)); root.AppendChild(xmlelem); //添加缩略图 xmlelem = xmldoc.CreateElement("img"); xmlelem.SetAttribute("Value", model.GetPicFromVideo(AbPath, "220*220", "5", PicName).Split('\\').Last()); root.AppendChild(xmlelem); //添加简介 xmlelem = xmldoc.CreateElement("Description"); xmlelem.SetAttribute("Value", "无"); root.AppendChild(xmlelem); xmldoc.Save(XmlConfig); } //读取配置参数 XmlDocument xmldocread = new XmlDocument(); xmldocread.Load(XmlConfig); model.Name = ((XmlElement)xmldocread.SelectSingleNode("EcoVideo").SelectSingleNode("Name")).GetAttribute("Value"); model.Directory = ((XmlElement)xmldocread.SelectSingleNode("EcoVideo").SelectSingleNode("Directory")).GetAttribute("Value"); model.Day = ((XmlElement)xmldocread.SelectSingleNode("EcoVideo").SelectSingleNode("DateAdd")).GetAttribute("Value"); model.count = ((XmlElement)xmldocread.SelectSingleNode("EcoVideo").SelectSingleNode("Count")).GetAttribute("Value"); model.Duration = ((XmlElement)xmldocread.SelectSingleNode("EcoVideo").SelectSingleNode("Duration")).GetAttribute("Value"); model.Path = ((XmlElement)xmldocread.SelectSingleNode("EcoVideo").SelectSingleNode("Path")).GetAttribute("Value"); model.img = name + "/" + ((XmlElement)xmldocread.SelectSingleNode("EcoVideo").SelectSingleNode("img")).GetAttribute("Value"); model.Description = ((XmlElement)xmldocread.SelectSingleNode("EcoVideo").SelectSingleNode("Description")).GetAttribute("Value"); _list.Add(model); } _list = _list.OrderByDescending(a => a.Day).ToList(); this.ReptVideo.DataSource = _list; this.ReptVideo.DataBind(); }
前台HTML节点代码这里就不写了,总之ffmpeg是个很强劲的视频转换插件,当然你必须要对这个文件是百分之百信任的,否则你的站点可能存在潜在的风险。