java实现视频上传和播放解读.docx
- 文档编号:11537026
- 上传时间:2023-03-19
- 格式:DOCX
- 页数:19
- 大小:248.89KB
java实现视频上传和播放解读.docx
《java实现视频上传和播放解读.docx》由会员分享,可在线阅读,更多相关《java实现视频上传和播放解读.docx(19页珍藏版)》请在冰豆网上搜索。
java实现视频上传和播放解读
Java实现视频网站的视频上传、视频转码、视频关键帧抽图,及视频播放功能
视频网站中提供的在线视频播放功能,播放的都是FLV格式的文件,它是Flash动画文件,可通过Flash制作的播放器来播放该文件.项目中用制作的player.swf播放器.
多媒体视频处理工具FFmpeg有非常强大的功能包括视频采集功能、视频格式转换、视频抓图、给视频加水印等。
ffmpeg视频采集功能非常强大,不仅可以采集视频采集卡或USB摄像头的图像,还可以进行屏幕录制,同时还支持以RTP方式将视频流传送给支持RTSP的流媒体服务器,支持直播应用。
1.能支持的格式
ffmpeg能解析的格式:
(asx,asf,mpg,wmv,3gp,mp4,mov,avi,flv等)
2.不能支持的格式
对ffmpeg无法解析的文件格式(wmv9,rm,rmvb等),可以先用别的工具(mencoder)转换为avi(ffmpeg能解析的)格式.
实例是将上传视频转码为flv格式,该格式ffmpeg支持,所以我们实例中需要ffmpeg视频处理工具.
数据库MySQL5.5
实例所需要的数据库脚本
dropdatabaseifexistsdb_mediaplayer;
createdatabasedb_mediaplayer;
usedb_mediaplayer;
createtabletb_media(
idintnotnullprimarykeyauto_incrementcomment'主键',
titlevarchar(50)notnullcomment'视频名称',
srcvarchar(200)notnullcomment'视频存放地址',
picturevarchar(200)notnullcomment'视频截图',
descriptvarchar(400)comment'视频描述',
uptimevarchar(40)comment'上传时间'
);
desctb_media;
项目结构图:
上传视频界面设计
在上传文件时,Form表单中 enctype属性值必须为"multipart/form-data".模块界面设计如下图:
enctype属性值说明
application/x-www-form-urlencoded
表单数据被编码为名称/值对,这是标准的编码格式
multipart/form-data
表单数据被编码为一条消息,页面上每个控件对应消息中的一部分
text/plain
表单数据以纯文本形式进行编码,其中不含任何控件格式的字符
业务接口定义
面向接口编程,接口中定义系统功能模块.这样方便理清业务,同时接口的对象必须由实现了该接口的对象来创建.这样就避免编码中的某些业务遗漏等,同时扩展性也增强了.
packagecom.webapp.dao;
importjava.util.List;
importcom.webapp.entity.Media;
/**
*
*MediaDao.java
*
*@version:
1.1
*
*@author:
苏若年 DennisIT@">发送邮件 * *@since: 1.0创建时间: 2013-2-07上午10: 19: 54 * *TODO: interfaceMediaDao.javaisusedfor... * */ publicinterfaceMediaDao{ /** *视频转码 *@paramffmpegPath转码工具的存放路径 *@paramupFilePath用于指定要转换格式的文件,要截图的视频源文件 *@paramcodcFilePath格式转换后的的文件保存路径 *@parammediaPicPath截图保存路径 *@return *@throwsException */ publicbooleanexecuteCodecs(StringffmpegPath,StringupFilePath,StringcodcFilePath,StringmediaPicPath)throwsException; /** *保存文件 *@parammedia *@return *@throwsException */ publicbooleansaveMedia(Mediamedia)throwsException; /** *查询本地库中所有记录的数目 *@return *@throwsException */ publicintgetAllMediaCount()throwsException; /** *带分页的查询 *@paramfirstResult *@parammaxResult *@return */ publicList /** *根据Id查询视频 *@paramid *@return *@throwsException */ publicMediaqueryMediaById(intid)throwsException; } 接口的实现,这里列出ffmpeg视频转码与截图模块 /** *视频转码 *@paramffmpegPath转码工具的存放路径 *@paramupFilePath用于指定要转换格式的文件,要截图的视频源文件 *@paramcodcFilePath格式转换后的的文件保存路径 *@parammediaPicPath截图保存路径 *@return *@throwsException */ publicbooleanexecuteCodecs(StringffmpegPath,StringupFilePath,StringcodcFilePath, StringmediaPicPath)throwsException{ //创建一个List集合来保存转换视频文件为flv格式的命令 List convert.add(ffmpegPath);//添加转换工具路径 convert.add("-i");//添加参数"-i",该参数指定要转换的文件 convert.add(upFilePath);//添加要转换格式的视频文件的路径 convert.add("-qscale");//指定转换的质量 convert.add("6"); convert.add("-ab");//设置音频码率 convert.add("64"); convert.add("-ac");//设置声道数 convert.add("2"); convert.add("-ar");//设置声音的采样频率 convert.add("22050"); convert.add("-r");//设置帧频 convert.add("24"); convert.add("-y");//添加参数"-y",该参数指定将覆盖已存在的文件 convert.add(codcFilePath); //创建一个List集合来保存从视频中截取图片的命令 List cutpic.add(ffmpegPath); cutpic.add("-i"); cutpic.add(upFilePath);//同上(指定的文件即可以是转换为flv格式之前的文件,也可以是转换的flv文件) cutpic.add("-y"); cutpic.add("-f"); cutpic.add("image2"); cutpic.add("-ss");//添加参数"-ss",该参数指定截取的起始时间 cutpic.add("17");//添加起始时间为第17秒 cutpic.add("-t");//添加参数"-t",该参数指定持续时间 cutpic.add("0.001");//添加持续时间为1毫秒 cutpic.add("-s");//添加参数"-s",该参数指定截取的图片大小 cutpic.add("800*280");//添加截取的图片大小为350*240 cutpic.add(mediaPicPath);//添加截取的图片的保存路径 booleanmark=true; ProcessBuilderbuilder=newProcessBuilder(); try{ mand(convert); builder.redirectErrorStream(true); builder.start(); mand(cutpic); builder.redirectErrorStream(true); //如果此属性为true,则任何由通过此对象的start()方法启动的后续子进程生成的错误输出都将与标准输出合并, //因此两者均可使用Process.getInputStream()方法读取。 这使得关联错误消息和相应的输出变得更容易 builder.start(); }catch(Exceptione){ mark=false; System.out.println(e); e.printStackTrace(); } returnmark; } 系统中可能存在多个模块,这些模块的业务DAO可以通过工厂来管理,需要的时候直接提供即可. 因为如果对象new太多,会不必要的浪费资源.所以工厂,采用单例模式,私有构造,提供对外可访问的方法即可. packagecom.webapp.dao; importcom.webapp.dao.impl.MediaDaoImpl; /** * *DaoFactory.java * *@version: 1.1 * *@author: 苏若年 DennisIT@">发送邮件 * *@since: 1.0创建时间: 2013-2-07下午02: 18: 51 * *TODO: classDaoFactory.javaisusedfor... * */ publicclassDaoFactory{//工厂模式,生产Dao对象,面向接口编程,返回实现业务接口定义的对象 privatestaticDaoFactorydaoFactory=newDaoFactory(); //单例设计模式,私有构造,对外提供获取创建的对象的唯一接口, privateDaoFactory(){ } publicstaticDaoFactorygetInstance(){ returndaoFactory; } publicstaticMediaDaogetMediaDao(){ returnnewMediaDaoImpl(); } } 视图提交请求,给控制器,控制器分析请求参数,进行相应的业务调用处理.servlet控制器相关代码如下 packagecom.webapp.service; importjava.io.File; importjava.io.IOException; importjava.io.PrintWriter; importjava.util.List; importjavax.servlet.ServletContext; importjavax.servlet.ServletException; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importmons.fileupload.FileItem; importmons.fileupload.disk.DiskFileItemFactory; importmons.fileupload.servlet.ServletFileUpload; importcom.webapp.dao.DaoFactory; importcom.webapp.dao.MediaDao; importcom.webapp.entity.Media; importcom.webapp.util.DateTimeUtil; /** * *MediaService.java * *@version: 1.1 * *@author: 苏若年 DennisIT@">发送邮件 * *@since: 1.0创建时间: 2013-2-08下午02: 24: 47 * *TODO: classMediaService.javaisusedfor... * */ publicclassMediaServiceextendsHttpServlet{ publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ doPost(request,response); } publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse) throwsServletException,IOException{ PrintWriterout=response.getWriter(); MediaDaomediaDao=DaoFactory.getMediaDao(); Stringmessage=""; Stringuri=request.getRequestURI(); Stringpath=uri.substring(uri.lastIndexOf("/"),uri.lastIndexOf(".")); if("/uploadFile".equals(path)){ //提供解析时的一些缺省配置 DiskFileItemFactoryfactory=newDiskFileItemFactory(); //创建一个解析器,分析InputStream,该解析器会将分析的结果封装成一个FileItem对象的集合 //一个FileItem对象对应一个表单域 ServletFileUploadsfu=newServletFileUpload(factory); try{ Mediamedia=newMedia(); List booleanflag=false;//转码成功与否的标记 for(inti=0;i FileItemitem=items.get(i); //要区分是上传文件还是普通的表单域 if(item.isFormField()){//isFormField()为true,表示这不是文件上传表单域 //普通表单域 StringparamName=item.getFieldName(); /* StringparamValue=item.getString(); System.out.println("参数名称为: "+paramName+",对应的参数值为: "+paramValue); */ if(paramName.equals("title")){ media.setTitle(newString(item.getString().getBytes("ISO8859-1"),"UTF-8")); } if(paramName.equals("descript")){ media.setDescript(newString(item.getString().getBytes("ISO8859-1"),"UTF-8")); } }else{ //上传文件 //System.out.println("上传文件"+item.getName()); ServletContextsctx=this.getServletContext(); //获得保存文件的路径 StringbasePath=sctx.getRealPath("videos"); //获得文件名 StringfileUrl=item.getName(); //在某些操作系统上,item.getName()方法会返回文件的完整名称,即包括路径 StringfileType=fileUrl.substring(fileUrl.lastIndexOf("."));//截取文件格式 //自定义方式产生文件名 StringserialName=String.valueOf(System.currentTimeMillis()); //待转码的文件 FileuploadFile=newFile(basePath+"/temp/"+serialName+fileType); item.write(uploadFile); if(item.getSize()>500*1024*1024){ message=" 您上传的文件太大,系统允许最大文件500M"; } StringcodcFilePath=basePath+"/"+serialName+".flv";//设置转换为flv格式后文件的保存路径 StringmediaPicPath=basePath+"/images"+File.separator+serialName+".jpg";//设置上传视频截图的保存路径 //获取配置的转换工具(ffmpeg.exe)的存放路径 StringffmpegPath=getServletContext().getRealPath("/tools/ffmpeg.exe"); media.setSrc("videos/"+serialName+".flv"); media.setPicture("videos/images/"+serialName+".jpg"); media.setUptime(DateTimeUtil.getYMDHMSFormat()); //转码 flag=mediaDao.executeCodecs(ffmpegPath,uploadFile.getAbsolutePath(),codcFilePath,mediaPicPath); } } if(flag){ //转码成功,向数据表中添加该视频信息 mediaDao.saveMedia(media); message=" "; } request.setAttribute("message",message); request.getRequestDispatcher("media_upload.jsp").forward(request,response); }catch(Exceptione){ e.printStackTrace(); thrownewServletException(e); } } if("/queryAll".equals(path)){ List try{ mediaList=mediaDao.queryALlMedia(0,5); request.setAttribute("mediaList",mediaList); request.getRequestDispatcher("media_list.jsp").forward(request,response); }catch(Exceptione){ e.printStackTrace(); } } if("/play".equals(path)){ Stringidstr=request.getParameter("id"); intmediaId=-1; Mediamedia=null; if(null! =idstr){ mediaId=Integer.parseInt(idstr); } try{ media=mediaDao.queryMediaById(mediaId); }catch(Exceptione){ e.printStackTrace(); } request.setAttribute("media",media); request.getRequestDispatcher("media_player.jsp").forward(request,response); } } } 可以通过分页查找,显示最新top5,展示到首页.相应特效可以使用JS实现. 相关代码如下: <%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageE
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- java 实现 视频 上传 播放 解读