Help Center

Local Navigation

Code Sample: Using the Multimedia API to record video

import java.io.*;

import javax.microedition.media.*;
import javax.microedition.media.control.*;
import javax.microedition.io.*;
import javax.microedition.io.file.*;

import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.util.*;
import net.rim.device.api.system.*;
import net.rim.device.api.media.*;

/*
 * the entry class
 */
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( VideoControl.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( STREAM_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( VideoControl.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 ) );
        }
    }
}

Was this information helpful? Send us your comments.