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

📄 shoutcast.c

📁 linux下网络收音机的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  info.streams = streams;  session = st_transfer_session_new();  stream_limit = st_handler_config_get_boolean(shoutcast_handler, CONFIG_STREAM_LIMIT_ENABLED)    ? st_handler_config_get_int(shoutcast_handler, CONFIG_STREAM_LIMIT)    : (! strcmp(category->name, "__main") ? 500 : -1); /* [1] */  /*   * [1] The main category contains all the SHOUTcast streams (a lot),   * so we just load the first 500.   */    do    {      char *url;      int rows;      if (requested_streams != 0 && st_is_aborted())	{	  status = FALSE;	  break;	}      rows = stream_limit == -1	? MAX_STREAMS_PER_PAGE	: MIN(stream_limit - received_streams, MAX_STREAMS_PER_PAGE);            url = g_strdup_printf(SHOUTCAST_ROOT "directory/?numresult=%i&startat=%i%s", rows, requested_streams, category->url_postfix);      requested_streams += rows;      info.page = 0;      info.npages = 0;      info.parent_node = NULL;      info.stream = NULL;      status = st_transfer_session_get_by_line(session,					       url,					       ST_TRANSFER_UTF8 | ST_TRANSFER_PARSE_HTTP_CHARSET | ST_TRANSFER_PARSE_HTML_CHARSET,					       NULL,					       NULL,					       reload_body_cb,					       &info,					       err);      g_free(url);      received_streams = g_list_length(*streams);      if (info.stream)	{	  stream_free_cb(info.stream, NULL);	  if (status) /* only display warning if the transfer was otherwise correct */	    PARSE_ERROR;	}    }  while (status && info.page > 0 && info.page < info.npages	 && (stream_limit == -1 || received_streams < stream_limit));        st_transfer_session_free(session);    return status;}static voidreload_body_cb (const char *line, gpointer data){  ReloadInfo *info = data;  char *s1, *s2, *s3, *s4, *s5;  char *word1, *word2;  if ((s1 = strstr(line, "sbin/shoutcast-playlist.pls"))      && (s2 = st_strstr_span(s1, "filename.pls")))    {      if (info->stream)	/* a malformed stream remains, free it */	{	  PARSE_ERROR;	  stream_free_cb(info->stream, NULL);	}	        info->stream = stream_new_cb(NULL);      info->stream->url_postfix = st_sgml_ref_expand_len(s1, s2 - s1);    }  else if (info->page < 2	   && (((s1 = st_str_has_prefix_span(line, "\t<OPTION VALUE=\""))		|| (s1 = st_str_has_prefix_span(line, "\t\t<OPTION VALUE=\"")))	       && (s2 = strstr(s1, "\">"))))    {      STCategory *category;      GNode *node;      char *escaped;      category = st_category_new();            category->name = st_sgml_ref_expand_len(s1, s2 - s1);      category->label = st_sgml_ref_expand(s2 + 2);            escaped = st_transfer_escape(category->name);      category->url_postfix = g_strconcat("&sgenre=", escaped, NULL);      g_free(escaped);            node = g_node_new(category);            if (g_str_has_prefix(category->label, " - "))	{	  if (info->parent_node)	    {	      char *new_label;	      new_label = g_strdup(category->label + 3);	      g_free(category->label);	      category->label = new_label;	      g_node_append(info->parent_node, node);	    }	  else	    {	      PARSE_ERROR;	      st_category_free(category);	      g_node_destroy(node);	    }	}      else	{	  g_node_append(*(info->categories), node);	  info->parent_node = node;	}    }  else if ((s1 = st_strstr_span(line, "<b>["))	   && (s2 = strstr(s1, "]</font>"))	   && (s3 = st_strstr_span(s2, "href=\""))	   && (s4 = strstr(s3, "\">"))	   && (s5 = strstr(s4, "</a>")))    {      if (info->stream)	{	  g_free(info->stream->genre);	  info->stream->genre = st_sgml_ref_expand_len(s1, s2 - s1);	  g_free(info->stream->homepage);	  info->stream->homepage = st_sgml_ref_expand_len(s3, s4 - s3);	  g_free(info->stream->description);	  s4 += 2; info->stream->description = st_sgml_ref_expand_len(s4, s5 - s4);	}      else	PARSE_ERROR;    }  else if ((s1 = st_strstr_span(line, "Now Playing:</font> "))	   && (s2 = strstr(s1, "</font>")))    {      if (info->stream)	{	  g_free(info->stream->now_playing);	  info->stream->now_playing = st_sgml_ref_expand_len(s1, s2 - s1);	}      else	PARSE_ERROR;    }  else if ((s1 = st_str_has_prefix_span(line, "Page "))	   && (s2 = strstr(s1, " of ")))    {      word1 = st_sgml_ref_expand_len(s1, s2 - s1);      s2 += 4; word2 = st_sgml_ref_expand_len(s2, strspn(s2, ST_NUMERIC));      if (st_str_like(word1, ST_NUMERIC) && st_str_like(word2, ST_NUMERIC))	{	  info->page = atoi(word1);	  info->npages = atoi(word2);	}      else	PARSE_ERROR;      g_free(word1);      g_free(word2);    }  else if ((s1 = st_strstr_span(line, "<font face="))	   && (s2 = st_strchr_span(s1, '>'))	   && (s3 = strstr(s2, "</font>")))    {      word1 = st_sgml_ref_expand_len(s2, s3 - s2);      if (st_str_like(word1, ST_NUMERIC "/"))	{	  if ((s1 = strchr(word1, '/')))	/* listeners */	    {	      *s1 = 0;	      if (info->stream)		{		  info->stream->listeners = atoi(word1);		  info->stream->max = atoi(s1 + 1);		}	      else		PARSE_ERROR;	    }	  else					/* bitrate */	    {	      if (info->stream)		{		  info->stream->bitrate = atoi(word1);		  		  if (info->stream->genre && info->stream->description && info->stream->homepage)		    {		      ((STStream *) info->stream)->name =			g_strdup_printf("%s%s%i",					info->stream->genre,					info->stream->description,					info->stream->bitrate);		      		      *(info->streams) = g_list_append(*(info->streams), info->stream);		    }		  else		    {		      PARSE_ERROR;		      stream_free_cb(info->stream, NULL);		    }		  		  info->stream = NULL;		}	      else		PARSE_ERROR;	    }	}      g_free(word1);    }}static gbooleansearch_url_cb (STCategory *category){  char *str;  str = st_search_dialog();  if (str)    {      char *escaped;      g_free(category->label);      category->label = g_strdup_printf(_("Search results for \"%s\""), str);      escaped = st_transfer_escape(str);      g_free(str);      g_free(category->url_postfix);      category->url_postfix = g_strconcat("&s=", escaped, NULL);      g_free(escaped);      return TRUE;    }  else    return FALSE;}static voidinit_handler (void){  GNode *stock_categories;  STCategory *category;  STHandlerField *field;  shoutcast_handler = st_handler_new_from_plugin(shoutcast_plugin);  st_handler_set_description(shoutcast_handler, _("SHOUTcast Yellow Pages"));  st_handler_set_home(shoutcast_handler, "http://www.shoutcast.com/");    stock_categories = g_node_new(NULL);  category = st_category_new();  category->name = "__main";  category->label = _("Top streams");  category->url_postfix = "&sgenre=TopTen";    g_node_append_data(stock_categories, category);    category = st_category_new();  category->name = "__search";  category->label = g_strdup(_("Search"));  category->url_cb = search_url_cb;  g_node_append_data(stock_categories, category);  st_handler_set_stock_categories(shoutcast_handler, stock_categories);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_RELOAD, reload_cb, NULL);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_STREAM_NEW, stream_new_cb, NULL);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_STREAM_FIELD_GET, stream_field_get_cb, NULL);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_STREAM_FIELD_SET, stream_field_set_cb, NULL);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_STREAM_STOCK_FIELD_GET, stream_stock_field_get_cb, NULL);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_STREAM_FREE, stream_free_cb, NULL);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_STREAM_RESOLVE, stream_resolve_cb, NULL);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_STREAM_TUNE_IN, stream_tune_in_cb, NULL);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_STREAM_RECORD, stream_record_cb, NULL);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_STREAM_BROWSE, stream_browse_cb, NULL);  st_handler_bind(shoutcast_handler, ST_HANDLER_EVENT_PREFERENCES_WIDGET_NEW, preferences_widget_new_cb, NULL);  field = st_handler_field_new(FIELD_GENRE,			       _("Genre"),			       G_TYPE_STRING,			       ST_HANDLER_FIELD_VISIBLE);  st_handler_field_set_description(field, _("The stream genre"));  st_handler_add_field(shoutcast_handler, field);  field = st_handler_field_new(FIELD_DESCRIPTION,			       _("Description"),			       G_TYPE_STRING,			       ST_HANDLER_FIELD_VISIBLE);  st_handler_field_set_description(field, _("The stream description"));  st_handler_add_field(shoutcast_handler, field);  field = st_handler_field_new(FIELD_NOW_PLAYING,			       _("Now playing"),			       G_TYPE_STRING,			       ST_HANDLER_FIELD_VISIBLE);  st_handler_field_set_description(field, _("The currently playing song"));  st_handler_add_field(shoutcast_handler, field);    field = st_handler_field_new(FIELD_LISTENERS,			       _("Listeners"),			       G_TYPE_INT,			       ST_HANDLER_FIELD_VISIBLE);  st_handler_field_set_description(field, _("The current number of listeners"));  st_handler_add_field(shoutcast_handler, field);   field = st_handler_field_new(FIELD_MAX,			       _("Max"),			       G_TYPE_INT,			       ST_HANDLER_FIELD_VISIBLE);  st_handler_field_set_description(field, _("The maximum number of listeners"));  st_handler_add_field(shoutcast_handler, field);  field = st_handler_field_new(FIELD_BITRATE,			       _("Bitrate"),			       G_TYPE_INT,			       ST_HANDLER_FIELD_VISIBLE);  st_handler_field_set_description(field, _("The stream bitrate, in kilobits per seconds"));  st_handler_add_field(shoutcast_handler, field);  st_handler_add_field(shoutcast_handler, st_handler_field_new(FIELD_URL_POSTFIX,							       _("URL postfix"),							       G_TYPE_STRING,							       0));  field = st_handler_field_new(FIELD_HOMEPAGE,			       _("Homepage"),			       G_TYPE_STRING,			       ST_HANDLER_FIELD_VISIBLE			       | ST_HANDLER_FIELD_START_HIDDEN);  st_handler_field_set_description(field, _("The stream homepage URL"));  st_handler_add_field(shoutcast_handler, field);    field = st_handler_field_new(FIELD_URL_LIST,			       _("URL list"),			       G_TYPE_VALUE_ARRAY,			       ST_HANDLER_FIELD_VISIBLE			       | ST_HANDLER_FIELD_START_HIDDEN);  st_handler_field_set_description(field, _("The stream listen URL list"));  st_handler_add_field(shoutcast_handler, field);  st_handler_config_register(shoutcast_handler,			     g_param_spec_boolean(CONFIG_STREAM_LIMIT_ENABLED,						  NULL,						  NULL,						  FALSE,						  G_PARAM_READWRITE));  st_handler_config_register(shoutcast_handler,			     g_param_spec_int(CONFIG_STREAM_LIMIT,					      NULL,					      NULL,					      MIN_STREAM_LIMIT,					      MAX_STREAM_LIMIT,					      100,					      G_PARAM_READWRITE));  st_handlers_add(shoutcast_handler);}static GtkWidget *preferences_widget_new_cb (gpointer data){  GtkWidget *box1;  GtkWidget *box2;  GtkWidget *section;  box1 = gtk_hbox_new(FALSE, 12);  preferences_stream_limit_check = gtk_check_button_new_with_mnemonic(_("_Load at most:"));  box2 = gtk_hbox_new(FALSE, 6);  preferences_stream_limit_spin = gtk_spin_button_new_with_range(MIN_STREAM_LIMIT, MAX_STREAM_LIMIT, 1);  preferences_stream_limit_label = gtk_label_new(_("streams per category"));  gtk_box_pack_start(GTK_BOX(box2), preferences_stream_limit_spin, FALSE, FALSE, 0);  gtk_box_pack_start(GTK_BOX(box2), preferences_stream_limit_label, FALSE, FALSE, 0);  gtk_box_pack_start(GTK_BOX(box1), preferences_stream_limit_check, FALSE, FALSE, 0);  gtk_box_pack_start(GTK_BOX(box1), box2, FALSE, FALSE, 0);  gtk_widget_show_all(box1);  section = st_hig_section_new(_("Streams Limit"), box1);  st_set_tooltip(preferences_stream_limit_check, _("If this option is enabled, the number of streams to download will be limited."));  st_set_tooltip(preferences_stream_limit_spin, _("The maximum number of streams to download per category"));  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(preferences_stream_limit_check), st_handler_config_get_boolean(shoutcast_handler, CONFIG_STREAM_LIMIT_ENABLED));  gtk_spin_button_set_value(GTK_SPIN_BUTTON(preferences_stream_limit_spin), st_handler_config_get_int(shoutcast_handler, CONFIG_STREAM_LIMIT));  preferences_update_sensitivity();  g_signal_connect(preferences_stream_limit_check, "toggled", G_CALLBACK(preferences_stream_limit_toggled_h), NULL);  g_signal_connect(preferences_stream_limit_spin, "value-changed", G_CALLBACK(preferences_stream_limit_changed_h), NULL);    return section;}static voidpreferences_update_sensitivity (void){  gboolean stream_limit_enabled;  stream_limit_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(preferences_stream_limit_check));  gtk_widget_set_sensitive(preferences_stream_limit_spin, stream_limit_enabled);  gtk_widget_set_sensitive(preferences_stream_limit_label, stream_limit_enabled);}static voidpreferences_stream_limit_toggled_h (GtkToggleButton *button, gpointer user_data){  st_handler_config_set_boolean(shoutcast_handler, CONFIG_STREAM_LIMIT_ENABLED, gtk_toggle_button_get_active(button));  preferences_update_sensitivity();}static voidpreferences_stream_limit_changed_h (GtkSpinButton *spin, gpointer user_data){  st_handler_config_set_int(shoutcast_handler, CONFIG_STREAM_LIMIT, gtk_spin_button_get_value_as_int(spin));}static gbooleancheck_api_version (GError **err){  if (st_check_api_version(5, 8))    return TRUE;  else    {      g_set_error(err, 0, 0, _("API version mismatch"));      return FALSE;    }}G_MODULE_EXPORT gbooleanplugin_get_info (STPlugin *plugin, GError **err){  GdkPixbuf *pixbuf;  if (! check_api_version(err))    return FALSE;  shoutcast_plugin = plugin;  st_plugin_set_name(plugin, "shoutcast");  st_plugin_set_label(plugin, "SHOUTcast");  pixbuf = st_pixbuf_new_from_file(UIDIR "/shoutcast.png");  if (pixbuf)    {      st_plugin_set_icon_from_pixbuf(plugin, pixbuf);      g_object_unref(pixbuf);    }  return TRUE;}G_MODULE_EXPORT gbooleanplugin_init (GError **err){  if (! check_api_version(err))    return FALSE;  init_handler();    st_action_register("play-m3u", _("Listen to a .m3u file"), "xmms %q");  st_action_register("record-stream", _("Record a stream"), "xterm -e streamripper %q");  st_action_register("view-web", _("Open a web page"), "epiphany %q");  return TRUE;}

⌨️ 快捷键说明

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