一引言 在当前世面上存在着大量的不同媒体格式并且还有许多新的媒体格式即将被建立 为了存储和传输这些不同的媒体格式存在着了许多不同格式的存储设备和传输协议例如大家常使用的媒体存储设备(如CDVCD以及DVD)有线传输协议(如UDPHTTP)无线传输协议(如WAP) 为了使移动装置能够访问这些不同格式的媒体数据必须为其设计一个规范化的强大的和可扩充的应用接口JME中就提供了一套为规范的播放和录制音频或视频接口即Mobile Media API (MMAPI) 二MMAPI体系结构 一般情况下可以将媒体处理过程分解为两个过程 ◆处理媒体数据的传输协议的过程 ◆处理媒体数据内容的过程 处理媒体数据的传输协议的过程 处理传输协议的过程是指从数据源(如一个文件一个捕获装置或一个流服务)上读取媒体数据内容后将其传送到媒体数据内容处理的过程 MMAPI使用Data Source来处理媒体数据的传输协议的过程一个Data Source知道如何从它的原始位置读取媒体数据并传送给媒体数据处理(Player)媒体数据可以被保存在不同的位置从远程服务器到资源文件或者RMS数据库媒体数据可以从原始位置通过HTTP像RTP一样的流式传输协议或者其他机制传输到媒体数据处理(Player)图一展示了Data Source的工作过程 图Data Source工作过程 jadiaprotocolDataSource提供了MMAPI的Data Source的支持 处理媒体数据内容的过程 处理媒体数据内容的过程通常需要对媒体数据进行解释和解码并且还需要认别该媒体的输出设置的类型如是音频设置或者视频设置举个例子当DataSource从某媒体数据源上获取一MP媒体数据并将其传送给处理媒体数据内容过程此过程首先对这个MP媒体数据进行解析和解码同时检测该MP媒体为音频数据打开装置的音频设备将解析和解码后的媒体数据直接传送到装置的音频设备缓沖中由该音频设备根据缓沖区中的数据内容产生音频信号 MMAPI使用Player来处理媒体数据内容一个Player是jadiaPlayer接口的一个实现实例它从Data Source中读取媒体数据解析和解码数据以及识别媒体输出设备和传送媒体数据到输出设备等Player提供了一套方法去控制媒体的重放和同步 MMAPI还提供了一个或多个Controls来调整player的行为可以在player从媒体转换数据的时候从一个player实例取得并且使用Controls我们可以通过Player中提供的一些特殊的Controls访问一些特殊的媒体类型Controls由jadiaControl接口实现 Manager JME为了实现对DataSource和Player有效管理使用了工厂机制由Manager来负责创建Player和DataSource这样的机制在JAVA中到处可见如JDBC中的DriverManager这里我就不对这种机制进行介绍了Manager不仅可以从DataSource中创建Player而且还可以从本地或InputStream中创建Player图二展示了MMAPI整体结构图 图MMAPI整体结构图 三使用MMAPI MMAPI提供的类和接口都在jadia中在程序中使用MMAPI时首先应该引用这些包否则程序无法编译 每个MMAPI程序都需要创建一个Player对象前面我们已经介绍过MMAPI使用Manager的CreatePlayer函数来创建Player对象该函数有三个版本其格式如下 public static Player createPlayer(String locator)throws IOException MediaExceptionpublic static Player createPlayer(DataSource source)throws IOException MediaExceptionpublic static Player createPlayer(InputStream stream String type)throws IOException MediaException 第一个版本实现通过URL字符串指定的协议和数据位置的信息创建一个Player对象其中locator的格式如下 Manager将对createPlayer函数中提供的URL字符串参数进行分析创建一个Data Source对象由该对象完成对媒体数据的传输工作并从数据中获取该媒体的数据内容类型Manager将根据这个媒体数据类型创建相应的Player对象如果Manager无法确定DataSource的内容类型它将抛出一个MediaException异常 例创建一个控制某网站MP音频的Player对象 Player pMP = ManagercreatePlayer( ) 第二版本实现通过已知的DataSource对象创建Player对象 第三版本实现通过InputStream流创建Player对象 我们根据应用实际的情况选择使用那种版本来创建Player对象有了一个Player对象以后接下来要通过这个Player对象提供的方法去控制媒体流下面我们列出常用的方法 ◆Playerstart()重放媒体流 ◆Playerstop()停止媒体流 ◆PlayersetMediaTime(long now)设置媒体时间 ◆Playerclose()关闭媒体流并释放资源 ◆PlayergetState()获取Player的当前状态 每个Player对象中都存在着一个状态变量用于表示该Player对象的生命周期当Player第一次被建立时处于UNREALIZED状态当为该Player设置了媒体数据的位置后它处于REALIZED状态(如Player正在从一个服务器的HTTP连接下载并解释数据的时或Player在Http请求已经发送到服务器收到HTTP响应后而且DataSource准备好接收媒体数据的时)当该Player已经读到足够的数据而开始解释和运算时处于PREFETCHED状态当数据在运算完毕后该Player的状态变成了STARTED我们在使用Player对象的方法对媒体流进行控制时应注意它们可能影响到Player状态的改变可以使用getState函数获取当前Player的状态图三展示了Player对象的状态转换图 图状态转换图 四播放常见媒体的方法 播放单音与序列音 如果要播放一个单音一次可使用 ManagerplayTone(notedurationvolume) 如果要播放序列音则必须使用ToneControl使用一个特别的定位器来创建一个Player对象获得ToneControl设置其命令序列然后启动播放器如 Player p = ManagercreatePlayer(MangerTONE_DEVICE_LOCATOR); prealize(); ToneControl tc = (ToneControl)(playergetControl(ToneControl)); tcsetSequence(new byte[] {ToneControlC ToneControlC+}); pstart(); 播放声讯和MIDI 声讯是指如WAV这样的声音格式在这种格式中数据是各种声讯样本的一个流它代表着该声讯每一秒钟的片断MIDI则是一系列的命令用作多乐器的某种虚拟合成器 如要播放一段能够通过HTTP访问的声音文件请使用 Player p = ManagercreatePlayer() pstart() 如要播放一段已经被置于MIDlet的JAR文件中的声音文件需要先了解其MIME类型(如audio/xwav)然后使用 InputStream is = getClass()getResourceAsStream(/somefilewav) Player p = ManagercreatePlayer(isaudio/xwav) pstart() 如要播放一段置于RMS中的声音文件请使用 RecordStore rs = RecordStoreopen(name);byte[] data = rsgetRecord(id);ByteArrayInputStream is = new ByteArrayInputStream(data);Player p = ManagercreatePlayer(isaudio/xwav);pstart(); 播放视频 播放视频类似于音频播放然而需要告诉视频播放器在哪里显示视频信号因此需要从视频播放器处得到一个视频控件然后在Form或Canvas中显示视频内容下面展示一个从Canvas中显示视频的例子 InputStream is = getClass()getResourceAsStream(/somefileavi); Player p = ManagercreatePlayer(isvideo/avi); prealize(); VideoControl vc = (VideoControl)pgetControl(VideoControl); if( vc != null ) { vcinitDisplayMode(VideoControlUSE_DIRECT_VIDEOcav); //cav为Canvas对象 vcsetVisible(true); pstart(); } |