为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

BlackBerry视频录制编程

2011-08-22 25页 pdf 843KB 25阅读

用户头像

is_359016

暂无简介

举报
BlackBerry视频录制编程 1 BlackBerry 视频录制编程 作者: 俞伟 目录 BlackBerry视频录制编程概述 ........................................................................................... 2 获取/选定视频格式/编码 .............................................................................................
BlackBerry视频录制编程
1 BlackBerry 视频录制编程 作者: 俞伟 目录 BlackBerry视频录制编程概述 ........................................................................................... 2 获取/选定视频格式/编码 ................................................................................................... 2 录制、存储视频................................................................................................................... 5 回放已录制的视频 ............................................................................................................... 8 完整代码 ............................................................................................................................ 11 类 VideoRecordingScreen.java ................................................................................... 11 类 VideoRecordingSetupScreen.java ........................................................................ 18 类 VideoPlaybackScreen.java .................................................................................... 20 类 VideoRecordingDemo.java .................................................................................... 24 2 BlackBerry 视频录制编程概述 BlackBerry 5.0 平台以及之前的版本对多媒体的支持依赖于 JSR 135,也就是 J2ME 平台 的 MMAPI。BlackBerry 手机上录制视频也依靠 MMAPI,支持 3gpp 视频格式,支持的视频编 码包括 MPEG-4, H263, H264, 音频编码包括 AAC, PCM, AMR。具体的视频音频编码支持依黑 莓机型而定。 BlackBerry 视屏录制编程包括以下几部分: 1. 获取/选定手机对视频格式/编码的支持 2. 录制/存储视频 3. 回放已录制的视频 获取/选定视频格式/编码 通过系统提供的 API 可以获得该机型视频支持的所有视频规格: encodingsString 包含了全部能够支持的视频规格,但它是一个 String,还不能够直接使用, 需要进一步解析。以下代码解析视频规格,并返回规格列表: /** * 获取黑莓手机所支持的视屏规格列表 */ public static String[] getVideoEncodings() { // 获取黑莓手机设备支持的视频格式/编码 String encodingsString = System.getProperty("video.encodings"); // 如果没有支持的视频编码,返回空 if( encodingsString == null ) { return null; } // 解析出视频规格 Vector encodings = new Vector(); int start = 0; int space = encodingsString.indexOf(' '); String encodingsString = System.getProperty("video.encodings"); 3 解析后的视频规格范例如下所示:  “encoding”字段表示视频格式  “mode”表示播放模式,模式会自动设置屏幕尺寸和编码  “width”表示屏幕宽度  “height”表示屏幕高度  “video_codec”表示视频编码  “audio_codec”表示音频编码 视频规格如图所示: while( space != -1 ) { encodings.addElement(encodingsString.substring(start, space)); start = space + 1; space = encodingsString.indexOf(' ', start); } encodings.addElement(encodingsString.substring(start, encodingsString.length())); String[] encodingArray = new String[encodings.size()]; encodings.copyInto(encodingArray); return encodingArray; } “encoding=video/3gpp&mode=standard” “encoding=video/3gpp&mode=mms” “encoding=video/3gpp&width=480&height=360&video_codec=MPEG-4&audio_codec=AMR” “encoding=video/3gpp&width=176&height=144&video_codec=H263&audio_codec=AMR” “encoding=video/3gpp&width=480&height=360&video_codec=H263&audio_codec=AAC” “encoding=video/3gpp&width=480&height=360&video_codec=H264&audio_codec=AAC” 4 5 录制、存储视频 录制视频主要用到 Player,VideoControl,RecordControl,ByteArrayOutputStream。使用 Player 打开摄像头,VideoControl 将捕捉的视频显示到屏幕上,RecordControl 控制录制过程, ByteArrayOutputStream 作为视频录制的缓存。以下三段代码范例分别为配置/启动摄像头, 开始录制,和保存已录制的视频。 /** * 构造一个屏幕显示和录制摄像头录制的视频 */ public VideoRecordingScreen(String encoding, String filePath) { try{ // 开始捕捉视频 // encoding 是上一部分提到的视频规格 _player = javax.microedition.media.Manager.createPlayer("capture://video?" + encoding); _player.start(); _videoControl = (VideoControl) _player.getControl("VideoControl"); _recordControl = (RecordControl) _player.getControl("RecordControl"); // 将捕捉的视频显示在 Field 控件上 Field videoField = (Field) _videoControl.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); try{ // 视频尺寸为全屏 _videoControl.setDisplaySize( Display.getWidth(), Display.getHeight() ); } catch( MediaException me ) {} add(videoField); // 视频缓存,捕捉到的视频将写入缓存 _outStream = new ByteArrayOutputStream(); _videoFile = filePath; startRecord(); } 6 以上代码配置并启动摄像头。 catch( Exception e ) { // Dispose of the player if it was created if( _player != null ) { _player.close(); } _player = null; deleteAll(); removeAllMenuItems(); VideoRecordingDemo.errorDialog(e.toString()); } } /** * 开始录制视频 */ private void startRecord() { try { if( !_pendingCommit ) { // 重置缓存 _outStream.reset(); // 将缓存作为录制缓存 _recordControl.setRecordStream(_outStream); _pendingCommit = true; _committed = false; } // 开始录制 _recordControl.startRecord(); _recording = true; } 7 以上代码开始录制视频。 catch( Exception e) { VideoRecordingDemo.errorDialog(e.toString()); } } /** * 保存录像 */ private void commitRecording() { try { // 这是最关键的一步,保存录制的视频 _recordControl.commit(); // 重置参数 _pendingCommit = false; _committed = true; _recording = false; // 获取视频数据流 byte[] data = _outStream.toByteArray(); // 以文件的形式保存视频 FileConnection fconn = (FileConnection) Connector.open(_videoFile); if (fconn.exists()){ fconn.delete(); } fconn.create(); OutputStream os = fconn.openOutputStream(); os.write(data); os.flush(); os.close(); fconn.close(); 8 以上代码保存/存储视频。 回放已录制的视频 前一步录制的视频以文件的形式保存在手机目录中,回放视频需要文件路径, 载入文件, 使用 Player 在 Field 上进行播放。代码如下: Dialog.alert("Committed"); } catch( Exception e ) { VideoRecordingDemo.errorDialog("RecordControl#commit() threw " + e.toString()); } } /** * 构造视频回放屏幕,按指定路径装载视频文件 */ Public VideoPlaybackScreen(String file) { boolean notEmpty; // 检测给定路径是否有媒体文件 try { FileConnection fconn = (FileConnection) Connector.open(file); notEmpty = fconn.exists() && fconn.fileSize() > 0; fconn.close(); } catch( IOException e ) { Dialog.alert("Exception while accessing the video filesize:\n\n" + e); notEmpty = false; } 9 使用给定的路径创建 _videoPlayer。 // 如有媒体文件并有内容,初始化界面进行播放 if( notEmpty ) { try { // 创建 Video Player _videoPlayer = javax.microedition.media.Manager.createPlayer(file); initScreen(); } catch( Exception e ) { Dialog.alert("Exception while initializing the playback video player\n\n" + e); } } else { add(new LabelField("The video file you are trying to play is empty")); } } private void initScreen() throws Exception{ _videoPlayer.realize(); // 注册媒体播放时间响应 _videoPlayer.addPlayerListener(new PlayerListener(){ public void playerUpdate(Player player, String event, Object eventData){ // 定义媒体文件播放完毕时的响应 if( event == PlayerListener.END_OF_MEDIA ){ UiApplication.getUiApplication().invokeLater(new Runnable(){ public void run(){ Dialog.alert("Finished playing"); close(); } }); } } }); 10 初始化屏幕开始回放视频。_videoPlayer.realize() 获取视频文件相关信息,为播放做好准备。 之后_videoPlayer 注册了媒体播放事件侦听,当媒体文件播放完毕时有事件响应。从 _videoPlayer 中获取 VideoControl,VideoControl 再返回视屏播放所占据的 Field,添加这个 Field 到屏幕上来显示视屏。VolumeControl 可以定义声音大小,也可以从_videoPlayer 中获取。 // 获取 VideoControl 来获得播放视频的 Field _videoControl = (VideoControl)_videoPlayer.getControl("VideoControl"); Field vField = (Field) _videoControl.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); add(vField); // 获取 VolumeControl 来指定声音大小 VolumeControl vol = (VolumeControl) _videoPlayer.getControl("VolumeControl"); vol.setLevel(30); } 11 完整代码 类 VideoRecordingScreen.java package com.rim.samples.device.videorecordingdemo; import net.rim.device.api.ui.*; import net.rim.device.api.ui.container.*; import net.rim.device.api.ui.component.*; import net.rim.device.api.system.Display; import javax.microedition.io.Connector; import javax.microedition.io.file.FileConnection; import javax.microedition.media.*; import javax.microedition.media.control.*; import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; import java.io.OutputStream; /** * This screen allows the user to record videos to a file or to a stream and * enables the user to open the VideoPlaybackScreen to play the recorded video. */ public class VideoRecordingScreen extends MainScreen { private boolean _pendingCommit; private boolean _committed; private boolean _recording; private String _videoFile; private Player _player; private VideoControl _videoControl; private RecordControl _recordControl; private boolean _displayVisible; private ByteArrayOutputStream _outStream; public VideoRecordingScreen(String encoding, String filePath) { 12 if (encoding == null) { throw new NullPointerException("Video encoding can not be null"); } if (filePath == null) { throw new NullPointerException("File path can not be null"); } try { // 开始捕捉视频 // encoding 是视频规格 _player = javax.microedition.media.Manager.createPlayer("capture://video?" + encoding); _player.start(); _videoControl = (VideoControl) _player.getControl("VideoControl"); _recordControl = (RecordControl) _player.getControl("RecordControl"); // 将捕捉的视频显示在 Field 控件上 Field videoField = (Field) _videoControl.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); try{ // 视频尺寸为全屏 _videoControl.setDisplaySize( Display.getWidth(), Display.getHeight() ); } catch( MediaException me ){ // setDisplaySize is not supported } add(videoField); // 视频缓存,捕捉到的视频将写入缓存 _outStream = new ByteArrayOutputStream(); _videoFile = filePath; startRecord(); } 13 catch( Exception e ) { // Dispose of the player if it was created if( _player != null ) { _player.close(); } _player = null; deleteAll(); removeAllMenuItems(); VideoRecordingDemo.errorDialog(e.toString()); } } /** * Commits the current recording */ private MenuItem _commit = new MenuItem("Commit recording", 0, 0){ public void run(){ commitRecording(); } }; /** * Plays the recording */ private MenuItem _playRecording = new MenuItem("Play recording", 0, 0){ public void run(){ // Create the playback screen from the chosen video source VideoPlaybackScreen playbackScreen = new VideoPlaybackScreen(_videoFile); // Hide the video feed since we cannot display video from the camera // and video from a file at the same time. _videoControl.setVisible(false); _displayVisible = false; UiApplication.getUiApplication().pushScreen(playbackScreen); } }; 14 /** * Resets the recording */ private MenuItem _reset = new MenuItem("Reset recording", 0, 0){ public void run(){ try{ _recordControl.reset(); } catch( Exception e ){ VideoRecordingDemo.errorDialog("RecordControl#reset threw " + e.toString()); } } }; /** * Shows the video display */ private MenuItem _showDisplay = new MenuItem("Show display", 0, 0){ public void run(){ _videoControl.setVisible(true); _displayVisible = true; } }; private MenuItem _hideDisplay = new MenuItem("Hide display", 0, 0){ /** * @see java.lang.Runnable#run() */ public void run(){ _videoControl.setVisible(false); _displayVisible = false; } }; private MenuItem _startRecord = new MenuItem("Start recording", 0, 0){ public void run() { startRecord(); } }; 15 private MenuItem _stopRecord = new MenuItem("Stop recording", 0, 0){ public void run(){ stopRecord(); } }; public boolean onClose(){ // Stop capturing video from the camera if( _player != null ){ _player.close(); } return super.onClose(); } protected boolean onSavePrompt(){ // Suppress the save prompt return true; } protected void makeMenu(Menu menu, int instance){ super.makeMenu(menu, instance); if(_recording){ menu.add(_stopRecord); } else{ menu.add(_startRecord); } if( _pendingCommit ){ menu.add(_commit); menu.add(_reset); } if(_committed){ menu.add(_playRecording); } if( _displayVisible){ menu.add(_hideDisplay); } else{ menu.add(_showDisplay); } } 16 protected boolean invokeAction(int action){ switch(action){ case ACTION_INVOKE: // Trackball click if(_recording){ int response = Dialog.ask(Dialog.D_YES_NO, "Recording paused. Commit recording?", Dialog.YES); if(response == Dialog.YES){ this.commitRecording(); } } return true; // We've consumed the event } return super.invokeAction(action); } protected void onVisibilityChange(boolean visible){ if( visible && _player != null ){ _videoControl.setVisible(true); _displayVisible = true; } } private void startRecord(){ try{ if( !_pendingCommit ){ _outStream.reset(); // 将缓存作为录制缓存 _recordControl.setRecordStream(_outStream); _pendingCommit = true; _committed = false; } // 开始录制 _recordControl.startRecord(); _recording = true; } catch( Exception e ){ VideoRecordingDemo.errorDialog(e.toString()); } } 17 private void stopRecord(){ try{ _recordControl.stopRecord(); _recording = false; } catch( Exception e ){ VideoRecordingDemo.errorDialog("RecordControl#stopRecord() threw " + e.toString()); } } private void commitRecording(){ try{ _recordControl.commit(); _pendingCommit = false; _committed = true; _recording = false; // 获取视频数据流 byte[] data = _outStream.toByteArray(); // 以文件的形式保存视频 FileConnection fconn = (FileConnection) Connector.open(_videoFile); if (fconn.exists()){ fconn.delete(); } fconn.create(); OutputStream os = fconn.openOutputStream(); os.write(data); os.flush(); os.close(); fconn.close(); Dialo
/
本文档为【BlackBerry视频录制编程】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索