I have used JMF to transmit and receive audio for an application using JAIN-SIP and below is my code:
import com.sun.media.rtp.RTPSessionMgr;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.*;
import javax.media.format.AudioFormat;
import javax.media.format.UnsupportedFormatException;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;
import javax.media.rtp.InvalidSessionAddressException;
import javax.media.rtp.ReceiveStream;
import javax.media.rtp.ReceiveStreamListener;
import javax.media.rtp.SendStream;
import javax.media.rtp.SessionAddress;
import javax.media.rtp.event.NewReceiveStreamEvent;
import javax.media.rtp.event.ReceiveStreamEvent;
import java.net.*;
import javax.media.control.TrackControl;
import javax.media.rtp.*;
import com.sun.media.rtp.*;
import javax.media.rtp.RTPManager;
/**
*
* @author dexter
*/
public class Transmitter extends Thread implements ReceiveStreamListener {
static Processor mp;
static DataSink ds;
String ip,port;
RTPManager rtp;
SendStream ss;
ReceiveStream rs;
DataSource rds,ods,source;
Player player;
SessionAddress remoteaddr;
public void run()
{
try {
Format[] formats= new Format[]{new AudioFormat(AudioFormat.ULAW_RTP)};
ContentDescriptor cd= new ContentDescriptor(ContentDescriptor.RAW_RTP);
Vector devices= CaptureDeviceManager.getDeviceList(new
AudioFormat("linear",8000,16,2));
System.out.println("devices="+devices);
CaptureDeviceInfo di=(CaptureDeviceInfo) devices.firstElement();
System.out.println("device info="+di);
MediaLocator ml= di.getLocator();
System.out.println("locator="+ml);
try {
source = javax.media.Manager.createDataSource(ml);
}
catch (Exception e) {
// Try JavaSound Locator as a last resort
try {
source= javax.media.Manager.createDataSource(new MediaLocator("javasound://"));
}
catch (Exception ee) {
System.err.println("Couldn't create DataSource");
}
}
mp=Manager.createRealizedProcessor(new ProcessorModel(source,formats,cd));
mp.start();
rtp=RTPManager.newInstance();
// rtp.addReceiveStreamListener((ReceiveStreamListener) this);
SessionAddress localaddr= new SessionAddress(InetAddress.getByName(Phone.ip),Integer.parseInt(SipLayer.caller_port));
remoteaddr= new SessionAddress(InetAddress.getByName(ip),new Integer(port));
rtp.initialize(localaddr);
rtp.addReceiveStreamListener(this);
rtp.addTarget(remoteaddr);
ss=rtp.createSendStream(mp.getDataOutput(),0);
// mp.start();
ss.start();
} catch (UnsupportedFormatException ex) {
Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidSessionAddressException ex) {
Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
} catch (CannotRealizeException ex) {
Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoProcessorException ex) {
Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
}
}
public Transmitter(String callee_ip,String callee_port)
{
ip=callee_ip;
port= callee_port;
}
public void update(ReceiveStreamEvent rse) {
if(rse instanceof NewReceiveStreamEvent)
{
try {
rs = rse.getReceiveStream();
rds = rs.getDataSource();
player = Manager.createPlayer(rds);
player.start();
} catch (IOException ex) {
Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoPlayerException ex) {
Logger.getLogger(Transmitter.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public void stop_media()
{
try{
player.stop();
player.deallocate();
player.close();
ss.stop();
// necessary for sending rtcp bye
mp.stop();
mp.close();
mp.deallocate();
ss.close();
//
rtp.removeTarget(remoteaddr," disconnected");
rtp.dispose();
}catch(Exception e){
}
}
}
The Problem is: when i create a connection from my application(i.e i call) there is no problem and i can send and receive audio. But when i receive the call , then i can hear the other side but other side can't hear me. In wireshark it comes destination port unreachable. Please suggest what is the solution to this problem and why it is coming.
Anyways i have solved the question and i think this has been problem for many, So please don't delete it. The reason 'Port Unreachable' comes is simple: The port that you have allocated might have been in use or you may have ignored the fact that RTP requires an even numbered port for sending data and odd numbered port for RTCP.AND RTCP is handled by JMF automatically.So just find an un-used even numbered UDP port and use it to send RTP. Also , disable firewall if unable to receive any packet(SIP or RTP)
public static int findFreePort() {
DatagramSocket socket = null;
int port=1;
try {
while(port%2!=0)
{
socket = new DatagramSocket(0);
socket.setReuseAddress(true);
port = socket.getLocalPort();
socket.close();
}
return port;
} catch (IOException e) {
} finally {
if (socket != null) {
socket.close();
}
}
throw new IllegalStateException("Could not find a free UDP port to start");
}