Skip to content

Instantly share code, notes, and snippets.

@carsontang
Created July 26, 2012 18:52
Show Gist options
  • Save carsontang/3183786 to your computer and use it in GitHub Desktop.
Save carsontang/3183786 to your computer and use it in GitHub Desktop.
Client
Client.java
/* ------------------
Client
usage: java Client [Server hostname] [Server RTSP listening port] [Video file requested]
---------------------- */
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;
public class Client{
//GUI
//----
JFrame f = new JFrame("Client");
JButton setupButton = new JButton("Setup");
JButton playButton = new JButton("Play");
JButton pauseButton = new JButton("Pause");
JButton tearButton = new JButton("Teardown");
JPanel mainPanel = new JPanel();
JPanel buttonPanel = new JPanel();
JLabel iconLabel = new JLabel();
ImageIcon icon;
//RTP variables:
//----------------
DatagramPacket rcvdp; //UDP packet received from the server
DatagramSocket RTPsocket; //socket to be used to send and receive UDP packets
static int RTP_RCV_PORT = 25000; //port where the client will receive the RTP packets
Timer timer; //timer used to receive data from the UDP socket
byte[] buf; //buffer used to store data received from the server
//RTSP variables
//----------------
//rtsp states
final static int INIT = 0;
final static int READY = 1;
final static int PLAYING = 2;
static int state; //RTSP state == INIT or READY or PLAYING
Socket RTSPsocket; //socket used to send/receive RTSP messages
//input and output stream filters
static BufferedReader RTSPBufferedReader;
static BufferedWriter RTSPBufferedWriter;
static String VideoFileName; //video file to request to the server
int RTSPSeqNb = 0; //Sequence number of RTSP messages within the session
int RTSPid = 0; //ID of the RTSP session (given by the RTSP Server)
final static String CRLF = "\r\n";
//Video constants:
//------------------
static int MJPEG_TYPE = 26; //RTP payload type for MJPEG video
//--------------------------
//Constructor
//--------------------------
public Client() {
//build GUI
//--------------------------
//Frame
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//Buttons
buttonPanel.setLayout(new GridLayout(1,0));
buttonPanel.add(setupButton);
buttonPanel.add(playButton);
buttonPanel.add(pauseButton);
buttonPanel.add(tearButton);
setupButton.addActionListener(new setupButtonListener());
playButton.addActionListener(new playButtonListener());
pauseButton.addActionListener(new pauseButtonListener());
tearButton.addActionListener(new tearButtonListener());
//Image display label
iconLabel.setIcon(null);
//frame layout
mainPanel.setLayout(null);
mainPanel.add(iconLabel);
mainPanel.add(buttonPanel);
iconLabel.setBounds(0,0,380,280);
buttonPanel.setBounds(0,280,380,50);
f.getContentPane().add(mainPanel, BorderLayout.CENTER);
f.setSize(new Dimension(390,370));
f.setVisible(true);
//init timer
//--------------------------
timer = new Timer(20, new timerListener());
timer.setInitialDelay(0);
timer.setCoalesce(true);
//allocate enough memory for the buffer used to receive data from the server
buf = new byte[15000];
}
//------------------------------------
//main
//------------------------------------
public static void main(String argv[]) throws Exception
{
//Create a Client object
Client theClient = new Client();
//get server RTSP port and IP address from the command line
//------------------
int RTSP_server_port = Integer.parseInt(argv[1]);
String ServerHost = argv[0];
InetAddress ServerIPAddr = InetAddress.getByName(ServerHost);
//get video filename to request:
VideoFileName = argv[2];
//Establish a TCP connection with the server to exchange RTSP messages
//------------------
theClient.RTSPsocket = new Socket(ServerIPAddr, RTSP_server_port);
//Set input and output stream filters:
RTSPBufferedReader = new BufferedReader(new InputStreamReader(theClient.RTSPsocket.getInputStream()) );
RTSPBufferedWriter = new BufferedWriter(new OutputStreamWriter(theClient.RTSPsocket.getOutputStream()) );
//init RTSP state:
state = INIT;
}
//------------------------------------
//Handler for buttons
//------------------------------------
//.............
//TO COMPLETE
//.............
//Handler for Setup button
//-----------------------
class setupButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e){
//System.out.println("Setup Button pressed !");
if (state == INIT)
{
//Init non-blocking RTPsocket that will be used to receive data
try{
//construct a new DatagramSocket to receive RTP packets from the server, on port RTP_RCV_PORT
//RTPsocket = ...
//set TimeOut value of the socket to 5msec.
//....
}
catch (SocketException se)
{
System.out.println("Socket exception: "+se);
System.exit(0);
}
//init RTSP sequence number
RTSPSeqNb = 1;
//Send SETUP message to the server
send_RTSP_request("SETUP");
//Wait for the response
if (parse_server_response() != 200)
System.out.println("Invalid Server Response");
else
{
//change RTSP state and print new state
//state = ....
//System.out.println("New RTSP state: ....");
}
}//else if state != INIT then do nothing
}
}
//Handler for Play button
//-----------------------
class playButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e){
//System.out.println("Play Button pressed !");
if (state == READY)
{
//increase RTSP sequence number
//.....
//Send PLAY message to the server
send_RTSP_request("PLAY");
//Wait for the response
if (parse_server_response() != 200)
System.out.println("Invalid Server Response");
else
{
//change RTSP state and print out new state
//.....
// System.out.println("New RTSP state: ...")
//start the timer
timer.start();
}
}//else if state != READY then do nothing
}
}
//Handler for Pause button
//-----------------------
class pauseButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e){
//System.out.println("Pause Button pressed !");
if (state == PLAYING)
{
//increase RTSP sequence number
//........
//Send PAUSE message to the server
send_RTSP_request("PAUSE");
//Wait for the response
if (parse_server_response() != 200)
System.out.println("Invalid Server Response");
else
{
//change RTSP state and print out new state
//........
//System.out.println("New RTSP state: ...");
//stop the timer
timer.stop();
}
}
//else if state != PLAYING then do nothing
}
}
//Handler for Teardown button
//-----------------------
class tearButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e){
//System.out.println("Teardown Button pressed !");
//increase RTSP sequence number
// ..........
//Send TEARDOWN message to the server
send_RTSP_request("TEARDOWN");
//Wait for the response
if (parse_server_response() != 200)
System.out.println("Invalid Server Response");
else
{
//change RTSP state and print out new state
//........
//System.out.println("New RTSP state: ...");
//stop the timer
timer.stop();
//exit
System.exit(0);
}
}
}
//------------------------------------
//Handler for timer
//------------------------------------
class timerListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//Construct a DatagramPacket to receive data from the UDP socket
rcvdp = new DatagramPacket(buf, buf.length);
try{
//receive the DP from the socket:
RTPsocket.receive(rcvdp);
//create an RTPpacket object from the DP
RTPpacket rtp_packet = new RTPpacket(rcvdp.getData(), rcvdp.getLength());
//print important header fields of the RTP packet received:
System.out.println("Got RTP packet with SeqNum # "+rtp_packet.getsequencenumber()+" TimeStamp "+rtp_packet.gettimestamp()+" ms, of type "+rtp_packet.getpayloadtype());
//print header bitstream:
rtp_packet.printheader();
//get the payload bitstream from the RTPpacket object
int payload_length = rtp_packet.getpayload_length();
byte [] payload = new byte[payload_length];
rtp_packet.getpayload(payload);
//get an Image object from the payload bitstream
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image = toolkit.createImage(payload, 0, payload_length);
//display the image as an ImageIcon object
icon = new ImageIcon(image);
iconLabel.setIcon(icon);
}
catch (InterruptedIOException iioe){
//System.out.println("Nothing to read");
}
catch (IOException ioe) {
System.out.println("Exception caught: "+ioe);
}
}
}
//------------------------------------
//Parse Server Response
//------------------------------------
private int parse_server_response()
{
int reply_code = 0;
try{
//parse status line and extract the reply_code:
String StatusLine = RTSPBufferedReader.readLine();
//System.out.println("RTSP Client - Received from Server:");
System.out.println(StatusLine);
StringTokenizer tokens = new StringTokenizer(StatusLine);
tokens.nextToken(); //skip over the RTSP version
reply_code = Integer.parseInt(tokens.nextToken());
//if reply code is OK get and print the 2 other lines
if (reply_code == 200)
{
String SeqNumLine = RTSPBufferedReader.readLine();
System.out.println(SeqNumLine);
String SessionLine = RTSPBufferedReader.readLine();
System.out.println(SessionLine);
//if state == INIT gets the Session Id from the SessionLine
tokens = new StringTokenizer(SessionLine);
tokens.nextToken(); //skip over the Session:
RTSPid = Integer.parseInt(tokens.nextToken());
}
}
catch(Exception ex)
{
System.out.println("Exception caught: "+ex);
System.exit(0);
}
return(reply_code);
}
//------------------------------------
//Send RTSP Request
//------------------------------------
//.............
//TO COMPLETE
//.............
private void send_RTSP_request(String request_type)
{
try{
//Use the RTSPBufferedWriter to write to the RTSP socket
//write the request line:
//RTSPBufferedWriter.write(...);
//write the CSeq line:
//......
//check if request_type is equal to "SETUP" and in this case write the Transport: line advertising to the server the port used to receive the RTP packets RTP_RCV_PORT
//if ....
//otherwise, write the Session line from the RTSPid field
//else ....
RTSPBufferedWriter.flush();
}
catch(Exception ex)
{
System.out.println("Exception caught: "+ex);
System.exit(0);
}
}
}//end of Class Client
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment