📄 network.c
字号:
if( fd<0 ) return -1; http_hdr = http_read_response( fd ); if( http_hdr==NULL ) return -1; switch( http_hdr->status_code ) { case 200: // OK mp_msg(MSGT_NETWORK,MSGL_V,"Content-Type: [%s]\n", http_get_field(http_hdr, "Content-Type") ); mp_msg(MSGT_NETWORK,MSGL_V,"Content-Length: [%s]\n", http_get_field(http_hdr, "Content-Length") ); if( http_hdr->body_size>0 ) { if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { http_free( http_hdr ); return -1; } } break; // Redirect case 301: // Permanently case 302: // Temporarily ret=-1; next_url = http_get_field( http_hdr, "Location" ); if (next_url != NULL) rd_url=url_new(next_url); if (next_url != NULL && rd_url != NULL) { mp_msg(MSGT_NETWORK,MSGL_STATUS,"Redirected: Using this url instead %s\n",next_url); stream->streaming_ctrl->url=check4proxies(rd_url); ret=nop_streaming_start(stream); //recursively get streaming started } else { mp_msg(MSGT_NETWORK,MSGL_ERR,"Redirection failed\n"); closesocket( fd ); fd = -1; } return ret; break; case 401: //Authorization required case 403: //Forbidden case 404: //Not found case 500: //Server Error default: mp_msg(MSGT_NETWORK,MSGL_ERR,"Server returned code %d: %s\n", http_hdr->status_code, http_hdr->reason_phrase ); closesocket( fd ); fd = -1; return -1; break; } stream->fd = fd; } else { http_hdr = (HTTP_header_t*)stream->streaming_ctrl->data; if( http_hdr->body_size>0 ) { if( streaming_bufferize( stream->streaming_ctrl, http_hdr->body, http_hdr->body_size )<0 ) { http_free( http_hdr ); stream->streaming_ctrl->data = NULL; return -1; } } } if( http_hdr ) { http_free( http_hdr ); stream->streaming_ctrl->data = NULL; } stream->streaming_ctrl->streaming_read = nop_streaming_read; stream->streaming_ctrl->streaming_seek = nop_streaming_seek; stream->streaming_ctrl->prebuffer_size = 64*1024; // 64 KBytes stream->streaming_ctrl->buffering = 1; stream->streaming_ctrl->status = streaming_playing_e; return 0;}intpnm_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) { return pnm_read(stream_ctrl->data, buffer, size);}intpnm_streaming_start( stream_t *stream ) { int fd; pnm_t *pnm; if( stream==NULL ) return -1; fd = connect2Server( stream->streaming_ctrl->url->hostname, stream->streaming_ctrl->url->port ? stream->streaming_ctrl->url->port : 7070,1 ); printf("PNM:// fd=%d\n",fd); if(fd<0) return -1; pnm = pnm_connect(fd,stream->streaming_ctrl->url->file); if(!pnm) return -2; stream->fd=fd; stream->streaming_ctrl->data=pnm; stream->streaming_ctrl->streaming_read = pnm_streaming_read;// stream->streaming_ctrl->streaming_seek = nop_streaming_seek; stream->streaming_ctrl->prebuffer_size = 8*1024; // 8 KBytes stream->streaming_ctrl->buffering = 1; stream->streaming_ctrl->status = streaming_playing_e; return 0;}intrealrtsp_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *stream_ctrl ) { return rtsp_session_read(stream_ctrl->data, buffer, size);}intrealrtsp_streaming_start( stream_t *stream ) { int fd; rtsp_session_t *rtsp; char *mrl; char *file; int port; int redirected, temp; if( stream==NULL ) return -1; temp = 5; // counter so we don't get caught in infinite redirections (you never know) do { redirected = 0; fd = connect2Server( stream->streaming_ctrl->url->hostname, port = (stream->streaming_ctrl->url->port ? stream->streaming_ctrl->url->port : 554),1 ); if(fd<0 && !stream->streaming_ctrl->url->port) fd = connect2Server( stream->streaming_ctrl->url->hostname, port = 7070, 1 ); if(fd<0) return -1; file = stream->streaming_ctrl->url->file; if (file[0] == '/') file++; mrl = malloc(sizeof(char)*(strlen(stream->streaming_ctrl->url->hostname)+strlen(file)+16)); sprintf(mrl,"rtsp://%s:%i/%s",stream->streaming_ctrl->url->hostname,port,file); rtsp = rtsp_session_start(fd,&mrl, file, stream->streaming_ctrl->url->hostname, port, &redirected); if ( redirected == 1 ) { url_free(stream->streaming_ctrl->url); stream->streaming_ctrl->url = url_new(mrl); closesocket(fd); } free(mrl); temp--; } while( (redirected != 0) && (temp > 0) ); if(!rtsp) return -1; stream->fd=fd; stream->streaming_ctrl->data=rtsp; stream->streaming_ctrl->streaming_read = realrtsp_streaming_read;// stream->streaming_ctrl->streaming_seek = nop_streaming_seek; stream->streaming_ctrl->prebuffer_size = 128*1024; // 8 KBytes stream->streaming_ctrl->buffering = 1; stream->streaming_ctrl->status = streaming_playing_e; return 0;}// Start listening on a UDP port. If multicast, join the group.static intrtp_open_socket( URL_t *url ) { int socket_server_fd, rxsockbufsz; int err, err_len; fd_set set; struct sockaddr_in server_address; struct ip_mreq mcast; struct timeval tv; struct hostent *hp; mp_msg(MSGT_NETWORK,MSGL_V,"Listening for traffic on %s:%d ...\n", url->hostname, url->port ); socket_server_fd = socket(AF_INET, SOCK_DGRAM, 0);// fcntl( socket_server_fd, F_SETFL, fcntl(socket_server_fd, F_GETFL) | O_NONBLOCK ); if( socket_server_fd==-1 ) { mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to create socket\n"); return -1; } if( isalpha(url->hostname[0]) ) {#ifndef HAVE_WINSOCK2 hp =(struct hostent*)gethostbyname( url->hostname ); if( hp==NULL ) { mp_msg(MSGT_NETWORK,MSGL_ERR,"Counldn't resolve name: %s\n", url->hostname); return -1; } memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length );#else server_address.sin_addr.s_addr = htonl(INADDR_ANY);#endif } else {#ifndef HAVE_WINSOCK2#ifdef USE_ATON inet_aton(url->hostname, &server_address.sin_addr);#else inet_pton(AF_INET, url->hostname, &server_address.sin_addr);#endif#else server_address.sin_addr.s_addr = htonl(INADDR_ANY);#endif } server_address.sin_family=AF_INET; server_address.sin_port=htons(url->port); if( bind( socket_server_fd, (struct sockaddr*)&server_address, sizeof(server_address) )==-1 ) {#ifndef HAVE_WINSOCK2 if( errno!=EINPROGRESS ) {#else if( WSAGetLastError() != WSAEINPROGRESS ) {#endif mp_msg(MSGT_NETWORK,MSGL_ERR,"Failed to connect to server\n"); closesocket(socket_server_fd); return -1; } } #ifdef HAVE_WINSOCK2 if (isalpha(url->hostname[0])) { hp =(struct hostent*)gethostbyname( url->hostname ); if( hp==NULL ) { mp_msg(MSGT_NETWORK,MSGL_ERR,"Counldn't resolve name: %s\n", url->hostname); return -1; } memcpy( (void*)&server_address.sin_addr.s_addr, (void*)hp->h_addr, hp->h_length ); } else { unsigned int addr = inet_addr(url->hostname); memcpy( (void*)&server_address.sin_addr, (void*)&addr, sizeof(addr) ); }#endif // Increase the socket rx buffer size to maximum -- this is UDP rxsockbufsz = 240 * 1024; if( setsockopt( socket_server_fd, SOL_SOCKET, SO_RCVBUF, &rxsockbufsz, sizeof(rxsockbufsz))) { mp_msg(MSGT_NETWORK,MSGL_ERR,"Couldn't set receive socket buffer size\n"); } if((ntohl(server_address.sin_addr.s_addr) >> 28) == 0xe) { mcast.imr_multiaddr.s_addr = server_address.sin_addr.s_addr; //mcast.imr_interface.s_addr = inet_addr("10.1.1.2"); mcast.imr_interface.s_addr = 0; if( setsockopt( socket_server_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mcast, sizeof(mcast))) { mp_msg(MSGT_NETWORK,MSGL_ERR,"IP_ADD_MEMBERSHIP failed (do you have multicasting enabled in your kernel?)\n"); return -1; } } tv.tv_sec = 0; tv.tv_usec = (1 * 1000000); // 1 second timeout FD_ZERO( &set ); FD_SET( socket_server_fd, &set ); if( select(socket_server_fd+1, &set, NULL, NULL, &tv)>0 ) { //if( select(socket_server_fd+1, &set, NULL, NULL, NULL)>0 ) { err_len = sizeof( err ); getsockopt( socket_server_fd, SOL_SOCKET, SO_ERROR, &err, &err_len ); if( err ) { mp_msg(MSGT_NETWORK,MSGL_ERR,"Timeout! No data from host %s\n", url->hostname ); mp_msg(MSGT_NETWORK,MSGL_DBG2,"Socket error: %d\n", err ); closesocket(socket_server_fd); return -1; } } return socket_server_fd;}static intrtp_streaming_read( int fd, char *buffer, int size, streaming_ctrl_t *streaming_ctrl ) { return read_rtp_from_server( fd, buffer, size );}static intrtp_streaming_start( stream_t *stream, int raw_udp ) { streaming_ctrl_t *streaming_ctrl; int fd; if( stream==NULL ) return -1; streaming_ctrl = stream->streaming_ctrl; fd = stream->fd; if( fd<0 ) { fd = rtp_open_socket( (streaming_ctrl->url) ); if( fd<0 ) return -1; stream->fd = fd; } if(raw_udp) streaming_ctrl->streaming_read = nop_streaming_read; else streaming_ctrl->streaming_read = rtp_streaming_read; streaming_ctrl->streaming_seek = nop_streaming_seek; streaming_ctrl->prebuffer_size = 64*1024; // 64 KBytes streaming_ctrl->buffering = 0; streaming_ctrl->status = streaming_playing_e; return 0;}intstreaming_start(stream_t *stream, int *demuxer_type, URL_t *url) { int ret; if( stream==NULL ) return -1; stream->streaming_ctrl = streaming_ctrl_new(); if( stream->streaming_ctrl==NULL ) { return -1; } stream->streaming_ctrl->url = check4proxies( url ); if (*demuxer_type != DEMUXER_TYPE_PLAYLIST){ ret = autodetectProtocol( stream->streaming_ctrl, &stream->fd, demuxer_type ); } else { ret=0; } if( ret<0 ) { return -1; } if( ret==1 ) { stream->flags |= STREAM_SEEK; stream->seek = http_seek; } ret = -1; // Get the bandwidth available stream->streaming_ctrl->bandwidth = network_bandwidth; // For RTP streams, we usually don't know the stream type until we open it. if( !strcasecmp( stream->streaming_ctrl->url->protocol, "rtp")) { if(stream->fd >= 0) { if(closesocket(stream->fd) < 0) mp_msg(MSGT_NETWORK,MSGL_ERR,"streaming_start : Closing socket %d failed %s\n",stream->fd,strerror(errno)); } stream->fd = -1; ret = rtp_streaming_start( stream, 0); } else if( !strcasecmp( stream->streaming_ctrl->url->protocol, "pnm")) { stream->fd = -1; ret = pnm_streaming_start( stream ); if (ret == -1) { mp_msg(MSGT_NETWORK,MSGL_INFO,"Can't connect with pnm, retrying with http.\n"); goto stream_switch; } } else if( (!strcasecmp( stream->streaming_ctrl->url->protocol, "rtsp")) && (*demuxer_type == DEMUXER_TYPE_REAL)) { stream->fd = -1; if ((ret = realrtsp_streaming_start( stream )) < 0) { mp_msg(MSGT_NETWORK,MSGL_INFO,"Not a Realmedia rtsp url. Trying standard rtsp protocol.\n");#ifdef STREAMING_LIVE_DOT_COM *demuxer_type = DEMUXER_TYPE_RTP; goto stream_switch;#else mp_msg(MSGT_NETWORK,MSGL_ERR,"RTSP support requires the \"LIVE.COM Streaming Media\" libraries!\n"); return -1;#endif } } else if(!strcasecmp( stream->streaming_ctrl->url->protocol, "udp")) { stream->fd = -1; ret = rtp_streaming_start(stream, 1); if(ret<0) { mp_msg(MSGT_NETWORK,MSGL_ERR,"rtp_streaming_start(udp) failed\n"); return -1; } *demuxer_type = DEMUXER_TYPE_UNKNOWN; } else // For connection-oriented streams, we can usually determine the streaming type.stream_switch: switch( *demuxer_type ) { case DEMUXER_TYPE_ASF: // Send the appropriate HTTP request // Need to filter the network stream. // ASF raw stream is encapsulated. // It can also be a playlist (redirector) // so we need to pass demuxer_type too ret = asf_streaming_start( stream, demuxer_type ); if( ret<0 ) { //sometimes a file is just on a webserver and it is not streamed. //try loading them default method as last resort for http protocol if ( !strcasecmp(stream->streaming_ctrl->url->protocol, "http") ) { mp_msg(MSGT_NETWORK,MSGL_STATUS,"Trying default streaming for http protocol\n "); //reset stream close(stream->fd); stream->fd=-1; ret=nop_streaming_start(stream); } if (ret<0) { mp_msg(MSGT_NETWORK,MSGL_ERR,"asf_streaming_start failed\n"); mp_msg(MSGT_NETWORK,MSGL_STATUS,"Check if this is a playlist which requires -playlist option\nExample: mplayer -playlist <url>\n"); } } break;#ifdef STREAMING_LIVE_DOT_COM case DEMUXER_TYPE_RTP: // RTSP/RTP streaming is handled separately: ret = rtsp_streaming_start( stream ); if( ret<0 ) { mp_msg(MSGT_NETWORK,MSGL_ERR,"rtsp_streaming_start failed\n"); } break;#endif case DEMUXER_TYPE_MPEG_ES: case DEMUXER_TYPE_MPEG_PS: case DEMUXER_TYPE_AVI: case DEMUXER_TYPE_MOV: case DEMUXER_TYPE_VIVO: case DEMUXER_TYPE_FLI: case DEMUXER_TYPE_REAL: case DEMUXER_TYPE_Y4M: case DEMUXER_TYPE_FILM: case DEMUXER_TYPE_ROQ: case DEMUXER_TYPE_AUDIO: case DEMUXER_TYPE_OGG: case DEMUXER_TYPE_PLAYLIST: case DEMUXER_TYPE_UNKNOWN: case DEMUXER_TYPE_NSV: // Generic start, doesn't need to filter // the network stream, it's a raw stream ret = nop_streaming_start( stream ); if( ret<0 ) { mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_start failed\n"); } break; default: mp_msg(MSGT_NETWORK,MSGL_ERR,"Unable to detect the streaming type\n"); ret = -1; } if( ret<0 ) { streaming_ctrl_free( stream->streaming_ctrl ); stream->streaming_ctrl = NULL; } else if( stream->streaming_ctrl->buffering ) { if(stream_cache_size<0) { // cache option not set, will use our computed value. // buffer in KBytes, *5 because the prefill is 20% of the buffer. stream_cache_size = (stream->streaming_ctrl->prebuffer_size/1024)*5; if( stream_cache_size<64 ) stream_cache_size = 64; // 16KBytes min buffer } mp_msg(MSGT_NETWORK,MSGL_INFO,"Cache size set to %d KBytes\n", stream_cache_size); } return ret;}intstreaming_stop( stream_t *stream ) { stream->streaming_ctrl->status = streaming_stopped_e; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -