Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Player realization in JMF using RTP

I am having an issue that I've been struggling with for the greater part of a week and have tried at least 10 different implementations and all seem to fail. There must be something that I am not understanding.

I am using jmf to transfer audio via rtp. The issue is that the clients player will never realize, and consequently, the code blocks, and nothing is ever played.

The code for the Transmitter is as follows:

import java.io.File;
import java.io.IOException;
import javax.media.DataSink;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoProcessorException;
import javax.media.NotRealizedError;
import javax.media.Processor;
import javax.media.control.FormatControl;
import javax.media.control.TrackControl;
import javax.media.format.AudioFormat;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;

public class RTPTransmitter
{

/**
 * @param args
 */
public static void main(String[] args)
{
    File f = new File("streamtest.wav");

    Format format;

    format = new AudioFormat(AudioFormat.ULAW_RTP, 8000, 8, 1);

    Processor processor = null;
    try
    {
        processor = Manager.createProcessor(f.toURI().toURL());
    } catch (IOException e)
    {
        e.printStackTrace();
        System.exit(-1);
    } catch (NoProcessorException e)
    {
        e.printStackTrace();
        System.exit(-1);
    }

    // configure the processor
    processor.configure();

    while (processor.getState() != Processor.Configured)
    {
        try
        {
            Thread.sleep(100);
        } catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    processor.setContentDescriptor(new ContentDescriptor(ContentDescriptor.RAW_RTP));

    TrackControl track[] = processor.getTrackControls();

    boolean encodingOk = false;

    // Go through the tracks and try to program one of them to
    // output gsm data.

    for (int i = 0; i < track.length; i++)
    {
        if (!encodingOk && track[i] instanceof FormatControl)
        {
            if (((FormatControl) track[i]).setFormat(format) == null)
            {

                track[i].setEnabled(false);
            } else
            {
                encodingOk = true;
            }
        } else
        {
            // we could not set this track to gsm, so disable it
            track[i].setEnabled(false);
        }
    }

    //realize the processor
    processor.realize();
    while(processor.getState() != processor.Realized){
        try
        {
            Thread.sleep(100);
        } catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    // At this point, we have determined where we can send out
    // gsm data or not.
    if (encodingOk)
    {       
        // get the output datasource of the processor and exit
        // if we fail
        DataSource ds = null;

        try
        {
            ds = processor.getDataOutput();
        } catch (NotRealizedError e)
        {
            e.printStackTrace();
            System.exit(-1);
        }

        // hand this datasource to manager for creating an RTP
        // datasink our RTP datasink will multicast the audio
        try
        {
            String url = "rtp://127.0.0.1:8000/audio/1";

            MediaLocator m = new MediaLocator(url);

            DataSink d = Manager.createDataSink(ds, m);
            d.open();
            d.start();

            System.out.println("Starting processor");
            processor.start();
            System.out.println("Processor Started");
            Thread.sleep(30000);
        } catch (Exception e)
        {
            e.printStackTrace();
            System.exit(-1);
        }
    }

}

}

And the code for the receiver is:

import java.io.IOException;
import java.net.MalformedURLException;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoPlayerException;
import javax.media.Player;

public class RTPReceiver
{

/**
 * @param args
 */
public static void main(String[] args)
{
    String url = "rtp://127.0.0.1:8000/audio/1";

    MediaLocator mrl = new MediaLocator(url);

    // Create a player for this rtp session
    Player player = null;
    try
    {
        player = Manager.createPlayer(mrl);
    } catch (NoPlayerException e)
    {
        e.printStackTrace();
        System.exit(-1);
    } catch (MalformedURLException e)
    {
        e.printStackTrace();
        System.exit(-1);
    } catch (IOException e)
    {
        e.printStackTrace();
        System.exit(-1);
    }

    if (player != null)
    {
        System.out.println("Player created.");
        player.realize();
        // wait for realizing
        while (player.getState() != Player.Realized)
        {
            try
            {
                Thread.sleep(10);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        System.out.println("Starting player");
        player.start();
    } else
    {
        System.err.println("Player won't create.");
        System.exit(-1);
    }

    System.out.println("Exiting.");
}

}

The transmitter starts up fine, everything gets started, and it all seems to work. So I start up the receiver and it just loops at

while (player.getState() != Player.Realized)

What frustrates me so much is that this is a simple test case and these files are directly adapted from examples. Further, they are as simple as I could make them and yet they still seem to not work.

Any help would be greatly appreciated! Thank YOU!

like image 630
Dabloons Avatar asked Feb 22 '23 18:02

Dabloons


2 Answers

hey i can understand the frustration. i was having a similar problem myself. Anyways i have almost the same transmitter but in the receiver i am using the ControlListener to listen for when the player is realized.

public AudioRTPRecv() {
    MediaLocator mrl= new MediaLocator("rtp://192.168.1.100:49151/audio/1");

    // Create a player for this rtp session
    try {
        player = Manager.createPlayer(mrl);
    } catch (Exception e) {
        System.err.println("Error:" + e);
        return;
    }

    if (player != null) {
        player.addControllerListener(this);
        player.realize();
    }
}

public synchronized void controllerUpdate(ControllerEvent ce) {
    System.out.println(ce);
    if(ce instanceof TransitionEvent) {
        if (((TransitionEvent)ce).getCurrentState() == Processor.Realized) {
            player.start();
            System.out.println("starting player now");
        }
    }
}

This has the added advantage that the print statement in controllerUpdate method gives you in idea of whats going on with the player.

like image 53
Hammad Khan Avatar answered Feb 26 '23 21:02

Hammad Khan


I also used to get same problem. It sticks on the "realizing" state. Your program just needs a little change. You know you will bang your table after reading the solution :D

That is, instead of typing "127.0.0.1", type your IP address. Thats it!

And run it.

like image 39
piyush jain Avatar answered Feb 26 '23 22:02

piyush jain