BlackBerry多媒体播放


1 BlackBerry 多媒体播放编程 作者:俞伟 目录 概述 ................................................................................................................................ 2 创建第一个 BlackBerry 媒体播放程序 ........................................................................ 2 BlackBerry 音频播放编程 ............................................................................................. 4 BlackBerry 视频播放编程 ........................................................................................... 12 2 概述 移动多媒体包括使用移动终端播放音乐,视频,拍照,录制视频,和在线影音。BlackBerry 支持 移动多媒体,你可以通过 BlackBerry Java 或 BlackBerry 浏览器来创建自己的媒体应用。功能包括 播放音频,视频, SVG 数据,录制音频,视频,流媒体,以及向蓝牙设备发送媒体流。 BlackBerry Java 提供的多媒体支持包括 MMAPI-JSR 135 和 Plazmic Media Engine。本章主要介绍 MMAPI 在 BlackBerry 平台上的应用。 创建第一个 BlackBerry 媒体播放程序 BlackBerry 为媒体开发提供了 MMAPI,即 Player 和 javax.microedition.media 包。它为媒体资源播 放,控制播放,和管理播放状态提供了一些列方法。 一个 Player 有五个状态:UNREALIZED, REALIZED, PREFETCHED, STARTED, CLOSED。 设计这些状态目 的是为消耗时间和资源的操作提供更好的控制。 Player 被创建后的初始状态是 UNREALIZED。在这个状态下,Player 实例不知道媒体文件的任何信 息,不能播放媒体文件。 Player.realize()方法会把 Player 的状体从 UNREALIZED 变为 REALIZED 状态。这个方法会访问媒体文 件或媒体资源来获取必要的媒体信息为播放做准备。 Player.prefetch()方法会把 Player 的状态变为 PREFETCHED。在这个状态下,Player 会进一步获取媒 体资源必要信息并装载部分媒体资源为播放媒体做好准备。 Player.start()方法会把 Player 的状态变为 STARTED,Player 将会立即开始播放媒体资源。 Player 如果没有经过 realize()和 prefetch()是不可能开始播放的。start()方法会间接的呼叫 prefetch(0),也就是 realize(),在媒体播放开始之前。直接呼叫 start()来播放会对媒体播放造成延 迟。 当 Player 播放媒体内容完毕或者 Player.stop()方法被叫时, player 会从 STARTED 状态 变为 PREFETECHED 状态。在 PREFECTED 状态的 Player 可以随时再次播放或循环播放。 在除 CLOSED 状态以外的任何状态都可以呼叫 close()方法,player 状态变为 CLOSED,这时 player 释放媒体资源,不再可用。 Player.deallocate()只能在 PREFETCHED,REALIZED 状态下呼叫,它使 player 返回前一个状态。 Player 的五个状态和状态之间的转换如下图 所示: 3 介绍了 Player,它的方法和状态,下面让我们来为 BlackBerry 创建第一个媒体播放程序。 1. 引入需要的类 2. 通过Manager.createPlayer()方法获得Player实例 3. 呼叫Player.realize()方法来为播放做准备,应用程序获取需要的媒体信息。 4. 呼叫Player.prefetch()使BlackBerry应用程序获取必要的媒体信息,装载部分媒体内容为 播放做好准备。 5. 呼叫Player.start()开始播放。 6. 呼叫Player.stop()来停止播放。 7. 呼叫 Player.close()使 Player 进入 CLOSED 状态,player 实例不再可用。 import javax.microedition.media.Manager; import javax.microedition.media.Player; import java.io.IOException; Player p = Manager.createPlayer("http://www.test.rim.net/abc.wav"); /** * 指向媒体文件的abc.wav的URL作为一个URI参数传入Manager.createPlayer()。 * * 最好规范是先叫realize(), 然后prefetch(), 再start()。按照这个持续可以减少 * 播放延迟。 * * 直接呼叫start()其实是先呼叫prefetch(0)也就是realize(),在开始播放。 */ p.start(); 4 BlackBerry 音频播放编程 播放音频范例 本节介绍如何在 BlackBerry 上创建一个音频播放器播放 mp3,并提供播放,暂停,停止的控制。 播放器如下图所示: 这个播放器运行在 BlackBerry 9700 模拟器上,界面显示了歌曲名,歌曲时长,播放状态,和操作 按钮 (暂停,播放,停止)。下列几幅图显示播放状态的变化: 5 上图播放状态为“正在播放”,歌曲 All Rise 正在被播放。 上图播放状态为暂停,歌曲暂停播放,但是按下播放按钮可以继续播放。 上图播放状态为停止。在停止状态,播放器实例不能够被重新利用。再按播放按钮,应用程序会 销毁 Player 实例并创建新的 Player 进行播放。 6 播放器源代码如下: 以上代码表示使用 BlackBerry 提供的 UI 来组建界面。getInstance()使用了单例,即程序运行环 境中只有一个 MusicPlayerApp 的实例,统一通过 getInstance()来调用,这样可以避免多个 MusicPlayerApp 实例而导致对象状态不稳定。getInstance().enterEventDispatcher(), 这行代码 创建了 MusicPlayerApp 的实例并调用 enterEventDispatcher()来启动应用。 public class MusicPlayerApp extends UiApplication{ public static void main(String[] args){ // 应用程序启动入口 getInstance().enterEventDispatcher(); } // MusicPlayerApp的单类 private static MusicPlayerApp m_instance; private MusicPlayerScreen musicPlayerScreen; public MusicPlayerApp(){ // 创建播放器屏幕 musicPlayerScreen = new MusicPlayerScreen(); // 推出屏幕堆栈,显示播放器屏幕 pushScreen(musicPlayerScreen); } // 实现 MusicPlayerApp 单类,运行环境中只有一个MusicPlayerApp实例 public static synchronized MusicPlayerApp getInstance(){ if (m_instance == null){ m_instance = new MusicPlayerApp(); } return m_instance; } 7 // 播放器屏幕 class MusicPlayerScreen extends MainScreen implements FieldChangeListener{ public static final String SONG_NAME = "All Rise"; // 指向歌曲的URI public static final String URI = "/sounds/all_rise.mp3"; // 歌曲的格式,audio/mpeg支持mp3 public static final String AUDIO_FORMAT = "audio/mpeg"; // 播放器的所有状态 public static final int PLAYING = 0; public static final int READY_FOR_PLAY = 1; public static final int PAUSE = 2; public static final int STOP = 3; // 播放器的当前状态 private int m_currentStatus = READY_FOR_PLAY; // 播放器实例 private Player m_player; // 播放器标签Layout private VerticalFieldManager m_labelManager; // 播放器标签 private LabelField m_songNameField; private LabelField m_durationField; private LabelField m_statusField; // 播放按钮Layout private HorizontalFieldManager m_buttonManager; // 播放器按钮 private ButtonField m_pauseButton; private ButtonField m_playButton; private ButtonField m_stopButton; public MusicPlayerScreen(){ super(Manager.NO_HORIZONTAL_SCROLL|Manager.NO_VERTICAL_SCROLL); // 创建播放器并做好播放准备 createPlayer(); // 创建界面 initializeUI(); } 8 MusicPlayerSceen 构造函数描述启动 MusicPlayerScreen 要执行的任务,创建播放器和初始化 界面。 函数 initializeUI()创建所有 UI 组建,并按一定结构组装标签和控制按钮。 private void initializeUI(){ setTitle(new LabelField("黑莓播放器", Field.FIELD_VCENTER|Field.FIELD_HCENTER)); // 歌曲名称标签 m_songNameField = new LabelField("歌曲名称: "+SONG_NAME, Field.USE_ALL_WIDTH); // 歌曲时长 m_durationField = new LabelField("播放时长: " +m_player.getDuration()/1000000/60+"分钟", Field.USE_ALL_WIDTH); // 播放状态 m_statusField = new LabelField("播放状态: "+getStatus(), Field.USE_ALL_WIDTH); m_labelManager = new VerticalFieldManager(Manager.NO_HORIZONTAL_SCROLL|Manager.NO_VERTICAL_SCROLL); m_labelManager.add(m_songNameField); m_labelManager.add(m_durationField); m_labelManager.add(m_statusField); add(m_labelManager); // 暂停按钮 m_pauseButton = new ButtonField("||", Field.FIELD_VCENTER|Field.FIELD_HCENTER); m_pauseButton.setChangeListener(this); // 播放按钮 m_playButton = new ButtonField(">", Field.FIELD_VCENTER|Field.FIELD_HCENTER); m_playButton.setChangeListener(this); // 停止按钮 m_stopButton = new ButtonField("O", Field.FIELD_VCENTER|Field.FIELD_HCENTER); m_stopButton.setChangeListener(this); m_buttonManager = new HorizontalFieldManager(Manager.NO_HORIZONTAL_SCROLL|Manager.NO_VERTICAL_SCROLL ); m_buttonManager.add(m_pauseButton); m_buttonManager.add(m_playButton); m_buttonManager.add(m_stopButton); add(m_buttonManager); } 9 函数 getStatus()根绝当前播放器状态来获取状态消息。 setPlayerStatus(int) 通过当前播放器状态来更新播放器状态标签。 // 获取当前播放状态 private String getStatus(){ switch(m_currentStatus){ case PLAYING: return "正在播放"; case READY_FOR_PLAY: return "准备完毕"; case PAUSE: return "暂停"; case STOP: return "停止"; } return null; } // 根据设置的播放状态更新状态标签 private void setPlayerStatus(int status){ m_currentStatus = status; m_statusField.setText("播放状态: "+getStatus()); } // 创建播放器 private void createPlayer(){ try{ // 关闭当前播放器 if (m_player != null){ m_player.close(); m_player = null; } // 创建新播放器 InputStream is = this.getClass().getResourceAsStream(URI); m_player = javax.microedition.media.Manager.createPlayer(is, AUDIO_FORMAT); // 预装媒体资源准备播放 m_player.prefetch(); }catch(Exception ex){ ex.printStackTrace(); } } 10 函数 createPlayer()创建 Player 实例,并预装载媒体内容为播放做好准备。如果当前 Player 实例 已经存在,它会先销毁当前 Player 然后再创建新 Player。 public void fieldChanged(Field field, int context) { if (field == m_playButton){ // 当播放按钮按下时 // 根据播放器当前状态进行处理 switch (m_currentStatus){ case PLAYING: this.setPlayerStatus(PLAYING); return; case READY_FOR_PLAY: try{ m_player.start(); }catch(Exception ex){} setPlayerStatus(PLAYING); return; case PAUSE: try{ m_player.start(); }catch(Exception ex){} setPlayerStatus(PLAYING); return; case STOP: createPlayer(); try{ m_player.start(); }catch(Exception ex){} setPlayerStatus(PLAYING); return; } }else if (field == m_pauseButton){ // 当暂停按钮按下时 // 根据播放器当前状态进行处理 switch (m_currentStatus){ case PLAYING: try{ m_player.stop(); }catch(Exception ex){} setPlayerStatus(PAUSE); return; case READY_FOR_PLAY: return; case PAUSE: return; case STOP: try{ m_player.close(); }catch(Exception ex){} setPlayerStatus(STOP); return; } } 11 fieldChanged(Field field, int context)做为按钮监听接口,根据按钮事件判断执行哪一段按钮事件。 三个按钮分别是:播放,暂停,停止。在每个按钮的事件响应根据播放器当前状态来执行不同任 务,详细描述请查看注释。 else if (field == m_stopButton){ // 当停止按按钮按下时 // 根据播放器当前状态进行处理 switch (m_currentStatus){ case PLAYING: try{ m_player.stop(); m_player.close(); }catch(Exception ex){} setPlayerStatus(STOP); return; case READY_FOR_PLAY: try{ m_player.close(); }catch(Exception ex){} setPlayerStatus(STOP); return; case PAUSE: try{ m_player.close(); }catch(Exception ex){} setPlayerStatus(STOP); return; case STOP: return; } } } } } 12 BlackBerry 视频播放编程 BlackBerry 平台支持 MMAPI,支持 Player 在 BlackBerry 界面框架上播放视频。视频格式包括 mpg, 3gp, avi 等等。以下代码片段分别解释在 MIDP 和 BlackBerry UI 两种框架下的视频播放。 对于提供了 LCDUI 支持的 MIDP 实现: 范例 (1) 在 MIDP 框架下界面方式有两种,Form 和 Canvas。Form 界面是 MIDP 框架下的高级 UI 组件,容 器与组件的结构。上述代码是在 MIDP 高级 UI 框架中播放视频。Canvas 是 MIDP 框架中的低级界 面,程序员需要在 Canvas 上绘制自己的 UI 组件。范例 (2) 为在 Canvas 上播放视频。 public void playVideo() { try { // 创建Player,媒体资源为网络上的视频,并获取视频信息 Player p = Manager.createPlayer("http://abc.mpg"); p.realize(); // 界面控制器 GUIControl gc; // 获取界面控制器 // 使用Item播放视频 // 把Item添加到Form,再显示Form // 实现了在Form播放视频 if ((gc = (GUIControl) p.getControl("GUIControl")) != null) { Form form = new Form("My GUI"); form.append((Item) gc.initDisplayMode( GUIControl.USE_GUI_PRIMITIVE, null)); Display.getDisplay(this).setCurrent(form); } // 开始播放 p.start(); } catch (MediaException pe) { } catch (IOException ioe) { } } 13 MIDP 框架下 Canvas 组件上播放视频: 范例 (2) 在使用 Canvas 播放视频时,需要获取 VideoControl,它可以把 Canvas 作为播放组件,同时提供一 些方法调整视频显示位置和尺寸。 以上是 MIDP 框架下高级 UI 和低级 UI 播放视频的方法。在 BlackBerry 平台上如果应用程序使用的 是 MIDP 框架开发视频播放,可以直接使用这两个范例。BlackBerry 平台提供 BlackBerry 特有的 UI 框架,框架结构与 J2SE 比较类似,Container-LayoutManager-Component 的结构。BlackBerry 最基 本的 UI 组件是 Field,视频需要在 Field 里进行播放,如范例 (3) 所示。 public void playVideo(Canvas canvas) { try { // 创建Player,媒体资源为网络上的视频,并获取视频信息 Player p = Manager.createPlayer("http://abc.mpg"); p.realize(); // 视频控制器 VideoControl vidc; // 获取视频控制器 // 传入Canvas,配置在Canvas里播放视频 // 使用视频控制配置播放参数 if((vidc = (VideoControl) p.getControl("VideoControl")) != null){ vidc.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, canvas); vidc.setDisplayFullScreen(true); vidc.setVisible(true); } // 开始播放 p.start(); } catch (MediaException pe) { } catch (IOException ioe) { } } 14 BlackBerry UI 框架下播放视频: 范例 (3) 创建播放器和播放流程与 MIDP 框架下的播放器相同,但在获取显示视频组件时有所不同,对于 BlackBerry 风格的界面要求在 Field 里显示视频: Field videoField = (Field) m_videoControl.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); public void playVideo(){ try{ // 创建新播放器 InputStream is = this.getClass().getResourceAsStream(URI); m_player = javax.microedition.media.Manager.createPlayer(is, VIDEO_FORMAT); // 获取视频文件信息,这一步一定要有,否则获取的VideoControl将无效 m_player.realize(); // 获取视频控制 m_videoControl = (VideoControl)m_player.getControl("VideoControl"); if (m_videoControl != null) { // 从视频控制获取UI组件,这个组件用来显示视频,常用组件比如Field m_videoField = (Field) m_videoControl.initDisplayMode (VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); // 设置显示尺寸 m_videoControl.setDisplayFullScreen(true); // 使视频可见 m_videoControl.setVisible(true); } if (m_videoField != null){ // 添加视频组件到屏幕并开始播放 add(m_videoField); m_player.start(); } }catch(Exception ex){ ex.printStackTrace(); } } 15 要注意的是获取 VideoControl 之前一定要让播放器获取媒体信息,Player.realize(),否则获取的 VideoControl 无效。 以上是在三种界面框架下的播放方式。针对 BlackBerry 平台 BlackBerry 风格界面的视频播放,以 下是一个完整的代码例子: import java.io.InputStream; import javax.microedition.media.Player; import javax.microedition.media.control.VideoControl; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.Manager; import net.rim.device.api.ui.UiApplication; import net.rim.device.api.ui.container.MainScreen; public class VideoPlayerApp extends UiApplication{ private static VideoPlayerApp m_instance; private VideoScreen m_videoPlayerScreen; public static void main(String[] args){ // 应用程序启动入口 getInstance().enterEventDispatcher(); } public VideoPlayerApp(){ // 创建播放器屏幕 m_videoPlayerScreen = new VideoScreen(); // 推出屏幕堆栈,显示播放器屏幕 pushScreen(m_videoPlayerScreen); } // 实现 VideoPlayerApp单类,运行环境中只有一个VideoPlayerApp实例 public static synchronized VideoPlayerApp getInstance(){ if (m_instance == null){ m_instance = new VideoPlayerApp(); } return m_instance; } // 播放器屏幕 class VideoScreen extends MainScreen{ // 指向本地视频的URI public static final String URI = "/video/song.3GP";; 16 // 播放器实例 private Player m_player; // 视频播放控制 private VideoControl m_videoControl; private Field m_videoField; public VideoScreen(){ super(Manager.NO_HORIZONTAL_SCROLL|Manager.NO_VERTICAL_SCROLL); // 在VideoScreen上播放视频 playVideo(); } // 创建播放器 private void playVideo(){ try{ // 创建新播放器 InputStream is = this.getClass().getResourceAsStream(URI); m_player = javax.microedition.media.Manager.createPlayer(is, VIDEO_FORMAT); // 获取视频文件信息,这一步一定要有,否则获取的VideoControl将无效 m_player.realize(); // 获取视频控制 m_videoControl = (VideoControl)m_player.getControl("VideoControl"); if (m_videoControl != null) { // 从视频控制获取UI组件,这个组件用来显示视频,常用组件比如Field m_videoField = (Field) m_videoControl.initDisplayMode (VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); // 设置显示尺寸 m_videoControl.setDisplayFullScreen(true); // 使视频可见 m_videoControl.setVisible(true); } if (m_videoField != null){ // 添加视频组件到屏幕并开始播放 add(m_videoField); m_player.start(); } 17 }catch(Exception ex){ ex.printStackTrace(); } } // 阻止屏幕弹出 save菜单 public boolean onSavePrompt(){ return true; } } }
还剩16页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 20 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

BlackBerry

贡献于2010-09-15

下载需要 20 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf