JAVA系统下的FLASH,FLV视频应用解决方案(转载)
2007-06-06 17:06
495 查看
JAVA系统下的FLASH,FLV视频应用解决方案 2006年11月20日15:59星期一 [资料]
最近网络上FLV视频应用越来越多了.使用这种方案的好处是:一定程度上可以保护作品版权,易于视频作品在网络上传播,更高的商业运作价值.这一切特点都是因为FLV是基于FLASH播放器的一种流媒体格式. 我们知道,FLASH是一种易于开发的网络媒体.FLASH开发人员可以不需要太复杂的工作便可以制作一个FLV视频播放器.此篇文章重点不在于教你怎么制作FLV播发器,我们着重讲解下如何在服务器端将用户上传的视频文件转换为FLV格式,以及如何在我们制作的FLASH里使用这个FLV等关键环节. 软件环境 WEB应用程序环境 JAVA 操作系统 WINDOWS 视频编/解码程序 FFMEPG 用户接口设计 由于用户所上传的视频文件一般都很大,所以使用简单的表单FILE控件来上传显然是不明智的.我们注重给用户更佳的操作体验. 通常开发者会使用javascript来实现一些例如文件上传进度反馈等效果.这做法非常不错,不过在这里我推荐的是使用FLASH8所支持的文件上传功能.其好处是可以通过FLASH编程达到更加丰富的用户交互体验. 在附件中带有该功能的FLASH源文件实例. 在"视频处理过程"中讲述了如何在JAVA程序下实现这一功能的服务器端操作. 客户端交互效果: 显示文件上传信息 支持批量上传 文件格式过滤 文件长度限制 视频处理过程 文件上传处理 我想,一些常用的J2EE文件上传组件会在你采用FLASH作为文件上传控件的时候令你束手无策.这是作者本人经历过的.至少,你需要烦琐的编码,甚至采取重写这些开源组件的手段以达到使其能够处理FLASH控件所提交过来的文件的目的.现在,我向你介绍的这个组件可能会减少你在这块的编程工作. 我采用的是oreilly提供的servlet辅助处理工具COS,并且使用其中的MultipartRequest来处理FLASH提交过来的文件流. 文件上传处理示例代码: ControllerServlet.java //...... ............ //你的Servlet中需要放置的代码 if (request.getContentLength() == 0)return null; String tempFilePath = "c:/" //文件存放目录 videoBO.uploadVideoFile(request,tempFilePath); //.................. 在Servlet中我们需要关注的是FLASH在一次文件提交操作时会向服务器发送两次请求.第一次附带的信息为空,第二次提交的才是正式的文件上传内容.如不在Servlet里判断request里的内容长度是否为0,则下面的程序执行时必定会抛出空指针的异常 负责文件上传处理的方法 VideoBO.java public String uploadVideoFile(HttpServletRequest request, String path){ File dir = new File(path); if (!dir.exists()) { dir.mkdir(); } MultipartRequest multi; try { multi = new MultipartRequest(request, path, 100 * 1024 * 1024,"UTF-8"); Enumeration files = multi.getFileNames(); if (files.hasMoreElements()) { String name = (String) files.nextElement(); File f = multi.getFile(name); return f.getName(); } } catch (IOException e) { e.printStackTrace(); } return null; } 看起来代码似乎很简单^^ 解决文件上传处理后,我们接着需要针对上传过来的视频文件做格式的转换. 视频格式转换 我们采用FFMEPG作为视频编/解码工具.相关FFMEPG的介绍请搜索网络 (FFMEPG二进制版本已经在附件中提供下载) 将得到的FFMEPG目录下的所有dll文件和exe文件复制到windows/system32目录下.我们将在java环境下调用系统命令的方式执行编码工作. FFMEPG是采用命令行的方式进行编译工作,所以,我们需要把这些命令写在一个批处理文件里. 在c盘根目录下建立一个批处理文件 c:encode.bat 内容: ffmpeg.exe -i %1 -y -s 400x300 -deinterlace -b 256 -ab 64 -ar 22050 -ac 2 %2 2>encode.txt 以上的命令表示: %1 :接收参数一 %2 :接受参数二 -y :默认覆盖已存在的输出文件 >encode.txt :将打印信息暂存在encode.txt中,以避免打印信息出现在java控制台中影响java程序执行. 另外我们还需要获取视频内容的缩略图 c:makeimg.bat ffmpeg.exe -i %1 -y -f image2 -ss 5 -t 0.001 -s 120x90 %2 2>encode.txt 更多的FFMEPGM命令解释请参考网络 在java程序中执行这个批处理文件 /* *String fileIn,视频原文件地址 *String fileOut,转换后输出到目标目录 *String fileName ,转换后的视频文件名称,例如:xxx.flv.注意文件名必须以.flv结束. */ public synchronized static boolean encode(String fileIn,String fileOut,String fileName){ String fullPath = fileOut+"/"+fileName; //完整文件路径 String cmd = "c:/encoder.bat "+fileIn+" "+fullPath; //命令字串 try { //如果目录路径不存在则创建 File file = new File(fileOut); if(!file.exists()){ file.mkdirs(); } Process p = Runtime.getRuntime().exec(cmd); p.waitFor();//java程序等待执行过程完毕 File filePath = new File(fullPath); //如果文件存在,并且长度不为0,则表示转换成功. boolean success = filePath.exists()&&filePath.length()>0; if(success){ //创建缩略图 Runtime.getRuntime().exec("c:/makeimg.bat "+fullPath+" "+fileOut+"/"+new MD5Helper().getMD5ofStr(fileName)+".jpg"); //依据FLV的文件名,我们有必要将缩略图名称用MD5加密,这样可以保护我们的FLV源文件地址信息泄露. } return success; } catch (Exception e) { e.printStackTrace(); return false; } } 视频转换过程是一个及其消耗系统性能的过程.所以,我们必须限制其系统进程数量.通过对JAVA方法的锁定(synchronized),可保持每次操作系统仅执行一个进程. 3.视频调用/输出 在FLASH中获取外部信息的方式很多,在此不累述.例如loadvars,xml,socket,webservice等.另外,使用FLASH中的NetStream类也可以直接播FLV放视频流. 我们需要在FLASH中播放服务器转换后的FLV文件.并且考虑采用哪一种数据交换方式最为恰当. 分析: loadvars,xml等方式具有域的限制,也就是说仅可以获取与FLASH同一个域内的数据(即同一个站点域名下).显然,此类数据交换形式不适合我们将视频内容在网站外部传播的需求. NetStream仅可以载入flv,mp3流媒体文件,而我们通常希望能够将一些文本信息加入到FLASH中,例如我们的广告,更新信息等.所以,这种方法也不是最好的. 最后,我们推荐webservice. webservice具有分布式,支持对象传递等特性,可以不受域的限制.并且其对象传输模式极有利于复杂的数据结构编程.也就是说,JAVA对象可以直接在FLASH使用. 在JAVA中搭建webservice框架 我们采用apache提供的axis作为我们的webservice服务容器. 在javaweb应用中配置axis并不复杂. axia程序包可以在http://ws.apache.org/获宮....类包添加至classpath中 在web.xml中配置axis 将所需要的类包添加至classpath中, 在WEB-INF目录下放置部署描述符号 一个axis配置大致是以下内容,(复制到web.xml中<web-app></web-app>节点中即可) <!--WebService--> <servlet> <servlet-name>SOAPMonitorService</servlet-name> <display-name>SOAP Monitor Service</display-name> <servlet-class>org.apache.axis.monitor.SOAPMonitorService</servlet-class> <init-param> <param-name>SOAPMonitorPort</param-name> <param-value>5001</param-value> </init-param> <load-on-startup>100</load-on-startup> </servlet> <servlet> <servlet-name>AdminServlet</servlet-name> <display-name>Axis Admin Servlet</display-name> <servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class> <load b37b -on-startup>100</load-on-startup> </servlet> <servlet> <servlet-name>AxisServlet</servlet-name> <display-name>Apache-Axis Servlet</display-name> <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>SOAPMonitorService</servlet-name> <url-pattern>/SOAPMonitor</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AdminServlet</servlet-name> <url-pattern>/servlet/AdminServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/servlet/AxisServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>*.jws</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/webservices/*</url-pattern> </servlet-mapping> <mime-mapping> <extension>wsdl</extension> <mime-type>text/xml</mime-type> </mime-mapping> <mime-mapping> <extension>xsd</extension> <mime-type>text/xml</mime-type> </mime-mapping> 配置部署描述符 在WEB-INF目录下建立server-config.wsdd <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns:handler="http://xml.apache.org/axis/wsdd/providers/handler" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="defaultClientConfig" xsi:type="deployment"> <globalConfiguration name="defaultClientConfig"> <parameter name="disablePrettyXML" value="true"/> <parameter name="dotNetSoapEncFix" value="true"/> <requestFlow name="RequestFlow1" type=""> <handler name="Handler1" type="java:org.apache.axis.handlers.JWSHandler"> <parameter name="scope" value="session"/> </handler> <handler name="Handler2" type="java:org.apache.axis.handlers.JWSHandler"> <parameter name="scope" value="request"/> <parameter name="extension" value=".jwr"/> </handler> </requestFlow> </globalConfiguration> <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/> <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/> <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/> <transport name="http" type=""> <parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/> <parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/> <parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/> <requestFlow name="RequestFlow1" type=""> <handler name="Handler1" type="URLMapper"/> <handler name="Handler2" type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/> </requestFlow> </transport> <transport name="local" type=""> <responseFlow name="ResponseFlow1" type=""> <handler name="Handler1" type="LocalResponder"/> </responseFlow> </transport> <!-- <service name="AdminService" type="" provider="java:MSG"> <parameter name="allowedMethods" value="AdminService"/> <parameter name="enableRemoteAdmin" value="false"/> <parameter name="className" value="org.apache.axis.utils.Admin"/> <namespace>http://xml.apache.org/axis/wsdd/</namespace> </service> <service name="Version" type="" provider="java:RPC"> <parameter name="allowedMethods" value="getVersion"/> <parameter name="className" value="org.apache.axis.Version"/> </service> --> <!-- 自定义一个服务,在以下节点中配置你的webservice --> <service name="PlayerService" type="" provider="java:RPC" style="rpc" use="encoded"> <parameter name="scope" value="Request"/> <parameter name="className" value="com.hizon.web.service.PlayerService"/> <parameter name="allowedMethods" value="*"/> <namespace>http://service.web.hizon.com</namespace> </service> </deployment> 部署描述文件可以由axis提供的工具生成,直接修改这个文件内容也可. PlayerService类 package com.hizon.web.service; import java.util.Map; public class PlayerService { public Map getVideo(String id) { Map videoMap = new HashMap(); //code return videoMap; } } PlayerService是一个普通的javabean,或者你可以直接在部署描述符中将负责数据提供的类指向你的POJO. ...... <parameter name="className" value="xxx.xxx.MyPOJO"/> ...... 视频表现方式 通过webservice,我们可以自由的获取服务器端提供的数据信息.包括视频作者资料,FLV文件地址等.接下来的工作便是如何在FLASH使用这些数据的问题了.由于时间和篇幅有限,不再累述. 总结 通过这篇文章,我们知道了如何flash和 MultipartRequest类的协助搭建我们的flash文件上传系统. 如何使用在java程序中使用ffmepg转换视频格式.以及如何使用axis搭建webservice容器为FLASH客户端提供数据. 文章所做的只是一个技术方案层面上的概述.并未涉及太多的编码细节.如有兴趣,请登录http://5do.com.cn/bbs和殮....术,或者访问我的blog: http://5do.com.cn/roller/bhlove 我将和你探讨更多的相关知识,以及与你共同解决存在的问题. 文章转载请注明出处:http://5do.com.cn/roller/bhlove,并且保持全文完整性,^^ |
相关文章推荐
- FLASH,FLV视频应用在JAVA系统下的解决方案
- JAVA系统下的FLASH,FLV视频应用解决方案
- JAVA系统下的FLASH,FLV视频应用解决方案
- 关于 flash (jw player)不能处理 flv视频 中文名文件 或者 中文路径 的 解决方案
- java系统高并发解决方案(转载)
- java系统高并发解决方案(转载)
- java系统高并发解决方案(转载)
- java系统高并发解决方案(转载)
- java系统高并发解决方案(转载)
- java系统高并发解决方案(转载)
- java系统高并发解决方案(转载)
- flv视频转换和flash播放的解决方案笔记
- java系统高并发解决方案(转载)
- java系统高并发解决方案(转载)
- Java 系统高并发解决方案(转载)
- 如何用Google APIs和Google的应用系统进行集成(7)----在把JSON转换成XML数据过程中,JSON数据中包含违背XML数据规范:XML节点名不支持数字的Java解决方案
- java系统高并发解决方案(转载)
- java系统高并发解决方案(转载)
- java系统高并发解决方案(转载)