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-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,并且保持全文完整性,^^

JAVA系统下的FLASH,FLV视频应用解决方案(转载)相关推荐

  1. java flash 压缩_JAVA系统下的FLASH,FLV视频应用解决方案

    最近网络上FLV视频应用越来越多了.使用这种方案的好处是:一定程度上可以保护作品版权,易于视频作品在网络上传播,更高的商业运作价值.这一切特点都是因为FLV是基于FLASH播放器的一种流媒体格式. 我 ...

  2. FLASH,FLV视频应用在JAVA系统下的解决方案

    FLASH,FLV视频应用在JAVA系统下的解决方案 来源 http://5do.com.cn/roller/page/bhlove?entry=jf 最近网络上FLV视频应用越来越多了.使用这种方案 ...

  3. Windows系统下好用的视频剪辑软件有哪些?有哪些推荐

    目前市场上有很多视频剪辑类的软件,比较出名的有:Adobe Effect.EDIUS.会声会影.Adobe Premiere等等.然而这些软件对于一些刚接触视频剪辑的小伙伴存在着很多问题,比方说学习过 ...

  4. Win10系统下软件UI显示不完整解决方案

    Win10系统下软件UI显示不完整解决方案 参考文章: (1)Win10系统下软件UI显示不完整解决方案 (2)https://www.cnblogs.com/wxjnew/p/5079726.htm ...

  5. redhat和ubuntu系统下挂载ntfs文件系统的方法(转载)

    1.首先确定你的linux kernel版本是什么(Redhat9.0默认的kernel版本是2.4.20-8 )  #> rpm -qa|grep kernel  会显示类式的如下信息:  k ...

  6. linux中split分割文件打开方式,Linux系统下使用split命令分割大文件 (转载)

    [小蜗牛闲情之作 ] 我想给一个朋友传一个大视频,有几百M,尝试多种传输办法失败后,最后想到的是把视频切开一片片"邮递"过去给他,让它自己组装起来吧. [root@pps publ ...

  7. linux文件分割命令性能,Linux系统下使用split命令分割大文件 (转载)

    [小蜗牛闲情之作 ] 我想给一个朋友传一个大视频,有几百M,尝试多种传输办法失败后,最后想到的是把视频切开一片片"邮递"过去给他,让它自己组装起来吧. [root@pps publ ...

  8. Win7系统下CAD鼠标中键不能平移的解决方案

    Win7系统下CAD鼠标中键不能平移怎么解决?AutoCAD是一款三维设计软件,在画图的时候,我们经常会用到CAD鼠标中键的平移功能,然而有Win7用户遇到CAD鼠标中键不能平移的情况,这该如何解决呢 ...

  9. flash player for linux 64位,linux 64位系统下安装flash player插件

    对像我这样用惯了xp而为了生活不得不工作在ubuntu11.04 64位系统下面的程序猿们来说,总是因为不熟悉系统而遇到诸多不便.比如工作过劳时想要忙里偷闲,看看湖人的比赛,打开直播网页却露给我如下一 ...

最新文章

  1. matlab绘图z=sin(x_「matlab画三维图」Matlab 应用之绘制三维图形(基础篇) - seo实验室...
  2. android 变量Map集合
  3. 我的10年富士康故事
  4. 程序人生:搜索引擎被禁用,你还会写代码吗?
  5. Quartz.NET simple_demo
  6. 《C++ Primer》2.1.2节练习
  7. 获取Spring的ApplicationContext的几种方式
  8. 区块链数学建模_试图通过高中数学课程来解释区块链
  9. android开发界面 淡出,Android 界面淡出 淡入效果
  10. 深入了解nginx.conf配置文件
  11. 两周从爬虫小白变大神,看完你就知道我不是标题党了【五万字教程,建议收藏】
  12. 小虾米的求助Massage
  13. 编写应用程序,计算两个非零正整数的最大公约数和最小公倍数,要求两个非零正整数从键盘输入。
  14. [Introduction to programming in Java 笔记] 1.3.8 Gambler's ruin simulation 赌徒破产模拟
  15. 物联网环境监测数据中心系统
  16. python 3.6.0.tgz,如何在Ubuntu和LinuxMint上安装Python 3.6.0
  17. 离职那天,我们复员……
  18. 条理清晰的入门:使用Java实现RSA加密解密
  19. ios代码混淆小工具
  20. 给DataTable中添加一行数据

热门文章

  1. 实变函数自制笔记5:勒贝格测度论
  2. Opencv4.5.2 + Opencv_contrib4.5.2 VS2015 Win7下编译过程和注意事项
  3. 多视角3D重建技术市场现状研究分析报告-
  4. c#位图转换未矢量图_C#中如何生成矢量图
  5. MRPII/ERP对企业经营方式转变的影响(转)
  6. Qt 绘图坐标系转换
  7. 一名新手测试经理3个月试用期转正总结【人情世故】
  8. 服务点赞点评时记录赞赏时间,如果有打赏钱的话,记录支付时间,服务员打赏平台
  9. 利用 PyQt5 + Pyinstaller 制作 个性动态二维码 桌面应用
  10. laravel mysql注入_详解 Laravel 中的依赖注入和 IoC