Problem with using JMF audio over a network
Hiya, I'm using IBM JMF code but I'm having problems trying to get it transmit data from the MediaTransmitter to the MediaPlayerFrame.
I'm kinda new to JMF so I assume I'm missing something basis for why this doesn't work.
Any help would be greatly appreciated.
MediaPlayerFrame
import javax.media.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
/**
* An instance of the MediaPlayerFrame may be used to display any media
* recognized * by JMF. This is intended to be a very simple GUI example,
* displaying all possible controls for the given media type.
*/
publicclass MediaPlayerFrameextends JFrame{
/**
* The frame title.
*/
privatestaticfinal String FRAME_TITLE ="developerWorks JMF Tutorial " +
"Media Player";
/**
* The panel title of the main control panel.
*/
privatestaticfinal String CONTROL_PANEL_TITLE ="Control Panel";
// location and size variables for the frame.
privatestaticfinalint LOC_X = 100;
privatestaticfinalint LOC_Y = 100;
privatestaticfinalint HEIGHT = 500;
privatestaticfinalint WIDTH = 500;
privatefinalstaticlong serialVersionUID = 1;
/**
* The current player.
*/
private Player player =null;
/**
* The tabbed pane for displaying controls.
*/
private JTabbedPane tabPane =null;
/**
* Create an instance of the media frame. No data will be displayed in the
* frame until a player is set.
*/
public MediaPlayerFrame(){
super(FRAME_TITLE);
System.out.println("MediaPlayerFrame");
setLocation(LOC_X, LOC_Y);
setSize(WIDTH, HEIGHT);
tabPane =new JTabbedPane();
getContentPane().add(tabPane);
/* adds a window listener so that the player may be cleaned up before
the frame actually closes.
*/
addWindowListener(new WindowAdapter(){
/**
* Invoked when the frame is being closed.
*/
publicvoid windowClosing(WindowEvent e){
closeCurrentPlayer();
/* Closing this frame will cause the entire
application to exit. When running this
example as its own application, this is
fine - but in general, a closing frame
would not close the entire application.
If this behavior is not desired, comment
out the following line:
*/
System.exit(0);
}
});
}
/**
* Creates the main panel. This panel will contain the following if they
* exist:
* - The visual component: where any visual data is displayed, i.e. a
* movie uses this control to display the video.
* - The gain component:where the gain/volume may be changed. This
* is often * contained in the control panel component (below.)
* - The control panel component: time and some extra info regarding
* the media.
*/
private JPanel createMainPanel(){
System.out.println("createMainPanel");
JPanel mainPanel =new JPanel();
GridBagLayout gbl =new GridBagLayout();
GridBagConstraints gbc =new GridBagConstraints();
mainPanel.setLayout(gbl);
boolean visualComponentExists =false;
// if the visual component exists, add it to the newly created panel.
if (player.getVisualComponent() !=null){
visualComponentExists =true;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
mainPanel.add(player.getVisualComponent(), gbc);
}
// if the gain control component exists, add it to the new panel.
if ((player.getGainControl() !=null) &&
(player.getGainControl().getControlComponent() !=null)){
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 0;
gbc.weighty = 1;
gbc.gridheight = 2;
gbc.fill = GridBagConstraints.VERTICAL;
mainPanel.add(player.getGainControl().getControlComponent(), gbc);
}
// Add the control panel component if it exists (it should exists in
// all cases.)
if (player.getControlPanelComponent() !=null){
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 1;
gbc.gridheight = 1;
if (visualComponentExists){
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weighty = 0;
}else{
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 1;
}
mainPanel.add(player.getControlPanelComponent(), gbc);
}
return mainPanel;
}
/**
* Sets the media locator. Setting this to a new value effectively
* discards any Player which may have already existed.
* @param locator the new MediaLocator object.
* @throws IOException indicates an IO error in opening the media.
* @throws NoPlayerException indicates no player was found for the
* media type.
* @throws CannotRealizeException indicates an error in realizing the
* media file or stream.
*/
publicvoid setMediaLocator(MediaLocator locator)throws IOException,
NoPlayerException, CannotRealizeException{
System.out.println("setMediaLocator: " +locator);
// create a new player with the new locator. This will effectively
// stop and discard any current player.
setPlayer(Manager.createRealizedPlayer(locator));
}
/**
* Sets the player reference. Setting this to a new value will discard
* any Player which already exists. It will also refresh the contents
* of the pane with the components for the new player. A null value will
* stop the discard the current player and clear the contents of the
* frame.
*/
publicvoid setPlayer(Player newPlayer){
System.out.println("setPlayer");
// close the current player
closeCurrentPlayer();
player = newPlayer;
// refresh the tabbed pane.
tabPane.removeAll();
if (player ==null)return;
// add the new main panel
tabPane.add(CONTROL_PANEL_TITLE, createMainPanel());
// add any other controls which may exist in the player. These
// controls should already contain a name which is used in the
// tabbed pane.
Control[] controls = player.getControls();
for (int i = 0; i < controls.length; i++){
if (controls[i].getControlComponent() !=null){
tabPane.add(controls[i].getControlComponent());
}
}
}
/**
* Stops and closes the current player if one exists.
*/
privatevoid closeCurrentPlayer(){
if (player !=null){
player.stop();
player.close();
}
}
/**
* Prints a usage message to System.out for how to use this class
* through the command line.
*/
publicstaticvoid printUsage(){
System.out.println("Usage: java MediaPlayerFrame mediaLocator");
}
/**
* Allows the user to run the class through the command line.
* Only one argument is allowed, which is the media locator.
*/
publicstaticvoid main(String[] args){
try{
if (args.length == 1){
MediaPlayerFrame mpf =new MediaPlayerFrame();
/* The following line creates a media locator using the String
passed in through the command line. This version should
be used when receiving media streamed over a network.
*/
mpf.setMediaLocator(new MediaLocator(args[0]));
/* the following line may be used to create and set the media
locator from a simple file name. This works fine when
playing local media. To play media streamed over a
network, you should use the previous setMediaLocator()
line and comment this one out.
*/
//mpf.setMediaLocator(new MediaLocator(
//new File(args[0]).toURL()));
mpf.setVisible(true);
}else{
printUsage();
}
}catch (Throwable t){
t.printStackTrace();
}
}
}
MediaTransmitter
import javax.media.*;
import javax.media.control.*;
import javax.media.protocol.*;
import javax.media.format.*;
import java.io.IOException;
import java.io.File;
/**
* Creates a new media transmitter. The media transmitter may be used to
* transmit a data source over a network.
*/
publicclass MediaTransmitter{
/**
* Output locator - this is the broadcast address for the media.
*/
private MediaLocator mediaLocator =null;
/**
* The data sink object used to broadcast the results from the processor
* to the network.
*/
private DataSink dataSink =null;
/**
* The processor used to read the media from a local file, and produce an
* output stream which will be handed to the data sink object for
* broadcast.
*/
private Processor mediaProcessor =null;
/**
* The track formats used for all data sources in this transmitter. It is
* assumed that this transmitter will always be associated with the same
* RTP stream format, so this is made static.
*/
privatestaticfinal Format[] FORMATS =new Format[]{
new AudioFormat(AudioFormat.MPEG_RTP)};
/**
* The content descriptor for this transmitter. It is assumed that this
* transmitter always handles the same type of RTP content, so this is
* made static.
*/
privatestaticfinal ContentDescriptor CONTENT_DESCRIPTOR =
new ContentDescriptor(ContentDescriptor.RAW_RTP);
/**
* Creates a new transmitter with the given outbound locator.
*/
public MediaTransmitter(MediaLocator locator){
mediaLocator = locator;
}
/**
* Starts transmitting the media.
*/
publicvoid startTransmitting()throws IOException{
// start the processor
mediaProcessor.start();
// open and start the data sink
dataSink.open();
dataSink.start();
}
/**
* Stops transmitting the media.
*/
publicvoid stopTransmitting()throws IOException{
// stop and close the data sink
dataSink.stop();
dataSink.close();
// stop and close the processor
mediaProcessor.stop();
mediaProcessor.close();
}
/**
* Sets the data source. This is where the transmitter will get the media
* to transmit.
*/
publicvoid setDataSource(DataSource ds)throws IOException,
NoProcessorException, CannotRealizeException, NoDataSinkException{
/* Create the realized processor. By calling the
createRealizedProcessor() method on the manager, we are guaranteed
that the processor is both configured and realized already.
For this reason, this method will block until both of these
conditions are true. In general, the processor is responsible
for reading the file from a file and converting it to
an RTP stream.
*/
mediaProcessor = Manager.createRealizedProcessor(
new ProcessorModel(ds, FORMATS, CONTENT_DESCRIPTOR));
/* Create the data sink. The data sink is used to do the actual work
of broadcasting the RTP data over a network.
*/
dataSink = Manager.createDataSink(mediaProcessor.getDataOutput(),
mediaLocator);
}
/**
* Prints a usage message to System.out for how to use this class
* through the command line.
*/
publicstaticvoid printUsage(){
System.out.println("Usage: java MediaTransmitter mediaLocator " +
"mediaFile");
System.out.println(" example: java MediaTransmitter " +
"rtp://192.168.1.72:49150/audio mysong.mp3");
System.out.println(" example: java MediaTransmitter " +
"rtp://192.168.1.255:49150/audio mysong.mp3");
}
/**
* Allows the user to run the class through the command line.
* Only two arguments are allowed; these are the output media
* locator and the mp3 audio file which will be broadcast
* in the order.
*/
publicstaticvoid main(String[] args){
try{
if (args.length == 2){
MediaLocator locator =new MediaLocator(args[0]);
MediaTransmitter transmitter =new MediaTransmitter(locator);
System.out.println("-> Created media locator: '" +
locator +"'");
/* Creates and uses a file reference for the audio file,
if a url or any other reference is desired, then this
line needs to change.
*/
File mediaFile =new File(args[1]);
DataSource source = Manager.createDataSource(
new MediaLocator(mediaFile.toURL()));
System.out.println("-> Created data source: '" +
mediaFile.getAbsolutePath() +"'");
// set the data source.
transmitter.setDataSource(source);
System.out.println("-> Set the data source on the transmitter");
// start transmitting the file over the network.
transmitter.startTransmitting();
System.out.println("-> Transmitting...");
System.out.println("Press the Enter key to exit");
// wait for the user to press Enter to proceed and exit.
System.in.read();
System.out.println("-> Exiting");
transmitter.stopTransmitting();
}else{
printUsage();
}
}catch (Throwable t){
t.printStackTrace();
}
System.exit(0);
}
}

