📄 javamf.txt
字号:
放器时,需要记录哪些播放器报告了PrefetchComplet。事件,以致于在调用syncStart之前能
确保所有的播放器皆已进入Prefetched状态。同样,在需要同步播放器在某一时刻停止
时,需要监听每个播放器报告的停止事件,以便确定何时所有播放器已实际停止C
在有些情况下,还得仔细对待同步播放器报告的事件。为了确信播放器的状态,在某
些阶段也许需要等待,直到所有同步播放器皆已进人相同状态,才能继续下去。
例如,假设正用一个播放器驱动一组同步播放器,一个与该播放器交互的用户将
media time设定为10,并启动了它,然后将media time改为20,那么,就得:
?向所有的同步播放器传递第一次,etMediaTime调用;
?对播放器调用prefetch,准备启动它们;
?当接收到第二个设定media time请求时,对播放器调用stop;
?用setMediaTime为播放器设定新的时间;
.重新开始预取操作;
?当所有的播放器已被预取后,通过调用syncStart启动它们,并考虑其启动延时
在这种情况下,只是简单地在调用syncStart之前监听来自所有播放器的Prefetch-
Complete事件是不够的。不能确定这些事件是否是因响应第一或第二次预取操作而报告
的。为避免这个问题,可以在调用stop时将播放器阻塞起来,并且等到所有播放器报告停
止事件,才继续下去。这就确保后面接收到的PrefetchComplete事件正是所感兴趣的。
1.8采用一个播放器管理和同步其他控制器
人工采用syncStart同步播放器要求必须仔细管理所有同步播放器的状态;必须逐个
地控制每个播放器,监听事件,适当地对它们调用控制方法。即使处理少数几个播放器,
这也很快变得困难起来。通过播放器接口,JMF提供了一个简单的解决方案:一个播放器
可用来管理任何控制器的操作。
当与一个管理播放器交互时,指令自动地传递给了被管理的控制器。管理播放器仔
细处理所有其他控制器的状态管理和同步。这种机制是通过addController和。e-
Controller方法实现的。在对播放器调用addControlle:时,定义的控制器被加人到播放器管
?22理的控制器表中。相反地,在调用removeController时,定义的控制器将从控制器表中删除。
通常当需要同步播放器或其他控制器时,应当使用addController机制。比起逐个管理
同步播放器来,该机制更简单、快捷、安全。
当播放器对一个控制器施加控制时,要求:
?控制器采用播放器的时基;
?播放器的持续时间为控制器持续时间与其自身持续时间中的较长者;如果有多个
控制器在播放器的控制之下,则播放器的持续时间为所有持续时间中的最长者;
?播放器的启动延时为控制器启动延时与其自身启动延时中的较长者;如果有多个
控制器在播放器的控制之下,则播放器的启动延时为所有启动延时中的最长者C
在每个增加的控制器报告事件之后,管理播放器才能对同步方法报告完成事件,并适
当地再次报告被管理的控制器产生的其他事件。
.8.1增加一个控制器
采用addController方法可将一个控制器增加到具体播放器管理的控制器表中。为了
能被增加进去,控制器必须处于Realized状态,否则将报告NotRealizedError。两个播放器
不能彼此控制。例如,如果playerl在player2的控制之下,在没有首先将playerl从player2
的控制中删除的话,player2不能由playerl控制。
一旦控制器被增加到播放器的控制器表中,就不能直接对该控制器调用方法。必须
通过与管理播放器交互来控制新增的控制器。
为了使player2对playerl施加控制,需要调用:
player2 .addController(playerl);
.8.2管理增加控制器的操作
为控制具体播放器管理的一组控制器的操作,只需直接与管理播放器交互,不要直接
对被管理的控制器调用控制方法。
例如,为了准备启动所有被管理的控制器,只需对管理播放器调用prefetch。同样,当
要启动它们时,对管理播放器调用start就行了。管理播放器确保所有控制器处于
Prefetched状态,判断控制器的最大启动延时,并调用syncStart来启动它们,同时定义了一
个表示最大启动延时的时间。
当对管理播放器调用一个控制器方法时,播放器适当地将该方法调用传播给被管理
的控制器。在对被管理的控制器调用控制器方法之前,播放器确保控制器处于合适的状
态。表1.2描述了在对管理播放器调用控制方法时,被管理的控制器发生的动作。
表1.2在对管理播放器调用控制方法时控制器发生的动作
方法
处于Stopped状态的播放器
处于Started状态的播放器
对所有被管理的控制器调用setMediaTime
停止所有被管理的控制器,调用setMedia-
Time,重新启动控制器续表
┌────┬────────────────────┬───────────────────┐
│方法 │处于Stopped状态的播放器 │处于Started状态的播放器 │
├────┼────────────────────┼───────────────────┤
│setRate │对所有被管理的控制器调用,tRate,返回 │停止所有被管理的控制器,调用setRate │
│ │所有控制器支持和设定的实际速度 │重新启动控制器,返回所有控制器支持和 │
│ │ │设定的实际速度 │
├────┼────────────────────┼───────────────────┤
│Stan │确保所有被管理的控制器处干Prefetched │依赖于播放器的实现。播放器也许会、7 │
│ │状态,对控制器逐个调用sync-Start,同时考│即报告一个StartEvent │
│ │虑它们的启动延时 │ │
├────┼────────────────────┼───────────────────┤
│realize │管理播放器立即报告一个Realize- │管理播放器立即报告一个Realize- │
│ │CompleteEvent为了增加进去,控制器必 │CompleteEvent。为了增加进去,控制器必 │
│ │须是已被实现一了的 │须是已被实现了的 │
└────┴────────────────────┴───────────────────┘
CompleteEvent,指出所有被管理的控制器
处于Prefetched状态
stop
deallocate
没有结果
对所有被管理的控制器调用deallocate
setSi州rim
亨被管理的控制器调用setStopTime
器必须处干Realized状态)
syneSlart
对所有被管理的控制器调用syncStart
(lose
对所有被管理的控制器调用。lose
对所有被管理的控制器调用,叩
对一个处于Started状态的播放器调用
deallocate是非法的
对所有被管理的控制器调用se6toopTime
(对处于Started状态的播放器只能设定一
次)
对一个处于Started状态的播放器调用
svncStart是非法的
对一个处于Started状态的播放器调川
clost,是非法的
1.8.3删除控制器
采用retnoveContnoller方法,可以从具体播放器管理的控制器表中删除控制器。例如,
为了使player2放弃对played的控制,只需调用:
player2 .removeController(playerl);
1.,扩展imw
JMF体系结构允许高级开发者产生、集成新的控制器类型和数据源。例如,可以实现
一个支持特种媒体格式的播放器。
本节将介绍JMF的播放器体系结构,并描述怎样将新的播放器和数据源集成到JMF
仁护。
241.9.1理解播放器体系结构
j以口1.3.1小节“产生播放器”中描述的那样,客户程序员通过调用Manager.
createPlayer为具体的媒体源获得一个播放器。调用createPlayer时,产生一个合适的播放
器,并将其返回给调用者。管理器为具体媒体源构造播放器。首先从URL或MediaLocator
构造出数据源(DataSource ),然后用它产生播放器。(数据源是一个与具体协议相关的媒
体数据源。播放器经常用数据源来管理媒体内容的转换。)
当产生一个播放器时,管理器要完成:
?为所定义的协议获取相关的数据源;
?为数据源定义的内容类型获取播放器;
?将数据源与播放器连接起来。如图1.6所示。
图1.6产生播放器时,管理器完成的操作
1.定位数据源
createDataSou,方法为定义的MediaLocator定位并实例化一个适当的数据源
(DataSource )。要实现这一目标,它首先产生一个数据源类名搜索表,然后逐个检查表中的
每个类,直到发现一个可用的数据源为止。为构造数据源类名搜索表,createDataSource必
须完成:
(1)从PackageManager中获取一个协议包前缀向量(vector of protocol package-prefixes)
(2)增加一个具有以下形式的类名:
<package}-pref ix>.media.protocol.<protocol).DataSource
for<package-prefix > in协议包前缀向量(the protocol package-prefix-vector)。管理器逐
个搜索表中的类名,直到发现一个能够实例化并能将MediaLocator与之连接的数据源。
2.定位播放器
createPlayer方法采用相同的机制来为具体数据源定位并实例化一个适当的播放器
播放器是媒体处理器(MediaHandler)的一种类型,是从数据源中读取数据的一个对象。媒
体处理器是由其支持的媒体内容类型标识的。管理器采用从数据源获得的媒体内容类型
的名字来发现媒体处理器对象。JMF支持两类媒体处理器:播放器和媒体代理
25(MediaProxy)。
媒体代理处理来自于一个数据源的媒体内容,以便产生另一个数据源。典型地,媒体
代理读取文本配置文件,该文件包含了连接服务器以及获取媒体数据所需的全部信息。
当调用createPlayer时,管理器首先用来自于数据源的媒体内容名字以及由包管理器
(PackageManager)返回的已被安装的包(package)组成的表,产生一个类名搜索表。然后逐
个搜索表中的类,直到发现一个能被构造出并可以将数据源与之相连接的媒体处理器。
如果媒体处理器是个播放器,该过程结束,管理器返回这个新的播放器。如果媒体处
理器是个媒体代理,管理器从媒体代理那里获取一个新的数据源,重新产生一个由该数据
源支持的媒体内容类型组成的表,并重复搜索过程。
如果找不到适当的播放器,过程继续下去,同时将该媒体内容类型名字替换为
" unknown"。类型为unknown的媒体内容是一般播放器都支持的。通常在平台独立的方
式下,一般播放器能够处理大量的媒体类型。
为了构造媒体处理器类名的搜索表,createPlayer要完成:
(1)从包管理器中获取一个媒体内容包前缀向量(vector of content package, prefixes)
(2)增加一个具有以下形式的类名:
< package-prefix>.media.content.<content-type>.Handler
for each < package-prefix > in媒体内容包前缀向量(content package-prefix-vector)
1.9.2集成新播放器实现
可以生成播放器的一个特制实现,它能与JMF其余部分无缝地工作。为了将一个播
放器与JMF集成起来,需要:
.实现Player. setSource,以便检查数据源,判断播放器是否能处理数据源类型。当客
户程序员调用createPlaye:时,setSource在管理器搜索适当播放器的过程中被调
用。
?安装包含新的播放器类型的包。
?将包前缀(package prefix)加人到由包管理器控制的媒体内容包前缀表中。管理器
查询包管理器,以便获取其用来搜
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -