Solutions for Programming Assignment 7

Below are the solutions for the RTSP/RTP lab. There are two classes: Client, RTPpacket.

Client.java

  1. import java.io.*;
  2. import java.net.*;
  3. import java.util.*;
  4. import java.awt.*;
  5. import java.awt.event.*;
  6. import javax.swing.*;
  7. import javax.swing.Timer;
  8. public class Client{
  9. //GUI
  10. //----
  11. JFrame f = new JFrame("Client");
  12. JButton setupButton = new JButton("Setup");
  13. JButton playButton = new JButton("Play");
  14. JButton pauseButton = new JButton("Pause");
  15. JButton tearButton = new JButton("Teardown");
  16. JPanel mainPanel = new JPanel();
  17. JPanel buttonPanel = new JPanel();
  18. JLabel iconLabel = new JLabel();
  19. ImageIcon icon;
  20. //RTP variables:
  21. //----------------
  22. DatagramPacket rcvdp; //UDP packet received from the server
  23. DatagramSocket RTPsocket; //socket to be used to send and receive UDP packets
  24. static int RTP_RCV_PORT = 25000; //port where the client will receive the RTP packets
  25. Timer timer; //timer used to receive data from the UDP socket
  26. byte[] buf; //buffer used to store data received from the server
  27. //RTSP variables
  28. //----------------
  29. //rtsp states
  30. final static int INIT = 0;
  31. final static int READY = 1;
  32. final static int PLAYING = 2;
  33. static int state; //RTSP state == INIT or READY or PLAYING
  34. Socket RTSPsocket; //socket used to send/receive RTSP messages
  35. //input and output stream filters
  36. static BufferedReader RTSPBufferedReader;
  37. static BufferedWriter RTSPBufferedWriter;
  38. static String VideoFileName; //video file to request to the server
  39. int RTSPSeqNb = 0; //Sequence number of RTSP messages within the session
  40. int RTSPid = 0; //ID of the RTSP session (given by the RTSP Server)
  41. final static String CRLF = "\r\n";
  42. //Video constants:
  43. //------------------
  44. static int MJPEG_TYPE = 26; //RTP payload type for MJPEG video
  45. //--------------------------
  46. //Constructor
  47. //--------------------------
  48. public Client() {
  49. //build GUI
  50. //--------------------------
  51. //Frame
  52. f.addWindowListener(new WindowAdapter() {
  53. public void windowClosing(WindowEvent e) {
  54. System.exit(0);
  55. }
  56. });
  57. //Buttons
  58. buttonPanel.setLayout(new GridLayout(1,0));
  59. buttonPanel.add(setupButton);
  60. buttonPanel.add(playButton);
  61. buttonPanel.add(pauseButton);
  62. buttonPanel.add(tearButton);
  63. setupButton.addActionListener(new setupButtonListener());
  64. playButton.addActionListener(new playButtonListener());
  65. pauseButton.addActionListener(new pauseButtonListener());
  66. tearButton.addActionListener(new tearButtonListener());
  67. //Image display label
  68. iconLabel.setIcon(null);
  69. //frame layout
  70. mainPanel.setLayout(null);
  71. mainPanel.add(iconLabel);
  72. mainPanel.add(buttonPanel);
  73. iconLabel.setBounds(0,0,380,280);
  74. buttonPanel.setBounds(0,280,380,50);
  75. f.getContentPane().add(mainPanel, BorderLayout.CENTER);
  76. f.setSize(new Dimension(390,370));
  77. f.setVisible(true);
  78. //init timer
  79. //--------------------------
  80. timer = new Timer(20, new timerListener());
  81. timer.setInitialDelay(0);
  82. timer.setCoalesce(true);
  83. //allocate enough memory for the buffer used to receive data from the server
  84. buf = new byte[15000];
  85. }
  86. //------------------------------------
  87. //main
  88. //------------------------------------
  89. public static void main(String argv[]) throws Exception
  90. {
  91. //Create a Client object
  92. Client theClient = new Client();
  93. //get server RTSP port and IP address from the command line
  94. //------------------
  95. int RTSP_server_port = Integer.parseInt(argv[1]);
  96. String ServerHost = argv[0];
  97. InetAddress ServerIPAddr = InetAddress.getByName(ServerHost);
  98. //get video filename to request:
  99. VideoFileName = argv[2];
  100. //Establish a TCP connection with the server to exchange RTSP messages
  101. //------------------
  102. theClient.RTSPsocket = new Socket(ServerIPAddr, RTSP_server_port);
  103. //Set input and output stream filters:
  104. RTSPBufferedReader = new BufferedReader(new InputStreamReader(theClient.RTSPsocket.getInputStream()) );
  105. RTSPBufferedWriter = new BufferedWriter(new OutputStreamWriter(theClient.RTSPsocket.getOutputStream()) );
  106. //init RTSP state:
  107. state = INIT;
  108. }
  109. //------------------------------------
  110. //Handler for buttons
  111. //------------------------------------
  112. //Handler for Setup button
  113. //-----------------------
  114. class setupButtonListener implements ActionListener{
  115. public void actionPerformed(ActionEvent e){
  116. //System.out.println("Setup Button pressed !");
  117. if (state == INIT)
  118. {
  119. //Init non-blocking RTPsocket that will be used to receive data
  120. try{
  121. //construct a new DatagramSocket to receive RTP packets from the server, on port RTP_RCV_PORT
  122. RTPsocket = new DatagramSocket(RTP_RCV_PORT);
  123. //set TimeOut value of the socket to 5msec.
  124. RTPsocket.setSoTimeout(5);
  125. }
  126. catch (SocketException se)
  127. {
  128. System.out.println("Socket exception: "+se);
  129. System.exit(0);
  130. }
  131. //init RTSP sequence number
  132. RTSPSeqNb = 1;
  133. //Send SETUP message to the server
  134. send_RTSP_request("SETUP");
  135. //Wait for the response
  136. if (parse_server_response() != 200)
  137. System.out.println("Invalid Server Response");
  138. else
  139. {
  140. //change RTSP state and print new state
  141. state = READY;
  142. System.out.println("New RTSP state: READY");
  143. }
  144. }//else if state != INIT then do nothing
  145. }
  146. }
  147. //Handler for Play button
  148. //-----------------------
  149. class playButtonListener implements ActionListener {
  150. public void actionPerformed(ActionEvent e){
  151. //System.out.println("Play Button pressed !");
  152. if (state == READY)
  153. {
  154. //increase RTSP sequence number
  155. RTSPSeqNb++;
  156. //Send PLAY message to the server
  157. send_RTSP_request("PLAY");
  158. //Wait for the response
  159. if (parse_server_response() != 200)
  160. System.out.println("Invalid Server Response");
  161. else
  162. {
  163. //change RTSP state and print out new state
  164. state = PLAYING;
  165. System.out.println("New RTSP state: PLAYING");
  166. //start the timer
  167. timer.start();
  168. }
  169. }//else if state != READY then do nothing
  170. }
  171. }
  172. //Handler for Pause button
  173. //-----------------------
  174. class pauseButtonListener implements ActionListener {
  175. public void actionPerformed(ActionEvent e){
  176. //System.out.println("Pause Button pressed !");
  177. if (state == PLAYING)
  178. {
  179. //increase RTSP sequence number
  180. RTSPSeqNb++;
  181. //Send PAUSE message to the server
  182. send_RTSP_request("PAUSE");
  183. //Wait for the response
  184. if (parse_server_response() != 200)
  185. System.out.println("Invalid Server Response");
  186. else
  187. {
  188. //change RTSP state and print out new state
  189. state = READY;
  190. System.out.println("New RTSP state: READY");
  191. //stop the timer
  192. timer.stop();
  193. }
  194. }
  195. //else if state != PLAYING then do nothing
  196. }
  197. }
  198. //Handler for Teardown button
  199. //-----------------------
  200. class tearButtonListener implements ActionListener {
  201. public void actionPerformed(ActionEvent e){
  202. //System.out.println("Teardown Button pressed !");
  203. //increase RTSP sequence number
  204. RTSPSeqNb++;
  205. //Send TEARDOWN message to the server
  206. send_RTSP_request("TEARDOWN");
  207. //Wait for the response
  208. if (parse_server_response() != 200)
  209. System.out.println("Invalid Server Response");
  210. else
  211. {
  212. //change RTSP state and print out new state
  213. state = INIT;
  214. System.out.println("New RTSP state: INIT");
  215. //stop the timer
  216. timer.stop();
  217. //exit
  218. System.exit(0);
  219. }
  220. }
  221. }
  222. //------------------------------------
  223. //Handler for timer
  224. //------------------------------------
  225. class timerListener implements ActionListener {
  226. public void actionPerformed(ActionEvent e) {
  227. //Construct a DatagramPacket to receive data from the UDP socket
  228. rcvdp = new DatagramPacket(buf, buf.length);
  229. try{
  230. //receive the DP from the socket :
  231. RTPsocket.receive(rcvdp);
  232. //create an RTPpacket object from the DP
  233. RTPpacket rtp_packet = new RTPpacket(rcvdp.getData(), rcvdp.getLength());
  234. //print important header fields of the RTP packet received:
  235. System.out.println("Got RTP packet with SeqNum # "+rtp_packet.getsequencenumber()+" TimeStamp "+rtp_packet.gettimestamp()+" ms, of type "+rtp_packet.getpayloadtype());
  236. //print header bitstream:
  237. rtp_packet.printheader();
  238. //get the payload bitstream from the RTPpacket object
  239. int payload_length = rtp_packet.getpayload_length();
  240. byte [] payload = new byte[payload_length];
  241. rtp_packet.getpayload(payload);
  242. //get an Image object from the payload bitstream
  243. Toolkit toolkit = Toolkit.getDefaultToolkit();
  244. Image image = toolkit.createImage(payload, 0, payload_length);
  245. //display the image as an ImageIcon object
  246. icon = new ImageIcon(image);
  247. iconLabel.setIcon(icon);
  248. }
  249. catch (InterruptedIOException iioe){
  250. //System.out.println("Nothing to read");
  251. }
  252. catch (IOException ioe) {
  253. System.out.println("Exception caught: "+ioe);
  254. }
  255. }
  256. }
  257. //------------------------------------
  258. //Parse Server Response
  259. //------------------------------------
  260. private int parse_server_response()
  261. {
  262. int reply_code = 0;
  263. try{
  264. //parse status line and extract the reply_code:
  265. String StatusLine = RTSPBufferedReader.readLine();
  266. //System.out.println("RTSP Client - Received from Server:");
  267. System.out.println(StatusLine);
  268. StringTokenizer tokens = new StringTokenizer(StatusLine);
  269. tokens.nextToken(); //skip over the RTSP version
  270. reply_code = Integer.parseInt(tokens.nextToken());
  271. //if reply code is OK get and print the 2 other lines
  272. if (reply_code == 200)
  273. {
  274. String SeqNumLine = RTSPBufferedReader.readLine();
  275. System.out.println(SeqNumLine);
  276. String SessionLine = RTSPBufferedReader.readLine();
  277. System.out.println(SessionLine);
  278. //if state == INIT gets the Session Id from the SessionLine
  279. tokens = new StringTokenizer(SessionLine);
  280. tokens.nextToken(); //skip over the Session:
  281. RTSPid = Integer.parseInt(tokens.nextToken());
  282. }
  283. }
  284. catch(Exception ex)
  285. {
  286. System.out.println("Exception caught : "+ex);
  287. System.exit(0);
  288. }
  289. return(reply_code);
  290. }
  291. //------------------------------------
  292. //Send RTSP Request
  293. //------------------------------------
  294. private void send_RTSP_request(String request_type)
  295. {
  296. try{
  297. //Use the RTSPBufferedWriter to write to the RTSP socket
  298. //write the request line:
  299. RTSPBufferedWriter.write(request_type+" "+VideoFileName+" RTSP/1.0"+CRLF);
  300. //write the CSeq line:
  301. RTSPBufferedWriter.write("CSeq: "+RTSPSeqNb+CRLF);
  302. //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
  303. if ((new String(request_type)).compareTo("SETUP") == 0)
  304. RTSPBufferedWriter.write("Transport: RTP/UDP; client_port= "+RTP_RCV_PORT+CRLF);
  305. else
  306. RTSPBufferedWriter.write("Session: "+RTSPid+"\n");
  307. RTSPBufferedWriter.flush();
  308. }
  309. catch(Exception ex)
  310. {
  311. System.out.println("Exception caught : "+ex);
  312. System.exit(0);
  313. }
  314. }
  315. }

RTPpacket.java

Click to view as text file (will not display properly in Internet Explorer)