Page 1

BlackBerry Java SDK Multimedia Version: 6.0

Development Guide


Published: 2010-11-1 SWD-1249411-1101032433-001


Contents 1

Working with audio on a BlackBerry device............................................................................................................................ Playing audio................................................................................................................................................................................... Play audio in a BlackBerry device application.................................................................................................................... Play audio in the BlackBerry Browser.................................................................................................................................. Code sample: Playing a sequence of tones......................................................................................................................... Recording audio.............................................................................................................................................................................. Record audio in a BlackBerry device application................................................................................................................

2 2 2 5 5 6 7

2 Working with video on a BlackBerry device............................................................................................................................. Playing video................................................................................................................................................................................... Play a video in a UI field in a BlackBerry device application............................................................................................ Recording video............................................................................................................................................................................... Record video to a file in a BlackBerry device application.................................................................................................. RIMM streaming video file............................................................................................................................................................. RIM proprietary video format (RIMM streaming file).........................................................................................................

17 17 17 22 22 34 34

3 Working with pictures on a BlackBerry device........................................................................................................................ Taking pictures................................................................................................................................................................................ Take a picture in a BlackBerry device application..............................................................................................................

41 41 41

4 Find more information................................................................................................................................................................

48

5 Provide feedback.........................................................................................................................................................................

49

6 Document revision history.........................................................................................................................................................

50

7 Legal notice..................................................................................................................................................................................

51


Working with audio on a BlackBerry device

Development Guide

Working with audio on a BlackBerry device

1

Playing audio You can play audio on a BlackBerry速 device through the BlackBerry速 Browser, or by generating a series of discrete tones, by using the javax.microedition.media.Player class in your BlackBerry device application. You can use the Player class to open a file that is stored on the BlackBerry device's internal media storage or media card, by specifying a URL, or by specifying a location in your .cod file and using the format: cod:///path. Player provides access to the associated Control classes (for example, VolumeControl) that control the playback and recording functionality (for example, the volume). You can use the browser to play an audio file by creating a new BrowserSession object and opening the audio file as you would any URI. You can also create a series of tones to play in your application. For example, you can use these tones as a notification sounds in your application. You can define the frequencies and length of the discrete tones and play them in a sequence.

Play audio in a BlackBerry device application 1.

Import the required classes and interfaces. import import import import import import

2.

net.rim.device.api.ui.*; net.rim.device.api.ui.container.*; net.rim.device.api.ui.component.*; javax.microedition.media.*; javax.microedition.media.control.*; java.io.*

Create the application framework by extending the UiApplication class. In main(), create an instance of the new class and invoke enterEventDispatcher() to enable the application to receive events. In the application constructor, invoke pushScreen() to display the custom screen for the application. The AudioPlaybackDemoScreen class, described in step 3, represents the custom screen. public class AudioPlaybackDemo extends UiApplication { public static void main(String[] args) { AudioPlaybackDemo app = new AudioPlaybackDemo(); app.enterEventDispatcher(); } public AudioPlaybackDemo() {

2


Playing audio

Development Guide

}

3.

}

pushScreen(new AudioPlaybackDemoScreen());

Create the framework for the custom screen by extending the MainScreen class. class AudioPlaybackDemoScreen extends MainScreen { public AudioPlaybackDemoScreen() { } }

4.

In the screen constructor, in a try/catch block, create an instance of the Player class by invoking Manager.createPlayer(String), and passing in the location of the audio file to play. try {

Player p = javax.microedition.media.Manager.createPlayer("http://abc .com/sounds/abc.wav");

} catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

5.

To control an aspect of playback, retrieve the appropriate Control object. Invoke the Player object's realize() method to access its associated Control object. The following code sample demonstrates how to retrieve the VolumeControl object and set the volume level of playback. try {

Player p = javax.microedition.media.Manager.createPlayer("http://abc .com/sounds/abc.wav"); p.realize(); VolumeControl volume = (VolumeControl) p.getControl("VolumeControl"); volume.setLevel(30);

} catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

3


Development Guide

6.

Invoke Player.start() to start playback. Invoking Player.start() implicitly performs all the necessary state transitions. In the following code sample, both realize() and prefetch() are invoked to demonstrate how to explicitly initialize the Player object before starting playback. try {

Player p = javax.microedition.media.Manager.createPlayer("http://abc .com/sounds/abc.wav"); p.realize(); VolumeControl volume = (VolumeControl)p.getControl("VolumeControl"); volume.setLevel(30); p.prefetch(); p.start();

} catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

Code sample: Playing media in a BlackBerry device application import import import import import import

net.rim.device.api.ui.*; net.rim.device.api.ui.container.*; net.rim.device.api.ui.component.*; javax.microedition.media.*; javax.microedition.media.control.*; java.io.*

public class AudioPlaybackDemo extends UiApplication { public static void main(String[] args) { AudioPlaybackDemo app = new AudioPlaybackDemo(); app.enterEventDispatcher(); } public AudioPlaybackDemo() { pushScreen(new AudioPlaybackDemoScreen()); } private class AudioPlaybackDemoScreen extends MainScreen { public AudioPlaybackDemoScreen() {

4

Playing audio


Playing audio

Development Guide

try {

Player p = javax.microedition.media.Manager.createPlayer("http://abc .com/sounds/abc.wav"); p.realize(); VolumeControl volume = (VolumeControl)p.getControl("VolumeControl"); volume.setLevel(30); p.prefetch(); p.start();

}

}

}

} catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

Play audio in the BlackBerry Browser 1.

Import the required classes. import net.rim.blackberry.api.browser.Browser; import net.rim.blackberry.api.browser.BrowserSession;

2.

Invoke Browser.getDefaultSession(). BrowserSession soundclip = Browser.getDefaultSession();

3.

Invoke BrowserSession.displaypage(). soundclip.displayPage("file:///SDCard/BlackBerry/music/yourFile .mp3");

Code sample: Playing a sequence of tones ToneControl is used to play a user-defined sequence of notes at a specific duration and tempo on a BlackBerry速 device. // "Mary Had A Little Lamb" has "ABAC" // Use block to repeat "A" section // Tempos ranging from 20 to 508 beats // to create a tempo modifier range of byte tempo_mod = 30; // 120 bpm // Note duration ranges from 128 (1/2 // with a default resolution of 64.

structure per minute are divided by 4 5 to 127. note) to 0 (128th of a note)

5


Development Guide

Recording audio

byte duration = 8; // Note length 8 (quaver) = 1/8th of a note duration // Notes are determined from ToneControl.C4 (Middle C), // which has a value of 60 and a frequency of 261.6 Hz. byte C4 = ToneControl.C4; // C note value = 60 (middle C) byte D4 = (byte)(C4 + 2); // D note value = 62 (a whole step) byte E4 = (byte)(C4 + 4); // E note value = 64 (a major third) byte G4 = (byte)(C4 + 7); // G note value = 67 (a fifth) byte rest = ToneControl.SILENCE; // rest byte[] mySequence = { ToneControl.VERSION, 1, // version 1 ToneControl.TEMPO, tempo_mod, // // Start define "A" section ToneControl.BLOCK_START, 0, // // Content of "A" section E4, duration, D4, duration, C4, duration, E4, duration, E4, duration, E4, duration, E4, duration, rest, duration, // // End define "A" section ToneControl.BLOCK_END, 0, // end of block number 0 // // Play "A" section ToneControl.PLAY_BLOCK, 0, // // Play "B" section D4, duration, D4, duration, D4, duration, rest, duration, E4, duration, G4, duration, G4, duration, rest, duration, // // Repeat "A" section ToneControl.PLAY_BLOCK, 0, // // Play "C" section D4, duration, D4, duration, E4, duration, D4, duration, C4, duration }; try{ Player p = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR); p.realize(); ToneControl c = (ToneControl)p.getControl("ToneControl"); c.setSequence(mySequence); p.start(); } catch (IOException ioe) { } } catch (MediaException me) { }

Recording audio You can record audio in a BlackBerry速 device application by using the javax.microedition.media.Player class and the associated RecordControl interface. The recording is saved to a file in built-in media storage, media card storage, or to a stream.

6


Recording audio

Development Guide

Record audio in a BlackBerry device application BlackBerry速 devices that operate on CDMA networks can record audio in the following formats: AMR 8 kHz mono, 16-bit PCM, GSM 6.10, and QCELP. The default audio recording format is AMR. 1. Import the required classes. import import import import import import import

2.

net.rim.device.api.ui.*; net.rim.device.api.ui.container.*; net.rim.device.api.ui.component.*; java.io.*; java.lang.*; javax.microedition.media.*; javax.microedition.media.control.*;

Create the application framework by extending the UiApplication class. In main(), create an instance of the new class and invoke enterEventDispatcher() to enable the application to receive events. In the application constructor, invoke pushScreen() to display the custom screen for the application. The AudioRecordingDemoScreen class, which is described in step 3, represents the custom screen. public class AudioRecordingDemo extends UiApplication { public static void main(String[] args) { AudioRecordingDemo app = new AudioRecordingDemo(); app.enterEventDispatcher(); }

}

3.

public AudioRecordingDemo() { pushScreen(new AudioRecordingDemoScreen()); }

Create the framework for the custom screen by extending the MainScreen class. Declare an instance of the AudioRecorderThread class, which is described in step 5. private class AudioRecordingDemoScreen extends MainScreen { private AudioRecorderThread _recorderThread;

}

4.

public AudioRecordingDemoScreen() { }

In the AudioRecordingDemoScreen constructor, invoke setTitle() to specify the title for the screen. Invoke addMenuItem() twice to add the menu items to start and stop the recording. which is described in step 5.

7


Development Guide

Recording audio

public AudioRecordingDemoScreen() { setTitle("Audio recording demo"); addMenuItem(new StartRecording()); addMenuItem(new StopRecording()); }

5.

In the AudioRecordingDemoScreen class, define the menu items to start the recording and to stop recording by invoking the start() and stop() methods of the AudioRecorderThread class respectively, which is described in step 6. in the following code sample, Player starts in its own thread to increase the responsiveness of the menu items. private class StartRecording extends MenuItem { public StartRecording() { super("Start recording", 0, 100); }

}

public void run() { try { AudioRecorderThread newRecorderThread = new AudioRecorderThread(); newRecorderThread.start(); _recorderThread = newRecorderThread; } catch (Exception e) { Dialog.alert(e.toString()); } }

private class StopRecording extends MenuItem { public StopRecording() { super("Stop recording", 0, 100); } public void run() { try { if (_recorderThread != null) { _recorderThread.stop(); } }

8


Recording audio

Development Guide

}

6.

}

catch (Exception e) { Dialog.alert(e.toString()); }

Inside the AudioRecordingDemo screen class, define an inner class that extends Thread and implements PlayerListener. In the inner class, create a variable of type Player and a variable of type RecordControl for recording media. Note: You are not required to record audio in a separate thread because recording operations are threaded by design. private class AudioRecorderThread extends Thread implements javax.microedition.media.PlayerListener { private Player _player; private RecordControl _recordControl; AudioRecorderThread() { } }

7.

In the AudioRecorderThread class, implement the Thread interface's run() method. In run() create a try/catch block and invoke Manager.createPlayer(String locator) to create a Player object to record audio, using as a parameter a value that specifies the encoding to use. public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://audio?encoding=audio/amr");

}

8.

} catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

Invoke Player.addPlayerListener() specifying this as a parameter because AudioRecorderThread implements PlayerListener.

9


Recording audio

Development Guide

public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://audio?encoding=audio/amr"); _player.addPlayerListener(this);

}

9.

} catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

To record, invoke Player.realize() method to access the RecordControl object. Then, invoke Player.getControl(), passing in the string, RecordControl, to retrieve the RecordControl object. public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://audio?encoding=audio/amr"); _player.addPlayerListener(this); _player.realize(); _recordControl = (RecordControl) _player.getControl( "RecordControl" );

}

} catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

10. Invoke RecordControl.setRecordLocation() to set the location on the device to save the audio recording. public void run() { try {

10


Recording audio

Development Guide

_player = javax.microedition.media.Manager .createPlayer("capture://audio?encoding=audio/amr"); _player.addPlayerListener(this); _player.realize(); _recordControl = (RecordControl) _player.getControl( "RecordControl" ); _recordControl.setRecordLocation("file:///store/home/user/ AudioRecordingTest .amr" ); } catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); } }

11.

Invoke RecordControl.startRecord() to start recording the audio and start playing the media. Invoke Player.start() to start Player. public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://audio?encoding=audio/amr"); _player.addPlayerListener(this); _player.realize(); _recordControl = (RecordControl) _player.getControl( "RecordControl" ); _recordControl.setRecordLocation("file:///store/home/user/ AudioRecordingTest .amr" ); _recordControl.startRecord(); _player.start(); } catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) {

11


Recording audio

Development Guide

}

}

Dialog.alert(e.toString());

12. In AudioRecorder, implement the Thread interface's stop() method. Check that Player is not null and invoke Player.close() to release the Player object's resources. Set Player to null. public void stop() { if (_player != null) { _player.close(); _player = null; } }

13. Check that RecordControl is not null and invoke RecordControl.stopRecord() to stop recording. In a try/ catch block, invoke RecordControl.commit() to save the recording to a specified file. Set RecordControl to null. public void stop() { if (_player != null) { _player.close(); _player = null; } if (_recordControl != null) { _recordControl.stopRecord(); try {

}

}

_recordControl.commit(); } catch (Exception e) { Dialog.alert(e.toString()); } _recordControl = null;

14. In AudioRecorderThread, implement the PlayerListener interface's playerUpdate() method which is invoked whenever the Player object generates an event. In the following code sample, the application outputs information about the event. public void playerUpdate(Player player, String event, Object eventData) {

12


Recording audio

Development Guide

}

Dialog.alert("Player " + player.hashCode() + " got event " + event + ": " + eventData);

Code sample: Recording audio in a BlackBerry device application import import import import import import import

net.rim.device.api.ui.*; net.rim.device.api.ui.container.*; net.rim.device.api.ui.component.*; java.lang.*; javax.microedition.media.*; java.io.*; javax.microedition.media.control.*;

public class AudioRecordingDemo extends UiApplication { public static void main(String[] args) { AudioRecordingDemo app = new AudioRecordingDemo(); app.enterEventDispatcher(); } public AudioRecordingDemo() { pushScreen(new AudioRecordingDemoScreen()); } private class AudioRecordingDemoScreen extends MainScreen { private AudioRecorderThread _recorderThread; public AudioRecordingDemoScreen() { setTitle("Audio recording demo");

}

addMenuItem(new StartRecording()); addMenuItem(new StopRecording());

private class StartRecording extends MenuItem { public StartRecording() { super("Start recording", 0, 100); } public void run() { try {

13


Recording audio

Development Guide

AudioRecorderThread newRecorderThread = new AudioRecorderThread(); newRecorderThread.start(); _recorderThread = newRecorderThread; } catch (Exception e) { Dialog.alert(e.toString()); } } } private class StopRecording extends MenuItem { public StopRecording() { super("Stop recording", 0, 100); }

}

public void run() { try { if (_recorderThread != null) { _recorderThread.stop(); } } catch (Exception e) { Dialog.alert(e.toString()); } }

private class AudioRecorderThread extends Thread implements javax.microedition.media.PlayerListener { private Player _player; private RecordControl _recordControl; AudioRecorderThread() { } public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://audio?encoding=audio/amr");

14


Recording audio

Development Guide

_player.addPlayerListener(this); _player.realize(); _recordControl = (RecordControl) _player.getControl( "RecordControl" ); _recordControl .setRecordLocation("file:///store/home/user/AudioRecordingTest.amr"); _recordControl.startRecord(); _player.start(); } catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

} public void stop() { if (_player != null) { _player.close(); _player = null; }

if (_recordControl != null) { _recordControl.stopRecord(); try {

}

}

_recordControl.commit(); } catch (Exception e) { Dialog.alert(e.toString()); } _recordControl = null;

public void playerUpdate(Player player, String event, Object eventData) { Dialog.alert("Player " + player.hashCode() + " got event " + event + ": " + eventData); }

15


Development Guide

}

16

}

}

Recording audio


Development Guide

Working with video on a BlackBerry device

Working with video on a BlackBerry device

2

Playing video You can play video in your application on a BlackBerry速 device by using the javax.microedition.media.Player class. The Player class lets you open a file that is stored on the BlackBerry device's built-in media storage or media card storage, by specifying a URL, or by specifying a location in your .cod file using the format: cod:///path. Player can retrieve the associated Control classes that you can use to control various aspects of playback (for example, the volume of the audio track). To create a UI component that displays the video playback, you can invoke VideoControl.initDisplay() to retrieve a Field object that is added to your UI.

Play a video in a UI field in a BlackBerry device application 1.

Import the required classes and interfaces. import net.rim.device.api.ui.*; import net.rim.device.api.ui.component.*; import net.rim.device.api.ui.container.*; import java.io.*; import javax.microedition.media.*; import javax.microedition.media.control.*;

2.

Create the application framework by extending the UiApplication class. In main(), create an instance of the new class and invoke enterEventDispatcher() to enable the application to receive events. In the application constructor, invoke pushScreen() to display the custom screen for the application. The VideoPlaybackDemoScreen class, which is described in step 3, represents the custom screen. public class VideoPlaybackDemo extends UiApplication { public static void main(String[] args) { VideoPlaybackDemo app = new VideoPlaybackDemo(); app.enterEventDispatcher(); }

}

3.

public VideoPlaybackDemo() { pushScreen(new VideoPlaybackDemoScreen()); }

Create the framework for the custom screen by extending the MainScreen class.

17


Development Guide

Playing video

private class VideoPlaybackDemoScreen extends MainScreen { public VideoPlaybackDemoScreen() { } }

4.

In the screen constructor, in a try/catch block, create an instance of the Player class by invoking Manager.createPlayer(String), passing in the location of the video file to play. try {

Player player = javax.microedition.media.Manager .createPlayer("file:///SDCard/BlackBerry/videos/soccer1.avi");

} catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

5.

To control an aspect of playback, retrieve the appropriate Control object. First, invoke the Player object's realize () method to access its associated Control object. Next , invoke Player.getControl() passing in the string, VideoControl, to retrieve the VideoControl object that is associated with Player. try {

Player player = javax.microedition.media.Manager .createPlayer("file:///SDCard/BlackBerry/videos/soccer1.avi"); player.realize(); VideoControl videoControl = (VideoControl) player.getControl("VideoControl");

} catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

6.

18

Invoke VideoControl.initDisplayMode(int mode, Object arg) passing an arg parameter specifying the UI primitive that displays the video to initialize the mode that a video field uses. Cast the returned object as a Field object. Note: You can invoke initDisplayMode() in different ways to return a Field , an Item for use with MIDlets, or to display a video on a Canvas class.


Development Guide

try {

Playing video

Player player = javax.microedition.media.Manager .createPlayer("file:///SDCard/BlackBerry/videos/soccer1.avi"); player.realize(); VideoControl videoControl = (VideoControl) player.getControl("VideoControl"); Field videoField = (Field)videoControl.initDisplayMode( VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field" );

} catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

7.

Invoke add() to add the returned Field object to your Screen or Manager, as you would add any other component to your UI. try {

Player player = javax.microedition.media.Manager .createPlayer("file:///SDCard/BlackBerry/videos/soccer1.avi"); player.realize(); VideoControl videoControl = (VideoControl) player.getControl("VideoControl"); Field videoField = (Field)videoControl.initDisplayMode( VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field" );

add(videoField); } catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

8.

To set the volume of playback, invoke Player.getControl() passing in the string, VolumeControl, to retrieve the VolumeControl object that is associated with Player. Invoke VolumeControl.setLevel() to specify the volume of playback. try {

Player player = javax.microedition.media.Manager .createPlayer("file:///SDCard/BlackBerry/videos/soccer1.avi"); player.realize(); VideoControl videoControl = (VideoControl) player.getControl("VideoControl");

19


Development Guide

Playing video

Field videoField = (Field)videoControl.initDisplayMode( VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field" ); add(videoField); VolumeControl volume = (VolumeControl) player.getControl("VolumeControl"); volume.setLevel(30);

} catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

9.

Invoke Player.start() to start playback. try {

Player player = javax.microedition.media.Manager .createPlayer("file:///SDCard/BlackBerry/videos/soccer1.avi"); player.realize(); VideoControl videoControl = (VideoControl) player.getControl("VideoControl"); Field videoField = (Field)videoControl.initDisplayMode( VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field" ); add(videoField); VolumeControl volume = (VolumeControl) player.getControl("VolumeControl"); volume.setLevel(30);

player.start(); } catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

Code sample: Playing video in a UI field in a BlackBerry device application import import import import import

20

net.rim.device.api.ui.*; net.rim.device.api.ui.container.*; net.rim.device.api.ui.component.*; javax.microedition.media.*; javax.microedition.media.control.*;


Development Guide

import java.io.*; public class VideoPlaybackDemo extends UiApplication { public static void main(String[] args) { VideoPlaybackDemo app = new VideoPlaybackDemo(); app.enterEventDispatcher(); } public VideoPlaybackDemo() { pushScreen(new VideoPlaybackDemoScreen()); } private class VideoPlaybackDemoScreen extends MainScreen { public VideoPlaybackDemoScreen() { try { Player player = javax.microedition.media.Manager.createPlayer("file:/// SDCard/BlackBerry/videos/soccer1.avi"); player.realize(); VideoControl videoControl = (VideoControl) player.getControl ("VideoControl"); Field videoField = (Field)videoControl.initDisplayMode ( VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field" ); add(videoField); VolumeControl volume = (VolumeControl) player.getControl ("VolumeControl"); volume.setLevel(30);

}

}

}

player.start(); } catch(MediaException me) { Dialog.alert(me.toString()); } catch(IOException ioe) { Dialog.alert(ioe.toString()); }

21


Recording video

Development Guide

Recording video You can record video in BlackBerry速 device application by using the Player class and the associated RecordControl interface. The recording is saved to a file in built-in storage, media card storage, or to a stream. To create a viewfinder to monitor what the camera is recording, you can use the VideoControl.initDisplay() method to retrieve a Field object that is added to your UI.

Record video to a file in a BlackBerry device application 1.

Import the required classes. import import import import import import import import

2.

net.rim.device.api.ui.*; net.rim.device.api.ui.component.*; net.rim.device.api.ui.container.*; net.rim.device.api.system.*; java.io.*; java.lang.*; javax.microedition.media.*; javax.microedition.media.control.*;

Create the application framework by extending the UiApplication class. In main(), create an instance of the new class and invoke enterEventDispatcher() to enable the application to receive events. In the application constructor, invoke pushScreen() to display the custom screen for the application. The VideoRecordingDemoScreen class, which is described in step 3, represents the custom screen. public class VideoRecordingDemo extends UiApplication { public static void main(String[] args) { VideoRecordingDemo app = new VideoRecordingDemo(); app.enterEventDispatcher(); }

}

3.

public VideoPlaybackDemo() { pushScreen(new VideoRecordingDemoScreen()); }

Create the framework for the custom screen by extending the MainScreen class. Declare an instance of the VideoRecorderThread class, which is described in step 5. class VideoRecordingDemoScreen extends MainScreen { private VideoRecorderThread _recorderThread; public VideoRecordingDemoScreen()

22


Development Guide

}

4.

Recording video

{ }

In the VideoRecordingDemoScreen constructor, invoke setTitle() to specify the title for the screen. Invoke addMenuItem() twice to add the menu items to start and stop the recording, which is described in step 5. public VideoRecordingDemoScreen() { setTitle("Video recording demo"); addMenuItem(new StartRecording()); addMenuItem(new StopRecording()); }

5.

In the VideoRecordingDemoScreen class, define the menu items to start recording and to stop recording by invoking the start() and stop() methods of the VideoRecorderThread class respectively, which is described in step 6. private class StartRecording extends MenuItem { public StartRecording() { super("Start recording", 0, 100); }

}

public void run() { try { VideoRecorderThread newRecorderThread = new VideoRecorderThread(); newRecorderThread.start(); _recorderThread = newRecorderThread; } catch (Exception e) { Dialog.alert(e.toString()); } }

private class StopRecording extends MenuItem { public StopRecording() { super("Stop recording", 0, 100); } public void run() { try {

23


Recording video

Development Guide

if (_recorderThread != null) { _recorderThread.stop(); }

}

6.

}

} catch (Exception e) { Dialog.alert(e.toString()); }

Inside the VideoRecordingDemo screen class, define an inner class that extends Thread and implements PlayerListener. In the class, create a variable of type Player, and a variable of type RecordControl for recording media from Player. Note: You are not required to record video in a separate thread because recording operations are threaded by design. private class VideoRecorderThread extends Thread implements javax.microedition.media.PlayerListener { private Player _player; private RecordControl _recordControl; VideoRecorderThread() { } }

7.

In the VideoRecorderThread class, implement run(). In run() create a try/catch block and invoke Manager.createPlayer(String locator) to create a Player object to capture video, using as a parameter a value that specifies the encoding to use to record video. Only the encoding video/3gpp is currently supported. public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://video?encoding=video/3gpp");

}

24

} catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }


Recording video

Development Guide

8.

Invoke Player.addPlayerListener() specifying this as a parameter because VideoRecorderThread implements the PlayerListener interface. public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://video?encoding=video/3gpp"); _player.addPlayerListener(this);

}

9.

} catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

Invoke Player.realize() to access the Control object. Then , invoke Player.getControl() passing in the string, VideoControl, to retrieve the VideoControl object that is associated with Player. public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://video?encoding=video/3gpp"); _player.addPlayerListener(this); _player.realize(); VideoControl videoControl = (VideoControl) _player.getControl("VideoControl");

}

} catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

10. Invoke Player.getControl(), passing in the string, RecordControl, to retrieve the RecordControl object.

25


Recording video

Development Guide

public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://video?encoding=video/3gpp"); _player.addPlayerListener(this); _player.realize(); VideoControl videoControl = (VideoControl) _player.getControl("VideoControl"); _recordControl = (RecordControl) _player.getControl( "RecordControl" );

}

11.

} catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

Invoke VideoControl.initDisplayMode(int mode, Object arg) passing an arg parameter specifying the UI primitive that displays the video to initialize the mode that a video field uses. Cast the returned object as a Field object. Note: You can invoke initDisplayMode() in different ways to return a Field, an Item for use with MIDlets, or to display a video on a Canvas class. public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://video?encoding=video/3gpp"); _player.addPlayerListener(this); _player.realize(); VideoControl videoControl = (VideoControl) _player.getControl("VideoControl"); _recordControl = (RecordControl) _player.getControl( "RecordControl" ); Field videoField = (Field) videoControl.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); } catch( IOException e ) {

26


Recording video

Development Guide

}

Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

12. In a try/catch block, invoke VideoControl.setDisplaySize() to set the size of the viewfinder to monitor your recording. In the following code sample, the size is set to the full screen of the device. Invoke add() to add the viewfinder to the screen. public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://video?encoding=video/3gpp"); _player.addPlayerListener(this); _player.realize(); VideoControl videoControl = (VideoControl) _player.getControl("VideoControl"); _recordControl = (RecordControl) _player.getControl( "RecordControl" ); 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); } catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

13. Invoke RecordControl.setRecordLocation() to specify the location on the device to save the video recording.

27


Recording video

Development Guide

public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://video?encoding=video/3gpp"); _player.addPlayerListener(this); _player.realize(); VideoControl videoControl = (VideoControl) _player.getControl("VideoControl"); _recordControl = (RecordControl) _player.getControl( "RecordControl" ); 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); _recordControl.setRecordLocation("file:///store/home/user/ VideoRecordingTest .3gpp" ); } catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); } }

14. Invoke RecordControl.startRecord() to start recording the video and start playing the media from Player. Invoke Player.start() to start Player. public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://video?encoding=video/3gpp");

28


Recording video

Development Guide

_player.addPlayerListener(this); _player.realize(); VideoControl videoControl = (VideoControl) _player.getControl("VideoControl"); _recordControl = (RecordControl) _player.getControl( "RecordControl" ); 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); _recordControl.setRecordLocation("file:///store/home/user/ VideoRecordingTest .3gpp" ); _recordControl.startRecord(); _player.start();

}

} catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

15. In VideoRecorderThread, implement the Thread interface's stop() method. Check that Player is not null and invoke Player.close() to release the Player object's resources. Set the Player to null. public void stop() { if (_player != null) { _player.close(); _player = null; } }

29


Recording video

Development Guide

16. Check that RecordControl is not null and invoke RecordControl.stopRecord() to stop recording. In a try/ catch block, invoke RecordControl.commit() to save the recording to a specified file. Set RecordControl to null. public void stop() { if (_player != null) { _player.close(); _player = null; } if (_recordControl != null) { _recordControl.stopRecord(); try {

}

}

_recordControl.commit(); } catch (Exception e) { Dialog.alert(e.toString()); } _recordControl = null;

17. In VideoRecorderThread, implement the PlayerListener interface's playerUpdate() method which is invoked when the Player object generates an event. In the following code sample, information about the event is displayed. public void playerUpdate(Player player, String event, Object eventData) { Dialog.alert("Player " + player.hashCode() + " got event " + event + ": " + eventData); }

Code sample: Recording video to a file in a BlackBerry device application import import import import import import import import

net.rim.device.api.ui.*; net.rim.device.api.ui.container.*; net.rim.device.api.ui.component.*; net.rim.device.api.system.*; java.lang.*; javax.microedition.media.*; java.io.*; javax.microedition.media.control.*;

public class VideoRecordingDemo extends UiApplication {

30


Recording video

Development Guide

public static void main(String[] args) { VideoRecordingDemo app = new VideoRecordingDemo(); app.enterEventDispatcher(); } public VideoRecordingDemo() { pushScreen(new VideoRecordingDemoScreen()); } private class VideoRecordingDemoScreen extends MainScreen { private VideoRecorderThread _recorderThread; public VideoRecordingDemoScreen() { setTitle("Video recording demo");

}

addMenuItem(new StartRecording()); addMenuItem(new StopRecording());

private class StartRecording extends MenuItem { public StartRecording() { super("Start recording", 0, 100); } public void run() { try { VideoRecorderThread newRecorderThread = new VideoRecorderThread(); newRecorderThread.start(); _recorderThread = newRecorderThread; } catch (Exception e) { Dialog.alert(e.toString()); } } } private class StopRecording extends MenuItem { public StopRecording() { super("Stop recording", 0, 100); }

31


Recording video

Development Guide

}

public void run() { try { if (_recorderThread != null) { _recorderThread.stop(); } } catch (Exception e) { Dialog.alert(e.toString()); } }

private class VideoRecorderThread extends Thread implements javax.microedition.media.PlayerListener { private Player _player; private RecordControl _recordControl; VideoRecorderThread() { } public void run() { try { _player = javax.microedition.media.Manager .createPlayer("capture://video?encoding=video/3gpp"); _player.addPlayerListener(this); _player.realize(); VideoControl videoControl = (VideoControl) _player.getControl("VideoControl"); _recordControl = (RecordControl) _player.getControl( "RecordControl" ); 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 )

32


Recording video

Development Guide

{ }

// setDisplaySize is not supported

add(videoField); _recordControl .setRecordLocation("file:///store/home/user/VideoRecordingTest.3gpp" ); _recordControl.startRecord(); _player.start(); } catch( IOException e ) { Dialog.alert(e.toString()); } catch( MediaException e ) { Dialog.alert(e.toString()); }

} public void stop() { if (_player != null) { _player.close(); _player = null; }

if (_recordControl != null) { _recordControl.stopRecord(); try {

}

}

_recordControl.commit(); } catch (Exception e) { Dialog.alert(e.toString()); } _recordControl = null;

public void playerUpdate(Player player, String event, Object eventData) { Dialog.alert("Player " + player.hashCode() + " got event " + event + ": " + eventData); }

33


RIMM streaming video file

Development Guide

}

}

}

RIMM streaming video file The RIM proprietary video format (RIMM streaming file) consists of a header, a list of frames, and a footer. The file also contains a descriptor which stores additional metadata. The location of this descriptor depends on the recording destination. If the recording destination is a file, the descriptor is located at the end of the header, before the list of frames. If the recording destination is a stream, the descriptor is located after the list of frames in the footer.

RIM proprietary video format (RIMM streaming file) The RIM proprietary video format consists of a header, a list of frames, and a footer. When parsing this file, all values of type int or short are little-endian. Header Field

Value

Size

ID tag version descriptor location

RIMM 0

4B 3B 1B

descriptor

descriptor values

• •

Field

Value

Size

stream type

• •

0 if this is a frame of audio 1 if this is a frame of video

1B

key frame

• •

1 if this is a key frame 0 otherwise

1b

config frame

• •

1 if this is a config frame 0 otherwise

1b

• •

0 if recording to a file 1 if recording to a stream

Frames

34

75 B if recording to a file 0 B if recording to a stream


RIMM streaming video file

Development Guide

Field

Value

Size

size duration data stream type

frame size, in bytes length of video, in milliseconds the actual frame data • •

0 if this is a frame of audio 1 if this is a frame of video

30 b 2B <size> B 1B

key frame

• •

1 if this is a key frame 0 otherwise

1b

config frame

• •

1 if this is a config frame 0 otherwise

1b

size duration

frame size, in bytes length of video, in milliseconds

30 b 2B

Note: The key frame, config frame, and size fields are stored in one 32-bit int with the key frame and config frame fields stored in the first two bits. Footer Field

Value

Size

Descriptor

descriptor values

• •

75 bytes if recording to a stream 0 bytes if recording to a file

Descriptor Field

Value

Size

audio frames video frames audio key frames video key frames audio frame rates

number of audio frames number of video frames number of audio key frames number of video key frames number of audio frame rates (number of frame rate changes + 1) number of video frame rates (number of frame rate changes + 1) size of audio stream in bytes size of video stream in bytes

4B 4B 4B 4B 4B

video frame rates audio size video size

4B 4B 4B

35


RIMM streaming video file

Development Guide

Field

Value

Size

video frame rate video max frame size audio duration video duration RESERVED width height video codec

the initial video frame rate, in frames per second size of largest video frame, in bytes length of audio stream, in milliseconds length of video stream, in milliseconds undefined the width of the video, in pixels the height of the video, in pixels • • •

2 if this video codec is mpeg4 5 if this video codec is H.263 6 if this video codec is H.264

4B 4B 4B 4B 20 B 2B 2B 2B

audio codec

• • •

0 if this audio codec is PCM 7 if this audio codec is AMR 0xA if this audio codec is AAC

1B

Code sample: Parsing a RIMM streaming video file import import import import

java.io.*; java.util.*; javax.microedition.io.*; javax.microedition.io.file.*;

/** * */ public class KeyFrameOutputStream extends OutputStream { // output locations on the sd card private static final String OUT_DIR = "file:///SDCard/securitycam/"; private static final String OUT_FILE = "output.frames"; // some size constants private static final int HEADER_SIZE = 8; private static final int CHUNK_INFO_SIZE = 7; // parsing states private static final private static final private static final private static final // member variables private int _state;

36

int int int int

STATE_HEADER STATE_CHUNK_INFO STATE_DATA STATE_WAIT_FOR_NEXT

= = = =

0; 1; 2; 3;


RIMM streaming video file

Development Guide

private private private private private private private private

int _pos; boolean _isVideoFrame; boolean _isKeyFrame; boolean _isConfigFrame; boolean _startSaving; boolean _saveFrame; int _dataSize; int _duration;

// temp buffer ref private byte[] _buf; private FileConnection _file; private OutputStream _out; private WriteThread _writer; private boolean _reading; public KeyFrameOutputStream() { _state = STATE_HEADER; _pos = 0; } public void open() { _reading = true; try { // create the file connection for our frame destination FileConnection dir = (FileConnection)Connector.open( OUT_DIR ); if( !dir.exists() ) { dir.mkdir(); } dir.close(); _file = (FileConnection)Connector.open( OUT_DIR + OUT_FILE ); if( !_file.exists() ) { _file.create(); } else { _file.truncate( 0L ); } _out = _file.openOutputStream(); } catch ( Exception e ) { }

}

// start the write thread _writer = new WriteThread( _out ); _writer.start();

public void startClosing() { // shuts down the write thread _reading = false; if( _writer != null ) _writer.stop();

37


RIMM streaming video file

Development Guide

} public void write( int b ) throws IOException { if( _reading ) { switch( _state ) { case STATE_HEADER: // read the video stream header _pos++; if( _pos == HEADER_SIZE ) { _state = STATE_CHUNK_INFO; _buf = new byte[CHUNK_INFO_SIZE]; _pos = 0; } break; case STATE_CHUNK_INFO: // parse the information about the next chunk _buf[_pos] = (byte)b; _pos++; if( _pos == CHUNK_INFO_SIZE ) { // 1 indicates video frame, 0 indicates audio _isVideoFrame = (_buf[0] != 0); //

// key frame and config frame flags are in the top two bits of the data size value _isKeyFrame = ((_buf[4] & 0x80) != 0); _isConfigFrame = ((_buf[4] & 0x40) != 0); _dataSize = ((int)(_buf[4] & 0x3f) << 24) | ((int)(_buf[3] & 0xff) << 16) | ((int)(_buf[2] & 0xff) << 8) | ((int)(_buf[1] & 0xff)); // duration is stored in the next two bytes _duration = ((int)(_buf[6] & 0xff) << 8) | ((int)(_buf[5] & 0xff));

//

output file

// we want the config frame to be the first frame in our if( !_startSaving ) { if( _isVideoFrame && _isConfigFrame ) { _startSaving = true; } }

// after that only save the key frames _saveFrame = _startSaving && _isVideoFrame && ( _isConfigFrame || _isKeyFrame ); _state = STATE_DATA; if( _saveFrame ) { _buf = new byte[_dataSize]; } _pos = 0;

38


RIMM streaming video file

Development Guide

}

}

}

} break; case STATE_DATA: // buffer the frame for writing to file if( _saveFrame ) _buf[_pos] = (byte)b; _pos++; if( _pos == _dataSize ) { if( _saveFrame ) { _writer.addFrame( _buf ); } _state = STATE_WAIT_FOR_NEXT; _buf = new byte[CHUNK_INFO_SIZE]; _pos = 0; } break; case STATE_WAIT_FOR_NEXT: // skip over the chunk footer _pos++; if( _pos == CHUNK_INFO_SIZE ) { _state = STATE_CHUNK_INFO; _buf = new byte[CHUNK_INFO_SIZE]; _pos = 0; } break;

public void close() throws IOException { // shut down the write thread and close our file try { _writer.join(); } catch ( InterruptedException ie ) { } _out.close(); _file.close(); } private static final class WriteThread extends Thread { // writes key frames to a file as they are found by our parser private Vector _frames; private boolean _running; private OutputStream _out; public WriteThread( OutputStream out ) { _frames = new Vector(); _running = true; _out = out; } public void run() { for( ;; ) {

39


RIMM streaming video file

Development Guide

ByteArray frame = null; synchronized( this ) { if( _frames.size() > 0 ) { frame = (ByteArray)_frames.elementAt( 0 ); if( frame == null ) break; _frames.removeElementAt( 0 ); } else { if( !_running ) break; try { wait(); if( _running ) continue; } catch ( InterruptedException ie ) { } } } if( frame == null ) break;

}

}

try { byte[] bytes = frame.array; _out.write( bytes, 0, bytes.length ); _out.flush(); } catch ( Exception e ) { }

public synchronized void addFrame( byte[] frame ) { _frames.addElement( new ByteArray( frame ) ); notifyAll(); }

}

}

40

public synchronized void stop() { _running = false; notifyAll(); }

private static final class ByteArray { public byte[] array; public ByteArray( byte[] array ) { this.array = array; } }


Working with pictures on a BlackBerry device

Development Guide

Working with pictures on a BlackBerry device

3

Taking pictures You can take a picture on a BlackBerry速 device by using the javax.microedition.media.Player class and the associated VideoControl interface in your BlackBerry device application. When you create an instance of the Player class, you can specify the appropriate file encoding and resolution of the picture. You can invoke VideoControl.getSnapshot() to take the picture. The image is returned as a byte array (the unprocessed image), which you can display on the device, save to a file, or process as required. To create a viewfinder to monitor the picture the camera is taking, you can invoke VideoControl.initDisplay() to retrieve a Field object that is added to your UI.

Take a picture in a BlackBerry device application 1.

Import the required classes and interfaces. import import import import

net.rim.device.api.amms.control.camera.*; net.rim.device.api.ui.*; net.rim.device.api.ui.component.*; net.rim.device.api.ui.container.*;

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

2.

Create the application framework by extending the UiApplication class. In main(), create an instance of the new class and invoke enterEventDispatcher() to enable the application to receive events. In the application constructor, invoke pushScreen() to display the custom screen for the application. The ImageCaptureDemoScreen class, which is described in step 3, represents the custom screen. public class ImageCaptureDemo extends UiApplication { public static void main(String[] args) { ImageCaptureDemo app = new ImageCaptureDemo(); app.enterEventDispatcher(); }

}

public ImageCaptureDemo() { pushScreen(new ImageCaptureDemoScreen()); }

41


Development Guide

3.

Taking pictures

Create the framework for the custom screen by extending the MainScreen class. Declare class variables for the Player and VideoControl classes that you create in the screen's constructor, which is described in step 4. class ImageCaptureDemoScreen extends MainScreen { Player _p; VideoControl _videoControl;

}

4.

public ImageCaptureDemoScreen() { }

In the screen constructor, initialize the camera. In a try/catch block, create an instance of the Player class by invoking Manager.createPlayer(String), passing in the encoding parameter. The jpeg and image/jpeg parameters are supported. If you do not specify the encoding parameter, by default the encoding parameter is image/jpeg. try {

_p = javax.microedition.media.Manager .createPlayer("capture://video?encoding=jpeg&width=1024&height=768");

} catch(Exception e) { Dialog.alert(e.toString()); }

5.

To control an aspect of taking the picture, retrieve the appropriate Control object. Invoke the Player object's realize () method to access the associated Control object. Next, invoke Player.getControl() to retrieve the Player object's VideoControl. try {

_p = javax.microedition.media.Manager .createPlayer("capture://video?encoding=jpeg&width=1024&height=768"); _p.realize(); _videoControl = (VideoControl) _p.getControl("VideoControl");

} catch(Exception e) { Dialog.alert(e.toString()); }

6.

42

Create a viewfinder in your application by invoking VideoControl.initDisplayMode(int mode, Object arg) and passing in a parameter specifying the UI primitive that displays the picture to initialize the mode that a video field uses. Cast the returned object as a Field object. Invoke VideoControl.setDisplayFullScreen() passing in true to set the viewfinder to take up the full screen of the device. Invoke VideoControl.setVisible() passing in true to display the viewfinder.


Taking pictures

Development Guide

try {

_p = javax.microedition.media.Manager .createPlayer("capture://video?encoding=jpeg&width=1024&height=768"); _p.realize(); _videoControl = (VideoControl) _p.getControl("VideoControl"); if (videoControl != null) { Field videoField = (Field) _videoControl.initDisplayMode (VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); _videoControl.setDisplayFullScreen(true); _videoControl.setVisible(true); }

} catch(Exception e) { Dialog.alert(e.toString()); }

7.

Invoke Player.start() to set the player to the STARTED state. try {

_p = javax.microedition.media.Manager .createPlayer("capture://video?encoding=jpeg&width=1024&height=768"); _p.realize(); _videoControl = (VideoControl) _p.getControl("VideoControl"); if (videoControl != null) { Field videoField = (Field) _videoControl.initDisplayMode (VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); _videoControl.setDisplayFullScreen(true); _videoControl.setVisible(true); }

_p.start();

} catch(Exception e) { Dialog.alert(e.toString()); }

8.

To enable autofocus for the camera, invoke Player.getContol() to retrieve the Player object's EnhancedFocusControl interface. Iinvoke EnhancedFocusControl.startAutoFocus(). try {

_p = javax.microedition.media.Manager

43


Taking pictures

Development Guide

.createPlayer("capture://video?encoding=jpeg&width=1024&height=768"); _p.realize(); _videoControl = (VideoControl) _p.getControl("VideoControl"); if (videoControl != null) { Field videoField = (Field) _videoControl.initDisplayMode (VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); _videoControl.setDisplayFullScreen(true); _videoControl.setVisible(true); _p.start(); EnhancedFocusControl efc = (EnhancedFocusControl)p.getControl("net.rim.device.api.amms.control.camera .EnhancedFocusControl"); efc.startAutoFocus(); }

} catch(Exception e) { Dialog.alert(e.toString()); }

9.

Check that videoField is not null and invoke add() to add the viewfinder to the screen. try {

_p = javax.microedition.media.Manager .createPlayer("capture://video?encoding=jpeg&width=1024&height=768"); _p.realize(); _videoControl = (VideoControl) _p.getControl("VideoControl"); if (videoControl != null) { Field videoField = (Field) _videoControl.initDisplayMode (VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); _videoControl.setDisplayFullScreen(true); _videoControl.setVisible(true); _p.start(); EnhancedFocusControl efc = (EnhancedFocusControl)p.getControl("net.rim.device.api.amms.control.camera .EnhancedFocusControl"); efc.startAutoFocus();

}

44

if(videoField != null) { add(videoField); }


Taking pictures

Development Guide

} catch(Exception e) { Dialog.alert(e.toString()); }

10. In ImageCaptureDemoScreen, invoke net.rim.device.api.ui.Screen.invokeAction(). This implementation takes the picture when the user clicks the trackpad, trackball, or touch screen. Return a boolean specifying if the action is consumed. protected boolean invokeAction(int action) { boolean handled = super.invokeAction(action); if(!handled) { if(action == ACTION_INVOKE) { } }

11.

}

return handled;

In the if(action == ACTION_INVOKE) statement, in a try/catch block, invoke VideoControl.getSnapshot () to take the picture, passing in null to use the encoding setting that you specified in step 4. The image is returned as a byte array. protected boolean invokeAction(int action) { boolean handled = super.invokeAction(action);

}

if(!handled) { if(action == ACTION_INVOKE) { try { byte[] rawImage = _videoControl.getSnapshot(null); } catch(Exception e) { Dialog.alert(e.toString()); } } } return handled;

45


Taking pictures

Development Guide

Code sample: Taking a picture in a BlackBerry device application import import import import import import

net.rim.device.api.ui.*; net.rim.device.api.ui.container.*; net.rim.device.api.ui.component.*; net.rim.device.api.amms.control.camera.*; javax.microedition.media.*; javax.microedition.media.control.*;

public class ImageCaptureDemo extends UiApplication { public static void main(String[] args) { ImageCaptureDemo app = new ImageCaptureDemo(); app.enterEventDispatcher(); } public ImageCaptureDemo() { pushScreen(new ImageCaptureDemoScreen()); } class ImageCaptureDemoScreen extends MainScreen { Player _p; VideoControl _videoControl; public ImageCaptureDemoScreen() { try { _p = javax.microedition.media.Manager .createPlayer("capture://video?encoding=jpeg&width=1024&height=768"); _p.realize(); _videoControl = (VideoControl) _p.getControl("VideoControl"); if (videoControl != null) { Field videoField = (Field) _videoControl.initDisplayMode (VideoControl.USE_GUI_PRIMITIVE, "net.rim.device.api.ui.Field"); _videoControl.setDisplayFullScreen(true); _videoControl.setVisible(true); _p.start(); EnhancedFocusControl efc = (EnhancedFocusControl)p.getControl("net.rim.device.api.amms.control.camera .EnhancedFocusControl"); efc.startAutoFocus(); if(videoField != null)

46


Taking pictures

Development Guide

{ }

}

add(videoField);

} } catch(Exception e) { Dialog.alert(e.toString()); }

protected boolean invokeAction(int action) { boolean handled = super.invokeAction(action);

}

}

}

if(!handled) { if(action == ACTION_INVOKE) { try { byte[] rawImage = _videoControl.getSnapshot(null); } catch(Exception e); { Dialog.alert(e.toString()); } } } return handled;

47


Development Guide

Find more information • • • • •

48

Find more information

4

www.blackberry.com/go/apiref: View the latest version of the API reference for the BlackBerry® Java® SDK. www.blackberry.com/go/devguides: Find development guides, release notes, and sample application overviews for the BlackBerry Java SDK. www.blackberry.com/developers: Visit the BlackBerry® Developer Zone for resources on developing BlackBerry device applications. www.blackberry.com/go/developerkb: View knowledge base articles on the BlackBerry Development Knowledge Base. www.blackberry.com/developers/downloads: Find the latest development tools and downloads for developing BlackBerry device applications.


Development Guide

Provide feedback

Provide feedback

5

To provide feedback on this deliverable, visit www.blackberry.com/docsfeedback.

49


Document revision history

Development Guide

Document revision history Date

Description

25 October 2010

Changed code samples in the topics: • •

3 August 2010

Record video to a file in a BlackBerry device application Recording video to a file in a BlackBerry device application

Moved the following topics to the BlackBerry® Java® SDK UI and Navigation Development Guide: • • • • • • • • • • • •

50

6

Access an encoded image through an input stream Code sample: Displaying a row of images for scrolling Code sample: Displaying an image for zooming and panning Display a row of images for scrolling Display an encoded image Display an image for zooming and panning Displaying a row of images for scrolling Displaying an image for zooming and panning Encode an image Specify the decoding mode for an image Specify the display size of an encoded image Using encoded images


Development Guide

Legal notice

Legal notice

7

息2010 Research In Motion Limited. All rights reserved. BlackBerry速, RIM速, Research In Motion速, and related trademarks, names, and logos are the property of Research In Motion Limited and are registered and/or used in the U.S. and countries around the world. Bluetooth is a trademark of Bluetooth SIG. Java and Javadoc are trademarks of Oracle America, Inc. Plazmic is a trademark of Plazmic Inc. All other trademarks are the property of their respective owners. This documentation including all documentation incorporated by reference herein such as documentation provided or made available at www.blackberry.com/go/docs is provided or made accessible "AS IS" and "AS AVAILABLE" and without condition, endorsement, guarantee, representation, or warranty of any kind by Research In Motion Limited and its affiliated companies ("RIM") and RIM assumes no responsibility for any typographical, technical, or other inaccuracies, errors, or omissions in this documentation. In order to protect RIM proprietary and confidential information and/or trade secrets, this documentation may describe some aspects of RIM technology in generalized terms. RIM reserves the right to periodically change information that is contained in this documentation; however, RIM makes no commitment to provide any such changes, updates, enhancements, or other additions to this documentation to you in a timely manner or at all. This documentation might contain references to third-party sources of information, hardware or software, products or services including components and content such as content protected by copyright and/or third-party web sites (collectively the "Third Party Products and Services"). RIM does not control, and is not responsible for, any Third Party Products and Services including, without limitation the content, accuracy, copyright compliance, compatibility, performance, trustworthiness, legality, decency, links, or any other aspect of Third Party Products and Services. The inclusion of a reference to Third Party Products and Services in this documentation does not imply endorsement by RIM of the Third Party Products and Services or the third party in any way. EXCEPT TO THE EXTENT SPECIFICALLY PROHIBITED BY APPLICABLE LAW IN YOUR JURISDICTION, ALL CONDITIONS, ENDORSEMENTS, GUARANTEES, REPRESENTATIONS, OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY CONDITIONS, ENDORSEMENTS, GUARANTEES, REPRESENTATIONS OR WARRANTIES OF DURABILITY, FITNESS FOR A PARTICULAR PURPOSE OR USE, MERCHANTABILITY, MERCHANTABLE QUALITY, NONINFRINGEMENT, SATISFACTORY QUALITY, OR TITLE, OR ARISING FROM A STATUTE OR CUSTOM OR A COURSE OF DEALING OR USAGE OF TRADE, OR RELATED TO THE DOCUMENTATION OR ITS USE, OR PERFORMANCE OR NON-PERFORMANCE OF ANY SOFTWARE, HARDWARE, SERVICE, OR ANY THIRD PARTY PRODUCTS AND SERVICES REFERENCED HEREIN, ARE HEREBY EXCLUDED. YOU MAY ALSO HAVE OTHER RIGHTS THAT VARY BY STATE OR PROVINCE. SOME JURISDICTIONS MAY NOT ALLOW THE EXCLUSION OR LIMITATION OF IMPLIED WARRANTIES AND CONDITIONS. TO THE EXTENT PERMITTED BY LAW, ANY IMPLIED WARRANTIES OR CONDITIONS RELATING TO THE DOCUMENTATION TO THE EXTENT THEY CANNOT BE EXCLUDED AS SET OUT ABOVE, BUT CAN BE LIMITED, ARE HEREBY LIMITED TO NINETY (90) DAYS FROM THE DATE YOU FIRST ACQUIRED THE DOCUMENTATION OR THE ITEM THAT IS THE SUBJECT OF THE CLAIM. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW IN YOUR JURISDICTION, IN NO EVENT SHALL RIM BE LIABLE FOR ANY TYPE OF DAMAGES RELATED TO THIS DOCUMENTATION OR ITS USE, OR PERFORMANCE OR NONPERFORMANCE OF ANY SOFTWARE, HARDWARE, SERVICE, OR ANY THIRD PARTY PRODUCTS AND SERVICES REFERENCED HEREIN INCLUDING WITHOUT LIMITATION ANY OF THE FOLLOWING DAMAGES: DIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, INDIRECT, SPECIAL, PUNITIVE, OR AGGRAVATED DAMAGES, DAMAGES FOR LOSS OF PROFITS OR REVENUES, FAILURE TO REALIZE ANY EXPECTED SAVINGS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, LOSS OF

51


Development Guide

Legal notice

BUSINESS OPPORTUNITY, OR CORRUPTION OR LOSS OF DATA, FAILURES TO TRANSMIT OR RECEIVE ANY DATA, PROBLEMS ASSOCIATED WITH ANY APPLICATIONS USED IN CONJUNCTION WITH RIM PRODUCTS OR SERVICES, DOWNTIME COSTS, LOSS OF THE USE OF RIM PRODUCTS OR SERVICES OR ANY PORTION THEREOF OR OF ANY AIRTIME SERVICES, COST OF SUBSTITUTE GOODS, COSTS OF COVER, FACILITIES OR SERVICES, COST OF CAPITAL, OR OTHER SIMILAR PECUNIARY LOSSES, WHETHER OR NOT SUCH DAMAGES WERE FORESEEN OR UNFORESEEN, AND EVEN IF RIM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW IN YOUR JURISDICTION, RIM SHALL HAVE NO OTHER OBLIGATION, DUTY, OR LIABILITY WHATSOEVER IN CONTRACT, TORT, OR OTHERWISE TO YOU INCLUDING ANY LIABILITY FOR NEGLIGENCE OR STRICT LIABILITY. THE LIMITATIONS, EXCLUSIONS, AND DISCLAIMERS HEREIN SHALL APPLY: (A) IRRESPECTIVE OF THE NATURE OF THE CAUSE OF ACTION, DEMAND, OR ACTION BY YOU INCLUDING BUT NOT LIMITED TO BREACH OF CONTRACT, NEGLIGENCE, TORT, STRICT LIABILITY OR ANY OTHER LEGAL THEORY AND SHALL SURVIVE A FUNDAMENTAL BREACH OR BREACHES OR THE FAILURE OF THE ESSENTIAL PURPOSE OF THIS AGREEMENT OR OF ANY REMEDY CONTAINED HEREIN; AND (B) TO RIM AND ITS AFFILIATED COMPANIES, THEIR SUCCESSORS, ASSIGNS, AGENTS, SUPPLIERS (INCLUDING AIRTIME SERVICE PROVIDERS), AUTHORIZED RIM DISTRIBUTORS (ALSO INCLUDING AIRTIME SERVICE PROVIDERS) AND THEIR RESPECTIVE DIRECTORS, EMPLOYEES, AND INDEPENDENT CONTRACTORS. IN ADDITION TO THE LIMITATIONS AND EXCLUSIONS SET OUT ABOVE, IN NO EVENT SHALL ANY DIRECTOR, EMPLOYEE, AGENT, DISTRIBUTOR, SUPPLIER, INDEPENDENT CONTRACTOR OF RIM OR ANY AFFILIATES OF RIM HAVE ANY LIABILITY ARISING FROM OR RELATED TO THE DOCUMENTATION. Prior to subscribing for, installing, or using any Third Party Products and Services, it is your responsibility to ensure that your airtime service provider has agreed to support all of their features. Some airtime service providers might not offer Internet browsing functionality with a subscription to the BlackBerry速 Internet Service. Check with your service provider for availability, roaming arrangements, service plans and features. Installation or use of Third Party Products and Services with RIM's products and services may require one or more patent, trademark, copyright, or other licenses in order to avoid infringement or violation of third party rights. You are solely responsible for determining whether to use Third Party Products and Services and if any third party licenses are required to do so. If required you are responsible for acquiring them. You should not install or use Third Party Products and Services until all necessary licenses have been acquired. Any Third Party Products and Services that are provided with RIM's products and services are provided as a convenience to you and are provided "AS IS" with no express or implied conditions, endorsements, guarantees, representations, or warranties of any kind by RIM and RIM assumes no liability whatsoever, in relation thereto. Your use of Third Party Products and Services shall be governed by and subject to you agreeing to the terms of separate licenses and other agreements applicable thereto with third parties, except to the extent expressly covered by a license or other agreement with RIM. Certain features outlined in this documentation require a minimum version of BlackBerry速 Enterprise Server, BlackBerry速 Desktop Software, and/or BlackBerry速 Device Software. The terms of use of any RIM product or service are set out in a separate license or other agreement with RIM applicable thereto. NOTHING IN THIS DOCUMENTATION IS INTENDED TO SUPERSEDE ANY EXPRESS WRITTEN AGREEMENTS OR WARRANTIES PROVIDED BY RIM FOR PORTIONS OF ANY RIM PRODUCT OR SERVICE OTHER THAN THIS DOCUMENTATION.

Research In Motion Limited 295 Phillip Street

52


Development Guide

Legal notice

Waterloo, ON N2L 3W8 Canada Research In Motion UK Limited Centrum House 36 Station Road Egham, Surrey TW20 9LF United Kingdom Published in Canada

53

BlackBerry_Java_SDK-Development_Guide--1249411-0803110230-001-6.0-US  

Development Guide Version: 6.0 Published: 2010-11-1 SWD-1249411-1101032433-001 6 Document revision history.....................................

Read more
Read more
Similar to
Popular now
Just for you