Browse DevX
Sign up for e-mail newsletters from DevX


Exploring the J2ME Mobile Media APIs : Page 2

The Mobile Media APIs provide a rich and extensible framework for playing and capturing a wide variety of media on mobile devices. Find out how to add sizzle to your application using these features.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Mobile Media Basics
So now that I've covered how the Mobile Media APIs may find their way onto devices, I'll dig into what the APIs are composed of and what developers can do with them. Regardless of whether you are using MIDP 2.0 features or the more advanced features of the Mobile Media API specification, the basic behavior and functionality for controlling media is the same. The media framework comprises the following participants:
  • Manager
  • Player
  • Control

The Manager class is a factory used to create Players. Player itself is an interface. The underlying implementation of a player is specific to the content type being requested. For example, if the requested media is in audio WAV format, a WAV Player implementation is returned to handle the content. If the media format is MPEG, a different Player is returned to handle the specifics of MPEG media.

Once a Player is created, an application can request Control objects that encapsulate behaviors to control the media playback, capture, and so forth. The Control objects available vary depending on the media supported by the player. Figure 1 shows how the Manager, Player, and Control classes relate.

Figure 1. Manager, Player, Control: Relationship of the framework classes and interfaces used to manage multimedia using the Mobile Media APIs.

Simple Audio Playback Example
Before delving into more concepts on controlling media I'll write some code that makes use of the core framework. The following example uses the Manager to create a Player that handles WAV audio format. The Manager.createPlayer() method determines the type of player to return by parsing the media locator string passed as a parameter. In this case, the player must read the WAV media using the HTTP network protocol. Once the Player instance is created, Player.start() is called to play the media on the device.

try { String wav = "http://java.sun.com/products/java"+ "media/mma/media/test-wav.wav"; Player p = Manager.createPlayer(wav); p.start(); } catch (IOException x) { x.printStackTrace(); } catch (MediaException x) { x.printStackTrace(); }

Player Lifecycle
Regardless of the protocol or media type involved, the Player moves through the same discrete states during its lifecycle. These states are listed in Table 3.

Table 3. Lifecycle states of a Player instance.




Initial state when a Player is created. In this state the player does not have enough information to acquire the necessary resources to process the media.


The Player moves into the Realized state once it has obtained the necessary information to acquire the resources. In this state it is likely that most of the resources have already been acquired to function. However, some resources may not have been acquired at this point, especially if there are system dependencies involved such as with an audio or video driver where exclusive access must be obtained.


The Player moves into the Prefetched state once all resources have been acquired, including scarce and system dependent resources. Once in the Prefetched state, the Player has everything necessary to perform its tasks.


A Player in the Started state indicates that the content associated with the Player is being processed.


A Player moves to the Closed state at the end of its lifecycle. A Player in the Closed state must not be used again.

The Player interface contains methods to explicitly move the Player through these various lifecycle states. However, in some cases, it is not necessary to call each one explicitly. In the previous code example, the player was created using Manager.createPlayer(), putting the player into the Unrealized state. The next line of code called Player.start(), which implicitly moved the player through the Realized and Prefetched states. The lifecycle methods of the Player interface are described in Table 4.

Table 4. Lifecycle methods of the Player interface.




Explicitly moves the player from the Unrealized state to the Realized state.


Explicitly moves the player from the Realized state to the Prefetched state.


Tells the player to start processing the media. Moves the Player to the Started state.


Tells a player in the Started state to pause. Moves the state of the player from Started to Prefetched.


Moves a player to the Closed state. This method may be called from the any of the other states.


Tells the player to release scares or exclusive resources (the types of resources usually acquired by a call to prefetch()).

Many of the Player methods listed in Table 4 are valid only when the player is in certain states. For example, calling stop() when the player is in the Realized state makes no sense. In some cases, the method call may be ignored; in other cases an IllegalStateException is thrown. State changes can be monitored by adding a PlayerListener to a player. A PlayerListener will receive state changes events as the Player moves through its lifecycle. Figure 2 shows a state diagram of the Player lifecycle.

Figure 2. Life of a Player: The State diagram below shows the Player lifecycle.
Figure 2. State diagram of the Player lifecycle.

More Media Examples
There are a number of ways to interact with the player and media. The following examples demonstrate some of these options.

Media can be stored as a resource within the JAR file. To access media bundled into the JAR file do something like the following:

InputStream is = getClass().getResourceAsStream("mymusic.mp3"); Player p = Manager.createPlayer(is, "audio/mpeg"); p.start();

Media can also be stored in a RecordStore and accessed by doing something like this:

InputStream is = new ByteArrayInputStream( myRecordStore.getRecord(id)); Player player = Manager.createPlayer( is, "audio/mpeg"); player.start();

Simple tone generation is also possible. The Manager class provides a convenience method Manager.playTone() that generates tones without needing to explicitly create a Player. This method takes three parameters: the note, which is an integer from 0 to 127, a duration in milliseconds for how long the tone should be generated, and the volume to use when generating the tone. The following example generates a sequence of random notes.

for(int ccnt=0; ccnt < 100; ccnt++){ int note = (int) (System.currentTimeMillis() % 127); Manager.playTone(note, 100, 100); //let the clock move ahead a bit Thread.currentThread().sleep(1); }

Thanks for your registration, follow us on our social networks to keep up-to-date