⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 real.c

📁 linux下流媒体下载程序代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    if(ret < 0) {	goto failed;    }    *rtsp_hdr_ret = rtsp_hdr;        if(options_uri) free(options_uri);    return ret;  failed:    if(rtsp_hdr)    free_rtsp_header(rtsp_hdr);    if(options_uri) free(options_uri);    *rtsp_hdr_ret = NULL;    return -1;}/* * send DESCRIBE request * return value:   -1: failure   status_code: success */static int real_rtsp_describe(struct stream_t *stream,char **description_ret){    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;    struct rtsp_ctrl_t *rtsp_ctrl = stream_ctrl->rtsp_ctrl;    struct rtsp_header_t *rtsp_hdr = NULL;    char *description = NULL;    char *buffer = xmalloc(BUFSIZE_1K);    char *field = NULL;    int len = 0;    int ret = 0;        rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);    rtsp_set_field(rtsp_hdr, "Accept: application/sdp");    rtsp_set_field(rtsp_hdr, real_useragent);    rtsp_set_field(rtsp_hdr, "Require: com.real.retain-entity-for-setup");      snprintf(buffer,BUFSIZE_1K - 1,"Bandwidth: %u",stream_ctrl->bandwidth);    rtsp_set_field(rtsp_hdr,buffer);       rtsp_set_field(rtsp_hdr, "Language: en-US");    rtsp_set_field(rtsp_hdr, "RegionData: 0");    rtsp_set_field(rtsp_hdr, real_clientid);    rtsp_set_field(rtsp_hdr, "GUID: 00000000-0000-0000-0000-000000000000");    rtsp_set_field(rtsp_hdr, "SupportsMaximumASMBandwidth: 1");        rtsp_request_describe(rtsp_hdr,rtsp_ctrl->mrl);    rtsp_send_request_and_free(stream,rtsp_hdr);        rtsp_hdr = new_rtsp_header();    ret = rtsp_recv_header(stream,rtsp_hdr);    if(ret < 0) {	free_rtsp_header(rtsp_hdr);	goto failed;    }        /* NOT OK */    if(!is_rtsp_response_ok(rtsp_hdr->status_code)) { 	display(MSDL_ERR,"DESCRIBE request returned: %d (%s)\n",		rtsp_hdr->status_code,rtsp_hdr->reason_phrase);		field = rtsp_get_field(rtsp_hdr,"Alert");	if(field) {	    while(*field == ' ') field++;	    display(MSDL_ERR,"message from server --> %s\n",field);	}	free_rtsp_header(rtsp_hdr);	goto failed;    }    len = 0;    /* Content-length must be present */    if((field = rtsp_get_field(rtsp_hdr,"Content-length")) != NULL) {	while(*field == ' ') field++;	len = atoi(field);    }    else { /* no Content-length */	display(MSDL_ERR,"warning: No Content-length in fields!!\n");    }      if((field = rtsp_get_field(rtsp_hdr,"ETag")) != NULL) {	while(*field == ' ') field++;	rtsp_ctrl->etag = strdup(field);    }    else {	display(MSDL_ERR,"warning: No ETag!!\n");	rtsp_ctrl->etag = NULL;    }    free_rtsp_header(rtsp_hdr);          /*      copy description (sdp)    */    description = (char *)xmalloc(len + 1);    read_data(stream,(uint8_t *)description,len);    description[len] = '\0';      display(MSDL_DBG,"==================\n%s\n=(%d bytes)========\n",	    description,(int)strlen(description));            if(buffer) free(buffer);    *description_ret = description;    return ret;      failed:    if(description) free(description);    if(buffer) free(buffer);    *description_ret = NULL;    return -1;}/* * send SETUP requst. 2 setups for multiple streams. * return value ...     what rtsp_recv_header returned */static int real_rtsp_setup(struct stream_t *stream,struct rmff_header_t *rmff_header){    struct rtsp_ctrl_t *rtsp_ctrl = stream->stream_ctrl->rtsp_ctrl;    struct rtsp_header_t *rtsp_hdr = NULL;    char *buffer = xmalloc(BUFSIZE_1K);    int ret = 0;    char challenge2[64];    char checksum[34];        rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);        real_calc_challenge2_and_checksum(rtsp_ctrl->challenge,challenge2,checksum);      snprintf(buffer,BUFSIZE_1K - 1,"RealChallenge2: %s, sd=%s",	     challenge2,checksum);    rtsp_set_field(rtsp_hdr,buffer);    snprintf(buffer,BUFSIZE_1K - 1,"If-Match: %s",rtsp_ctrl->etag);    rtsp_set_field(rtsp_hdr,buffer);    rtsp_set_field(rtsp_hdr,"RDTFeatureLevel: 2");    rtsp_set_field(rtsp_hdr,real_transport);    snprintf(buffer,BUFSIZE_1K - 1,"%s/streamid=0",rtsp_ctrl->mrl);    rtsp_request_setup(rtsp_hdr,buffer);    rtsp_send_request_and_free(stream,rtsp_hdr);        /* receive message for SETUP */    ret = rtsp_recv_header_ignore_message(stream);            /*      send messages if multiple stream exists (max is 2 streams anyways...)    */    if(rmff_header->prop->num_streams > 1) {	rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);	rtsp_set_field(rtsp_hdr,real_transport);	snprintf(buffer,BUFSIZE_1K - 1,"If-Match: %s",rtsp_ctrl->etag);	rtsp_set_field(rtsp_hdr,buffer);	snprintf(buffer,BUFSIZE_1K - 1,"%s/streamid=1",rtsp_ctrl->mrl);	rtsp_request_setup(rtsp_hdr,buffer);    	rtsp_send_request_and_free(stream,rtsp_hdr);		/* receive message for SETUP */	ret = rtsp_recv_header_ignore_message(stream);    }        free(buffer);    return ret; }/* * send SET_PARAMETER, with stream choosing subscribe. * return value ...     what rtsp_recv_header returned */static int real_rtsp_set_parameter(struct stream_t *stream,char *subscribe){    struct rtsp_ctrl_t *rtsp_ctrl = stream->stream_ctrl->rtsp_ctrl;    struct rtsp_header_t *rtsp_hdr = NULL;    int ret = 0;        rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);    rtsp_set_field(rtsp_hdr,subscribe);    if(stream->dlopts->bandwidth) { /* when user specified bandwidth */	char *buffer = xmalloc(BUFSIZE_1K);	snprintf(buffer,BUFSIZE_1K - 1,		 "SetDeliveryBandwidth: Bandwidth=%d;BackOff=0",stream->dlopts->bandwidth);	rtsp_set_field(rtsp_hdr,buffer);	free(buffer);    }        rtsp_request_set_parameter(rtsp_hdr,rtsp_ctrl->mrl);    rtsp_send_request_and_free(stream,rtsp_hdr);    ret = rtsp_recv_header_ignore_message(stream);    return ret;}/* * send PLAY request * return value ...     what rtsp_recv_header returned */static int real_rtsp_play(struct stream_t *stream){    struct rtsp_ctrl_t *rtsp_ctrl = stream->stream_ctrl->rtsp_ctrl;    struct rtsp_header_t *rtsp_hdr = NULL;    char *field = NULL;    int ret = 0;        /*      * Sending part      */    rtsp_hdr = new_rtsp_header_with_standard_fields(rtsp_ctrl);    if(stream->dlopts->resume_download) {	real_prepare_resuming(stream);    }    if(stream->dlopts->bandwidth) { /* when user specified bandwidth */	char *buffer = xmalloc(BUFSIZE_1K);	snprintf(buffer,BUFSIZE_1K - 1,		 "Bandwidth: %d",stream->dlopts->bandwidth);	rtsp_set_field(rtsp_hdr,buffer);	free(buffer);    }        rtsp_set_range_field(rtsp_hdr,stream->dlopts->range);    rtsp_set_speed_field(rtsp_hdr,stream->dlopts->speed);        rtsp_request_play(rtsp_hdr,rtsp_ctrl->mrl);      rtsp_send_request_and_free(stream,rtsp_hdr);            /*      * Receiving part      */    /* receive message for PLAY request */    rtsp_hdr = new_rtsp_header();    ret = rtsp_recv_header(stream,rtsp_hdr);        if(!is_rtsp_response_ok(rtsp_hdr->status_code)) { 	display(MSDL_ERR,"PLAY request returned: %d (%s)\n",		rtsp_hdr->status_code,rtsp_hdr->reason_phrase);		field = rtsp_get_field(rtsp_hdr,"Alert");	if(field) {	    while(*field == ' ') field++;	    display(MSDL_ERR,"message from server --> %s\n",field);	}	free_rtsp_header(rtsp_hdr);	goto failed;    }    /* display real speed (might differ from user requested) */    if((field = rtsp_get_field(rtsp_hdr,"Speed")) != NULL) {    	if(stream->dlopts->speed) {	    while(*field == ' ') field++;	    display(MSDL_NOR,"Speed: %s\n",field);	}    }    if((field = rtsp_get_field(rtsp_hdr,"Range")) != NULL) {    	if(stream->dlopts->range) {	    while(*field == ' ') field++;	    display(MSDL_NOR,"Range: %s\n",field);	}    }    /* skip content-length bytes from network */    rtsp_ignore_data_after_header(stream,rtsp_hdr);    free_rtsp_header(rtsp_hdr);        return ret;  failed:    return -1;}/* * send SETUP,SEND_REQUEST,PLAY requests. * *      return value               1: success *                                -1: error */int real_setup_and_get_header(struct stream_t *stream,			      struct rmff_header_t **rmff_header_ret){    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;    struct rmff_header_t *rmff_header = NULL;        char *description = NULL;    char *subscribe = NULL;    /*      !!!CAUTION!!!      setting maxbw too high may cause download failure!!    */        /* don't use this value, its just for choosing highest rate stream */    if(stream->dlopts->bandwidth) {	stream_ctrl->bandwidth = stream->dlopts->bandwidth;    }    else {	stream_ctrl->bandwidth = 10485800;    }    if(real_rtsp_describe(stream,&description) < 0) {	goto failed;    }        /* parse sdp and get information about file to download */    rmff_header = real_parse_sdp(description,&subscribe,stream_ctrl->bandwidth);    if(!rmff_header) {	goto failed;    }    display(MSDL_VER,"sdp parse done.\n");    /* send SETUP request */    if(real_rtsp_setup(stream,rmff_header) < 0) {	goto failed;    }        /* send SET_PARAMETER request to download stream */    if(real_rtsp_set_parameter(stream,subscribe) < 0) {	goto failed;    }        /*  send PLAY request to download stream */    if(real_rtsp_play(stream) < 0) {	goto failed;    }        free(subscribe);    free(description);        *rmff_header_ret = rmff_header;    return 1;    failed:    if(subscribe) free(subscribe);    if(description) free(description);    if(rmff_header) free_rmff_header_t(rmff_header);    *rmff_header_ret = NULL;    return -1;}/* * read from media stream. (real rdp packet) *  * fill 'buffer' with data, and buffer size is 'max_size'. * receive one chunk from netsock->sock, and fills 'max_size' bytes to buffer. * and if there are more bytes in the chunk, the data is stored to * stream->netsock->buffer. * *    return value: positive value ... bytes written to buffer. *                  0              ... END OF STREAM *                 -1              ... ERROR */int real_rdt_get_media_packet(struct stream_t *stream,			      uint8_t *buffer,size_t max_size){    int ret = 0;    uint8_t header[8];        ret = read_data(stream,header,8);    if(ret < 0) {	goto failed;    }    while(!strncasecmp((char *)header,"SET_",4) ||	  !strncasecmp((char *)header,"GET_",4) ||	  !strncasecmp((char *)header,"OPTI",4) ||	  !strncasecmp((char *)header,"RTSP",4) ||	  !strncasecmp((char *)header,"ANNO",4)) {	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -