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

📄 asf_streaming.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	waiting = asf_http_ctrl->packet_size;      } else {	waiting = chunk_size;      }    } else if (rest){      chunk_size = rest;      rest = 0;    }    read = 0;    if ( waiting >= chunk_size) {      if (chunk_size > size){	rest = chunk_size - size;	chunk_size = size;      }      while(read < chunk_size) {	int got = nop_streaming_read( fd,buffer+read,chunk_size-read,streaming_ctrl );	if(got <= 0) {	  if(got < 0)	    mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_ErrReadingChunk);	  return -1;	}	read += got;      }      waiting -= read;      if (drop_chunk) continue;    }    if (rest == 0 && waiting > 0 && size-read > 0) {      int s = FFMIN(waiting,size-read);      memset(buffer+read,0,s);      waiting -= s;      read += s;    }    break;  }  return read;}static int asf_http_streaming_seek( int fd, off_t pos, streaming_ctrl_t *streaming_ctrl ) {	return -1;	// to shut up gcc warning	fd++;	pos++;	streaming_ctrl=NULL;}static int asf_header_check( HTTP_header_t *http_hdr ) {	ASF_obj_header_t *objh;	if( http_hdr==NULL ) return -1;	if( http_hdr->body==NULL || http_hdr->body_size<sizeof(ASF_obj_header_t) ) return -1;	objh = (ASF_obj_header_t*)http_hdr->body;	if( ASF_LOAD_GUID_PREFIX(objh->guid)==0x75B22630 ) return 0;	return -1;}static int asf_http_streaming_type(char *content_type, char *features, HTTP_header_t *http_hdr ) {	if( content_type==NULL ) return ASF_Unknown_e;	if( 	!strcasecmp(content_type, "application/octet-stream") ||		!strcasecmp(content_type, "application/vnd.ms.wms-hdr.asfv1") ||        // New in Corona, first request		!strcasecmp(content_type, "application/x-mms-framed") ||                // New in Corana, second request		!strcasecmp(content_type, "video/x-ms-asf")) {               		if( strstr(features, "broadcast") ) {			mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF Live stream\n");			return ASF_Live_e;		} else {			mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF Prerecorded\n");			return ASF_Prerecorded_e;		}	} else {		// Ok in a perfect world, web servers should be well configured		// so we could used mime type to know the stream type,		// but guess what? All of them are not well configured.		// So we have to check for an asf header :(, but it works :p		if( http_hdr->body_size>sizeof(ASF_obj_header_t) ) {			if( asf_header_check( http_hdr )==0 ) {				mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF Plain text\n");				return ASF_PlainText_e;			} else if( (!strcasecmp(content_type, "text/html")) ) {				mp_msg(MSGT_NETWORK,MSGL_V,"=====> HTML, MPlayer is not a browser...yet!\n");				return ASF_Unknown_e;			} else {				mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF Redirector\n");				return ASF_Redirector_e;			}		} else {			if(	(!strcasecmp(content_type, "audio/x-ms-wax")) ||				(!strcasecmp(content_type, "audio/x-ms-wma")) ||				(!strcasecmp(content_type, "video/x-ms-asf")) ||				(!strcasecmp(content_type, "video/x-ms-afs")) ||				(!strcasecmp(content_type, "video/x-ms-wmv")) ||				(!strcasecmp(content_type, "video/x-ms-wma")) ) {				mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_ASFRedirector);				return ASF_Redirector_e;			} else if( !strcasecmp(content_type, "text/plain") ) {				mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF Plain text\n");				return ASF_PlainText_e;			} else {				mp_msg(MSGT_NETWORK,MSGL_V,"=====> ASF unknown content-type: %s\n", content_type );				return ASF_Unknown_e;			}		}	}	return ASF_Unknown_e;}static HTTP_header_t *asf_http_request(streaming_ctrl_t *streaming_ctrl) {	HTTP_header_t *http_hdr;	URL_t *url = NULL;	URL_t *server_url = NULL;	asf_http_streaming_ctrl_t *asf_http_ctrl;	char str[250];	char *ptr;	int i, enable;	int offset_hi=0, offset_lo=0, length=0;	int asf_nb_stream=0, stream_id;	// Sanity check	if( streaming_ctrl==NULL ) return NULL;	url = streaming_ctrl->url;	asf_http_ctrl = (asf_http_streaming_ctrl_t*)streaming_ctrl->data;	if( url==NULL || asf_http_ctrl==NULL ) return NULL;	// Common header for all requests.	http_hdr = http_new_header();	http_set_field( http_hdr, "Accept: */*" );	http_set_field( http_hdr, "User-Agent: NSPlayer/4.1.0.3856" );	http_add_basic_authentication( http_hdr, url->username, url->password );	// Check if we are using a proxy	if( !strcasecmp( url->protocol, "http_proxy" ) ) {		server_url = url_new( (url->file)+1 );		if( server_url==NULL ) {			mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_InvalidProxyURL);			http_free( http_hdr );			return NULL;		}		http_set_uri( http_hdr, server_url->url );		sprintf( str, "Host: %.220s:%d", server_url->hostname, server_url->port );		url_free( server_url );	} else {		http_set_uri( http_hdr, url->file );		sprintf( str, "Host: %.220s:%d", url->hostname, url->port );	}		http_set_field( http_hdr, str );	http_set_field( http_hdr, "Pragma: xClientGUID={c77e7400-738a-11d2-9add-0020af0a3278}" );	sprintf(str, 		"Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=%u:%u,request-context=%d,max-duration=%u",		offset_hi, offset_lo, asf_http_ctrl->request, length );	http_set_field( http_hdr, str );	switch( asf_http_ctrl->streaming_type ) {		case ASF_Live_e:		case ASF_Prerecorded_e:			http_set_field( http_hdr, "Pragma: xPlayStrm=1" );			ptr = str;			ptr += sprintf( ptr, "Pragma: stream-switch-entry=");			if(asf_http_ctrl->n_audio > 0) {				for( i=0; i<asf_http_ctrl->n_audio ; i++ ) {					stream_id = asf_http_ctrl->audio_streams[i];					if(stream_id == asf_http_ctrl->audio_id) {						enable = 0;					} else {						enable = 2;						continue;					}					asf_nb_stream++;					ptr += sprintf(ptr, "ffff:%d:%d ", stream_id, enable);				}			}			if(asf_http_ctrl->n_video > 0) {				for( i=0; i<asf_http_ctrl->n_video ; i++ ) {					stream_id = asf_http_ctrl->video_streams[i];					if(stream_id == asf_http_ctrl->video_id) {						enable = 0;					} else {						enable = 2;						continue;					}					asf_nb_stream++;					ptr += sprintf(ptr, "ffff:%d:%d ", stream_id, enable);				}			}			http_set_field( http_hdr, str );			sprintf( str, "Pragma: stream-switch-count=%d", asf_nb_stream );			http_set_field( http_hdr, str );			break;		case ASF_Redirector_e:			break;		case ASF_Unknown_e:			// First request goes here.			break;		default:			mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_UnknownASFStreamType);	}	http_set_field( http_hdr, "Connection: Close" );	http_build_request( http_hdr );	return http_hdr;}static int asf_http_parse_response(asf_http_streaming_ctrl_t *asf_http_ctrl, HTTP_header_t *http_hdr ) {	char *content_type, *pragma;	char features[64] = "\0";	size_t len;	if( http_response_parse(http_hdr)<0 ) {		mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_Failed2ParseHTTPResponse);		return -1;	}	switch( http_hdr->status_code ) {		case 200:			break;		case 401: // Authentication required			return ASF_Authenticate_e;		default:			mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_ServerReturn, http_hdr->status_code, http_hdr->reason_phrase);			return -1;	}	content_type = http_get_field( http_hdr, "Content-Type");//printf("Content-Type: [%s]\n", content_type);	pragma = http_get_field( http_hdr, "Pragma");	while( pragma!=NULL ) {		char *comma_ptr=NULL;		char *end;//printf("Pragma: [%s]\n", pragma );		// The pragma line can get severals attributes 		// separeted with a comma ','.		do {			if( !strncasecmp( pragma, "features=", 9) ) {				pragma += 9;				end = strstr( pragma, "," );				if( end==NULL ) {				  len = strlen(pragma);				} else { 				  len = (unsigned int)(end-pragma);				}				if(len > sizeof(features) - 1) {				  mp_msg(MSGT_NETWORK,MSGL_WARN,MSGTR_MPDEMUX_ASF_ASFHTTPParseWarnCuttedPragma,pragma,len,sizeof(features) - 1);				  len = sizeof(features) - 1;				}				strncpy( features, pragma, len );				features[len]='\0';				break;			}			comma_ptr = strstr( pragma, "," );			if( comma_ptr!=NULL ) {				pragma = comma_ptr+1;				if( pragma[0]==' ' ) pragma++;			}		} while( comma_ptr!=NULL );		pragma = http_get_next_field( http_hdr );	}	asf_http_ctrl->streaming_type = asf_http_streaming_type( content_type, features, http_hdr );	return 0;}static int asf_http_streaming_start( stream_t *stream, int *demuxer_type ) {	HTTP_header_t *http_hdr=NULL;	URL_t *url = stream->streaming_ctrl->url;	asf_http_streaming_ctrl_t *asf_http_ctrl;	char buffer[BUFFER_SIZE];	int i, ret;	int fd = stream->fd;	int done;	int auth_retry = 0;	asf_http_ctrl = malloc(sizeof(asf_http_streaming_ctrl_t));	if( asf_http_ctrl==NULL ) {		mp_msg(MSGT_NETWORK,MSGL_FATAL,MSGTR_MemAllocFailed);		return -1;	}	asf_http_ctrl->streaming_type = ASF_Unknown_e;	asf_http_ctrl->request = 1;	asf_http_ctrl->audio_streams = asf_http_ctrl->video_streams = NULL;	asf_http_ctrl->n_audio = asf_http_ctrl->n_video = 0;	stream->streaming_ctrl->data = (void*)asf_http_ctrl;	do {		done = 1;		if( fd>0 ) closesocket( fd );		if( !strcasecmp( url->protocol, "http_proxy" ) ) {			if( url->port==0 ) url->port = 8080;		} else {			if( url->port==0 ) url->port = 80;		}		fd = connect2Server( url->hostname, url->port, 1);		if( fd<0 ) return fd;		http_hdr = asf_http_request( stream->streaming_ctrl );		mp_msg(MSGT_NETWORK,MSGL_DBG2,"Request [%s]\n", http_hdr->buffer );		for(i=0; i < (int)http_hdr->buffer_size ; ) {			int r = send( fd, http_hdr->buffer+i, http_hdr->buffer_size-i, 0 );			if(r <0) {				mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_SocketWriteError,strerror(errno));				goto err_out;			}			i += r;		}       		http_free( http_hdr );		http_hdr = http_new_header();		do {			i = recv( fd, buffer, BUFFER_SIZE, 0 );//printf("read: %d\n", i );			if( i<=0 ) {				perror("read");				goto err_out;			}			http_response_append( http_hdr, buffer, i );		} while( !http_is_header_entire( http_hdr ) );		if( mp_msg_test(MSGT_NETWORK,MSGL_V) ) {			http_hdr->buffer[http_hdr->buffer_size]='\0';			mp_msg(MSGT_NETWORK,MSGL_DBG2,"Response [%s]\n", http_hdr->buffer );		}		ret = asf_http_parse_response(asf_http_ctrl, http_hdr);		if( ret<0 ) {			mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_HeaderParseFailed);			goto err_out;		}		switch( asf_http_ctrl->streaming_type ) {			case ASF_Live_e:			case ASF_Prerecorded_e:			case ASF_PlainText_e:				if( http_hdr->body_size>0 ) {					if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {						goto err_out;					}				}				if( asf_http_ctrl->request==1 ) {					if( asf_http_ctrl->streaming_type!=ASF_PlainText_e ) {						// First request, we only got the ASF header.						ret = asf_streaming_parse_header(fd,stream->streaming_ctrl);						if(ret < 0) goto err_out;						if(asf_http_ctrl->n_audio == 0 && asf_http_ctrl->n_video == 0) {							mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_NoStreamFound);							goto err_out;						}						asf_http_ctrl->request++;						done = 0;					} else {						done = 1;					}				}				break;			case ASF_Redirector_e:				if( http_hdr->body_size>0 ) {					if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) {						goto err_out;					}				}				*demuxer_type = DEMUXER_TYPE_PLAYLIST;				done = 1;				break;			case ASF_Authenticate_e:				if( http_authenticate( http_hdr, url, &auth_retry)<0 ) return -1;				asf_http_ctrl->streaming_type = ASF_Unknown_e;				done = 0;				break;			case ASF_Unknown_e:			default:				mp_msg(MSGT_NETWORK,MSGL_ERR,MSGTR_MPDEMUX_ASF_UnknownASFStreamingType);				goto err_out;		}	// Check if we got a redirect.		} while(!done);	stream->fd = fd;	if( asf_http_ctrl->streaming_type==ASF_PlainText_e || asf_http_ctrl->streaming_type==ASF_Redirector_e ) {		stream->streaming_ctrl->streaming_read = nop_streaming_read;		stream->streaming_ctrl->streaming_seek = nop_streaming_seek;	} else {		stream->streaming_ctrl->streaming_read = asf_http_streaming_read;		stream->streaming_ctrl->streaming_seek = asf_http_streaming_seek;		stream->streaming_ctrl->buffering = 1;	}	stream->streaming_ctrl->status = streaming_playing_e;	stream->close = close_s;	http_free( http_hdr );	return 0;err_out:	if (fd > 0)		closesocket(fd);	stream->fd = -1;	http_free(http_hdr);	return -1;}static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {	URL_t *url;	stream->streaming_ctrl = streaming_ctrl_new();	if( stream->streaming_ctrl==NULL ) {		return STREAM_ERROR;	}	stream->streaming_ctrl->bandwidth = network_bandwidth;	url = url_new(stream->url);	stream->streaming_ctrl->url = check4proxies(url);	url_free(url);		mp_msg(MSGT_OPEN, MSGL_INFO, MSGTR_MPDEMUX_ASF_InfoStreamASFURL, stream->url);	if((!strncmp(stream->url, "http", 4)) && (*file_format!=DEMUXER_TYPE_ASF && *file_format!=DEMUXER_TYPE_UNKNOWN)) {		streaming_ctrl_free(stream->streaming_ctrl);		stream->streaming_ctrl = NULL;		return STREAM_UNSUPPORTED;	}	if(asf_streaming_start(stream, file_format) < 0) {		mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_MPDEMUX_ASF_StreamingFailed);		streaming_ctrl_free(stream->streaming_ctrl);		stream->streaming_ctrl = NULL;		return STREAM_UNSUPPORTED;	}		*file_format = DEMUXER_TYPE_ASF;	stream->type = STREAMTYPE_STREAM;	fixup_network_stream_cache(stream);	return STREAM_OK;}stream_info_t stream_info_asf = {  "mms and mms over http streaming",  "null",  "Bertrand, Reimar Doeffinger, Albeu",  "originally based on work by Majormms (is that code still there?)",  open_s,  {"mms", "mmsu", "mmst", "http", "http_proxy", "mmshttp", NULL},  NULL,  0 // Urls are an option string};

⌨️ 快捷键说明

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