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

📄 http.c

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 C
📖 第 1 页 / 共 2 页
字号:
				int udp_port;

				if (flac_cfg.stream.use_udp_channel)
				{
					udp_port = udp_establish_listener (&udp_sock);
					if (udp_port > 0) 
						sprintf (udpspace, "x-audiocast-udpport: %d\r\n", udp_port);
					else
						udp_sock = 0;
				}
					
				if(user && pass)
					auth = basic_authentication_encode(user, pass, "Authorization");

				if (flac_cfg.stream.use_proxy)
				{
					file = g_strdup(url);
					if(flac_cfg.stream.proxy_use_auth && flac_cfg.stream.proxy_user && flac_cfg.stream.proxy_pass)
					{
						proxy_auth = basic_authentication_encode(flac_cfg.stream.proxy_user,
											 flac_cfg.stream.proxy_pass,
											 "Proxy-Authorization");
					}
				}
				else
					file = g_strconcat("/", filename, NULL);

				temp = g_strdup_printf("GET %s HTTP/1.0\r\n"
						       "Host: %s\r\n"
						       "User-Agent: %s/%s\r\n"
						       "%s%s%s%s",
						       file, host, "Reference FLAC Player", FLAC__VERSION_STRING, 
						       proxy_auth ? proxy_auth : "", auth ? auth : "",
						       flac_cfg.stream.cast_title_streaming ?  "Icy-MetaData:1\r\n" : "",
						       flac_cfg.stream.use_udp_channel ? udpspace : "");
				if (offset && !head) {
					gchar *temp_dead = temp;
					temp = g_strconcat ("%sRange: %ll-\r\n", temp, offset);
					fprintf (stderr, "%s", temp);
					g_free (temp_dead);
				}
				
				g_free(file);
				if(proxy_auth)
					g_free(proxy_auth);
				if(auth)
					g_free(auth);
				write(sock, temp, strlen(temp));
				write(sock, "\r\n", 2);
				g_free(temp);
				flac_ip.set_info_text(_("CONNECTED: WAITING FOR REPLY"));
				while (going && !eof)
				  {
					if (http_check_for_data())
					{
						if (flac_http_read_line(line, 1024))
						{
							status = strchr(line, ' ');
							if (status)
							{
								if (status[1] == '2')
									break;
								else if(status[1] == '3' && status[2] == '0' && status[3] == '2')
								{
									while(going)
									{
										if(http_check_for_data())
										{
											if((cnt = flac_http_read_line(line, 1024)) != -1)
											{
												if(!cnt)
													break;
												if(!strncmp(line, "Location:", 9))
												{
													g_free(url);
													url = g_strdup(line+10);
												}
											}
											else
											{
												eof=TRUE;
												flac_ip.set_info_text(NULL);
												break;
											}
										}
									}			
									redirect=TRUE;
									break;
								}
								else
								{
									status = g_strdup_printf(_("Couldn't connect to host %s\nServer reported: %s"), chost, status);
									show_error_message(status);
									g_free(status);
									break;
								}
							}
						}
						else
						{
							eof = TRUE;
							flac_ip.set_info_text(NULL);
						}
					}
				}

				while (going && !redirect)
				{
					if (http_check_for_data())
					{
						if ((cnt = flac_http_read_line(line, 1024)) != -1)
						{
							if (!cnt)
								break;
							if (!strncmp(line, "icy-name:", 9))
								icy_name = g_strdup(line + 9);
							else if (!strncmp(line, "x-audiocast-name:", 17))
								icy_name = g_strdup(line + 17);
							if (!strncmp(line, "icy-metaint:", 12))
								icy_metaint = atoi(line + 12);
							if (!strncmp(line, "x-audiocast-udpport:", 20)) {
#ifdef DEBUG_UDP
								fprintf (stderr, "Server wants udp messages on port %d\n", atoi (line + 20));
#endif
								/*udp_serverport = atoi (line + 20);*/
							}
							
						}
						else
						{
							eof = TRUE;
							flac_ip.set_info_text(NULL);
							break;
						}
					}
				}
			}
		}
	
		if(redirect)
		{
			if (output_file)
			{
				fclose(output_file);
				output_file = NULL;
			}
			close(sock);
		}

		g_free(user);
		g_free(pass);
		g_free(host);
		g_free(filename);
	} while(redirect);

	g_free(url);
	return eof ? -1 : sock;
}

static void *http_buffer_loop(void *arg)
{
	gchar *status, *url, *temp, *file;
	gint cnt, written;
	int udp_sock = 0;

	url = (gchar *) arg;
	sock = http_connect (url, false, offset);
	
	if (sock >= 0 && flac_cfg.stream.save_http_stream) {
		gchar *output_name;
		file = flac_http_get_title(url);
		output_name = file;
		if (!strncasecmp(output_name, "http://", 7))
			output_name += 7;
		temp = strrchr(output_name, '.');
		if (temp && (!strcasecmp(temp, ".fla") || !strcasecmp(temp, ".flac")))
			*temp = '\0';

		while ((temp = strchr(output_name, '/')))
			*temp = '_';
		output_name = g_strdup_printf("%s/%s.flac", flac_cfg.stream.save_http_path, output_name);

		g_free(file);

		output_file = fopen(output_name, "wb");
		g_free(output_name);
	}

	while (going)
	{

		if (!http_used() && !flac_ip.output->buffer_playing())
			prebuffering = TRUE;
		if (http_free() > 0 && !eof)
		{
			if (http_check_for_data())
			{
				cnt = min(http_free(), buffer_length - wr_index);
				if (cnt > 1024)
					cnt = 1024;
				written = read(sock, buffer + wr_index, cnt);
				if (written <= 0)
				{
					eof = TRUE;
					if (prebuffering)
					{
						prebuffering = FALSE;

						flac_ip.set_info_text(NULL);
					}

				}
				else
					wr_index = (wr_index + written) % buffer_length;
			}

			if (prebuffering)
			{
				if (http_used() > prebuffer_length)
				{
					prebuffering = FALSE;
					flac_ip.set_info_text(NULL);
				}
				else
				{
					status = g_strdup_printf(_("PRE-BUFFERING: %dKB/%dKB"), http_used() / 1024, prebuffer_length / 1024);
					flac_ip.set_info_text(status);
					g_free(status);
				}

			}
		}
		else
			xmms_usleep(10000);

		if (flac_cfg.stream.use_udp_channel && udp_sock != 0)
			if (udp_check_for_data(udp_sock) < 0)
			{
				close(udp_sock);
				udp_sock = 0;
			}
	}
	if (output_file)
	{
		fclose(output_file);
		output_file = NULL;
	}
	if (sock >= 0) {
		close(sock);
	}
	if (udp_sock != 0)
		close(udp_sock);

	g_free(buffer);
	g_free(url);
	
	pthread_exit(NULL);
	return NULL; /* avoid compiler warning */
}

int flac_http_open(gchar * _url, guint64 _offset)
{
	gchar *url;

	url = g_strdup(_url);

	rd_index = 0;
	wr_index = 0;
	buffer_length = flac_cfg.stream.http_buffer_size * 1024;
	prebuffer_length = (buffer_length * flac_cfg.stream.http_prebuffer) / 100;
	buffer_read = 0;
	icy_metaint = 0;
	prebuffering = TRUE;
	going = TRUE;
	eof = FALSE;
	buffer = g_malloc(buffer_length);
	offset = _offset;

	pthread_create(&thread, NULL, http_buffer_loop, url);

	return 0;
}

char *flac_http_get_title(char *url)
{
	if (icy_name)
		return g_strdup(icy_name);
	if (g_basename(url) && strlen(g_basename(url)) > 0)
		return g_strdup(g_basename(url));
	return g_strdup(url);
}

/* Start UDP Channel specific stuff */

/* Find a good local udp port and bind udp_sock to it, return the port */
static int udp_establish_listener(int *sock)
{
	struct sockaddr_in sin;
	socklen_t sinlen = sizeof (struct sockaddr_in);
	
#ifdef DEBUG_UDP
	fprintf (stderr,"Establishing udp listener\n");
#endif
	
	if ((*sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
	{
		g_log(NULL, G_LOG_LEVEL_CRITICAL,
		      "udp_establish_listener(): unable to create socket");
		return -1;
	}

	memset(&sin, 0, sinlen);
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = g_htonl(INADDR_ANY);
			
	if (bind(*sock, (struct sockaddr *)&sin, sinlen) < 0)
	{
		g_log(NULL, G_LOG_LEVEL_CRITICAL,
		      "udp_establish_listener():  Failed to bind socket to localhost: %s", strerror(errno));
		close(*sock);
		return -1;
	}
	if (fcntl(*sock, F_SETFL, O_NONBLOCK) < 0)
	{
		g_log(NULL, G_LOG_LEVEL_CRITICAL,
		      "udp_establish_listener():  Failed to set flags: %s", strerror(errno));
		close(*sock);
		return -1;
	}

	memset(&sin, 0, sinlen);
	if (getsockname(*sock, (struct sockaddr *)&sin, &sinlen) < 0)
	{
		g_log(NULL, G_LOG_LEVEL_CRITICAL,
		      "udp_establish_listener():  Failed to retrieve socket info: %s", strerror(errno));
		close(*sock);
		return -1;
	}

#ifdef DEBUG_UDP
	fprintf (stderr,"Listening on local %s:%d\n", inet_ntoa(sin.sin_addr), g_ntohs(sin.sin_port));
#endif
	
	return g_ntohs(sin.sin_port);
}

static int udp_check_for_data(int sock)
{
	char buf[1025], **lines;
	char *valptr;
	gchar *title;
	gint len, i;
	struct sockaddr_in from;
	socklen_t fromlen;

	fromlen = sizeof(struct sockaddr_in);
	
	if ((len = recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&from, &fromlen)) < 0)
	{
		if (errno != EAGAIN)
		{
			g_log(NULL, G_LOG_LEVEL_CRITICAL,
			      "udp_read_data(): Error reading from socket: %s", strerror(errno));
			return -1;
		}
		return 0;
	}
	buf[len] = '\0';
#ifdef DEBUG_UDP
	fprintf (stderr,"Received: [%s]\n", buf);
#endif
	lines = g_strsplit(buf, "\n", 0);
	if (!lines)
		return 0;
	
	for (i = 0; lines[i]; i++)
	{
		while ((lines[i][strlen(lines[i]) - 1] == '\n') ||
		       (lines[i][strlen(lines[i]) - 1] == '\r'))
			lines[i][strlen(lines[i]) - 1] = '\0';
		
		valptr = strchr(lines[i], ':');
		
		if (!valptr)
			continue;
		else
			valptr++;
		
		g_strstrip(valptr);
		if (!strlen(valptr))
			continue;
		
		if (strstr(lines[i], "x-audiocast-streamtitle") != NULL)
		{
			title = g_strdup_printf ("%s (%s)", valptr, icy_name);
			if (going)
				set_track_info(title, -1);
			g_free (title);
		}

#if 0
		else if (strstr(lines[i], "x-audiocast-streamlength") != NULL)
		{
			if (atoi(valptr) != -1)
				set_track_info(NULL, atoi(valptr));
		}
#endif
				
		else if (strstr(lines[i], "x-audiocast-streammsg") != NULL)
		{
			/* set_track_info(title, -1); */
/*  			xmms_show_message(_("Message"), valptr, _("Ok"), */
/*  					  FALSE, NULL, NULL); */
			g_message("Stream_message: %s", valptr);
		}

#if 0
		/* Use this to direct your webbrowser.. yeah right.. */
		else if (strstr(lines[i], "x-audiocast-streamurl") != NULL)
		{
			if (lasturl && g_strcmp (valptr, lasturl))
			{
				c_message (stderr, "Song URL: %s\n", valptr);
				g_free (lasturl);
				lasturl = g_strdup (valptr);
			}
		}
#endif
		else if (strstr(lines[i], "x-audiocast-udpseqnr:") != NULL)
		{
			gchar obuf[60];
			sprintf(obuf, "x-audiocast-ack: %ld \r\n", atol(valptr));
			if (sendto(sock, obuf, strlen(obuf), 0, (struct sockaddr *) &from, fromlen) < 0)
			{
				g_log(NULL, G_LOG_LEVEL_WARNING,
				      "udp_check_for_data(): Unable to send ack to server: %s", strerror(errno));
			}
#ifdef DEBUG_UDP
			else
				fprintf(stderr,"Sent ack: %s", obuf);
			fprintf (stderr,"Remote: %s:%d\n", inet_ntoa(from.sin_addr), g_ntohs(from.sin_port));
#endif
		}
	}
	g_strfreev(lines);
	return 0;
}

⌨️ 快捷键说明

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