FileDocCategorySizeDatePackage
RtspUtil.javaAPI DocJMF 2.1.1e20193Mon May 12 12:20:58 BST 2003com.sun.media.content.rtsp

RtspUtil

public class RtspUtil extends Object implements RtspListener

Fields Summary
private final int
TIMER_1
private final int
TIMER_2
private RtspManager
rtspManager
private RTPManager[]
mgrs
private String[]
mediaTypes
private long
sequenceNumber
private int
numberOfTracks
private String
userAgent
private RtspUrl
rtspUrl
private String[]
mediaControls
private int[]
server_ports
private int[]
client_ports
private String[]
session_ids
private Message
message
private int
connectionId
private String
url
private double
startPos
private String
processError
private long
duration
private Vector
listeners
private ReceiveStreamListener
parent
boolean
responseReceived
boolean
dataReceived
Object
responseSync
Constructors Summary
public RtspUtil(ReceiveStreamListener parent)


        
	this.parent= parent;
	
        listeners = new Vector();
	
	rtspManager = new RtspManager(false);
		
        sequenceNumber = (long)(Math.random() * 1000);

	userAgent = "User-Agent: JMF RTSP Player " + BasicPlayer.VERSION; 
	
        rtspManager.addListener(this);
    
Methods Summary
private voidaddDynamicPayload(javax.media.rtp.RTPManager mgr, java.lang.String typeStr, java.lang.String dpStr)
Parse the dynamic payload string and add the payload type to the RTPManager.


	// Parse the dynamic payload.
	int payload;
	Format fmt;
	int c;
	String tmpStr;

	// Skip leading spaces.
	c = 0;
	while (dpStr.length() > 0 && dpStr.charAt(c) == ' ") c++;
	if (c > 0)
	    dpStr = dpStr.substring(c);

	// Parse the payload number.
	c = 0;
	while (dpStr.length() > 0 && dpStr.charAt(c) != ' ") c++;
	if (c < 0)
	    return;

	tmpStr = dpStr.substring(0, c);
	dpStr = dpStr.substring(c);

	Integer integer = Integer.valueOf(tmpStr);
	if (integer == null)
	    return;

	// Check the payload value.
	payload = integer.intValue();
	if (payload < 96 || payload > 127)
	    return;

	// Skip leading spaces.
	c = 0;
	while (dpStr.length() > 0 && dpStr.charAt(c) == ' ") c++;
	if (c > 0)
	    dpStr = dpStr.substring(c);

	if (dpStr.length() == 0)
	    return;
		
	// Parse the format string.
	c = 0;
	while (dpStr.length() > 0 && dpStr.charAt(c) != '/") c++;
	if (c > 0)
	    tmpStr = dpStr.substring(0, c);
	else
	    tmpStr = dpStr;

	if (tmpStr.length() == 0)
	    return;

	// Append "/rtp" to generate a JMF RTP encoding.
	tmpStr = tmpStr.toLowerCase() + "/rtp";

	// Add the payload type to format mapping the the manager.

	if ("video".equalsIgnoreCase(typeStr)) {
	    mgr.addFormat(new VideoFormat(tmpStr), payload);
	    Log.comment("Add RTP dynamic payload for video: " + payload + " : " + tmpStr);
	} if ("audio".equalsIgnoreCase(typeStr)) {
	    mgr.addFormat(new AudioFormat(tmpStr), payload);
	    Log.comment("Add RTP dynamic payload for audio: " + payload + " : " + tmpStr);
	}
    
public voidaddListener(com.sun.media.rtsp.RtspAppListener listener)

        listeners.addElement(listener);
    
public voidcloseConnection()

        rtspManager.closeConnection(connectionId);
    
public booleancreateConnection()

	boolean realized= true;
	
	try {
            rtspUrl = new RtspUrl(url);
	} catch( MalformedURLException e) {
	    processError= "Invalid RTSP URL: " + url;
	    return false;
	}

        String ipAddress = getServerIpAddress();

	if( ipAddress == null) {
            Log.error( "Invalid server address:" + url);	    
	    processError= "Invalid Server adress: " + url;
	    return false;
	}
	
        connectionId = rtspManager.createConnection(ipAddress, rtspUrl.getPort());

        if (connectionId < 0) {
            switch (connectionId) {
                case - 2:
                    processError = "Unknown RTSP Host!";
                    break;
                case - 3:
                    processError = "Can't connect to RTSP Server!";
                    break;
                default:
                    processError = "Unknown reason";
                break;
            }

            realized = false;
        }

        return realized;
    
public javax.media.rtp.RTPManagercreateSessionManager(int index)

	RTPManager rtpManager= RTPManager.newInstance();

        if (rtpManager == null) {
            return null;
        }

        rtpManager.addReceiveStreamListener((ReceiveStreamListener) parent);

        try {
            // create the local Session Address:
            InetAddress localHost = InetAddress.getLocalHost();

            // SessionAddress localAddress = new SessionAddress( localHost,
	    // client_port);

	    SessionAddress localAddress= new SessionAddress();
	    
            // initialize the RTP Manager:
            rtpManager.initialize( localAddress);

	    client_ports[ index] = localAddress.getDataPort();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
	}

        return rtpManager;
    
private java.lang.StringgetContentBase()

        String contentBase= "";

	try {
            ResponseMessage responseMsg = (ResponseMessage) message.getParameter();

            Header header = responseMsg.getResponse().getHeader( Header.CONTENT_BASE);

            ContentBaseHeader cbh = (ContentBaseHeader)header.parameter;

            contentBase = cbh.getContentBase();
	} catch( Exception e) {
	}

        return contentBase;
    
private java.lang.StringgetCurMediaType(int i)

	String type = null;

	try {
	    ResponseMessage msg = (ResponseMessage) message.getParameter();

            SdpParser sdp = msg.getResponse().sdp;

	    MediaDescription md = (MediaDescription) sdp.getMediaDescriptions().elementAt( i);

            type = md.name;
	} catch( Exception e) {
	}

	return type;
    
public longgetDuration()

	return duration;
    
public static java.lang.StringgetMediaAttribute(com.sun.media.sdp.MediaDescription md, java.lang.String attribute)


        String mediaAttribute= "";

        if( md != null) {
            MediaAttribute ma = md.getMediaAttribute( "control");

	    if( ma != null) {
                mediaAttribute= ma.getValue();
	    }
	}

        return mediaAttribute;
    
private java.lang.StringgetMediaAttributeValue(int i, java.lang.String attribute)

	String value = null;

	try {
	    ResponseMessage msg = (ResponseMessage) message.getParameter();

            SdpParser sdp = msg.getResponse().sdp;

	    MediaDescription md = (MediaDescription) sdp.getMediaDescriptions().elementAt( i);

	    MediaAttribute ma= md.getMediaAttribute( attribute);

	    value= ma.getValue();
	} catch( Exception e) {
	}

	return value;
    
private com.sun.media.sdp.MediaDescriptiongetMediaDescription(java.lang.String mediaName)

        MediaDescription description = null;

	try {
            ResponseMessage msg = (ResponseMessage) message.getParameter();
	
            SdpParser sdp = msg.getResponse().sdp;

            description = sdp.getMediaDescription(mediaName);
	} catch( Exception e) {
	}

        return description;
    
public java.lang.StringgetMediaType(int i)

	return mediaTypes[ i];
    
public java.lang.String[]getMediaTypes()

	return mediaTypes;
    
private intgetNumTracks()

	int numTracks = 0;
	
	ResponseMessage msg = (ResponseMessage) message.getParameter();

        SdpParser sdp = msg.getResponse().sdp;

	if (sdp != null) {
	    numTracks = sdp.getMediaDescriptions().size();
	}

	return numTracks;
    
public intgetNumberOfTracks()

	return numberOfTracks;
    
public java.lang.StringgetProcessError()

	return processError;
    
public javax.media.rtp.RTPManagergetRTPManager(int i)

	return mgrs[ i];
    
public javax.media.rtp.RTPManager[]getRTPManagers()

	return mgrs;
    
private intgetServerDataPort()

	int port= -1;

	try {
            ResponseMessage responseMsg = (ResponseMessage) message.getParameter();
	    
            TransportHeader transport_hdr =
                    (TransportHeader) responseMsg.getResponse()
	                .getHeader( Header.TRANSPORT).parameter;

	    port= transport_hdr.getServerDataPort();
	} catch( Exception e) {
	}

	return port;
    
public java.lang.StringgetServerIpAddress()

        String ipAddress = null;

	try {
	    if( rtspUrl == null) {
		rtspUrl= new RtspUrl( url);
	    }
	    
            String host = rtspUrl.getHost();

	    if( host != null) {		
                ipAddress = InetAddress.getByName(host).getHostAddress();
	    }
	} catch( MalformedURLException e) {
	    // System.err.println( "Malformed URL Exception: " + e);
	} catch (UnknownHostException e) {
            // System.err.println( "Host unknown: " + name);
        }
	
        return ipAddress;
    
public int[]getServerPorts()

	return server_ports;
    
private java.lang.StringgetSessionId()

	String id= null;

	try {
            ResponseMessage responseMsg = (ResponseMessage) message.getParameter();

            SessionHeader hdr = (SessionHeader) responseMsg.getResponse().getHeader(
                    Header.SESSION).parameter;

	     id= hdr.getSessionId();
	} catch( Exception e) {
	}

	return id;
    
public intgetStatusCode()

	int code= -1;

	try { 
            ResponseMessage responseMsg = (ResponseMessage) message.getParameter();
	    code= responseMsg.getResponse().getStatusLine().getCode();
	} catch( Exception e) {
	}

	return code;
    
private java.lang.StringgetStatusText(int code)

	return StatusCode.getStatusText( code);
    
private java.lang.StringgetTrackID(java.lang.String mediaName)

        String trackId = null;

	try {
            ResponseMessage msg = (ResponseMessage) message.getParameter();

            SdpParser sdp = msg.getResponse().sdp;

            MediaDescription description = sdp.getMediaDescription(mediaName);

            MediaAttribute attribute = description.getMediaAttribute("control");

            trackId = attribute.getValue();
        } catch( Exception e) {
	}

        return trackId;
    
private voidprocessRtspRequest(int connectionId, Message message)

        if (message.getType() == MessageType.OPTIONS) {
            OptionsMessage msg = (OptionsMessage) message.getParameter();

            sendResponse(connectionId, msg.getRequest());
        }
    
private voidprocessRtspResponse(int connectionId, Message message)

        this.message = message;

        responseReceived = true;

        synchronized (responseSync) {
            responseSync.notify();
        }
    
public voidremoveListener(com.sun.media.rtsp.RtspAppListener listener)

        listeners.removeElement(listener);
    
public voidremoveTrack(int trackId)

	Log.comment( "track removed: " + mediaTypes[ trackId]);

	mgrs[ trackId].removeTargets( "media track not supported");
	mgrs[ trackId].dispose();	
	
	numberOfTracks--;

	if( trackId  + 1 > mgrs.length) {
	    int length= mgrs.length - trackId - 1;
	
	    System.arraycopy( mgrs, trackId + 1, mgrs, trackId, length);
	}
    
private booleanresponseOk()

	boolean result= false;
	
        int statusCode= getStatusCode();
	
        if (statusCode == com.sun.media.rtsp.protocol.StatusCode.OK) {
	    result= true;            
        } else { 
            processError =  "Message from RTSP Server - " + getStatusText(statusCode);
        }
	
        return result;
    
public voidrtspConnectionTerminated(int connectionId)

        // System.out.println( "RtspPlayer::rtspConnectionTerminated");
    
public voidrtspMessageIndication(int connectionId, Message message)

	if (message.getType() == MessageType.RESPONSE) {
            processRtspResponse(connectionId, message);
        } else {
            processRtspRequest(connectionId, message);
        }
    
public booleanrtspSetup()

        String msg = "DESCRIBE rtsp://" + rtspUrl.getHost() + "/" + rtspUrl.getFile() +
                     " RTSP/1.0\r\n" + "CSeq: " + sequenceNumber + "\r\n" +
                     "Accept: application/sdp\r\n" + userAgent + "\r\n\r\n";

        sendMessage(msg);

        boolean timeout = waitForResponse(TIMER_1);

        if (timeout) {
            sendStatusMessage(StatusMessage.TIMEOUT, "Timeout received.");

            return false;
        }

	if( !responseOk()) {
	    return false;
	}

        setDuration();

	// create the RTP Managers:
	numberOfTracks = getNumTracks();

	client_ports = new int[ numberOfTracks];

        mgrs = new RTPManager[ numberOfTracks];
	
	// get control strings and media types:
	mediaControls = new String[ numberOfTracks];
	mediaTypes= new String[ numberOfTracks];
	String dynamicPayloads[]= new String[ numberOfTracks];

	for( int i = 0; i < numberOfTracks; i++) {	             
	    mgrs[ i] = createSessionManager( i);

	    mediaTypes[ i] = getCurMediaType( i);
	    mediaControls[ i] = getMediaAttributeValue( i, "control");	    
	    dynamicPayloads[ i] = getMediaAttributeValue( i, "rtpmap");

	    // Add the dynamic payloads if there's one.
	    if (mediaTypes[i] != null && dynamicPayloads[i] != null) {
		addDynamicPayload(mgrs[i], mediaTypes[i], dynamicPayloads[i]);
	    }
	}

	// get the content base:
        String contentBase = getContentBase();

	session_ids = new String[ numberOfTracks];

	server_ports = new int[ numberOfTracks];

	// setup the individual tracks:	    
        for( int i = 0; i < numberOfTracks; i++) {
	    if( i == 0) {            	      	   
                msg = "SETUP " + contentBase + mediaControls[ i] + " RTSP/1.0\r\n" + 
                      "CSeq: " + sequenceNumber + "\r\n" +
                      "Transport: RTP/AVP;unicast;client_port=" + client_ports[ i] +
                      "-" + (client_ports[ i] + 1) + "\r\n" + userAgent + "\r\n\r\n";
	    } else {
                msg = "SETUP " + contentBase + mediaControls[ i] + " RTSP/1.0\r\n" + 
                      "CSeq: " + sequenceNumber + "\r\n" +
                       "Transport: RTP/AVP;unicast;client_port=" + client_ports[ i] +
                       "-" + (client_ports[ i] + 1) + "\r\n" + "Session: " +
                       session_ids[ 0] + "\r\n" + userAgent + "\r\n\r\n";
	    }

            sendMessage(msg);

            timeout = waitForResponse(TIMER_2);

            if (timeout) {
                Log.error("ERROR: Timeout received (1).");
		processError= "Server is not responding";		
                return false;
            }

	    if( !responseOk()) {
	        return false;
	    }	    

	    String sessionId= getSessionId();

	    if( sessionId == null) {
		processError= "Invalid session ID";
		return false;
	    }
	    
            session_ids[ i] = sessionId;

            int pos = session_ids[ i].indexOf(';");

            if (pos > 0) {
                session_ids[ i] = session_ids[ i].substring(0, pos);
            }

	    int serverPort= getServerDataPort();

	    if( serverPort == -1) {
		processError= "Invalid server data port";
		return false;
	    }

            server_ports[ i] = serverPort;	    
	}

        return true;
    
public booleanrtspStart()

        String msg;

	// start all tracks in one compound statement:
        msg = "PLAY rtsp://" + rtspUrl.getHost() + "/" +
                rtspUrl.getFile() + " RTSP/1.0\r\n" + "CSeq: " +
                sequenceNumber + "\r\n" + "Range: npt=" +
                (startPos / 1000000000) + "-\r\n" + "Session: " +
                 session_ids[ 0] + "\r\n" + userAgent + "\r\n\r\n";

        sendMessage(msg);

        boolean timeout = waitForResponse(TIMER_2);

        if (timeout) {
	    processError= "Server is not responding";
            return false;
        }

	int code= getStatusCode();

	if( code == -1) {
	    processError= "Received invalid status code";
	    return false;
	}
	
        if (getStatusCode() == com.sun.media.rtsp.protocol.StatusCode.SESSION_NOT_FOUND) {
	    for( int i = 0; i < numberOfTracks; i++) {
		mgrs[ i].removeTargets( "session not found");
		mgrs[ i].dispose();

                return false;
            }
	}

        return true;
    
public voidrtspStop()

        String msg = "PAUSE rtsp://" + rtspUrl.getHost() +
		     "/" + rtspUrl.getFile() +
                     " RTSP/1.0\r\n" + "CSeq: " + sequenceNumber + "\r\n" +
                     "Session: " + session_ids[ 0] + "\r\n" + userAgent +
		     "\r\n\r\n";

        sendMessage(msg);

        boolean timeout = waitForResponse(TIMER_2);

        if (timeout) {
            sendStatusMessage(StatusMessage.TIMEOUT, "Timeout received.");

            return;
        }
    
public voidrtspTeardown()

        String msg = "TEARDOWN rtsp://" + rtspUrl.getHost() + "/" +
                rtspUrl.getFile() + " RTSP/1.0\r\n" + "CSeq: " +
                sequenceNumber + "\r\n" + "Session: " + session_ids[ 0] +
                "\r\n" + userAgent + "\r\n\r\n";

        sendMessage(msg);
        
        boolean timeout= waitForResponse( TIMER_2);

        if (timeout) {
            sendStatusMessage( StatusMessage.TIMEOUT,
                               "Timeout received.");

            return;
         }
    
private voidsendMessage(java.lang.String message)

        responseReceived = false;

        boolean success = rtspManager.sendMessage(connectionId, message);

        if (!success) {
            String ipAddress = getServerIpAddress();

            connectionId = rtspManager.createConnection(ipAddress, rtspUrl.getPort());

            rtspManager.sendMessage(connectionId, message);
        }
    
private voidsendResponse(int connectionId, com.sun.media.rtsp.protocol.Request msg)

        String type = null;

        Header header = msg.getHeader(Header.CSEQ);

        if( header != null) {
            CSeqHeader cSeqHeader = (CSeqHeader) header.parameter;

            String message = "RTSP/1.0 200 OK\r\n" + "CSeq: " +
                    cSeqHeader.getSequenceNumber() + "\r\n\r\n";

            sendMessage(message);
	}
    
private voidsendStatusMessage(int code, java.lang.String message)

        for (int i = 0; i < listeners.size(); i++) {
            ((RtspAppListener) listeners.elementAt(i)).postStatusMessage(code,
                    message);
        }
    
private voidsetDuration()

        duration= 0;

        ResponseMessage msg = (ResponseMessage) message.getParameter();

        double start_time = 0.0;
        double end_time = 0.0;

        SdpParser sdp = msg.getResponse().sdp;

        if (sdp != null) {
            MediaAttribute attribute = sdp.getSessionAttribute("range");

            if (attribute != null) {
                String value=  attribute.getValue();

                if (value.startsWith("npt")) {
                    int start = value.indexOf('=") + 1;
                    int end = value.indexOf('-");

                    String startTime = value.substring(start, end).trim();

                    String endTime = value.substring(end + 1).trim();

                    end_time = new Double(endTime).doubleValue();

                    duration = (long)(end_time * 1000000000);
                }
            }
        }
    
public voidsetProcessError(java.lang.String error)

	processError= error;
    
public voidsetStartPos(double startPos)

	
	this.startPos = startPos;
    
public voidsetUrl(java.lang.String url)

	this.url = url;	
    
private synchronized booleanwaitForResponse(int time)


         
        boolean timeout = false;

        try {
            synchronized (responseSync) {

		if (!responseReceived) {
		    responseSync.wait(time);
		}

                if (responseReceived) {
                    sequenceNumber++;
                } else {
                    timeout = true;
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return timeout;