Implementation

For information about the design and functionality of the MIDlet, see section Design.

The MediaList view is created and displayed by the MediaSamplerMIDlet class. A reference of MediaSamplerMIDlet is passed to all LCDUI elements used by the application (MediaList, AudioCanvas, VideoSourceSelector, and so on). The reference is used for getting the display and for displaying an alert when an error occurs. MediaList creates and displays the classes AudioCanvas, VideoSourceSelector, and SupportForm.

The MediaFactory class provides media-specific information such as available sound and video medias, and their MIME types and file paths in the MIDlet package (JAR file). MediaFactory reads resource-specific file path properties from the application descriptor (JAD file). Data information returned from MediaFactory is encapsulated in the Media class.

UI classes in the viewer package display the UI or route to another display.

For more information about the key aspects of implementing the MIDlet, see:

Media loading

The following code shows the method for loading resources as InputStream objects:

    public InputStream getInputStream() throws IOException {
        if (location == LOCATION_JAR) {
            return getClass().getResourceAsStream(file);
        } else if (location == LOCATION_HTTP) {
            return urlToStream(file);
        }
        throw new IOException("Not supported location type!");
    }

The following code shows the method for fetching content from a specified HTTP URL in the form of InputStream objects:

    private InputStream urlToStream(String url) throws IOException {
        // Open connection to the http url...
        HttpConnection connection = (HttpConnection) Connector.open(url);
        DataInputStream dataIn = connection.openDataInputStream();
        byte[] buffer = new byte[1000];
        int read = -1;
        // Read the content from url.
        ByteArrayOutputStream byteout = new ByteArrayOutputStream();
        while ((read = dataIn.read(buffer)) >= 0) {
            byteout.write(buffer, 0, read);
        }
        dataIn.close();
        // Fill InputStream to return with content read from the URL.
        ByteArrayInputStream byteIn = new ByteArrayInputStream(byteout.toByteArray());
        return byteIn;
    }

ToneControl is the interface that enables playback of a user-defined monotonic tone sequence:

    public static byte[] getToneSequence() {
        byte[] sequence = {ToneControl.VERSION, 1, ToneControl.TEMPO, 30, // times 4 = 120 beats-per-minute
            ToneControl.C4, 16, ToneControl.C4 + 2, 16, // D4
            ToneControl.C4 + 4, 16, // E4
            ToneControl.C4 + 5, 16, // F4 (note E# does not exist)
            ToneControl.C4 + 7, 16, // G4
            ToneControl.C4 + 9, 16, // A4
            ToneControl.C4 + 11, 16, // B4
            ToneControl.C4 + 9, 8, // A4
            ToneControl.C4 + 7, 8, // G4
            ToneControl.C4 + 5, 8, // F4 (note E# does not exist)
            ToneControl.C4 + 4, 8, // E4
            ToneControl.C4 + 2, 8, // D4
            ToneControl.C4, 8,};
        return sequence;
    }

Video playback

The following code shows the methods for stopping, and initializing and starting the player:

    void doStop() {
        if (player != null) {
            try {
                player.stop();
            } catch (MediaException e) {
                e.printStackTrace();
            }
        }
    }

    // ...

    void play() {
        try {
            if (!initDone || player == null) {
                initPlayer();
            }

            int state = player.getState();
            if (state == Player.CLOSED) {
                player.prefetch();
            } else if (state == Player.UNREALIZED) {
                player.realize();
            } else if (state == Player.REALIZED) {
                player.prefetch();
            }
            player.start();
        } catch (MediaException me) {
            discardPlayer();
            midlet.alertError("MediaException: " + me.getMessage());
        } catch (SecurityException se) {
            discardPlayer();
            midlet.alertError("SecurityException: " + se.getMessage());
        } catch (Exception e) {
            discardPlayer();
            midlet.alertError("Exception: " + e.getMessage());
        }
    }

The following code shows the method for initializing the video player:

    void initPlayer() {
        try {
            initDone = false;
            if (videoFile == null) {
                midlet.alertError("No video file specified");
                return;
            }
            boolean fromHttp = videoFile.startsWith("http://");
            InputStream is = fromHttp ? urlToStream(videoFile) : getClass().getResourceAsStream(videoFile);
            player = Manager.createPlayer(is, "video/3gpp");
            player.addPlayerListener(this);
            player.prefetch();
            player.realize();

            // get the video control and attach it to our canvas
            VideoControl videoControl = (VideoControl) (player.getControl("VideoControl"));
            if (videoControl == null) {
                midlet.alertError("VideoControl not supported");
            } else {
                videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);
                videoControl.setVisible(true);
            }
            initDone = true;
        } catch (IOException ioe) {
            discardPlayer();
            midlet.alertError("IOException: " + ioe.getMessage());
        } catch (MediaException me) {
            discardPlayer();
            midlet.alertError("MediaException: " + me.getMessage());
        } catch (SecurityException se) {
            discardPlayer();
            midlet.alertError("SecurityException: " + se.getMessage());
        } catch (Exception ex) {
            discardPlayer();
            midlet.alertError("Exception: " + ex.getMessage());
        }
    }

The VideoControl class controls the display of video. A Player which supports the playback of video must provide a VideoControl through its getControl and getControls methods. The initDisplayMode method initializes the mode on how the video is displayed.

Supported media types

The SupportForm class shows supported media types:

    private void init() {
        String apiVersion = System.getProperty("microedition.media.version");
        append("MM API version:" + apiVersion + "\n");
        append("Mixing supported: " + System.getProperty("supports.mixing") + "\n");
        append("Audio capture supported: " + System.getProperty("supports.audio.capture") + "\n");
        append("Video capture supported: " + System.getProperty("supports.video.capture") + "\n");
        append("Recording supported: " + System.getProperty("supports.recording") + "\n");
        append("Supported audio encodings: " + System.getProperty("audio.encodings") + "\n");
        append("Supported video encodings: " + System.getProperty("video.encodings") + "\n");
        append("Supported video snaphot encodings: " + System.getProperty("video.snapshot.encodings") + "\n");
        append("\n");
        String streamable = System.getProperty("streamable.contents");
        if (streamable == null) {
            append("Streaming: not supported.\n");
        } else {
            append("Streamable contents: " + streamable);
            String[] rtp = Manager.getSupportedContentTypes("rtp");
            if (rtp != null && rtp.length > 0) {
                append("RTP protocol supported.");
            }
            String rtsp[] = Manager.getSupportedContentTypes("rtsp");
            if (rtsp != null && rtsp.length > 0) {
                append("RTSP protocol supported.");
            }
        }
        String[] contentTypes = Manager.getSupportedContentTypes(null);
        if (contentTypes != null) {
            append("\n\nAll supported content types:\n");
            for (int i = 0; i < contentTypes.length; i++) {
                append(contentTypes[i] + "\n");
            }
        }
    }