live365.c
来自「linux下网络收音机的源码」· C语言 代码 · 共 1,418 行 · 第 1/3 页
C
1,418 行
else PARSE_ERROR; } else if (strstr(line, "TD CLASS=\"tabledesc2\"")) { if (info->stream) { if (info->stream->station_id) { ((STStream *) info->stream)->name = g_strdup_printf("%i", info->stream->station_id); *(info->streams) = g_list_append(*(info->streams), info->stream); } else { PARSE_ERROR; stream_free_cb(info->stream, NULL); } info->finished_stream = info->stream; info->stream = NULL; } else PARSE_ERROR; } else if ((s1 = st_strstr_span(line, "<a class='desc-link' href='")) && (s2 = st_strchr_span(s1, '>')) && (s3 = strstr(s2, "<BR>"))) { if (info->finished_stream) { info->finished_stream->description = st_sgml_ref_expand_len(s2, s3 - s2); info->finished_stream = NULL; } else PARSE_ERROR; } else if (strstr(line, "Next</A>")) info->has_next_page = TRUE;}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(DIRECTORY_PREFIX, "search&searchdesc=", escaped, NULL); g_free(escaped); return TRUE; } else return FALSE;}static GtkWidget *preferences_widget_new_cb (gpointer data){ GtkWidget *widget; GtkWidget *hbox1; GtkWidget *hbox2; GtkWidget *vbox1; GtkWidget *section; GtkSizeGroup *size_group; char *name; char *password; widget = gtk_vbox_new(FALSE, 18); hbox1 = gtk_hbox_new(FALSE, 12); preferences_stream_limit_check = gtk_check_button_new_with_mnemonic(_("_Load at most:")); gtk_box_pack_start(GTK_BOX(hbox1), preferences_stream_limit_check, FALSE, FALSE, 0); hbox2 = 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(hbox2), preferences_stream_limit_spin, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox2), preferences_stream_limit_label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox1), hbox2, FALSE, FALSE, 0); section = st_hig_section_new(_("Streams Limit"), hbox1); gtk_widget_show_all(section); gtk_box_pack_start(GTK_BOX(widget), section, FALSE, FALSE, 0); vbox1 = gtk_vbox_new(FALSE, 6); preferences_use_membership_check = gtk_check_button_new_with_mnemonic(_("_Use membership")); gtk_box_pack_start(GTK_BOX(vbox1), preferences_use_membership_check, FALSE, FALSE, 0); hbox1 = gtk_hbox_new(FALSE, 12); preferences_name_label = gtk_label_new_with_mnemonic(_("_Name:")); preferences_name_entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(hbox1), preferences_name_label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox1), preferences_name_entry, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0); hbox1 = gtk_hbox_new(FALSE, 12); preferences_password_label = gtk_label_new_with_mnemonic(_("_Password:")); preferences_password_entry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(hbox1), preferences_password_label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox1), preferences_password_entry, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0); gtk_misc_set_alignment(GTK_MISC(preferences_name_label), 1, 0.5); gtk_misc_set_alignment(GTK_MISC(preferences_password_label), 1, 0.5); gtk_label_set_mnemonic_widget(GTK_LABEL(preferences_name_label), preferences_name_entry); gtk_label_set_mnemonic_widget(GTK_LABEL(preferences_password_label), preferences_password_entry); gtk_entry_set_visibility(GTK_ENTRY(preferences_password_entry), FALSE); section = st_hig_section_new(_("Membership"), vbox1); gtk_widget_show_all(section); gtk_box_pack_start(GTK_BOX(widget), section, FALSE, FALSE, 0); size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); gtk_size_group_add_widget(size_group, preferences_stream_limit_check); gtk_size_group_add_widget(size_group, preferences_name_label); gtk_size_group_add_widget(size_group, preferences_password_label); g_object_unref(size_group); 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")); st_set_tooltip(preferences_use_membership_check, _("If this option is enabled, streamtuner will log into Live365 before tuning into streams or recording them.")); st_set_tooltip(preferences_name_entry, _("Your Live365 member name.\n" "\n" "If left blank, you will be prompted for your member name when needed.")); st_set_tooltip(preferences_password_entry, _("Your Live365 password.\n" "\n" "If left blank, you will be prompted for your password when needed.")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(preferences_stream_limit_check), st_handler_config_get_boolean(live365_handler, CONFIG_STREAM_LIMIT_ENABLED)); gtk_spin_button_set_value(GTK_SPIN_BUTTON(preferences_stream_limit_spin), st_handler_config_get_int(live365_handler, CONFIG_STREAM_LIMIT)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(preferences_use_membership_check), st_handler_config_get_boolean(live365_handler, CONFIG_USE_MEMBERSHIP)); name = st_handler_config_get_string(live365_handler, CONFIG_NAME); password = st_handler_config_get_string(live365_handler, CONFIG_PASSWORD); gtk_entry_set_text(GTK_ENTRY(preferences_name_entry), name ? name : ""); gtk_entry_set_text(GTK_ENTRY(preferences_password_entry), password ? password : ""); g_free(name); g_free(password); 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); g_signal_connect(preferences_use_membership_check, "toggled", G_CALLBACK(preferences_use_membership_toggled_h), NULL); g_object_connect(preferences_name_entry, "signal::activate", preferences_credentials_activate_h, preferences_password_entry, "signal::focus-out-event", preferences_credentials_focus_out_event_h, CONFIG_NAME, NULL); g_object_connect(preferences_password_entry, "signal::activate", preferences_credentials_activate_h, preferences_name_entry, "signal::focus-out-event", preferences_credentials_focus_out_event_h, CONFIG_PASSWORD, NULL); return widget;}static voidpreferences_update_sensitivity (void){ gboolean stream_limit_enabled; gboolean use_membership; 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); use_membership = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(preferences_use_membership_check)); gtk_widget_set_sensitive(preferences_name_label, use_membership); gtk_widget_set_sensitive(preferences_name_entry, use_membership); gtk_widget_set_sensitive(preferences_password_label, use_membership); gtk_widget_set_sensitive(preferences_password_entry, use_membership);}static voidpreferences_stream_limit_toggled_h (GtkToggleButton *button, gpointer user_data){ st_handler_config_set_boolean(live365_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(live365_handler, CONFIG_STREAM_LIMIT, gtk_spin_button_get_value_as_int(spin));}static voidpreferences_use_membership_toggled_h (GtkToggleButton *button, gpointer user_data){ st_handler_config_set_boolean(live365_handler, CONFIG_USE_MEMBERSHIP, gtk_toggle_button_get_active(button)); preferences_update_sensitivity();}static voidpreferences_credentials_activate_h (GtkEntry *entry, gpointer user_data){ GtkWidget *next = user_data; gtk_widget_grab_focus(next);}static gbooleanpreferences_credentials_focus_out_event_h (GtkWidget *widget, GdkEventFocus *event, gpointer user_data){ const char *key = user_data; const char *str; str = gtk_entry_get_text(GTK_ENTRY(widget)); st_handler_config_set_string(live365_handler, key, *str ? str : NULL); return FALSE; /* propagate event */}static voidinit_handler (void){ GNode *stock_categories; STCategory *category; STHandlerField *field; const char *default_user = NULL; live365_handler = st_handler_new_from_plugin(live365_plugin); st_handler_set_description(live365_handler, "Live365 Internet Radio"); st_handler_set_home(live365_handler, LIVE365_ROOT); stock_categories = g_node_new(NULL); category = st_category_new(); category->name = "__main"; category->label = _("Editor's Picks"); category->url_postfix = DIRECTORY_PREFIX "ESP"; 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(live365_handler, stock_categories); st_handler_bind(live365_handler, ST_HANDLER_EVENT_RELOAD, reload_cb, NULL); st_handler_bind(live365_handler, ST_HANDLER_EVENT_STREAM_NEW, stream_new_cb, NULL); st_handler_bind(live365_handler, ST_HANDLER_EVENT_STREAM_FIELD_GET, stream_field_get_cb, NULL); st_handler_bind(live365_handler, ST_HANDLER_EVENT_STREAM_FIELD_SET, stream_field_set_cb, NULL); st_handler_bind(live365_handler, ST_HANDLER_EVENT_STREAM_STOCK_FIELD_GET, stream_stock_field_get_cb, NULL); st_handler_bind(live365_handler, ST_HANDLER_EVENT_STREAM_FREE, stream_free_cb, NULL); st_handler_bind(live365_handler, ST_HANDLER_EVENT_STREAM_TUNE_IN, stream_tune_in_cb, NULL); st_handler_bind(live365_handler, ST_HANDLER_EVENT_STREAM_RECORD, stream_record_cb, NULL); st_handler_bind(live365_handler, ST_HANDLER_EVENT_STREAM_BROWSE, stream_browse_cb, NULL); st_handler_bind(live365_handler, ST_HANDLER_EVENT_PREFERENCES_WIDGET_NEW, preferences_widget_new_cb, NULL); field = st_handler_field_new(FIELD_TITLE, _("Title"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE); st_handler_field_set_description(field, _("The stream title")); st_handler_add_field(live365_handler, field); 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(live365_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(live365_handler, field); field = st_handler_field_new(FIELD_BROADCASTER, _("Broadcaster"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE); st_handler_field_set_description(field, _("The stream broadcaster")); st_handler_add_field(live365_handler, field); field = st_handler_field_new(FIELD_AUDIO, _("Audio"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE); st_handler_field_set_description(field, _("The stream audio properties")); st_handler_add_field(live365_handler, field); 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(live365_handler, field); st_handler_add_field(live365_handler, st_handler_field_new(FIELD_STATION_ID, _("Station ID"), G_TYPE_INT, 0)); field = st_handler_field_new(FIELD_URL, _("URL"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_START_HIDDEN | ST_HANDLER_FIELD_VOLATILE); st_handler_field_set_description(field, _("The stream listen URL")); st_handler_add_field(live365_handler, field); st_handler_add_field(live365_handler, st_handler_field_new(FIELD_ACCESS, _("Access"), G_TYPE_INT, 0)); field = st_handler_field_new(FIELD_ACCESS_STRING, _("Access"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_START_HIDDEN | ST_HANDLER_FIELD_VOLATILE); st_handler_field_set_description(field, _("The type of members allowed to tune into the stream")); st_handler_add_field(live365_handler, field); field = st_handler_field_new(FIELD_TLH, /* translator: "TLH" means "Total Listening Hours", translate the acronym properly */ _("TLH"), G_TYPE_INT, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_START_HIDDEN); st_handler_field_set_description(field, _("The stream total listening hours")); st_handler_add_field(live365_handler, field); st_handler_add_field(live365_handler, st_handler_field_new(FIELD_RATING, _("Rating"), G_TYPE_DOUBLE, 0)); field = st_handler_field_new(FIELD_RATING_STRING, _("Rating"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_START_HIDDEN | ST_HANDLER_FIELD_VOLATILE); st_handler_field_set_description(field, _("The stream rating")); st_handler_add_field(live365_handler, field); default_user = g_getenv("STREAMTUNER_LIVE365_USER"); if (default_user) st_handler_notice(live365_handler, _("the STREAMTUNER_LIVE365_USER environment variable is deprecated")); st_handler_config_register(live365_handler, g_param_spec_boolean(CONFIG_USE_MEMBERSHIP, NULL, NULL, FALSE, G_PARAM_READWRITE)); st_handler_config_register(live365_handler, g_param_spec_string(CONFIG_NAME, NULL, NULL, default_user, G_PARAM_READWRITE)); st_handler_config_register(live365_handler, g_param_spec_string(CONFIG_PASSWORD, NULL, NULL, NULL, G_PARAM_READWRITE)); st_handler_config_register(live365_handler, g_param_spec_boolean(CONFIG_STREAM_LIMIT_ENABLED, NULL, NULL, FALSE, G_PARAM_READWRITE)); st_handler_config_register(live365_handler, g_param_spec_int(CONFIG_STREAM_LIMIT, NULL, NULL, MIN_STREAM_LIMIT, MAX_STREAM_LIMIT, 100, G_PARAM_READWRITE)); if (g_getenv("STREAMTUNER_LIVE365_SESSION")) st_handler_notice(live365_handler, _("the STREAMTUNER_LIVE365_SESSION environment variable is obsolete, ignored")); st_handlers_add(live365_handler);}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; live365_plugin = plugin; st_plugin_set_name(plugin, "live365"); st_plugin_set_label(plugin, "Live365"); pixbuf = st_pixbuf_new_from_file(UIDIR "/live365.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("record-stream", _("Record a stream"), "xterm -e streamripper %q"); st_action_register("view-web", _("Open a web page"), "epiphany %q"); st_action_register("play-stream", _("Listen to a stream"), "xmms %q"); return TRUE;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?