📄 rtspapi.c
字号:
debug(DEBUG_MISC, "RTSP_ReceiveResponse", "No content length\n"); } } else { content_length = -1; } DStringFree(&header); state = Body; } else state = Header; break; case Body: cl++; break; } } /* We now have a complete message, with header and content. */ if (r) { r->content = DStringValue(&body); debug(DEBUG_MISC, "RTSPTcp", "Message Body is (%d bytes)\n%s\n", content_length, r->content ? r->content : "NULL"); if (r->p.type != http_response) { debug(DEBUG_MISC, "RTSP_ReceiveResponse", "No a response\n"); RTSP_ResponseFree(r); return NULL; } else { return (r); } } else { return NULL; }} /**************** Actual RTSP methods ***********************/char *RTSP_Describe(rtspcontext_t c) /* DESCRIBE */{ rtspsession_t *s = (rtspsession_t *) c; DString msg; char *sdp = NULL; char *uri_str; rtsp_response_t *r; if (s == NULL || s->uri.scheme == NULL) { debug(DEBUG_MISC, "RTSP_Describe", "Context is NULL or no URL specified.\n"); return NULL; } uri_str = URI_AsString(s->uri); if (uri_str == NULL) { debug(DEBUG_MISC, "RTSP_Describe", "Could not convert URI to string\n"); return NULL; } /* Build the request */ DStringInit(&msg); DStringPrintf(&msg, "DESCRIBE %s %s\r\n", uri_str, RTSP_VERSION); DStringPrintf(&msg, "CSeq: %u\r\n", s->cseq_tx++); DStringPrintf(&msg, "Accept: application/sdp\r\n"); DStringAppend(&msg, "\r\n", -1); /* Send the message */ if (RTSP_Send(s, &msg) == 0) { /* Successful; */ r = RTSP_ReceiveResponse(s); /* Parse the response, and return SDP if successful */ if (r && r->p.status >= 200 && r->p.status < 300) { if (r->content) { char *str; sdp = strdup(r->content); /* Get the length of the file in npt and * put it in s->length */ if ((str = strstr(sdp, "a=length:npt=")) != NULL && str != sdp) { str = str + strlen("a=length:npt="); debug(DEBUG_MISC, "RTSP_ReceiveResponse", "string is %s\n", str ? str : "NULL"); if (sscanf(str, "%f", &s->duration) <= 0) { debug(DEBUG_MISC, "RTSP_ReceiveResponse", "sscanf returned <=0\n"); s->duration = 0.; } debug(DEBUG_MISC, "RTSP_ReceiveResponse", "Duration of the file is %g\n", s->duration); if (s->duration > 10.) { debug(DEBUG_MISC, "RTSP_ReceiveResponse", "Duration should not be more than 10\n"); } } } } RTSP_ResponseFree(r); } free_valid(uri_str); DStringFree(&msg); return sdp;}int RTSP_Setup(rtspcontext_t c, const char * mode, const struct sockaddr_storage *media, const char *body) /* SETUP */{ rtspsession_t *s = (rtspsession_t *) c; DString msg; int oRet = -1; char *uri_str; rtsp_response_t *r; char *dotted; int af; if (s == NULL || s->uri.scheme == NULL) { debug(DEBUG_MISC, "RTSP_Function", "Context is NULL or no URL specified.\n"); return oRet; } debug(DEBUG_MISC, "RTSP_Setup", "Scheme is %s\n", s->uri.scheme ? s->uri.scheme : "NULL"); uri_str = URI_AsString(s->uri); if (uri_str == NULL) { debug(DEBUG_MISC, "RTSP_Function", "Could not convert URI to string\n"); return oRet; } /* Set the media address */ memcpy(&s->media_rx, media, sizeof(*media)); /* convert the host name into a dotted address */ dotted = AFIGetDottedAddress((struct sockaddr*)&s->media_rx); af = media->ss_family; if (af != AF_INET && af != AF_INET6) { error("RTSP_Setup", "Unrecognized protocol family %d\n", af); free_valid(uri_str); return oRet; } /* Build the request */ DStringInit(&msg); DStringPrintf(&msg, "SETUP %s %s\r\n", uri_str, RTSP_VERSION); DStringPrintf(&msg, "CSeq: %u\r\n", s->cseq_tx++); DStringPrintf(&msg, "Transport: RTP/AVP;unicast"); if (!strcmp(mode, "play")) { DStringPrintf(&msg, ";destination=%s", dotted); free(dotted); } if (AFIGetPort(&s->media_rx) != 0) { DStringPrintf(&msg, ";client_port=%u-%u", AFIGetPort(&s->media_rx), (AFIGetPort(&s->media_rx)+1)); } DStringPrintf(&msg, ";mode=%s\r\n", mode); if (body != NULL) { DStringPrintf(&msg, "Content-Type: text/plain\r\n"); DStringPrintf(&msg, "Content-Length: %lu\r\n", (long)strlen(body)); DStringPrintf(&msg, "\r\n%s", body); } else { /* Do not put an extra \r\n for the case when body is present */ DStringAppend(&msg, "\r\n", -1); } /* Store the mode */ strassign(&s->mode, mode); /* Send the message */ if (RTSP_Send(c, &msg) == 0) { /* Successful; */ r = RTSP_ReceiveResponse(c); /* Parse the response, and return SDP if successful */ if (r && r->p.status >= 200 && r->p.status < 300) { rtsp_session_t session; rtsp_transport_t transport; /* Extract session id */ memset(&session, 0, sizeof(session)); session = RTSP_Session(&r->p); s->session = (session.id ? strdup(session.id) : NULL); /* Extract the transport parameters */ memset(&session, 0, sizeof(session)); transport = RTSP_Transport(&r->p); if (transport.af == AF_UNSPEC) { transport.af = af; } if (transport.server_port[0] > 0) { AFISetPort(&s->media_tx, transport.server_port[0]); } else { AFISetPort(&s->media_tx, transport.port[0]); } if (((af == AF_INET && transport.destination4.s_addr != INADDR_ANY) || (af == AF_INET6 && memcmp(&transport.destination6, &in6addr_any, sizeof(in6addr_any)))) && !strcmp(s->mode, "record")) { if (af == AF_INET) { struct sockaddr_in* p4 = (struct sockaddr_in*)&s->media_tx; p4->sin_addr.s_addr = transport.destination4.s_addr; } else { struct sockaddr_in6* p6 = (struct sockaddr_in6*)&s->media_tx; memcpy(&p6->sin6_addr, &transport.destination6, sizeof(struct in6_addr)); } } oRet = 0; } RTSP_ResponseFree(r); } free_valid(uri_str); DStringFree(&msg); return oRet;}int RTSP_Teardown(rtspcontext_t c) /* TEARDOWN */{ rtspsession_t *s = (rtspsession_t *) c; DString msg; int oRet = -1; char *uri_str; rtsp_response_t *r; if (s == NULL || s->uri.scheme == NULL) { debug(DEBUG_MISC, "RTSP_Function", "Context is NULL or no URL specified.\n"); return oRet; } uri_str = URI_AsString(s->uri); if (uri_str == NULL) { debug(DEBUG_MISC, "RTSP_Function", "Could not convert URI to string\n"); return oRet; } /* Build the request */ DStringInit(&msg); DStringPrintf(&msg, "TEARDOWN %s %s\r\n", uri_str, RTSP_VERSION); DStringPrintf(&msg, "CSeq: %u\r\n", s->cseq_tx++); if (s->session) { DStringPrintf(&msg, "Session: %s\r\n", s->session); } DStringAppend(&msg, "\r\n", -1); /* Send the message */ if (RTSP_Send(c, &msg) == 0) { /* Successful; */ r = RTSP_ReceiveResponse(c); /* Parse the response, and return SDP if successful */ if (r && r->p.status >= 200 && r->p.status < 300) { oRet = 0; } RTSP_ResponseFree(r); } /* Close the socket connection */ closesocket(s->sock); s->connected = 0; free_valid(uri_str); DStringFree(&msg); return oRet;}int RTSP_PlayRange(rtspcontext_t c, const char *starttime, const char *endtime) /* PLAY */{ rtspsession_t *s = (rtspsession_t *) c; DString msg; int oRet = -1; char *uri_str; rtsp_response_t *r; if (s == NULL || s->uri.scheme == NULL) { debug(DEBUG_MISC, "RTSP_Function", "Context is NULL or no URL specified.\n"); return oRet; } uri_str = URI_AsString(s->uri); if (uri_str == NULL) { debug(DEBUG_MISC, "RTSP_Function", "Could not convert URI to string\n"); return oRet; } /* Build the request */ DStringInit(&msg); DStringPrintf(&msg, "PLAY %s %s\r\n", uri_str, RTSP_VERSION); DStringPrintf(&msg, "CSeq: %u\r\n", s->cseq_tx++); if (s->session) { DStringPrintf(&msg, "Session: %s\r\n", s->session); } DStringPrintf(&msg, "Range: npt=%s-%s\r\n", starttime, endtime); DStringAppend(&msg, "\r\n", -1); /* Send the message */ if (RTSP_Send(c, &msg) == 0) { /* Successful; */ r = RTSP_ReceiveResponse(c); /* Parse the response, and return SDP if successful */ if (r && r->p.status >= 200 && r->p.status < 300) { oRet = 0; } RTSP_ResponseFree(r); } free_valid(uri_str); DStringFree(&msg); return oRet;}int RTSP_Play(rtspcontext_t c){ return RTSP_PlayRange(c, "0", "");}int RTSP_Pause(rtspcontext_t c) /* PAUSE */{ rtspsession_t *s = (rtspsession_t *) c; DString msg; int oRet = -1; char *uri_str; rtsp_response_t *r; if (s == NULL || s->uri.scheme == NULL) { debug(DEBUG_MISC, "RTSP_Function", "Context is NULL or no URL specified.\n"); return oRet; } uri_str = URI_AsString(s->uri); if (uri_str == NULL) { debug(DEBUG_MISC, "RTSP_Function", "Could not convert URI to string\n"); return oRet; } /* Build the request */ DStringInit(&msg); DStringPrintf(&msg, "PAUSE %s %s\r\n", uri_str, RTSP_VERSION); DStringPrintf(&msg, "CSeq: %u\r\n", s->cseq_tx++); if (s->session) { DStringPrintf(&msg, "Session: %s\r\n", s->session); } DStringAppend(&msg, "\r\n", -1); /* Send the message */ if (RTSP_Send(c, &msg) == 0) { /* Successful; */ r = RTSP_ReceiveResponse(c); /* Parse the response, and return SDP if successful */ if (r && r->p.status >= 200 && r->p.status < 300) { oRet = 0; } RTSP_ResponseFree(r); } free_valid(uri_str); DStringFree(&msg); return oRet;}int RTSP_Record(rtspcontext_t c, long maxsize) /* RECORD */{ rtspsession_t *s = (rtspsession_t *) c; DString msg; int oRet = -1; char *uri_str; rtsp_response_t *r; if (s == NULL || s->uri.scheme == NULL) { debug(DEBUG_MISC, "RTSP_Function", "Context is NULL or no URL specified.\n"); return oRet; } uri_str = URI_AsString(s->uri); if (uri_str == NULL) { debug(DEBUG_MISC, "RTSP_Function", "Could not convert URI to string\n"); return oRet; } /* Build the request */ DStringInit(&msg); DStringPrintf(&msg, "RECORD %s %s\r\n", uri_str, RTSP_VERSION); DStringPrintf(&msg, "CSeq: %u\r\n", s->cseq_tx++); if (s->session) { DStringPrintf(&msg, "Session: %s\r\n", s->session); } /* MaxSize if a rtspd/sipum specific feature */ if (maxsize >= 0) { DStringPrintf(&msg, "MaxSize: %ld\r\n", maxsize); } DStringAppend(&msg, "\r\n", -1); /* Send the message */ if (RTSP_Send(c, &msg) == 0) { /* Successful; */ r = RTSP_ReceiveResponse(c); /* Parse the response, and return SDP if successful */ if (r && r->p.status >= 200 && r->p.status < 300) { oRet = 0; } RTSP_ResponseFree(r); } free_valid(uri_str); DStringFree(&msg); return oRet;}/************************** END OF FILE *********************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -