Are you a musician?
Register here
Mobilmenu

Playing music with MIDP2.0 classes

Standard Java Micro Edition MIDP2.0 supports playback of MIDI and AMR files. But most manufactures also implements support for MP3 and WAV files.

In this little help file, I'll show you how to load and play music in JavaME, regardless of the file being a MIDI, AMR, MP3 or WAV.

Let's get started

You need Manager and Player, so start by importing those.

import javax.microedition.media.Manager; import javax.microedition.media.Player;

In our example, we use a file called music.mid, but any of the mentioned filetypes can be used with this same example, by replacing mime-type "audio/midi" with "audio/x-wav" for WAV files, "audio/amr" for AMR files, and "audio/mpeg" for MP3 files.

First thing to do is to create a Player object

Player myPlayer = null; try { myPlayer = Manager.createPlayer(getClass().getResourceAsStream("/music.mid"), "audio/midi"); } catch (Exception e) {}

This will create the Player object. Now we need to get it playing, and this is where we need to do a bit of work. JavaME is (like many other platforms) buggy and can't be trusted. Different phones act in different ways, so we need to work around that. The solution is simple:

try { myPlayer.realize(); } catch (Exception e) {} try { myPlayer.prefetch(); } catch (Exception e) {} try { myPlayer.start(); } catch (Exception e) {}

We use 3 try/catch blocks to get the Player object started, because: Some phones don't like the prefetch() method, while others don't like the realize() method. But some phones require one of them. The only solution is to use multiple try/catch blocks

Pausing / Resuming playback

Unfortunately there is no pause() method of the Player object, so you can't pause a track and resume it later.

The stop() method functions as a pause method on some devices though, since calling start() will resume playback from the point it was stopped. But this is not universal.

One way of creating a pause method, is to store the mediatime in a variable before calling stop(), and setting it again right after calling start().

public long pausedTime = 0; public void pauseMusic() { try { pausedTime = myPlayer.getMediaTime(); } catch (Exception e) {} try { myPlayer.stop(); } catch (Exception e) {} } public void resumeMusic() { try { myPlayer.start(); } catch (Exception e) {} try { myPlayer.setMediaTime(pausedTime); } catch (Exception e) {} }

This however, like most things in JavaME, doesn't work on all devices either. But it'll do for most devices.

Stopping the player

In order to stop the player again, we do this:

try { myPlayer.stop(); } catch (Exception e) {} try { myPlayer.deallocate(); } catch (Exception e) {} myPlayer.close(); myPlayer = null;

Looping music

The Player object has a method called setLoopCount(), but as usual this one can't be trusted either. Too buggy on various devices

If you'd like to loop the music, you can do this using the PlayerListener. Simply implement the PlayerListener, listen for when the END_OF_MEDIA event occurs, and then restart the Player object.

public void playerUpdate(Player player, String event, Object eventData) { if (event.equals(PlayerListener.END_OF_MEDIA)) { try { player.stop(); // Make sure the player has stopped. Thread.sleep(50); // If you don't wait a little bit // before attempting to restart, // it may not start on some devices. player.start(); } catch (Exception e) {} } }

It should be noted, that the majority of JavaME enabled phones cannot perform a smooth loop. There will always be a small pause before the music loops. Therefore, many JavaME-optimized MIDI tracks at IndieGameMusic.com are deliberately composed with an ending that makes this pause less apparent. Either by fading down the music at the end, or by making a break in the tune that makes it less apparent that it's actually restarting.


Back to table of contents