Creating the UI elements

AudioCanvas class

  1. Create the AudioCanvas class

  2. Import the required classes and assign this class to the com.nokia.example.mmapi.mediasampler.viewer package.

    package com.nokia.example.mmapi.mediasampler.viewer;
    
    import java.util.Vector;
    
    import javax.microedition.lcdui.Canvas;
    import javax.microedition.lcdui.Command;
    import javax.microedition.lcdui.CommandListener;
    import javax.microedition.lcdui.Display;
    import javax.microedition.lcdui.Displayable;
    import javax.microedition.lcdui.Font;
    import javax.microedition.lcdui.Graphics;
    import javax.microedition.media.MediaException;
    
    import com.nokia.example.mmapi.mediasampler.MediaSamplerMIDlet;
    import com.nokia.example.mmapi.mediasampler.data.Media;
    import com.nokia.example.mmapi.mediasampler.data.MediaFactory;
    import com.nokia.example.mmapi.mediasampler.model.PlayerPool;
    
    
  3. Create the AudioCanvas class and set it to extend Canvas and implement CommandListener. Define the required constants and create to constructor.

    /**
     * Audio play canvas. Audio clip is played when a key is pressed.
     */
    public class AudioCanvas extends Canvas implements CommandListener
    {
        private PlayerPool pool;
    
        private MediaSamplerMIDlet midlet;
    
        private Displayable returnScreen;
    
        protected String[] supportedMediaNames;
    
        protected String[] unsupportedMediaNames;
    
        protected int countOfPlayers = 0;
    
        protected int volume = 100;
    
        private boolean initDone;
    
        private boolean infoMode;
    
        private Command infoCommand = new Command("Info", Command.SCREEN, 1);
    
        private Command backCommand = new Command("Back", Command.BACK, 1);
    
        public AudioCanvas(MediaSamplerMIDlet midlet, Displayable returnScreen,
                int latency)
        {
            this.midlet = midlet;
            this.returnScreen = returnScreen;
    
            pool = new PlayerPool(midlet, latency);
            initSounds();
            // Init volume level of Players in pool
            pool.setVolumeLevel(volume);
            addCommand(backCommand);
            addCommand(infoCommand);
            setCommandListener(this);
        }
    
    
  4. Create a method for releasing loaded resources from the pool.

        /**
         * Release loaded resources
         */
        public void releaseResources()
        {
            pool.releaseResources();
        }
    
    
  5. Write code for monitoring commands.

        /**
         * Implemented CommandListener method.
         */
        public void commandAction(Command cmd, Displayable d)
        {
            if (cmd == backCommand)
            {
                if (infoMode)
                {
                    infoMode = false;
                    addCommand(infoCommand);
                    repaint();
                }
                else
                {
                    Display.getDisplay(midlet).setCurrent(returnScreen);
                }
            }
            else if (cmd == infoCommand)
            {
                infoMode = true;
                removeCommand(infoCommand);
                repaint();
            }
        }
    
    
  6. Write code for monitoring key presses.

        public void keyPressed(int key)
        {
            int keyCode = key - KEY_NUM0;
            int gameAction = getGameAction(key);
    
            // Check is the selected audio available for playing.
            if (keyCode > 0 && keyCode <= countOfPlayers)
            {
                try
                {
                    pool.playSound(keyCode - 1);
                }
                catch (MediaException e)
                {
                    // Swallow the exception.
                }
    
            }
            else if (gameAction == UP)
            {
                increaseVolume();
            }
            else if (gameAction == DOWN)
            {
                decreaseVolume();
            }
        }
    
    
  7. Create the paint method for creating the visual outlook of the canvas.

        /**
         * Paint the canvas.
         */
        protected void paint(Graphics g)
        {
            int x = 0;
            int y = 0;
            int w = getWidth();
            int h = getHeight();
    
            g.setColor(0xFFFFFF);
            g.fillRect(x, y, w, h);
    
            Font fontPlain = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN,
                    Font.SIZE_SMALL);
            Font fontBold = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
                    Font.SIZE_SMALL);
    
            g.setColor(0x000000);
    
            if (infoMode)
            {
                boolean multiSupport = pool.supportsMulplePlayers();
                boolean mixSupport = "true".equals(System
                        .getProperty("supports.mixing"));
    
                g.setFont(fontBold);
                y = paintTextRow(g, "Supports multiple players:", x, y);
                g.setFont(fontPlain);
                y = paintTextRow(g, "" + multiSupport, x, y);
                g.setFont(fontBold);
                y = paintTextRow(g, "Supports audio mixing:", x, y);
                g.setFont(fontPlain);
                y = paintTextRow(g, "" + mixSupport, x, y);
                if (unsupportedMediaNames.length > 0)
                {
                    g.setFont(fontBold);
                    g.setColor(0x000000);
                    y = paintTextRow(g, "Unsupported sounds:", x, y);
                    g.setFont(fontPlain);
                    for (int i = 0; i < unsupportedMediaNames.length; i++)
                    {
                        String str = unsupportedMediaNames[i];
                        String strToPaint = str;
                        y = paintTextRow(g, strToPaint, x, y);
                    }
                }
    
            }
            else
            {
                g.setFont(fontBold);
                y = paintTextRow(g, "Sound key mapping:", x, y);
                g.setFont(fontPlain);
                for (int i = 0; i < supportedMediaNames.length; i++)
                {
                    String str = supportedMediaNames[i];
                    String strToPaint = (i + 1) + " = " + str;
                    y = paintTextRow(g, strToPaint, x, y);
                }
                y = paintTextRow(g, "Volume level: " + volume, x, y);
            }
    
        }
    
    
  8. Create a method for rendering a row of text to the canvas.

        /**
         * Renders a text row to Canvas.
         */
        private int paintTextRow(Graphics g, String text, int x, int y)
        {
            int w = getWidth();
    
            Font font = g.getFont();
            for (int j = 0; j < text.length(); j++)
            {
                char c = text.charAt(j);
                int cw = font.charWidth(c);
                if (x + cw > w)
                {
                    x = 0;
                    y += font.getHeight();
                }
                g.drawChar(c, x, y, Graphics.TOP | Graphics.LEFT);
                x += cw;
            }
            y += font.getHeight();
            return y;
        }
    
    
  9. Create the methods for increasing and decreasing the volume.

        private void increaseVolume()
        {
            volume += 10;
            if (volume > 100)
            {
                volume = 100;
            }
            pool.setVolumeLevel(volume);
            repaint();
        }
    
        private void decreaseVolume()
        {
            volume -= 10;
            if (volume < 0)
            {
                volume = 0;
            }
            pool.setVolumeLevel(volume);
            repaint();
        }
    
    
  10. Create a method for loading the sounds and tones to the canvas.

        /**
         * Loads the medias available on this canvas. Loaded sounds are passed to
         * PlayerPool class which creates players and initializes player states.
         */
        protected void initSounds()
        {
            if (!initDone)
            {
                countOfPlayers = 0;
                Vector supportedMedias = new Vector();
                Vector unsupportedMedias = new Vector();
    
                // Sound media clips
                Media[] medias = MediaFactory.getSoundMedias();
                for (int i = 0; i < medias.length; i++)
                {
                    Media media = medias[i];
                    String mediaName = null;
                    try
                    {
                        mediaName = media.getFile() + " [" + media.getType() + "]";
                        pool.addMedia(media);
                        supportedMedias.addElement(mediaName);
                        countOfPlayers++;
                    }
                    catch (MediaException e)
                    {
                        System.out.println("unsupported media: " + media.getType());
                        unsupportedMedias.addElement(mediaName);
                    }
                }
    
                // Tone sequences
                String mediaName = null;
                try
                {
                    mediaName = "Tone sequence";
                    pool.addToneSequence(MediaFactory.getToneSequence());
                    supportedMedias.addElement(mediaName);
                    countOfPlayers++;
                }
                catch (MediaException e)
                {
                    System.out.println("Unsupported type: Tone sequence");
                    e.printStackTrace();
                    unsupportedMedias.addElement(mediaName);
                }
    
                // Stores results of success and failed Players to String array
                supportedMediaNames = new String[supportedMedias.size()];
                supportedMedias.copyInto(supportedMediaNames);
    
                unsupportedMediaNames = new String[unsupportedMedias.size()];
                unsupportedMedias.copyInto(unsupportedMediaNames);
                initDone = true;
            }
        }
    
    }
    

MediaList class

  1. Create the MediaList class

  2. Import the required classes and assign this class to the com.nokia.example.mmapi.mediasampler.viewer package.

    package com.nokia.example.mmapi.mediasampler.viewer;
    
    import javax.microedition.lcdui.*;
    
    import com.nokia.example.mmapi.mediasampler.MediaSamplerMIDlet;
    import com.nokia.example.mmapi.mediasampler.data.Media;
    import com.nokia.example.mmapi.mediasampler.data.MediaFactory;
    import com.nokia.example.mmapi.mediasampler.model.DRMPlayer;
    
    
  3. Create the MediaList class and set it to extend List and implement CommandListener. Define the constants and create the constructor.

    /**
     * Media list is the main view in the MIDlet. From this view the user may swich
     * to other views.
     */
    public class MediaList extends List implements CommandListener
    {
        private final MediaSamplerMIDlet midlet;
    
        private final VideoSourceSelector sourceSelector;
    
        private AudioCanvas audioCanvas;
    
        private SupportForm form;
    
        private final Command exitCommand;
    
        public MediaList(MediaSamplerMIDlet midlet)
        {
            super("Media Sampler", IMPLICIT);
    
            this.midlet = midlet;
    
            sourceSelector = new VideoSourceSelector(midlet, this);
    
            append("Play audio", null);
            append("Play video", null);
            append("DRM MIDI", null);
            append("Check MM API support", null);
    
            exitCommand = new Command("Exit", Command.EXIT, 1);
            addCommand(exitCommand);
            setCommandListener(this);
        }
    
    
  4. Create a method for releasing all resources that have been loaded by subcomponents.

        /**
         * Release all resources loaded by sub components.
         */
        public void releaseResources()
        {
            if (audioCanvas != null)
            {
                audioCanvas.releaseResources();
            }
        }
    
    
  5. Write code for monitoring commands.

        /**
         * Implemented CommandListener method.
         * 
         * Sets the selected Example visible
         */
        public void commandAction(Command cmd, Displayable disp)
        {
            if (cmd == List.SELECT_COMMAND)
            {
                int index = getSelectedIndex();
                if (index != -1) // -1 means nothing selected
                {
                    String selected = getString(index);
    
                    if (selected.equals("Play video"))
                    {
                        Display.getDisplay(midlet).setCurrent(sourceSelector);
                    }
                    else if (selected.equals("DRM MIDI"))
                    {
                        Media media = MediaFactory.getDRMMidi();
                        DRMPlayer player = new DRMPlayer(midlet, this);
                        player.playDRMprotected(media.getFile(), media.getType());
                    }
                    else if (selected.equals("Play audio"))
                    {
                        if (audioCanvas == null)
                        {
                            audioCanvas = new AudioCanvas(midlet, this, 0);
                        }
                        Display.getDisplay(midlet).setCurrent(audioCanvas);
                    }
                    else if (selected.equals("Check MM API support"))
                    {
                        if (form == null)
                        {
                            form = new SupportForm(midlet, this);
                        }
                        Display.getDisplay(midlet).setCurrent(form);
                    }
                }
            }
            else if (cmd == exitCommand)
            {
                midlet.listExit();
            }
        }
    }
    

SupportForm class

  1. Create the SupportForm class

  2. Import the required classes and assign this class to the com.nokia.example.mmapi.mediasampler.viewer package.

    package com.nokia.example.mmapi.mediasampler.viewer;
    
    import javax.microedition.lcdui.Command;
    import javax.microedition.lcdui.CommandListener;
    import javax.microedition.lcdui.Display;
    import javax.microedition.lcdui.Displayable;
    import javax.microedition.lcdui.Form;
    import javax.microedition.media.Manager;
    
    import com.nokia.example.mmapi.mediasampler.MediaSamplerMIDlet;
    
    
  3. Create the SupportForm class and set it to extend Form and implement CommandListener. Define the constants and create the constructor.

    /**
     * View that outputs MM API's System properties to a Form.
     */
    public class SupportForm extends Form implements CommandListener
    {
        private MediaSamplerMIDlet midlet;
    
        private Displayable medialist;
    
        private Command backCmd = new Command("Back", Command.STOP, 1);
    
        public SupportForm(MediaSamplerMIDlet midlet, Displayable medialist)
        {
            super("MM API support check");
    
            this.midlet = midlet;
            this.medialist = medialist;
    
            addCommand(backCmd);
            setCommandListener(this);
    
            init();
        }
    
  4. Create the init method that adds the various media properties to the Form.

    
        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");
                }
            }
        }
    
    
  5. Write code for monitoring commands.

        public void commandAction(Command cmd, Displayable d)
        {
            Display.getDisplay(midlet).setCurrent(medialist);
        }
    
    }
    

VideoCanvas class

  1. Create the VideoCanvas class.

  2. Import the required classes and assign this class to the com.nokia.example.mmapi.mediasampler.viewer package.

    package com.nokia.example.mmapi.mediasampler.viewer;
    
    import java.io.*;
    
    import javax.microedition.io.Connector;
    import javax.microedition.io.HttpConnection;
    import javax.microedition.lcdui.*;
    import javax.microedition.media.*;
    import javax.microedition.media.control.*;
    
    import com.nokia.example.mmapi.mediasampler.MediaSamplerMIDlet;
    
    
  3. Create the VideoCanvas class and set it to extend Canvas and implement CommandListener and PlayerListener. Define the constants and create the constructor.

    /**
     * VideoCanvas renders video on Canvas.
     */
    class VideoCanvas extends Canvas implements CommandListener, PlayerListener
    {
        private PlayerController controller;
    
        private MediaSamplerMIDlet midlet;
    
        private Displayable returnScreen;
    
        private String videoFile;
    
        private Command stopCommand;
    
        private Command replayCommand;
    
        private Command backCommand;
    
        private Player player;
    
        private boolean initDone;
    
        private boolean playPending = false;
    
        /**
         * Constructor.
         * 
         * @param midlet
         *            MediaSamplerMIDlet
         * @param returnScreen
         *            Displayable to set visible when returned from this Canvas
         * @param videoFile
         *            String as path of the source viudeo file.
         */
        VideoCanvas(MediaSamplerMIDlet midlet, Displayable returnScreen,
                String videoFile)
        {
            this.midlet = midlet;
            this.returnScreen = returnScreen;
            this.videoFile = videoFile;
            controller = new PlayerController();
    
            replayCommand = new Command("Replay", Command.SCREEN, 1);
            stopCommand = new Command("Stop", Command.SCREEN, 2);
            backCommand = new Command("Back", Command.BACK, 1);
            addCommand(backCommand);
            setCommandListener(this);
        }
    
    
  4. Create a method for changing the play status to "pending" and a method for checking if the system screen is visible.

        /**
         * Set play status to "pending".
         */
        void prepareToPlay()
        {
            controller.start();
            playPending = true;
        }
    
        /**
         * Play video only when we're displayed. Use playPending flag to avoid
         * restarting if a system screen is visiable.
         */
        public void showNotify()
        {
            if (playPending)
            {
                playPending = false;
                controller.playVideo();
            }
        }
    
    
  5. Create a method for rendering the canvas.

        /**
         * Renders the Canvas.
         */
        public void paint(Graphics g)
        {
            g.setColor(0x00FFFF00); // yellow
            g.fillRect(0, 0, getWidth(), getHeight());
        }
    
    
  6. Write code for monitoring commands.

        /**
         * Implemented CommandListener method. Indicates that a command event has
         * occurred on Displayable d.
         */
        public void commandAction(Command c, Displayable d)
        {
            if (c == stopCommand)
            {
                controller.stopVideo();
            }
            else if (c == replayCommand)
            {
                controller.playVideo();
            }
            else if (c == backCommand)
            {
                discardPlayer();
            }
        }
    
    
  7. Write code for monitoring key presses.

        /**
         * Overriden Canvas method.
         */
        public void keyPressed(int keyCode)
        {
            if (getGameAction(keyCode) == FIRE)
            {
                int state = player.getState();
                if (state == Player.STARTED)
                {
                    controller.stopVideo();
                }
                else
                {
                    controller.playVideo();
                }
            }
        }
    
    
  8. Create a method for fetching content from a specified HTTP URL and returning it as an InputStream.

        /**
         * Reads the content from the specified HTTP URL and returns InputStream
         * where the contents are read.
         * 
         * @return InputStream
         * @throws IOException
         */
        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();
            connection.close();
            // Fill InputStream to return with content read from the URL.
            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteout
                    .toByteArray());
            return byteIn;
        }
    
    
  9. Create the methods for stopping and initializing and starting the player.

        /**
         * Stops the Player.
         */
        void doStop()
        {
            if (player != null)
            {
                try
                {
                    player.stop();
                }
                catch (MediaException e)
                {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * Initializes and starts the Player.
         */
        void doPlay()
        {
            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());
            }
        }
    
    
  10. Create a method for initializing the video player. The VideoControl class controls the display of video. A Player which supports the playback of video must provide a VideoControl via its getControl and getControls method. The initDisplayMode method initializes the mode on how the video is displayed.

    For more information, see VideoControl, getControl, and initDisplayMode in the MM API specification.

        /**
         * Initializes the video player.
         * 
         * Player is initialized only once to save the memory resources and to
         * increase performance.
         */
        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());
            }
    
        }
    
    
  11. Create methods for closing invalid players and updating players with new event data.

        /**
         * Called in case of exception to make sure invalid players are closed
         */
        void discardPlayer()
        {
            if (player != null)
            {
                controller.setStopped();
                player.close();
                player = null;
                Display.getDisplay(midlet).setCurrent(returnScreen);
            }
        }
    
        /**
         * Implemented javax.microedition.media.PlayerListener method.
         */
        public void playerUpdate(final Player p, final String event,
                final Object eventData)
        {
            // queue a call to updateEvent in the user interface event queue
            Display display = Display.getDisplay(midlet);
            display.callSerially(new Runnable()
            {
                public void run()
                {
                    VideoCanvas.this.updateEvent(p, event, eventData);
                }
            });
        }
    
    
  12. Create a method for handling update events for the player.

        /**
         * Handles playerUpdate events of the Player.
         * 
         * @param p
         * @param event
         * @param eventData
         */
        void updateEvent(Player p, String event, Object eventData)
        {
            if (event == END_OF_MEDIA)
            {
                addCommand(replayCommand);
                removeCommand(stopCommand);
            }
            else if (event == CLOSED)
            {
                addCommand(replayCommand);
                removeCommand(stopCommand);
            }
            else if (event == STARTED)
            {
                removeCommand(replayCommand);
                addCommand(stopCommand);
            }
            else if (event.equals(ERROR))
            {
            }
        }
    
    
  13. Create a code for calling the play and stop methods of the Player. This method is designed to separate the Player method calls from other event threads.

        /**
         * PlayerController calls the play and stop methods of the Player. The
         * purpose of this class is only to isolate Player method calls from the
         * event threads (such commandAction(...))
         */
        public class PlayerController extends Thread
        {
            private boolean running;
    
            // Lock object of this Thread
            private Object controllLock = new Object();
    
            public PlayerController()
            {
            }
    
            // Activates the Player
            public void playVideo()
            {
                synchronized (controllLock)
                {
                    controllLock.notify();
                }
            }
    
            // Deactivates the player
            public void stopVideo()
            {
                synchronized (controllLock)
                {
                    doStop();
                }
            }
    
            // Terminates this thread
            public void setStopped()
            {
                running = false;
                synchronized (controllLock)
                {
                    controllLock.notify();
                }
            }
    
            public void run()
            {
                VideoCanvas.this.doPlay();
    
                running = true;
                while (running)
                {
                    try
                    {
                        synchronized (controllLock)
                        {
                            // Set this thread to wait for playVideo() method call.
                            controllLock.wait();
                            if (!running) // Leave if controller is stopped.
                            {
                                break;
                            }
                            VideoCanvas.this.doPlay();
                        }
                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    

VideoSourceSelector

  1. Create the VideoSourceSelector class

  2. Import the required classes and assign this class to the com.nokia.example.mmapi.mediasampler.viewer package.

    package com.nokia.example.mmapi.mediasampler.viewer;
    
    import javax.microedition.lcdui.Command;
    import javax.microedition.lcdui.CommandListener;
    import javax.microedition.lcdui.Display;
    import javax.microedition.lcdui.Displayable;
    import javax.microedition.lcdui.Form;
    import javax.microedition.lcdui.List;
    import javax.microedition.lcdui.TextField;
    
    import com.nokia.example.mmapi.mediasampler.MediaSamplerMIDlet;
    import com.nokia.example.mmapi.mediasampler.data.MediaFactory;
    
    
  3. Create the VideoSourceSelector class and set it to extend List and implement CommandListener. Define the constants and create the constructor.

    /**
     * List that allow user to select Video source.
     */
    public class VideoSourceSelector extends List implements CommandListener
    {
        private MediaSamplerMIDlet midlet;
    
        private List returnList;
    
        private HTTPUrlForm urlForm;
    
        private Command backCommand = new Command("Back", Command.BACK, 1);
    
        public VideoSourceSelector(MediaSamplerMIDlet midlet, MediaList list)
        {
            super("Select Video Source", List.IMPLICIT);
            this.midlet = midlet;
            this.returnList = list;
            urlForm = new HTTPUrlForm();
            append("From http", null);
            append("From jar", null);
            addCommand(backCommand);
            setCommandListener(this);
        }
    
    
  4. Write code for monitoring commands.

        public void commandAction(Command cmd, Displayable d)
        {
            if (cmd == SELECT_COMMAND)
            {
                int selection = getSelectedIndex();
                if (selection == 0) // URL source selected
                {
                    Display.getDisplay(midlet).setCurrent(urlForm);
                }
                else if (selection == 1) // JAR source selected
                {
                    // File name returned by the MediaFactory refers to the
                    // "Video-Clip" application property...
                    String videoFile = MediaFactory.getDefaultVideo().getFile();
                    commitSelection(videoFile);
                }
            }
            else if (cmd == backCommand)
            {
                Display.getDisplay(midlet).setCurrent(returnList);
            }
        }
    
    
  5. Create a method for initializing the video canvas with the selected video source and setting it visible.

        /**
         * Initializes and set visible the video canvas with the selected video
         * source.
         * 
         * @param input
         *            String as video http url or file path.
         */
        private void commitSelection(String url)
        {
            try
            {
                VideoCanvas canvas = new VideoCanvas(midlet, returnList, url);
                canvas.prepareToPlay();
                Display.getDisplay(midlet).setCurrent(canvas);
            }
            catch (Exception e)
            {
                midlet.alertError("Cannot open connection: " + e.getMessage());
            }
        }
    
    
  6. Create a Form for the video URL input.

        /**
         * Form for the video URL input.
         */
        public class HTTPUrlForm extends Form implements CommandListener
        {
            TextField tf = new TextField("URL", "http://", 100, TextField.URL);
    
            Command cmdOK = new Command("OK", Command.OK, 1);
    
            Command cmdBack = new Command("Back", Command.BACK, 1);
    
            public HTTPUrlForm()
            {
                super("HTTP Address");
                String defaultURL = VideoSourceSelector.this.midlet
                        .getAppProperty("Video-URL");
                if (defaultURL != null && defaultURL.length() > 0)
                {
                    tf.setString(defaultURL);
                }
                append(tf);
                addCommand(cmdOK);
                addCommand(cmdBack);
                setCommandListener(this);
            }
    
            public void commandAction(Command cmd, Displayable d)
            {
                if (cmd == cmdOK)
                {
                    String url = tf.getString();
                    commitSelection(url);
                }
                else
                {
                    Display.getDisplay(midlet).setCurrent(VideoSourceSelector.this);
                }
            }
        }
    }