📄 用java多媒体框架设计自动播放机_开 发 者_网上学园_科技时代_新浪网.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0047)http://tech.sina.com.cn/c/2004-02-12/27742.html -->
<!--[2,68,27742] published at 2004-03-31 15:40:32 from #004 by 571--><HTML><HEAD><TITLE>用Java多媒体框架设计自动播放机_开 发 者_网上学园_科技时代_新浪网</TITLE>
<META http-equiv=content-type content="text/html; charset=gb2312">
<STYLE type=text/css>TD {
FONT-SIZE: 12px
}
SELECT {
FONT-SIZE: 12px
}
INPUT {
FONT-SIZE: 12px
}
LI {
FONT-SIZE: 14px
}
P {
FONT-SIZE: 14px
}
.f7 {
FONT-SIZE: 7px
}
.f24 {
FONT-SIZE: 24px
}
.f14 {
FONT-SIZE: 14px; LINE-HEIGHT: 130%
}
.12v {
FONT-SIZE: 14px; LINE-HEIGHT: 130%
}
.l17 {
LINE-HEIGHT: 170%
}
.title12 {
FONT-SIZE: 12px
}
.title14 {
FONT-SIZE: 14px; LINE-HEIGHT: 130%
}
.tail12 {
FONT-SIZE: 12px
}
.code {
FONT-SIZE: 12px; LINE-HEIGHT: 130%; FONT-FAMILY: verdana
}
A:link {
COLOR: #0000ff
}
A:visited {
COLOR: #800080
}
A:active {
COLOR: #ff0000
}
A:hover {
COLOR: #ff0000
}
A.a01:link {
COLOR: #07015b; TEXT-DECORATION: none
}
A.a01:visited {
COLOR: #07015b; TEXT-DECORATION: none
}
A.a01:active {
COLOR: #ff0000; TEXT-DECORATION: none
}
A.a01:hover {
COLOR: #ff0000; TEXT-DECORATION: none
}
A.a02:link {
COLOR: #0000ff; TEXT-DECORATION: none
}
A.a02:visited {
COLOR: #0000ff; TEXT-DECORATION: none
}
A.a02:active {
COLOR: #ff0000; TEXT-DECORATION: none
}
A.a02:hover {
COLOR: #ff0000; TEXT-DECORATION: none
}
</STYLE>
<META content="MSHTML 6.00.2900.2963" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff leftMargin=0 topMargin=5 marginwidth="0" marginheight="5"><!-- SUDA_CODE_START -->
<DIV id=sudsclickstreamdiv
style="Z-INDEX: 1; LEFT: 100px; VISIBILITY: hidden; WIDTH: 80px; POSITION: absolute; TOP: -300px"></DIV>
<SCRIPT type=text/javascript>//<!--var _S_JV_="webbug_meta_ref_mod_noiframe_async_:8.37a";var cp_rf="http://beacon.sina.com.cn/a.gif";var cp_rf_d="http://beacon.sina.com.cn/d.gif";var _S_DPID_="-9999-0-0-1";var _S_DOMAINROOT="sina.com.cn";var _S_PW_=window;var _S_PWD_=_S_PW_.document;var _S_BN_=navigator;var _S_NAN_=_S_BN_.appName;var _S_NAV_=_S_BN_.appVersion;var _S_PREF_=_S_PWD_.referrer;var _SP_MPID_="";var _S_PID_="";var _S_UNA_="UNIPROU";var _S_UID_="nick";var _S_SID_="Apache";var _S_GID_="SINAGLOBAL";var _S_IFW=700;var _S_IFH=600;var _S_SID_V="";var _S_GID_V="";try{if (_S_ET>=0){_S_ET=_S_ET;}else{var _S_ET=0;}}catch(e){var _S_ET=0;}function _S_gUCk(ckName){if (("undefined"==ckName)||(""==ckName))return ""; var _S_PWDC_=_S_PWD_.cookie;var start=_S_PWDC_.indexOf(ckName+"=");if (-1==start){return "";} start=_S_PWDC_.indexOf("=", start)+1;var end=_S_PWDC_.indexOf(";", start);if (0 >=end){end=_S_PWDC_.length;} ckValue=_S_PWDC_.substring(start, end);return ckValue;}function _S_sUCk(ckName, ckValue, ckdays){if (ckValue !=null){if (("undefined"==ckdays)||(null==ckdays)){_S_PWD_.cookie=ckName + "=" + ckValue + "; domain="+_S_DOMAINROOT+"; path=/" ;} else{var now=new Date();var time=now.getTime();time=time + 86400000 * ckdays;now.setTime(time);time=now.getTime();_S_PWD_.cookie=ckName + "=" + ckValue + "; domain="+_S_DOMAINROOT+"; expires=" +now.toUTCString()+ "; path=/";} }}function _S_gMeta(MName){pMeta=_S_PWD_.getElementsByName(MName);if(pMeta.length>0){return pMeta[0].content;} else{return "";}}function _S_gCid(){try {metaTxt=_S_gMeta("publishid");if(""!=metaTxt) {pbidList=metaTxt.split(","); if(pbidList.length>0) {if(pbidList.length>=3){_S_DPID_="-9999-0-"+pbidList[1]+"-"+pbidList[2];}return pbidList[0];}} else{return "0";}} catch(e){return "0";}}function _S_sSID(){_S_p2Bcn("",cp_rf_d);} function _S_sSIDV(_s_sidv){if(""!=_s_sidv){_S_sUCk(_S_SID_,_s_sidv);}}function _S_gsSID(){if(""!=_S_SID_){var sid=_S_gUCk(_S_SID_);if(""==sid){_S_sSID();}_S_SID_V=sid;return sid;}else{return "";}}function _S_sGID(_s_gidv){if(""!=_s_gidv){_S_sUCk(_S_GID_,_s_gidv,3650);}}function _S_gsGID(){if(""!=_S_GID_){var gid=_S_gUCk(_S_GID_);if(""==gid){var sid=_S_gsSID();if(""!=sid){gid=sid;_S_sGID(gid);}}_S_GID_V=gid;return gid;}else{return "";}}function _S_p2Bcn(strQuest,wb_url){var _sl_scsd=_S_PWD_.getElementById("sudsclickstreamdiv");if(null!=_sl_scsd){_sl_scsd.innerHTML="<img width=0 height=0 src='"+wb_url+"?"+strQuest+"gUid_"+Math.random()+"' border='0' alt='' />";}} function _S_gConType(){var contype="";try{_S_PWD_.body.addBehavior("#default#clientCaps");contype=_S_PWD_.body.connectionType;}catch(e){contype="unkown";} return contype;} function _S_isHome(){var cul="";var isH="";try{cul=_S_PWD_.location.href;_S_PWD_.body.addBehavior("#default#homePage");isH=_S_PWD_.body.isHomePage(cul)?"Y":"N";}catch(e){isH="unkown";} return isH;}function _S_isExistsFreshMeta(){ var _s_head_=_S_PWD_.documentElement.innerHTML.substring(0,1024); var reg=new RegExp("<meta\\s*http-equiv\\s*=((\\s*refresh\\s*)|(\'refresh\')|(\"refresh\"))\s*content\s*=","ig"); return reg.test(_s_head_); }function _S_isIFrameSelf(){if(_S_PW_.top ==_S_PW_){return false;}else{try{if((_S_PW_.document.body.clientHeight>=_S_IFH)&&(_S_PW_.document.body.clientWidth>=_S_IFW)){return false;}else{return true;}}catch(e){return true;}}}function _S_gJVer(){var p,appsign,appver,jsver=1.0,isN6=0;if ('Microsoft Internet Explorer'==_S_NAN_){appsign='MSIE';p=_S_NAV_.indexOf(appsign);if (p>=0){appver=parseInt(_S_NAV_.substring(p+5));if (3<=appver){jsver=1.1; if (4<=appver) {jsver=1.3;}}}} else if (("Netscape"==_S_NAN_)||("Opera"==_S_NAN_)||("Mozilla"==_S_NAN_)){jsver=1.3; appsign='Netscape6';p=_S_NAV_.indexOf(appsign);if (p>=0) {jsver=1.5; } } return jsver;}function _S_gPageInfo(PageID,_sp_rfurl){var sid=_S_gsSID();var pid="pid:"+PageID;var currPath="";var st="st:0";var et="et:"+_S_ET;var hp="hp:"+_S_isHome();var lb="lb:1";var pgls="PGLS:"+_S_gMeta("stencil");var key="keys:"+_S_gMeta("keywords");return sid+"|"+pid+"|"+currPath+"|"+st+"|"+et+"|"+escape(_sp_rfurl)+"|"+hp+"|"+lb+"|"+pgls+"|"+key+"|*|";}function _S_gEnvInfo(){var now=new Date();var pct=0;var ckValue="sz:"+screen.width+"x"+screen.height+"||";ckValue=ckValue+"dp:"+screen.colorDepth+"||";ckValue=ckValue+"ac:"+_S_BN_.appCodeName+"||";ckValue=ckValue+"an:"+_S_NAN_+"||";ckValue=ckValue+"av:0||";ckValue=ckValue+"cpu:"+_S_BN_.cpuClass+"||"; ckValue=ckValue+"pf:"+_S_BN_.platform+"||";ckValue=ckValue+"jv:"+_S_gJVer()+"||";ckValue=ckValue+"ct:"+_S_gConType()+"||";ckValue=ckValue+"lg:"+_S_BN_.systemLanguage+"||";ckValue=ckValue+"tz:"+now.getTimezoneOffset()/60;return ckValue;}function _S_pSt(_sp_mpid){try {if (("undefined"==_sp_mpid)||(""==_sp_mpid)){_sp_mpid=_S_gCid()+_S_DPID_;} if((_S_isExistsFreshMeta())||(_S_isIFrameSelf())){return;}if(_S_ET>0){return;}_S_ET=_S_ET+1;_SP_MPID_=_sp_mpid;window.setTimeout("_S_gsSID()",500);window.setTimeout("_S_pBeacon()",2000);window.setTimeout("_S_rset()",60000);}catch(e){}}function _S_pBeacon(){try {var sudsid=_S_gsGID();var ckValue=_S_gEnvInfo();var unStr=_S_gUCk(_S_UNA_);var uidStr=_S_gUCk(_S_UID_);var envStr="UNIPROINFO="+ckValue+"||un:"+unStr+"||uid:"+uidStr+";";var refUrl=_S_PREF_;_S_PREF_=_S_PWD_.location.href;var cPageStr=_S_gPageInfo(_SP_MPID_,refUrl);var lbStr=sudsid+"|*|"+cPageStr;lbStr=envStr+"UNIPROPATH="+lbStr+";";_S_p2Bcn(lbStr,cp_rf);}catch(e){}}function _S_rset(){if(""==_S_gUCk(_S_GID_)){if(""==_S_GID_V){_S_GID_V=_S_SID_V;}_S_sGID(_S_GID_V);} if(""==_S_gUCk(_S_SID_)){_S_sSIDV(_S_SID_V);}}//--></SCRIPT>
<SCRIPT type=text/javascript>//<!--_S_pSt("");//--></SCRIPT>
<!-- SUDA_CODE_END -->
<CENTER>
<STYLE>.h3 {
FONT-SIZE: 7px; COLOR: #ffbd00
}
</STYLE>
<TABLE cellSpacing=0 cellPadding=0 width=750 border=0>
<TBODY>
<TR align=middle>
<TD align=right><A class=a01 href="http://www.sina.com.cn/">首页</A> <SPAN
class=h3>●</SPAN> <A class=a01 href="http://news.sina.com.cn/">新闻</A>
<SPAN class=h3>●</SPAN> <A class=a01
href="http://sports.sina.com.cn/">体育</A> <SPAN class=h3>●</SPAN> <A
class=a01 href="http://ent.sina.com.cn/">娱乐</A> <SPAN class=h3>●</SPAN> <A
class=a01 href="http://games.sina.com.cn/">游戏</A> <SPAN class=h3>●</SPAN>
<A class=a01 href="http://mail.sina.com.cn/">邮箱</A> <SPAN
class=h3>●</SPAN> <A class=a01 href="http://search.sina.com.cn/">搜索</A>
<SPAN class=h3>●</SPAN> <A class=a01 href="http://sms.sina.com.cn/">短信</A>
<SPAN class=h3>●</SPAN> <A class=a01
href="http://newchat.sina.com.cn/">聊天</A> <SPAN class=h3>●</SPAN> <A
class=a01 href="http://sinapay.sina.com.cn/">点卡</A> <SPAN
class=h3>●</SPAN> <A class=a01 href="http://weather.sina.com.cn/">天气</A>
<SPAN class=h3>●</SPAN> <A class=a01
href="http://tech.sina.com.cn/focus/sinahelp.shtml">答疑</A> <SPAN
class=h3>●</SPAN> <A class=a01 href="http://jiaoyou.sina.com.cn/"><FONT
color=red>交友</FONT></A> <SPAN class=h3>●</SPAN> <A class=a01
href="http://news.sina.com.cn/guide/"><FONT color=red>导航</FONT></A>
</TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=750 border=0>
<TBODY>
<TR>
<TD height=9></TD></TR>
<TR>
<TD width=140><A
href="http://ad.doubleclick.net/clk;2842202;5752542;b?http://dailynews.sina.com.cn/images/ad/monternet/MONTERNET0.htm"
target=_blank>上移动梦网<BR>赢手机大奖</A><BR></TD>
<TD width=610><IFRAME marginWidth=0 marginHeight=0
src="用Java多媒体框架设计自动播放机_开 发 者_网上学园_科技时代_新浪网.files/adfshow.htm"
frameBorder=0 width=468 scrolling=no
height=60>
<SCRIPT LANGUAGE="JavaScript1.1" SRC="http://sina.allyes.com/main/adfshow?user=AFP6_for_SINA|Tech|WebBn&db=sina&local=yes&js=on"></SCRIPT>
<NOSCRIPT><A HREF="http://sina.allyes.com/main/adfclick?user=AFP6_for_SINA|Tech|WebBn&db=sina"><IMG SRC="http://sina.allyes.com/main/adfshow?user=AFP6_for_SINA|Tech|WebBn&db=sina" WIDTH=468 HEIGHT=60 BORDER=0></a></NOSCRIPT></IFRAME></TD></TR></TBODY></TABLE><!--头部结束-->
<TABLE cellSpacing=0 cellPadding=0 width=750 border=0>
<TBODY>
<TR>
<TD width=150 height=34><A href="http://tech.sina.com.cn/"><IMG height=34
src="用Java多媒体框架设计自动播放机_开 发 者_网上学园_科技时代_新浪网.files/sina_kjsd.gif" width=134
border=0></A></TD>
<TD vAlign=bottom width=440><FONT color=#0000ff><A class=a02
href="http://home.sina.com.cn/">新浪首页</A> > <A class=a02
href="http://tech.sina.com.cn/">科技时代</A> > <A class=a02
href="http://tech.sina.com.cn/introduction/">网上学园</A> > <A class=a02
href="http://tech.sina.com.cn/introduction/developer_.shtml">开 发 者</A>
> 正文</FONT></TD>
<TD vAlign=bottom align=right width=150><A
href="http://www.chinabyte.com/"><IMG height=28
src="用Java多媒体框架设计自动播放机_开 发 者_网上学园_科技时代_新浪网.files/1_2-50-629_20030509144114.gif"
border=0></A></TD>
<TD width=10></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=750 border=0>
<TBODY>
<TR>
<TD height=8></TD></TR>
<TR>
<TD bgColor=#747474 height=1><IMG height=1
src="用Java多媒体框架设计自动播放机_开 发 者_网上学园_科技时代_新浪网.files/c.gif" width=1></TD></TR>
<TR>
<TD height=15></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=750 border=0>
<TBODY>
<TR>
<TD align=middle width=600 rowSpan=2>
<TABLE cellSpacing=0 cellPadding=0 width=560 border=0>
<TBODY>
<TR>
<TH class=f24><FONT color=#05006c>用Java多媒体框架设计自动播放机</FONT></TH></TR>
<TR>
<TD>
<HR SIZE=1 bgcolor="#d9d9d9">
</TD></TR>
<TR>
<TD align=middle height=20>http://www.sina.com.cn
2004/02/12 15:14 <FONT color=#a20010>ChinaByte</FONT></TD></TR>
<TR>
<TD height=15></TD></TR>
<TR>
<TD class=l17>
<P> 如果把Java媒体框架(http://java.sun.com/jmf)看作客户端安装的媒体播放机的话,那么这种框架并不是非常激动人心。它只支持少量媒体类型,并且事实上这些媒体类型都被象Windows媒体播放机以及QuickTime等其它的应用程序支持。</P>
<P> 但是从内容供应商的观点来看,下面这个事实更加有意义:JMF在所有的Java类型中都可用,这使在客户端上不必要有任何特定的媒体技术就可以部署媒体--所需要的只是J2SE
Java运行时间。</P>
<P> 更重要的是它能利用.jar文件格式的一些性能把解码器和媒体组成到一个文件中,创建一个"自我播放电影",使用了象WinZip和StuffIt这样的压缩应用程序大致相同的方式来创建自我展开文档。</P>
<P> 我们把此分为三个阶段:</P>
<P> 1.使JMF能够播放.jar文件中的媒体。</P>
<P> 2.只使用需要播放本地媒体所需的JMF的一部分创建一个轻量级.jar文件。</P>
<P> 3.将代码和媒体放入.jar文件,并且创建一个合适的manifest文档以使它可以双击。</P>
<P> 基本的JMF播放的关键是获得Player,能解码和渲染你的媒体。一般来说,这通过使用Manager获得合适的DataSource来完成,在一个播放实例中提供了媒体流和流元数据,例如媒体格式。Manager然后找到一个Player来处理DataSource。在两种情况下,Manager结合一个带有程序包前缀列表(象javax.media、com.ibm.media等等)的反射方案来试图寻找合适的类,例如如果一个计划的播放程序不能接受提供给它的DataSource,那么它就会抛出异常。</P>
<P> Manager没有太多事要做,只是察看一下URL中的协议和文件扩展名,所以虽然它可以很容易的知道如何处理file:///Users/cadamson/mymp3stash/some.mp3,但是它不知道如何处理象jar:file:/Users/cadamson/dev/jmftests/spmovie-old/src/gatsbymovie.jar!/movie/themovie.mov这样的URL。</P>
<P> 为了缓和这种情况,我们可以写一个DataSource,说得更准确一点就是一个PullDataSource,担负为Manager描述细节的责任。JarEntryDataSource中没有一个方法特别难;我们提供的PullSourceStream还需要实现几个超级接口。</P>
<P> 它有些不够完美,但是这个类依靠文件扩展名来返回"内容类型"。这多多少少有点象一个MIME类型,除了使用句号代替斜线符号来格式化以外,所以它可被用于程序包名称(例如video/mpeg
MIME类型变成video.mpeg,所以Manager可以找到com.sun.media.codec.video.mpeg包)。下面是我们的简单的实现:</P>
<P> public String getContentType() {</P>
<P> try {</P>
<P> URL url = getLocator().getURL();</P>
<P> String urlFile = url.getFile();</P>
<P> if (urlFile.endsWith(".mov"))</P>
<P> return "video.quicktime";</P>
<P> else if (urlFile.endsWith(".mpg"))</P>
<P> return "video.mpeg";</P>
<P> else if (urlFile.endsWith(".avi"))</P>
<P> // Manager needs '_' insted of '-'</P>
<P> return "video.x_msvideo";</P>
<P> else</P>
<P> return "unknown";</P>
<P> } catch (MalformedURLException murle) {</P>
<P> return "unknown";</P>
<P> }</P>
<P> } </P>
<P> 另一个烦恼是JMF源代码表明如果提供的流是Seekable的话(这是一个提供随机存取seek()方法的接口),默认Player只能播放一个QuickTime
DataSource。如果寻找点在流的非常上流的地方,那么JarEntryDataSource中的策略是使用InputStream.skip()。如果寻找点在当前读取点之后(调用tellPoint,因为它的值通过Seekable.tell
()方法返回),然后它必须关闭InputStream,再重新打开,跳到寻找点。它使用一个内部的thoroughSkip()方法来确定我们实际上停在哪里。</P>
<P> public long seek (long position) {</P>
<P> try {</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -