Friday, September 20, 2024

Exploring the J2ME Mobile Media APIs

As J2ME gains prominence, the range of things that developers can do with Java on devices is expanding. This month I’ll cover the Mobile Media API (JSR-135), which is an optional J2ME package. The Mobile Media APIs enable the playing and recording of audio, taking pictures and playing videos, and other things.

The Mobile Media APIs find their way onto devices through several different means. They are designed to be compatible with both the CDC and CLDC configurations, which makes them available to any J2ME device regardless of whether the application profile is MIDP, Personal Profile, or PDA Profile. The Mobile Media APIs are also included as part of the Java Technology for the Wireless Industry (JTWI) specification (JSR-185), which serves to unify a number of related specifications around MIDP 2.0.

In either case the Mobile Media APIs are optional. A device can become JTWI-certified without support for the Mobile Media APIs. Furthermore, a device may choose to support a subset of the Mobile Media API capabilities.

What Optional Means in the Mobile Media APIs

The optional nature of the Mobile Media APIs is based on the reality that different devices have different needs and capabilities. It is unrealistic to require every device to support the entire Mobile Media API specification. Allowing many of the Mobile Media features to be optional allows implementers to better support the features that make sense. However, if a device supports a multimedia feature, such as audio capture, the implementation must follow the Mobile Media API specification. For application developers this means that although multimedia support will vary between devices, if a feature is supported it will be done in a standard way.

Mobile Media APIs and MIDP 2.0

There is a strong relationship between the Mobile Media API specification and the MIDP 2.0 specification. This is to provide compatibility between the media capabilities of MIDP 2.0 devices and devices that include the more advanced capabilities of the Mobile Media APIs. MIDP 2.0 contains a direct subset of the Mobile Media APIs in order to provide capabilities such as audio playback and tone generation. Table 1 lists features of the Mobile Media APIs included by MIDP 2.0.

Table 1. Subset of Mobile Media APIs included in MIDP 2.0.

The Mobile Media API specification expands on the MIDP 2.0 subset to include features listed in Table 2.

Table 2. Mobile Media API features that expand on features also defined in MIDP 2.0.

The relationship of the Mobile Media APIs and MIDP 2.0 is unique in that other application specifications, such as the Personal Profile, do not include a subset of Mobile Media capabilities.

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 {
    &nbsp String wav = "http://java.sun.com/products/java"+
    &nbsp "media/mma/media/test-wav.wav";
    &nbsp Player p = Manager.createPlayer(wav);
    &nbsp p.start();
    &nbsp} catch (IOException x) {
    &nbsp x.printStackTrace();
    &nbsp} catch (MediaException x) {
    &nbsp 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.

    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.

    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. State diagram of the Player lifecycle.


    Figure 2. Life of a Player: The State diagram below shows 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 =
    &nbsp 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 =
    &nbsp new ByteArrayInputStream(
    &nbsp myRecordStore.getRecord(id));
    Player player = Manager.createPlayer(
    &nbsp 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

    Adding Control

    Up to this point I've focused mostly on the Player and Manager. However, for each type of media there may be capabilities for controlling the flow and behavior of how the content is processed. To provide more content-specific behaviors players can make use of the Control interface. For example, if the media is a video, there may be a need to control the size of the display. Or, if an application is capturing audio there is a need to start recording and pipe the input to memory or a RecordStore. Control instances can be obtained by making a call to the factor method Player.getControl() and passing in a control type. The control type parameter is the class name of the control to be created. If the control type parameter is not a fully qualified class name, the package javax.microedition.medial.control is assumed.

    There are two standard controls defined as part of the MIDP 2.0 Mobile Media subset: ToneControl, which used to define a sequence of tones, and VolumeControl, which can be used to control the volume as the media is processed. Within the Mobile Media APIs, many more Control interfaces are defined, such as VideoControl, TempoControl, RecordControl, and MIDIControl just to name a few. Implementers can also provide additional controls as needed.

    Playing More Complex Media

    Playing audio can be fun, but it's pretty basic. So far, all the code examples shown are supported within the MIDP 2.0 specification. Now I'll show you something only the Mobile Media API specification can provide. The next example demonstrates how to play video on a device. For the most part, showing video is similar to audio playback. The primary difference is that you need something to display the video on. This is where the Control interface comes into play.

    String url = "http://java.sun.com /"+
    &nbsp "products/java-media/mma/media/test-mpeg.mpg";
    Player p = Manager.createPlayer(url);
    p.realize();//must do this before getting the control

    //get the video controller
    VideoControl video = (VideoControl) p.getControl("VideoControl");

    //get a GUI to display the video
    Item videoItem = (Item)video.initDisplayMode(
    &nbsp VideoControl.USE_GUI_PRIMITIVE, null);

    //append the GUI to a form
    videoForm.append(videoItem);

    //start the video
    p.start();

    This code retrieves an MPG video using HTTP, obtains an Item from the VideoControl that can be place onto a Form, and runs the video.
    The Mobile Media APIs provide a rich and extensible framework for playing and capturing media content on mobile devices. I am only able to skim the surface in this article; however, there are interfaces and protocols defined for doing a lot of interesting things in your applications such as real-time streaming of Internet radio content, streaming other RTP (Real-time Transport Protocol) content, capturing audio, and taking pictures. However, an application can only do these things if the underlying content types and protocols are supported. To find out what is supported on a device, the Mobile Media APIs provide some query mechanisms to help developers discover capabilities and limitations of a device.

    Knowing What Is Available

    Let's face it: While the flexibility and power provided by the Mobile Media API is exciting, this excitement is tempered by the realization that support for Mobile Media features is likely to vary from one device to another. Even applications that support media only within the MIDP 2.0 specification must be able to adapt to the absence of certain media features and capabilities. For example, while audio playback may be supported, an application cannot assume that a device supports WAV, MP3, and AU formats. The specification does not require any specific audio formats. Furthermore, an application cannot assume that just because WAV format is supported that HTTP can be used to stream or download the content.

    To address these problems applications can gain insight to the supported capabilities of a device by querying a couple of methods on the Manager class:

  • getSupportedContentTypes(), which accepts a protocol identifier, such as "http" and returns a list of content types supported by this protocol.
  • getSupportedProtocols(), which accepts a content type identifier, such as "audio/mpeg" and returns a list of protocols (such as http) supporting this content type.
  • In addition to the content and protocol support, there are other multimedia landmines to avoid. For example, the methods above may indicate WAV format is supported through HTTP, but can the device play 16-bit sound samples recorded at 44100 Hz? To gain insight to some of these details a few calls to System.getProperty() may be necessary. Table 5 lists some of the properties available.

    Table 5. Mobile Media API system properties that can be accessed by calling System.getProperty().

    Device Support is Developers' Challenge

    The Mobile Media API provides a rich and extensible framework for incorporating media into J2ME applications. While there are a number of verification steps an application will want to perform in order to ensure a device can handle specific media content, the Mobile Media API does a good job of providing developers with enough information to make informed decisions regarding a device's capabilities. Fortunately, the competitive mobile device market that currently exists puts the odds in the developer's favor that most of the popular media types will be supported.

    *Originally published at DevX.com

    David Hemphill is the Lead Architect for Gearworks, Inc., a company that creates mobile and wireless software for field service industries. David is the co-author of Java 2 Micro Edition from Manning Publications and is a frequent speaker on J2ME at industry conferences. He can be reached at dhemphill@mn.rr.com.

    Previous article
    Next article

    Related Articles

    1 COMMENT

    LEAVE A REPLY

    Please enter your comment!
    Please enter your name here

    Latest Articles