我正在为BlackBerry开发并试图通过推出视频摄像头应用程序来录制视频。
我可以创建Player
对象并在屏幕上创建Field
,以显示相机可以看到的内容。我尝试了录音并且工作正常 - 但是当我在commit()
上调用RecordControl
时,文件被写入0KB的SD卡。我已经在这一段时间里一直在摸不着头脑,无法解决这个问题。这是开始和完成录制的代码:
private void displayVideoRecorder()
{
initVideoRecorder();
if (mTimeLeft == null)
{
mTimeLeft = UIFactory.createLabel("Time left: " + (mMaxVideoDuration - mCurrVideoDuration));
}
// Create a stop recording button and a listener for the saving video functionality
if (mStopRecording == null)
{
mStopRecording = UIFactory.createButtonField("Begin recording");
mStopRecording.setChangeListener(new FieldChangeListener()
{
public void fieldChanged(Field field, int context)
{
if (mRecordingVideo)
{
// Stop the messages
if (mHandlerID != -1)
{
UiApplication.getUiApplication().cancelInvokeLater(mHandlerID);
mHandlerID = -1;
}
new Runnable()
{
public void run()
{
// Save the video
stopRecordingVideo();
// Reset the flag
mRecordingVideo = false;
}
}.run();
// Return to the main page
displayFirstPage();
}
else
{
// Start recording
new Runnable()
{
public void run()
{
mRecordControl.startRecord();
mRecordingVideo = true;
// Queue a message for however long the maximum time for a video is
mHandlerID = UiApplication.getUiApplication().invokeLater(mHandler, 1000, true);
}
}.run();
// Set a flag and change the text of the button
mStopRecording.setLabel("Stop recording");
}
}
});
}
mCurrVideoDuration = 0;
mStopRecording.setLabel("Begin recording");
mTimeLeft.setText("Time left: " + (mMaxVideoDuration - mCurrVideoDuration));
// Add the video & a button to go back
getContentArea().deleteAll();
getContentArea().add(mVideoField);
getContentArea().add(mTimeLeft);
getContentArea().add(mStopRecording);
try
{
// Show what the camera can see
mPlayer.start();
}
catch (Exception e)
{
Out.p("Failed to begin video player");
Out.printStackTrace(e);
}
}
/**
* Stops recording the video and saves the file to the file system. If a video is not recording this call is ignored
*/
private void stopRecordingVideo()
{
if (mRecordingVideo)
{
try
{
mRecordingVideo = false;
// Stop recording and save the file name
mRecordControl.stopRecord();
mPlayer.stop();
mRecordControl.commit();
}
catch (Exception e)
{
Out.alert(e.toString());
}
}
}
private void initVideoRecorder()
{
try
{
Out.p("Beginning initialise of recorder");
mPlayer = Manager.createPlayer("capture://video?" + getEncodings()[0]);// "capture://video?encoding=video/3gpp");
mPlayer.addPlayerListener(new PlayerListener()
{
public void playerUpdate(Player player, String event, Object eventData)
{
Out.p("Player " + player.hashCode() + " got event " + event + ": " + eventData);
}
});
mPlayer.realize();
mVideoControl = (VideoControl) mPlayer.getControl("VideoControl");
mRecordControl = (RecordControl) mPlayer.getControl("RecordControl");
Out.p("Record Control: " + mRecordControl);
// Set where the video will record to
mRecordControl.setRecordLocation(mFilePath);
mVideoField = (Field) mVideoControl.initDisplayMode(GUIControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field");
// add(mVideoField);
Out.p("Video Field: " + mVideoField);
}
catch (Exception e)
{
Out.alert(e.toString());
Out.p("Failed to start recording");
displayFirstPage();
}
}
在能够保存实际视频之后,我跟随了许多指南,但没有成功。任何帮助表示赞赏。
答案 0 :(得分:0)
试试这个 -
public class VideoRecordingApplication extends UiApplication
{
/*
* working constants hard coded to create video files on the SD media card
*/
private static final String VIDEO_FILE = "file:///SDCard/BlackBerry/videos/mmapi_rimlet.3GP";
private static final String STREAM_VIDEO_FILE = "file:///SDCard/BlackBerry/videos/mmapi_stream.sbv";
/*
* video recording screen object used in several places within
*/
private static VideoRecordingScreen _vrs;
/*
* constructor
*/
private VideoRecordingApplication()
{
/*
* to select the video encoding
*/
pushScreen( new ChooseEncodingScreen() );
}
/*
* main() entry point
*/
public static void main( String[] args )
{
/*
* fire up the event dispatcher loop
*/
new VideoRecordingApplication().enterEventDispatcher();
}
/*
* select video encoding screen
* called by the VideoRecordingApplication class constructor
*/
private static final class ChooseEncodingScreen extends MainScreen
{
private static ObjectChoiceField _encodings;
/*
* constructor
*/
public ChooseEncodingScreen()
{
super();
setTitle( "Choose an encoding" );
/*
* load String[] array with all MMAPI video encoding system property values
*/
String[] encodings = getEncodings();
/*
* prep for display
*/
_encodings = new ObjectChoiceField( "Encoding:", encodings, 0 );
/*
* add field to this screen's manager
*/
add( _encodings );
/*
* create a menu item to start recording using the selected encoding scheme
*/
addMenuItem( new MenuItem( "Go", 0, 0 )
{
public void run()
{
/*
* create and display the video recording screen, passing the selected video encoding scheme
*/
_vrs = new VideoRecordingScreen( (String)_encodings.getChoice( _encodings.getSelectedIndex() ) );
UiApplication.getUiApplication().pushScreen( _vrs );
}
} );
}
/*
* returns all MMAPI video encoding system property values
*/
private String[] getEncodings()
{
String[] encodings = new String[0];
/*
* load String with all video.encodings property values
* each value is separated by a space
*/
String encodingsString = System.getProperty( "video.encodings" );
/*
* determine where the first value ends
*/
int space = encodingsString.indexOf( ' ' );
/*
* loop through values, end when a new field separator is not found
*/
while( space != -1 )
{
/*
* add a new String array element that contains the system property value
*/
Arrays.add( encodings, encodingsString.substring( 0, space ) );
/*
* remove the last property value from the encoding string
*/
encodingsString = encodingsString.substring( space + 1 );
/*
* determine where the first value ends
*/
space = encodingsString.indexOf( ' ' );
}
/*
* add a new String array element that contains the final system property value
*/
Arrays.add( encodings, encodingsString );
/*
* return the resulting String[] array
*/
return encodings;
}
}
/*
* video recording screen displayed after the user selects "Go" from the menu
*/
private static final class VideoRecordingScreen extends MainScreen
{
private static Player _player;
private static VideoControl _vc;
private static RecordControl _rc;
private static boolean _visible = true;
private static boolean _locationSet = false;
private static RichTextField _status;
private static CheckboxField _stream;
private static OutputStream _out;
private static FileConnection _fc;
private static RichTextField _flashIndicator;
/*
* constructor passed the chosen video encoding property value
*/
public VideoRecordingScreen( String encoding )
{
super();
try {
/*
* create a video media player to capture video using the passed encoding value
*/
_player = javax.microedition.media.Manager.createPlayer( "capture://video?" + encoding );
/*
* try to start the player
*/
_player.start();
_vc = (VideoControl)_player.getControl( "VideoControl" );
_rc = (RecordControl)_player.getControl( "RecordControl" );
/*
* Initialize the mode on how the video is displayed.
* This method must be called before the video can be displayed.
*
* USE_GUI_PRIMITIVE defines a mode on how the GUI is displayed.
* It is used in conjunction with initDisplayMode(int, java.lang.Object).
*/
Field videoField = (Field)_vc.initDisplayMode( GUIControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field" );
/*
* add field to this screen's manager
*/
add( videoField );
_status = new RichTextField( "Idle" );
add( _status );
_stream = new CheckboxField( "Use OutputStream", false );
add( _stream );
} catch ( Exception e ) {
System.out.println( "Exception in VideoScreen constructor" );
}
addMenuItem( new MenuItem( "Start Record", 0, 0 )
{
public void run()
{
startRecord();
}
} );
addMenuItem( new MenuItem( "Stop Record", 0, 0 )
{
public void run()
{
stopRecord();
}
} );
addMenuItem( new MenuItem( "Commit Record", 0, 0 )
{
public void run()
{
commit();
}
} );
addMenuItem( new MenuItem( "Toggle Visibility", 0, 0 )
{
public void run()
{
toggleVisibility();
}
} );
addMenuItem( new MenuItem( "Play Recording", 0, 0 )
{
public void run()
{
//InputStream recording = _stream.getChecked() ? new ByteArrayInputStream( _out.toByteArray() ) : null;
Application.getApplication().invokeLater( new ShowVideoRunnable( null ) );
}
} );
/*
* this loads the streamed video into memory then does nothing with it
*/
addMenuItem( new MenuItem( "Analyze Recording Stream", 0, 0 )
{
public void run()
{
try {
/*
* get a handle to the streaming video file located on the SDCard (declared near the start of this file)
*/
_fc = (FileConnection)Connector.open( STREAM_VIDEO_FILE );
/*
* determine the file size
*/
long size = _fc.fileSize();
/*
* declare a block of ram to store the file
*/
byte[] file = new byte[(int)size];
/*
* open the stream for read
*/
InputStream in = _fc.openInputStream();
/*
* load the file into memory
*/
in.read( file );
} catch ( Exception e ) {
}
}
} );
}
/*
* decipher and act upon shortcut keys
*/
protected boolean keyChar( char c, int status, int time )
{
switch( c ) {
case 's':
startRecord();
return true;
case 'x':
stopRecord();
return true;
case 'c':
commit();
return true;
case 'v':
toggleVisibility();
return true;
case 'r':
reset();
return true;
default:
return false;
}
}
/*
* record captured video
*/
private void startRecord()
{
try {
/*
* _locationSet == false by default
*/
if( !_locationSet )
{
/*
* test if "Use OutputStream" CheckboxField is set
*/
if( _stream.getChecked() )
{
try {
_fc = (FileConnection)Connector.open( VIDEO_FILE );
/*
* create streaming file if it does not exist
*/
if( !_fc.exists() )
{
_fc.create();
}
/*
* zap the file
*/
_fc.truncate( 0 );
/*
* ready to write video stream
*/
_out = _fc.openOutputStream();
} catch ( Exception e ) {
return;
}
_rc.setRecordStream( _out );
} else {
/*
* FileConnection: Set the output stream where the data will be recorded.
* The locator specifying where the recorded media will be saved.
* The locator must be specified as a URL.
*/
_rc.setRecordLocation( VIDEO_FILE );
}
_locationSet = true;
}
/*
* Start recording the media.
*/
_rc.startRecord();
_status.setText( "Recording" );
} catch ( Exception e ) {
}
}
private void stopRecord()
{
try {
/*
* Stop recording the media.
* stopRecord will not automatically stop the Player.
* It only stops the recording, putting the Player in "standby" mode
*/
_rc.stopRecord();
_status.setText( "Recording stopped" );
} catch ( Exception e ) {
}
}
private void commit()
{
try {
/*
* Complete the current recording.
* If the recording is in progress, commit will implicitly call stopRecord.
*/
_rc.commit();
Dialog.alert( "Committed" );
_locationSet = false;
_status.setText( "Committed" );
/*
* video stream was recorded
*/
if( _stream.getChecked() )
{
/*
* close the stream
*/
try {
_out.close();
_fc.close();
} catch ( Exception e ) {
}
}
} catch ( Exception e ) {
}
}
/*
* toggle video visibility
*/
private void toggleVisibility()
{
try {
_visible = !_visible;
/*
* show or hide the video
*/
_vc.setVisible( _visible );
} catch ( Exception e ) {
}
}
/*
* Erase the current recording
*/
private void reset()
{
try {
_rc.reset();
_status.setText( "Reset called, idle" );
} catch ( Exception e ) {
}
}
/*
* hide the video
*/
public void hide()
{
try {
_visible = false;
_vc.setVisible( _visible );
} catch ( Exception e ) {
}
}
/*
* show the video
*/
public void show()
{
try {
_visible = true;
_vc.setVisible( _visible );
} catch ( Exception e ) {
}
}
}
/*
* ShowVideoRunnable() called within VideoRecordingScreen() through the "Play Recording" menu
*/
private static final class VideoPlaybackScreen extends MainScreen
{
private Player _video;
private VideoControl _vc;
public VideoPlaybackScreen( InputStream vid )
{
super();
try {
/*
* existing video stream passed
*/
if( vid != null )
{
/*
* Create a Player to play back media from an InputStream (streamed video)
*/
_video = javax.microedition.media.Manager.createPlayer( vid, "video/x-rim" );
} else {
/*
* Create a Player from an input locator (a standard video file in .3GP format)
*/
_video = javax.microedition.media.Manager.createPlayer( VIDEO_FILE );
}
/*
* Constructs portions of the Player without acquiring the scarce and exclusive resources.
*/
_video.realize();
/*
* Obtain the object that implements the specified Control interface.
*/
_vc = (VideoControl)_video.getControl( "VideoControl" );
/*
* Initialize the mode on how the video is displayed
*/
Field vField = (Field)_vc.initDisplayMode( GUIControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field" );
add( vField );
VolumeControl vol = (VolumeControl)_video.getControl( "VolumeControl" );
vol.setLevel( 30 );
} catch ( Exception e ) {
System.out.println( "Exception while showing video" );
}
}
protected void onVisibilityChange( boolean visible )
{
if( visible ) {
try {
/*
* Starts the Player as soon as possible.
*/
_video.start();
} catch ( Exception e ) {
}
}
}
public boolean onClose() {
try {
/*
* Close the Player and release its resources.
*/
_video.close();
} catch ( Exception e ) {
}
_vrs.show();
return super.onClose();
}
}
/*
* called within VideoRecordingScreen() through the "Play Recording" menu
*/
private static final class ShowVideoRunnable implements Runnable
{
private InputStream _in;
public ShowVideoRunnable( InputStream in )
{
_in = in;
}
public void run()
{
/*
* hide the VideoRecordingScreen
*/
_vrs.hide();
/*
* Retrieves this UI application object.
*/
UiApplication ui = UiApplication.getUiApplication();
/*
* handle video playback
*/
ui.pushScreen( new VideoPlaybackScreen( _in ) );
}
}
}