 |
» |
|
|
 |
|  |  |
You can use the sampleclient.c program, a minimal RTSP client, to send RTSP messages
to a server.The program is interactive and allows you to choose
the type of RTSP message to be sent to a server. Based on the RTSP
message type, you may be prompted to enter additional information. The following is a sample program for the RTSP module of the
MSP suite of libraries:  |
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <rtsp.h> /* * connect2server : * Parse the url string and create a RTSP * Connection to the server identified by the url. */ rtsp_conn_t * connect2server(char *mediaurl) { rtsp_error_t err; rtsp_conn_t *rtspconn = NULL; rtsp_url_t rtspurl; /* Parse the url string and fill up rtspurl */ err = rtsp_parse_url(mediaurl, &rtspurl); if( err!=RTSP_SUCCESS ) { printf(“Error parsing media url %s\n”, mediaurl); return rtspconn; } printf(“Connecting to server ... “); /* Create a RTSP Connection */ err = rtsp_open(&rtspurl, RTSP_CFLAG_CS, &rtspconn); if( err!=RTSP_SUCCESS ) { printf(“Error\n”); return rtspconn; } printf(“Success\n”); return rtspconn; } void display_msg_menu() { printf(“\nAvailable RTSP Messages : \n” “1. DESCRIBE\n2. SETUP\n3. PLAY\n” “4. PAUSE\n5. TEARDOWN\n6. EXIT\n” “Choose one [1-6]: “); } /* * The basic flow of operations for the process_* routines * is as follows : * * Create and Initialize the request message. * Set the header information in the request message. * Send the request message to the server * Free the request message * Receive the response message from the server. * Retrieve header information from the response message. * Retrieve message body from the response message. * Free the response message * * In all the process_* routines, the following variables * are used. * * req_msg => The RTSP Request Message * rsp_msg => The RTSP Response Message * err => error number returned by RTSP APIs * rtspconn => The RTSP Connection over which messages * are sent and received. * */ /* * process_describe : * Creates and sends a DESCRIBE Request message to the * server. Receives and processes the response message. */ rtsp_error_t process_describe(rtsp_conn_t *rtspconn, char *mediaurl) { rtsp_msg_t *reqmsg = NULL; rtsp_msg_t *rspmsg = NULL; rtsp_error_t err; char accepttype[] = “application/sdp”; uint8_t *sdpbuf; uint16_t sdpbuflen; /* Create a DESCRIBE RTSP Request Message */ err = rtsp_init_request_msg(RTSP_DESCRIBE, mediaurl, &reqmsg); if( err!=RTSP_SUCCESS ) return err; /* Specify the Accept RTSP Header in the Request Message */ err = rtsp_set_msg_hdr(reqmsg, RTSP_ACCEPT_HDR, accepttype, strlen(accepttype)); if( err!=RTSP_SUCCESS ) { rtsp_free_msg(reqmsg); return err; } /* Send the Request Message */ err = rtsp_send_msg(rtspconn, NULL, reqmsg, 0); rtsp_free_msg(reqmsg); if( err<0 ) return err; /* Receive the response for the request Message. We pass * NULL for channel and size argument since we are sure we * would be receiving only a RTSP Message and not an * interleaved media stream. */ err = rtsp_recv(rtspconn, &rspmsg, NULL, NULL); if( err<0 ) return err; /* Retrieve the Content-Length Header information */ err = rtsp_get_msg_hdr(rspmsg, RTSP_CONTENT_LENGTH_HDR, &sdpbuflen, NULL); if( err!=RTSP_SUCCESS ) { rtsp_free_msg(rspmsg); return err; } /* Allocate a buffer to hold the message body * (i.e) SDP Description */ sdpbuf = malloc(sdpbuflen*sizeof(uint8_t)); if( !sdpbuf ) { rtsp_free_msg(rspmsg); return err; } /* Get the body of the Response Message */ err = rtsp_get_msg_body(rspmsg, (uint8_t *)sdpbuf, &sdpbuflen); if( err!=RTSP_SUCCESS ) { free(sdpbuf); rtsp_free_msg(rspmsg); return err; } printf(“SDP Description for %s is : \n” “%.*s\n”, mediaurl, (int)sdpbuflen, sdpbuf); free(sdpbuf); /* Free the resources allocated for the RTSP Message */ rtsp_free_msg(rspmsg); return RTSP_SUCCESS; } /* * process_setup : * Creates and sends a SETUP Request message to the * server. Receives and processes the response message. */ rtsp_error_t process_setup(rtsp_conn_t *rtspconn, char *setupurl, int crtpport, int crtcpport) { rtsp_msg_t *reqmsg = NULL; rtsp_msg_t *rspmsg = NULL; rtsp_error_t err; rtsp_xport_spec_t xspec, *serverxspec=NULL; char *sessionid; int sessionidlen; /* Create a SETUP RTSP Request Message */ err = rtsp_init_request_msg(RTSP_SETUP, setupurl, &reqmsg); if( err!=RTSP_SUCCESS ) return err; /* Initialize and fill up the Transport Header */ rtsp_init_xport_spec(&xspec); xspec.xport_id = (uint8_t *)”RTP/AVP”; xspec.ncast = RTSP_TRANSMIT_UNICAST; xspec.cport.rtp = crtpport; xspec.cport.rtcp = crtcpport; /* Set the Transport RTSP Header in the Request Message */ err = rtsp_set_msg_hdr(reqmsg, RTSP_TRANSPORT_HDR, &xspec, 0); if( err!=RTSP_SUCCESS ) { rtsp_free_msg(reqmsg); return err; } /* Send the Request Message */ err = rtsp_send_msg(rtspconn, NULL, reqmsg, 0); /* Free the resources allocated for the request message */ rtsp_free_msg(reqmsg); /* Check for rtsp_send_msg errors */ if( err<0 ) return err; /* Receive the response for the request Message. We pass * NULL for channel and size argument since we are sure we * would be receiving only a RTSP Message and not an * interleaved media stream. */ err = rtsp_recv(rtspconn, &rspmsg, NULL, NULL); if( err<0 ) return err; /* Get Transport Header information from the Response */ err = rtsp_get_msg_hdr(rspmsg, RTSP_TRANSPORT_HDR, &serverxspec, NULL); if( err!=RTSP_SUCCESS ) { rtsp_free_msg(rspmsg); return err; } printf(“\nServer RTP and RTCP ports are %d %d\n”, (int)serverxspec->sport.rtp, (int)serverxspec->sport.rtcp); /* Free the resources allocated to the entire linked * list of rtsp_xport_spec_t structures */ rtsp_free_xport_spec(serverxspec); /* Retrieve Session Header information from message */ err = rtsp_get_msg_hdr(rspmsg, RTSP_SESSION_HDR, &sessionid, &sessionidlen); if( err!=RTSP_SUCCESS ) { rtsp_free_msg(rspmsg); return err; } printf(“Session ID is %.*s\n”, sessionidlen, sessionid); free(sessionid); /* Free the resources allocated for the response Message */ rtsp_free_msg(rspmsg); return RTSP_SUCCESS; } /* * process_play : * Creates and sends a PLAY Request message to the server. * Receives and process the response message for PLAY. */ rtsp_error_t process_play(rtsp_conn_t *rtspconn, char *mediaurl) { rtsp_msg_t *reqmsg = NULL; rtsp_msg_t *rspmsg = NULL; rtsp_error_t err; rtsp_rtpinfo_t *rtpinfo = NULL, *prtpinfo; /* Create a PLAY RTSP Request Message */ err = rtsp_init_request_msg(RTSP_PLAY, mediaurl, &reqmsg); if( err!=RTSP_SUCCESS ) return err; /* Send the Request Message */ err = rtsp_send_msg(rtspconn, NULL, reqmsg, 0); /* Free the resources allocated for the request message */ rtsp_free_msg(reqmsg); /* Check for rtsp_send_msg errors */ if( err<0 ) return err; /* Receive the response for the request Message. We pass * NULL for channel and size argument since we are sure we * would be receiving only a RTSP Message and not an * interleaved media stream. */ err = rtsp_recv(rtspconn, &rspmsg, NULL, NULL); if( err<0 ) return err; /* Retrieve RTP-Info Header information from the message */ err = rtsp_get_msg_hdr(rspmsg, RTSP_RTP_INFO_HDR, &rtpinfo, NULL); if( err!=RTSP_SUCCESS ) { rtsp_free_msg(rspmsg); return err; } printf(“\nServer RTP Info : \n”); /* * The RTP-Info header can have multiple rtp-info-spec * entries. The multiple rtp-info-spec entries are linked * together through the next structure member */ for(prtpinfo=rtpinfo; prtpinfo!=NULL; prtpinfo=prtpinfo->next) { printf(“\t”); /* If url member is NULL, then URL was not * specified in the rtp-info-spec entry in the header */ if(prtpinfo->url) printf(“URL=%s, “, prtpinfo->url); /* If seq member is -1, then sequence number was not * specified in the rtp-info-spec entry in the header */ if(prtpinfo->seq!=-1) printf(“seq=%d, “, prtpinfo->seq); /* If rtptime member is -1, then RTP Timestamp was not * specified in the rtp-info-spec entry in the header */ if(prtpinfo->rtptime!=-1) printf(“rtptime=%lld”, prtpinfo->rtptime); printf(“\n”); } /* Free the resources allocated to the entire linked * list of rtsp_rtpinfo_t structures */ rtsp_free_rtpinfo(rtpinfo); /* Free the resources allocated for the Response Message */ rtsp_free_msg(rspmsg); return RTSP_SUCCESS; } /* * process_pause : * Creates and sends a PAUSE Request message to the * server. Receives and process the response message. */ rtsp_error_t process_pause(rtsp_conn_t *rtspconn, char *mediaurl) { rtsp_msg_t *reqmsg = NULL; rtsp_msg_t *rspmsg = NULL; rtsp_error_t err; int statuscode; /* Create a PAUSE RTSP Request Message */ err = rtsp_init_request_msg(RTSP_PAUSE, mediaurl, &reqmsg); if( err!=RTSP_SUCCESS ) return err; /* Send the Request Message */ err = rtsp_send_msg(rtspconn, NULL, reqmsg, 0); /* Free the resources allocated for the request message */ rtsp_free_msg(reqmsg); /* Check for rtsp_send_msg errors */ if( err<0 ) return err; /* Receive the response for the request Message. We pass * NULL for channel and size argument since we are sure we * would be receiving only a RTSP Message and not an * interleaved media stream. */ err = rtsp_recv(rtspconn, &rspmsg, NULL, NULL); if( err<0 ) return err; /* Get the status code of the Response Message */ statuscode = rtsp_get_msg_response_line(rspmsg, NULL, NULL); if( statuscode!=200 ) { rtsp_free_msg(rspmsg); return err; } /* Free the resources allocated for the Response Message */ rtsp_free_msg(rspmsg); printf(“\nPAUSE Succeeded\n”); return RTSP_SUCCESS; } /* * process_teardown : * Creates and sends a TEARDOWN Request message to the * server. Receives and processes the response message for * TEARDOWN. */ rtsp_error_t process_teardown(rtsp_conn_t *rtspconn, char *mediaurl) { rtsp_msg_t *reqmsg = NULL; rtsp_msg_t *rspmsg = NULL; rtsp_error_t err; int statuscode; rtsp_session_t *session; /* Create a TEARDOWN RTSP Request Message */ err = rtsp_init_request_msg(RTSP_TEARDOWN, mediaurl, &reqmsg); if( err!=RTSP_SUCCESS ) return err; /* Send the Request Message */ err = rtsp_send_msg(rtspconn, NULL, reqmsg, 0); /* Free the resources allocated for the request message */ rtsp_free_msg(reqmsg); /* Check for rtsp_send_msg errors */ if( err<0 ) return err; /* Receive the response for the request message. We pass * NULL for channel and size argument since we are sure we * would be receiving only a RTSP Message and not an * interleaved media stream. */ err = rtsp_recv(rtspconn, &rspmsg, NULL, NULL); if( err<0 ) return err; /* Get the status code of the Response Message */ statuscode = rtsp_get_msg_response_line(rspmsg, NULL, NULL); if( statuscode!=200 ) { rtsp_free_msg(rspmsg); return err; } /* Free the resources allocated for the Response Message */ rtsp_free_msg(rspmsg); printf(“\nTEARDOWN Succeeded\n”); return RTSP_SUCCESS; } main(int argc, char *argv[]) { /* * mediaurl points to the url passed as a * command-line argument to the program */ char *mediaurl; /* msgcode identifies the RTSP Method chosen by the user */ int msgcode; /* rtspconn represents the RTSP Connection to the peer */ rtsp_conn_t *rtspconn=NULL; /* mapsession represents the mapped session for the * RTSP connection */ rtsp_session_t *mapsession=NULL; /* err will hold the error numbers returned by RTSP APIs */ rtsp_error_t err; /* * crtpport and crtcpport will hold the client * RTP and RTCP ports for SETUP Request */ int crtpport, crtcpport; /* setupurl holds the URL to be used in SETUP Request */ char setupurl[256]; int setupurllen; /* * The mthd variable will hold the enumerated RTSP * Method type for the Method chosen by the user */ rtsp_method_t mthd; int close=0; if( argc!=2 ) { printf(“Usage : %s <media url>\n”, argv[0]); exit(-1); } mediaurl = argv[1]; /* Connect to the server specified by the mediaurl */ rtspconn = connect2server(mediaurl); if( rtspconn==NULL ) exit(-1); do { display_msg_menu(); scanf(“%d”, &msgcode); switch(msgcode) { case 1: mthd = RTSP_DESCRIBE; err = process_describe(rtspconn, mediaurl); break; case 2: mthd = RTSP_SETUP; printf(“Enter SETUP URL (max 255 char) : “); fflush(stdin); fgets(setupurl, 256, stdin); setupurllen = strlen(setupurl); if( setupurl[setupurllen-1]==’\n’ ) setupurl[setupurllen-1]=’\0’; printf(“Enter Client RTP RTCP Ports : “); scanf(“%d %d”, &crtpport, &crtcpport); err = process_setup(rtspconn, setupurl, crtpport, crtcpport); break; case 3: mthd = RTSP_PLAY; err = process_play(rtspconn, mediaurl); break; case 4: mthd = RTSP_PAUSE; err = process_pause(rtspconn, mediaurl); break; case 5: mthd = RTSP_TEARDOWN; err = process_teardown(rtspconn, mediaurl); close = 1; break; case 6: close = 1; err = RTSP_SUCCESS; break; default: err = RTSP_SUCCESS; printf(“Invalid value\n”); break; } /* * The rtsp_methods array contains the strings for RTSP * Methods. The array index should be an enumerated RTSP * Method type */ if( err!=RTSP_SUCCESS ) printf(“\nError occurred during %s message “ “processing\n”, rtsp_methods[mthd]); } while(!close); /* Close the RTSP Connection and free the resources */ rtsp_get_conn_opt(rtspconn, RTSP_OPT_SESSION, &mapsession, NULL); if( mapsession ) rtsp_free_session(mapsession); rtsp_close(rtspconn); } |
 |
The usage of this sample program is as follows: sampleclient <mediaurl> Example: sampleclient rtsp://serveraddress/mediafile Compiling
the Sample RTSP Program |  |
This section describes how to compile the sample RTSP program. Before compiling the program, enure that the rtsp.h header file and the librtsp library provided by the HP-UX MSP suite are available
on the machine. The rtsp.h header file is assumed to be in the /usr/include directory and the librtsp library in the /usr/lib directory.To compile, issue the following command: $ cc sampleclient.c -o sampleclient -lrtsp
|