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

📄 mmsh.c

📁 linux下流媒体下载程序代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return -1;    }    ret = mmsh_parse_response(stream->stream_ctrl->mmsh_ctrl,http_hdr);    if(ret < 0) {	display(MSDL_ERR,"mmsh_parse_response failed\n");	return -1;    }    return http_hdr->status_code;}/* * mmsh_parse_response : addtional header parse for mmsh *                       do this after http_parse_response * basically parse Pragma lines. * return value:  1 ... success *               -1 ... failure */static int mmsh_parse_response(struct mmsh_ctrl_t *mmsh_ctrl,			       struct http_header_t *http_hdr){    char *content_type, *pragma;    char features[128] = "\0";        content_type = http_get_field(http_hdr, "Content-Type");    pragma = http_get_field(http_hdr, "Pragma");    while(pragma != NULL) {	char *p = NULL;	/* we have to get features="" string to judge mmsh stream type */		if((p = xstrcasestr(pragma,"features=")) != NULL) { /* found */	    char *startp = NULL;	    char *endp = NULL;	    p += 9;	    while(*p == ' ') p++; /* skip whitespace */	    startp = p; /* save start pos */	    if(*p == '\"') { /* if '"', go to next '"' or EOS */		p++;		while(*p != '\"' && *p != '\0') p++;	    }	    if(*p == '\0') { /* EOS */		endp = p;	    }	    else if(*p == '\"'){		endp = p+1; /* char after '"' */	    }	    /* "aaa", */	    if(endp - startp < 128) {		strncpy(features,startp,endp-startp);		features[endp - startp] = '\0';	    }	    else {		strncpy(features,startp,127);		features[127] = '\0';	    }	}	/*	  ==caution==	  if there are multipule features, get the newest one	 */		pragma = http_get_next_field(http_hdr); /* keep getting Pragma lines. */    }        mmsh_ctrl->streaming_type	= mmsh_streaming_type(content_type,features,http_hdr);        return 1;}/* * interpret asf_stream_chunk. *           return value: type of chunk */static int asf_streaming(struct asf_stream_chunk_t *stream_chunk){        /* little endian */    display(MSDL_DBG,"ASF chunk == type: 0x%02x, size: %d (0x%02x), seq: 0x%04x\n",	    le2me_16(stream_chunk->type),	    le2me_16(stream_chunk->size),le2me_16(stream_chunk->size), 	    le2me_32(stream_chunk->seqnum));      switch(le2me_16(stream_chunk->type)) {    case ASF_STREAMING_CLEAR:          /* $C  Clear ASF configuration  */	display(MSDL_DBG,"Clearing ASF stream configuration\n");	break;        case ASF_STREAMING_DATA:           /* $D  Data follows             */    case ASF_STREAMING_DATA2:	/*display(MSDL_DBG,"Data follows\n"); */	break;        case ASF_STREAMING_END_TRANS:      /* $E  End of transfer          */	display(MSDL_DBG,"Transfer complete!!\n");	break;    case ASF_STREAMING_HEADER:         /* $H  ASF Header chunk follows */	/* display(MSDL_DBG,"ASF header chunk follows\n"); */	break;    case ASF_STREAMING_IGNORE:	break;    default:	display(MSDL_DBG,"not ASF chunk: [0x%x]!!\n",		le2me_16(stream_chunk->type));    }    return le2me_16(stream_chunk->type);}/* * fallback from mmsh to http WITHOUT re-sending GET * message to server. * this will be more pleasant to server. * * this function must be called when * [ no data in http_hdr->body (already moved)] * [ http_hdr is alreadyh set ] *    return value:     */int mmsh_fallback_to_http(struct stream_t *stream,			  struct http_header_t *http_hdr){    struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;    int ret;    display(MSDL_VER,"probably not mmsh. fallback to http.\n");      /* quit mmsh, and start http */    free_mmsh_ctrl_t(stream_ctrl->mmsh_ctrl);    stream_ctrl->http_ctrl = new_http_ctrl_t();      stream->start = http_streaming_start;    stream->read  = http_streaming_read;    stream->close = http_streaming_close;    /* read content-length */    ret = http_parse_response(stream_ctrl->http_ctrl,http_hdr);    stream->stream_ctrl->file_size = stream_ctrl->http_ctrl->content_length;        /*        free_http_header(http_hdr);  don't free it here.       it will be free()ed later    */      stream_ctrl->protocol = HTTP;      return ret;}/* * get entire asf header. * this function is needed because asf_header might come * within more than 2 packets. *  *** CAUTION *** *  DO NOT FORGET TO free() asfheader later!! *  all header is going to stored in buffer. *                    return value:   -1  ... failure *                                  other ... length of asf header */static int mmsh_get_asf_header(struct stream_t *stream,uint8_t **asfheader,			       struct asf_stream_chunk_t *first_chunk){    struct asf_stream_chunk_t chunk;    struct asf_stream_chunk_extra_t chunk_extra;    struct asf_header_t asfh;    uint8_t *buffer = NULL;      int asf_header_len = 0;    int total;    int ret;      total = 0;    memcpy(&chunk,first_chunk,sizeof(chunk));      for(;;) {	/* read chunk extra */	read_data(stream,&chunk_extra,sizeof(chunk_extra));	ret = le2me_16(chunk.size) - sizeof(chunk);    	buffer = (uint8_t *)xrealloc(buffer,ret + total);    	stream->stream_ctrl->packet_count++; /* increment packet count */    	ret = read_data(stream,buffer + total,ret);	if(ret < 0) {	    goto failed;	}    	if(asf_header_len == 0) { /* first loop */	    if(ret < sizeof(struct asf_header_t)) {		display(MSDL_ERR,"1st chunk %d shorter than asf_header_t\n",ret);		goto failed;	    }	    memcpy(&asfh,buffer,sizeof(struct asf_header_t));	    asf_header_len = le2me_64(asfh.objh.size);	    if(asf_header_len == 0) {		display(MSDL_ERR,"asf_header_len is zero\n");		goto failed;	    }	}    	total += ret;    	if(total >= asf_header_len) {	    break; /* got entire header --- break */	}	else {	    int chunk_type;	    /* get chunk for next loop */	    read_data(stream,&chunk,sizeof(chunk));	    chunk_type = asf_streaming(&chunk);      	    if(chunk_type != ASF_STREAMING_HEADER) { /* not a header packet */		display(MSDL_ERR,"non-header paceket when header packet expected\n");		goto failed;	    }	}    }       *asfheader = buffer;    return total;    failed:    free(buffer);    *asfheader = NULL;    return -1;}/* * starts mms over http streaming. (mmsh) *  *    return value :   negative or 0  ... error *                                 1  ... success */int mmsh_streaming_start(struct stream_t *stream){      struct stream_ctrl_t *stream_ctrl = stream->stream_ctrl;    struct mmsh_ctrl_t *mmsh_ctrl = stream_ctrl->mmsh_ctrl;    struct url_t *url = stream->url;    struct download_opts_t *dlopts = stream->dlopts;    struct http_header_t *http_hdr = NULL;    int asf_header_len = 0;      int sock = 0; /* socket to use   */    int ret = 0;    stream_ctrl->status = STREAMING_HANDSHAKING;      mmsh_ctrl->streaming_type = ASF_Unknown_e;        if(dlopts->bandwidth) {	stream_ctrl->bandwidth = dlopts->bandwidth;    }    else {	stream_ctrl->bandwidth = INT_MAX_BANDWIDTH;    }        set_serverinfo_by_proxy_string(stream->serverinfo,url->hostname,url->port,				   dlopts->http_proxy,				   HTTP_PORT,HTTP_PROXY_PORT);    /* proxy setting: done */    sock = server_connect(stream->serverinfo->connect_host,stream->serverinfo->connect_port);    if(sock < 0) {	return sock; /* failure */    }    stream->netsock->sock = sock; /* set socket# to stream_t */        /* send 1st request */    stream_ctrl->packet_count = 0;        http_hdr = new_http_header();    if(dlopts->resume_download) {	http_prepare_resuming(stream);    }    /* byte range specified */    if(dlopts->byterange) {	http_set_byterange_field(http_hdr,dlopts->byterange);    }    mmsh_1st_request(stream,http_hdr);    http_send_header(stream,http_hdr);    free_http_header(http_hdr);    http_hdr = NULL;        /* get 1st reply */    http_hdr = new_http_header();    mmsh_recv_header(stream,http_hdr);    ret = http_process_reply(stream,http_hdr); // interpret http_hdr which just received    if(ret < 0) {	goto failed; // including complete    }        switch(mmsh_ctrl->streaming_type) {    case ASF_Seekable_e:    case ASF_Nonseekable_e:		stream->stream_ctrl->protocol = MMSH;	struct asf_stream_chunk_t chunk; /* for chunk header for asf header */	int chunk_type; /* little endian */	uint8_t *buffer = NULL;	/* we are supposed to get the ASF header! ( 100% ) */	display(MSDL_VER,"1st response from server...  \n");		/* keep getting chunk until stop getting IGNORE */	for(;;) {	    read_data(stream,&chunk,sizeof(chunk));	    chunk_type = asf_streaming(&chunk);	    if(chunk_type != ASF_STREAMING_IGNORE) break;	  	    buffer = xmalloc(chunk.size - 4);	    read_data(stream,buffer,chunk.size - 4);	    free(buffer);	} 		if(chunk_type == ASF_STREAMING_HEADER) {	  	    /* header may come within more than 2 packets */	    asf_header_len = mmsh_get_asf_header(stream,&buffer,&chunk);	  	    if(asf_header_len < 0) goto failed;	  	    display(MSDL_VER,"ASF header received (size = %d)\n",asf_header_len);	  	    /* interpret M$ asf header */	    ret = asf_interpret_header(mmsh_ctrl->hinfo,stream_ctrl->bandwidth,				       buffer,asf_header_len);	  	    /* set necessary information to mmsh_ctrl */	    stream_ctrl->file_size = mmsh_ctrl->hinfo->fileh->file_size;	    stream_ctrl->packet_length = mmsh_ctrl->packet_size =		mmsh_ctrl->hinfo->fileh->max_packet_size;	    /* and everything is done */	  	    free(buffer);	    buffer = NULL;	  	    if(ret < 0) goto failed;	  	    if(mmsh_ctrl->hinfo->streams->n_audio == 0 &&	       mmsh_ctrl->hinfo->streams->n_video == 0) {		/* this means no stream to DL */		display(MSDL_ERR,"No stream to download!\n");		goto failed;	    }	    display(MSDL_VER,"\n");	}	else if(chunk_type == ASF_STREAMING_CLEAR || 		chunk_type == ASF_STREAMING_DATA  || 		chunk_type == ASF_STREAMING_END_TRANS) {	    display(MSDL_ERR,"ASF header expected!!\n");	    goto failed;	}	else { /* not mmsh, try http here. */	  	    /* push back "chunk" to be read again */	  	    stream_data_push_back(stream,&chunk,sizeof(chunk));	    mmsh_fallback_to_http(stream,http_hdr);	    goto http_fallback;	}	break;          case ASF_Unknown_e:	mmsh_fallback_to_http(stream,http_hdr);	goto http_fallback;	    default: /* should not come here */

⌨️ 快捷键说明

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