1、 n现在能播放音乐的手机已经是很常见的了,同时手机游戏也需要声音来增加动感效果,所以手机音效也成为了开发热点。nJ2ME针对多种媒体格式,提供了一套播放接口,那就是:MMAPI(Mobile Media API)。p 1 MMAPI体系结构n 现在多媒体的格式很多,要顺利地播放这些不同格式的音乐,一种比较好的方式就是把这些不同格式的数据都转换为统一的格式,然后统一使用一个播放器接口类来播放。n 在MMAPI中,首先从数据源(如一个文件、一个捕获装置或一个流式服务)上读取媒体数据内容后,然后传输给专门的处理程序进行处理。n 处理过程主要是由DataSource类和Player类完成。DataSo
2、urce类的作用就是读取和转换多媒体数据,Player类的作用就是播放这类数据。n 然后提供一系列的播放、暂停、停止等播放器相关功能,DataSource类和Player类的工作过程如图所示。数据流图数据流图 p 2 Player接口n 要使用MMAPI进行音效开发,首先需要导入相关的开发包,例如:n import javax.microedition.media.*使用使用Player接口来播放音频的步骤接口来播放音频的步骤n1、通过Manager.createPlayer()方法创 建一个播放器n2、调用prefetch()方法开始获取音频并 减少滞后n3、调用start()方法开始回放n
3、4、如果需要的话,调用stop()方法停 止回放n5、调用close()方法关闭播放器 n 1UNREALIZED 状态 n 2REALIZED状态n 3PREFETCHED状态n 4STARTED状态n 5CLOSED状态播放器的五种状态播放器的五种状态状态之间的转换状态之间的转换n1、播放器开始处于UNREALIZED状态;n2、当播放器具备了开始获取媒体资源所需的 一切的时候,播放器进入REALIZED状态;n3、当获取到媒体资源并准备回放的时候,播 放器进入了PREFETCHED状态;n4、当回放开始的时候,播放器进入了STARTED 状态;状态之间的转换状态之间的转换n5、当回放结束
4、的时候,播放器返回到 PREFETCHED状态;n6、当播放器关闭的时候,播放器进入CLOSED 状态。状态转换图状态转换图player接口中的一些重要方法接口中的一些重要方法nrealize()实现没有获取媒体资源的播放器(通常不需要显式调用);nprefetch()获取媒体资源以便减小回放滞后(调用它来首次初始化播放器);ngetState()获取播放器状态;nsetLoopCount()设置播放声音的循环次数(必须在调用start()之前调用);nstart()开始播放声音;nstop()停止播放声音;ngetDuration()获取声音持续时间(单位:毫秒);ngetMediaTime
5、()获取当前的媒体时间(单位:毫秒);nsetMediaTime()设置当前的媒体时间(单位:毫秒);nclose()关闭播放器。3 在手机游戏中播放声波声音n在手机中播放声波声音并不难,你只需要知道声音来自于哪里即可。更具体地说,声波文件是存储在一个MIDlet的JAR文件中,还是通过网络可以访问到。显然,通过MIDlet的JAR文件来访问一个声波文件要高效很多,因此,这也是大多数手机游戏所采用的方式。从一个从一个JAR文件播放声波文件播放声波n要通过一个MIDlet的JAR文件访问声波声音,你必须先确保在构建这个MIdlet的时候声波文件添加到了JAR文件中。只要你把声波文件放置到主MID
6、let目录下的res文件夹中,当你在kToolbar开发工具中编译MIDlet的时候,声波文件就会自动地包含到JAR文件中。之后简单的几行代码就可以播放这个声音了。示例示例ntryn Player gamePlayer;n InputStream is=getClass().getResourceAsStream(game.wav);/创建一个基于声波文件的输入流,作为创建播放器的基础 gamePlayer=Manager.createPlayer(is,audio/X-wav);gamePlayer.prefetch();gamePlayer.start();catch(IOExceptio
7、n ioe)catch(MediaException e)n当声波文件的名字被传递给getResourceAsStream()方法的时候,这个方法在getClass()方法所访问的对象的运行时调用。尽管获得输入流需要一点技巧,但是当你得到以后,你只需要把它和声波声音的MIME类型一起传递给Manager.createPlayer()方法就可以了。n为了确保声音已经准备好以最小的滞后播放,我们需要调用prefetch()方法。最后,调用start()方法来开始播放声波声音。由于这些方法中都可能抛出异常,所有的这些调用都要包含在异常处理子句中。n当需要重复播放声音时,可以选择多次调用start()
8、方法。可是,当一个声音仍在播放的时候调用start()方法并不能重新开始播放声音。n要重新开始播放声音,必须调用setMediaTime()方法并把0传递给该方法,这表示你希望把媒体时间设置到声音的开始处:gamePlayer.setMediaTime(0);n对于声音的媒体时间,你可以使用getDuration()和getMediaTime()方法来确定声音已经播放了多少。这两个方法都会以毫秒为单位返回一个时间量:getDuration()方法告诉你一个声音的总的持续时间,而getMediaTime()方法则告诉你声音已经播放了多少。n在前面的方法中,还有一个setLoopCount()方法
9、,这是用来设置音乐循环次数的方法,也是一个很重要的方法。缺省情况下,循环计数是1,也就是音乐只播放一次。在很多情况下,我们希望游戏的音乐能够无限循环,这时候对于这个方法的调用就很关键了。实现方法是:gamePlayer.setLoopCount(-1);/传递-1这个值就能使音乐无限循环下去。要注意,这个方法必须在start()方法调用前调用!n之后,调用close()方法就能关闭播放器。n这就是成功地播放存储在一个JAR文件中的声波声音所需要的所有工作。这也是大多数手机游戏推荐的方法,因为这样声音可以相当快速地载入而没有滞后。播放来自一个播放来自一个URL的声波的声波n在一些情况下,你可能需
10、要通过一个网络连接来播放声波声音。例如,也许你的游戏要播放动态生成的声音,而这些声音必须通过一个网络服务器获得。这时,播放器需要从一个URL中获得声波。示例示例ntryn Player gamePlayer;gamePlayer=Manager.createPlayer(http:/ser/game.wav);gamePlayer.prefetch();gamePlayer.start();catch(IOException ioe)catch(MediaException e)很明显,这段代码要更为简单,因为不需要为声波文件创建一个输入流。但是,使用这种方法载入声音可能会有明显地滞后。当然,这一切取决于声波文件的大小以及网络连接的速度。n当然,手机所支持的音频不只声波一种,比如还有MIDI、MP3音乐等,我们在播放这些声音时,只需将Manager.createPlayer(is,audio/*);中的*部分进行替换即可。n例如:midiMIDI音乐 mpegMP3音频谢谢!谢谢!
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。