USING JMF
SOUND &
MULTI-MEDIA
IN JAVA PROGRAMS
by
R.S.Ramaswamy
(rs.ramaswamy@gmail.com)
--------------------------
In this brief tutorial, the author deals with the method
of playing audio files in stand-alone programs and also using JMF to
play audio and audio-video files.
Prior to JDK1.2,
it was not possible to play audio files in stand-alone Java programs. From JDK1.2
upwards, a simple method for playing audio files in such applications, was
devised. Actually, the code is very simple and can be tested in a console
program itself as given below.
============================================
// audio.java
import java.applet.*;
import java.net.*;
class audio
{
public static void main(String args[])
{
try
{
URL url = new URL(args[0]);
Applet.newAudioClip(url).play();
}
catch(Exception e1)
{ System.out.println(""+e1);}
}
}
===========================================
We can test various types of audio files by running this program
with appropriate argument.
set path=c:\windows\command;d:\jdk1.3\bin
>javac
audio.java
>java audio "file:/c:/spacemusic.au"
(It is assumed that we have placed all the
audio files in C drive).
Hit control & c to exit.
--
Similarly, we can play midi file,
aif file and wav file.
Samples have been given as:
a) flutemusic.aif
b) cardring.wav
c) trips.mid
d) spacemusic.au
===========================================
For such readers who prefer to have a gui for the above program, it is
given below. The code should be self-explanatory.
==============================
// tunes.java
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.net.*;
import java.util.*;
public class tunes extends
Frame
implements ActionListener
{
Choice combo1;
Button button1,button2,button3;
AudioClip clip1;
Label label1;
String s;
public static void main(String
args[])
{
tunes
app=new tunes();
app.setSize(400,400);
app.show();
}
//---------------
tunes()
{
setLayout(new FlowLayout());
label1=new Label("choose the tune");
add(label1);
combo1 = new Choice();
combo1.addItem("spacemusic.au");
combo1.addItem("trips.mid");
combo1.addItem("cardring.wav");
combo1.addItem("chimes.wav");
combo1.addItem("flutemusic.aif");
add(combo1);
button1 = new Button("confirm");
button2 = new Button("stop");
button3 = new Button("exit");
add(button1);
add(button2);
add(button3);
s="tune";
label1 = new Label(s);
button1.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);
}
public void actionPerformed
(ActionEvent e)
{
if(e.getSource()==button1)
{
s = combo1.getSelectedItem();
try
{
URL url
= new URL("file:/c:/"+ s);
clip1 = Applet.newAudioClip(url);
clip1.play();
}catch(Exception e1)
{System.out.println(""+e1);}
}
if(e.getSource()==button2)
{
clip1.stop();
}
if(e.getSource()==button3)
{
System.exit(0);
}
}
}
======================================
We now take up JMF (Java Media Framework).We
have to download JMF from
http://java.sun.com/products/java-media/jmf
The reference implementation is jmf2.1
It is about 4 mb zip file.( We are using
the version meant for Windows platform). We can directly instal this in our
system. The installation will automatically create the correct
classpath
also.
We have imported java.media.* in the jmf program and it will be
available now.
We
get the selected URL of the media file when the user double-clicks on
the list item. A mediaplayer instance is created by Manager.createPlayer(url)
command.
The player generates controller events
and so we add listener for these events.We
then provide a controllerUpdate()
method, which is called when a Controller generates an event.
The player can have the following states.
1
Realizing: In the realizing state, the Player is in the
process of determining its resource requirements. A realizing Player often
downloads assets over the network.
2
Realized: In this state the Player knows what resources
it needs and has information about the type of media it is to present. It can
also provide visual components and controls.
3
Prefetching: During this phase, the Player preloads its
media data, and does whatever else is needed to play the media data.
4
Prefetched:
The state where the Player has finished prefetching media data -- it's ready to
start.
5 Started:
This state is entered when you call the start() method. The Player is now ready
to present the media data.
Thus, when the player has been created and
its realize() method is called, it does realizing task. When realizing
is complete, it generates the corresponding event, and then the prefetch() method
of the player is called. After this, the player is started.In order to
simplify the code, we are dealing with audio only and we are not showing the
visible component of the player.( which we illustrate in the next example).
*************************************
// jmfmusic.java
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import javax.media.*;
public class jmfmusic extends Frame
implements ControllerListener,
ActionListener
{
Player
player1 = null;
Component
component1 = null;
URL url1;
Label label1;
List list1;
Button button1;
public static void main(String args[])
{
jmfmusic
app = new jmfmusic();
app.setBounds(200,150,400,200);
app.show();
}
jmfmusic()
{
setLayout(new BorderLayout());
list1 = new List();
list1.addItem("spacemusic.au");
list1.addItem("chimes.wav");
list1.addItem("trips.mid");
list1.addItem("jayentho.mp3");
add("West",list1);
list1.addActionListener(this);
label1 = new Label("playing audio");
label1.setBackground(Color.black);
label1.setForeground(Color.green);
add("Center",label1);
button1 = new Button("exit");
button1.setBackground(Color.black);
button1.setForeground(Color.red);
add("South",button1);
button1.addActionListener(this);
}
public
void actionPerformed
(ActionEvent e)
{
if(e.getSource()==list1)
{
String
s = list1.getSelectedItem();
try
{
url1=new URL("file:/c:/"+s);
player1=Manager.createPlayer(url1);
player1.addControllerListener(this);
player1.realize();
label1.setText(s);
}
catch(Exception e1)
{label1.setText(""+e1); }
}
if(e.getSource()==button1)
{
System.exit(0);
}
}
public synchronized void controllerUpdate(ControllerEvent e2)
{
if(e2 instanceof
RealizeCompleteEvent)
{player1.prefetch();}
if(e2 instanceof PrefetchCompleteEvent)
{ player1.start();}
}
public void stop()
{
player1.stop();
player1.deallocate();
}
}
==========================================
In the final demo(listjmf.java),we
deal with audio-video files .The
code is almost the same as above but for the addition of visible component and
ControPanelComponent.
player1.getVisualComponent() and player1.getControlPanelComponent()
are the required methods.These methods can be called only after the player has
been realized. The code should be clear now.
We have tested the program with mpg, avi,
wav,mid and au files.
-------------------------------------------
// listjmf.java
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import javax.media.*;
public class listjmf extends
Frame implements ControllerListener,ActionListener
{
Player player1 =
null;
Component component1
= null;
Component component2
= null;
URL url;
List list1;
Button button1;
Label label1;
public static void main(String args[])
{
listjmf app = new listjmf();
app.setBounds(200,150,400,200);
app.show();
}
listjmf()
{
setLayout(new BorderLayout());
list1 = new List();
list1.addItem("good.avi");
list1.addItem("trips.mid");
list1.addItem("spacemusic.au");
list1.addItem("cardring.wav");
list1.addItem("somersault.mpg");
add("West",list1);
button1 = new Button("exit");
button1.setBackground(Color.black);
button1.setForeground(Color.red);
add("North",button1);
label1 = new Label();
label1.setBackground(Color.black);
label1.setForeground(Color.green);
list1.addActionListener(this);
button1.addActionListener(this);
}
public void actionPerformed(ActionEvent
e)
{
if(e.getSource()==list1)
{
String s = list1.getSelectedItem();
String s1="file:/c:/"+s;
label1.setText(s1);
try
{
url1=new URL(s1);
player1=Manager.createPlayer(url1);
player1.addControllerListener(this);
player1.realize();
System.out.println("player realized");
}
catch(Exception e1)
{System.out.println(""+e1); }
}
if(e.getSource()==button1)
{
System.exit(0);
}
}
//------------------
public synchronized void controllerUpdate(ControllerEvent e2)
{
if(e2 instanceof RealizeCompleteEvent)
{ job1();}
if(e2 instanceof PrefetchCompleteEvent)
{job2(); }
}
//------------------------
void job1()
{
component1 =
player1.getVisualComponent();
component2 = player1.getControlPanelComponent();
invalidate();
if(component1 != null)
{
add("Center",component1); }
else { add("Center",label1);}
if(component2 != null)
{ add("South",component2);}
validate();
player1.prefetch();
}
//-------------------------
void job2()
{
player1.start();
}
//---------------------------
public void stop()
{
player1.stop();
player1.deallocate();
}
//--------------------
}
===========================================
JMF is a powerful package with much more
functionality than what has been indicated here. This is just an introductory
lesson. More details can be obtained from jmf site ============================================