local.c
来自「linux下网络收音机的源码」· C语言 代码 · 共 1,065 行 · 第 1/2 页
C
1,065 行
GNode **categories, GList **streams, gpointer data, GError **err){ char *music_dir; gboolean status; *categories = g_node_new(NULL); music_dir = st_settings_get_music_dir(); if (! music_dir) { g_set_error(err, 0, 0, _("you must set your music folder in the Preferences")); return FALSE; } status = reload_categories(music_dir, *categories, err) && reload_streams(music_dir, category, streams, err); g_free(music_dir); return status;}static gbooleanreload_categories (const char *music_dir, GNode *root, GError **err){ GDir *dir; char *dirname; const char *filename; gboolean status = TRUE; GError *tmp_err = NULL; g_return_val_if_fail(music_dir != NULL, FALSE); g_return_val_if_fail(root != NULL, FALSE); dirname = root->data ? g_build_filename(music_dir, ((STCategory *) root->data)->url_postfix, NULL) : g_strdup(music_dir); dir = g_dir_open(dirname, 0, &tmp_err); if (! dir) { g_set_error(err, 0, 0, _("unable to open directory %s: %s"), dirname, tmp_err->message); g_error_free(tmp_err); status = FALSE; goto end; } while ((filename = g_dir_read_name(dir))) { GNode *node; char *pathname; if (st_is_aborted()) { status = FALSE; goto end; } if (filename[0] == '.') continue; pathname = g_build_filename(dirname, filename, NULL); if (g_file_test(pathname, G_FILE_TEST_IS_DIR)) { STCategory *category; category = st_category_new(); category->name = root->data ? g_build_filename(((STCategory *) root->data)->url_postfix, filename, NULL) : g_strdup(filename); category->label = g_filename_to_utf8(filename, -1, NULL, NULL, &tmp_err); if (! category->label) { st_handler_notice(local_handler, _("%s: unable to convert directory name to UTF-8 encoding: %s"), pathname, tmp_err->message); g_clear_error(&tmp_err); } category->url_postfix = g_strdup(category->name); node = g_node_append_data(root, category); if (! reload_categories(music_dir, node, err)) { status = FALSE; goto end; } } g_free(pathname); } end: if (dir) g_dir_close(dir); g_free(dirname); return status;}static gbooleanreload_streams (const char *music_dir, STCategory *category, GList **streams, GError **err){ GDir *dir; char *dirname; const char *filename; gboolean status = TRUE; GError *tmp_err = NULL; g_return_val_if_fail(music_dir != NULL, FALSE); g_return_val_if_fail(category != NULL, FALSE); g_return_val_if_fail(streams != NULL, FALSE); dirname = category->url_postfix ? g_build_filename(music_dir, category->url_postfix, NULL) : g_strdup(music_dir); dir = g_dir_open(dirname, 0, &tmp_err); if (! dir) { g_set_error(err, 0, 0, _("unable to open directory %s: %s"), dirname, tmp_err->message); g_error_free(tmp_err); status = FALSE; goto end; } while ((filename = g_dir_read_name(dir))) { LocalStream *stream; char *extension; if (st_is_aborted()) { status = FALSE; goto end; } if (filename[0] == '.') continue; extension = strrchr(filename, '.'); if (! (extension++ && (! g_ascii_strcasecmp(extension, "mp3") || ! g_ascii_strcasecmp(extension, "ogg") || ! g_ascii_strcasecmp(extension, "m3u") || ! g_ascii_strcasecmp(extension, "pls")))) continue; /* unhandled */ stream = stream_new_cb(NULL); stream->pathname = g_build_filename(dirname, filename, NULL); ((STStream *) stream)->name = g_strdup(filename); stream->filename = g_filename_to_utf8(filename, -1, NULL, NULL, &tmp_err); if (! stream->filename) { st_handler_notice(local_handler, _("%s: unable to convert filename to UTF-8 encoding: %s"), stream->pathname, tmp_err->message); g_clear_error(&tmp_err); } #ifdef WITH_LOCAL_METADATA metadata_read(stream);#endif *streams = g_list_append(*streams, stream); } end: if (dir) g_dir_close(dir); g_free(dirname); return status;}#ifdef WITH_LOCAL_METADATAstatic voidmetadata_read (LocalStream *stream){ TagLib_File *file; TagLib_Tag *tag; const TagLib_AudioProperties *audio_properties; g_return_if_fail(stream != NULL); file = taglib_file_new(stream->pathname); if (! file) { st_handler_notice(local_handler, _("unable to open %s"), stream->pathname); return; } tag = taglib_file_tag(file); if (tag) { char *title; char *artist; char *album; unsigned int year; char *genre; char *comment; title = taglib_tag_title(tag); g_return_if_fail(title != NULL); artist = taglib_tag_artist(tag); g_return_if_fail(artist != NULL); album = taglib_tag_album(tag); g_return_if_fail(album != NULL); year = taglib_tag_year(tag); genre = taglib_tag_genre(tag); g_return_if_fail(genre != NULL); comment = taglib_tag_comment(tag); g_return_if_fail(comment != NULL); if (*title) stream->title = g_strdup(title); if (*artist) stream->artist = g_strdup(artist); if (*album) stream->album = g_strdup(album); if (year != 0) stream->year = g_strdup_printf("%u", year); if (*genre) stream->genre = g_strdup(genre); if (*comment) stream->comment = g_strdup(comment); taglib_tag_free_strings(); } else st_handler_notice(local_handler, _("%s has no tag"), stream->pathname); audio_properties = taglib_file_audioproperties(file); if (audio_properties) { int length; length = taglib_audioproperties_length(audio_properties); if (length != 0) stream->duration = g_strdup_printf("%02u:%02u", length / 60, length % 60); stream->bitrate = taglib_audioproperties_bitrate(audio_properties); stream->samplerate = taglib_audioproperties_samplerate(audio_properties); stream->channels = taglib_audioproperties_channels(audio_properties); } else st_handler_notice(local_handler, _("%s has no audio properties"), stream->pathname); taglib_file_free(file);}static gbooleanmetadata_write (LocalStream *stream, GSList *fields, GSList *values, GError **err){ TagLib_File *file; TagLib_Tag *tag; gboolean status; g_return_val_if_fail(stream != NULL, FALSE); file = taglib_file_new(stream->pathname); if (! file) { g_set_error(err, 0, 0, _("unable to open file")); return FALSE; } tag = taglib_file_tag(file); if (tag) { GSList *f; GSList *v; for (f = fields, v = values; f && v; f = f->next, v = v->next) { STHandlerField *field = f->data; const GValue *value = v->data; const char *str = g_value_get_string(value); char **ptr = NULL; switch (field->id) { case FIELD_TITLE: taglib_tag_set_title(tag, POINTER_TO_STRING(str)); ptr = &stream->title; break; case FIELD_ARTIST: taglib_tag_set_artist(tag, POINTER_TO_STRING(str)); ptr = &stream->artist; break; case FIELD_ALBUM: taglib_tag_set_album(tag, POINTER_TO_STRING(str)); ptr = &stream->album; break; case FIELD_YEAR: { int year = str ? atoi(str) : 0; taglib_tag_set_year(tag, year); ptr = &stream->year; } break; case FIELD_GENRE: taglib_tag_set_genre(tag, POINTER_TO_STRING(str)); ptr = &stream->genre; break; case FIELD_COMMENT: taglib_tag_set_comment(tag, POINTER_TO_STRING(str)); ptr = &stream->comment; break; } if (ptr) { g_free(*ptr); *ptr = g_strdup(str); } } status = taglib_file_save(file); if (! status) g_set_error(err, 0, 0, _("unable to save file")); } else { status = FALSE; g_set_error(err, 0, 0, _("the tag structure is missing")); } taglib_file_free(file); return status;}#endif /* WITH_LOCAL_METADATA */static voidinit_handler (void){ GNode *stock_categories; STCategory *category; STHandlerField *field; local_handler = st_handler_new_from_plugin(local_plugin); st_handler_set_description(local_handler, _("Local Music Collection")); stock_categories = g_node_new(NULL); category = st_category_new(); category->name = "__main"; category->label = _("Root"); g_node_append_data(stock_categories, category); st_handler_set_stock_categories(local_handler, stock_categories); st_handler_set_flags(local_handler, ST_HANDLER_CONFIRM_DELETION); st_handler_bind(local_handler, ST_HANDLER_EVENT_RELOAD, reload_cb, NULL); st_handler_bind(local_handler, ST_HANDLER_EVENT_STREAM_NEW, stream_new_cb, NULL); st_handler_bind(local_handler, ST_HANDLER_EVENT_STREAM_FIELD_GET, stream_field_get_cb, NULL); st_handler_bind(local_handler, ST_HANDLER_EVENT_STREAM_FIELD_SET, stream_field_set_cb, NULL); st_handler_bind(local_handler, ST_HANDLER_EVENT_STREAM_STOCK_FIELD_GET, stream_stock_field_get_cb, NULL); st_handler_bind(local_handler, ST_HANDLER_EVENT_STREAM_MODIFY, stream_modify_cb, NULL); st_handler_bind(local_handler, ST_HANDLER_EVENT_STREAM_DELETE, stream_delete_cb, NULL); st_handler_bind(local_handler, ST_HANDLER_EVENT_STREAM_FREE, stream_free_cb, NULL); st_handler_bind(local_handler, ST_HANDLER_EVENT_STREAM_TUNE_IN_MULTIPLE, stream_tune_in_multiple_cb, NULL); st_handler_bind(local_handler, ST_HANDLER_EVENT_STREAM_BROWSE, stream_browse_cb, NULL); st_handler_add_field(local_handler, st_handler_field_new(FIELD_PATHNAME, _("Pathname"), G_TYPE_STRING, 0)); field = st_handler_field_new(FIELD_FILENAME, _("Filename"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_EDITABLE); st_handler_field_set_description(field, _("The song filename")); st_handler_add_field(local_handler, field); field = st_handler_field_new(FIELD_TITLE, _("Title"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_EDITABLE); st_handler_field_set_description(field, _("The song title")); st_handler_add_field(local_handler, field); field = st_handler_field_new(FIELD_ARTIST, _("Artist"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_EDITABLE); st_handler_field_set_description(field, _("The performing artist")); st_handler_add_field(local_handler, field); field = st_handler_field_new(FIELD_ALBUM, _("Album"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_EDITABLE); st_handler_field_set_description(field, _("The album the song was released on")); st_handler_add_field(local_handler, field); field = st_handler_field_new(FIELD_YEAR, _("Year"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_EDITABLE); st_handler_field_set_description(field, _("The song release year")); st_handler_add_field(local_handler, field); field = st_handler_field_new(FIELD_GENRE, _("Genre"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_EDITABLE | ST_HANDLER_FIELD_START_HIDDEN); st_handler_field_set_description(field, _("The song genre")); st_handler_add_field(local_handler, field); field = st_handler_field_new(FIELD_COMMENT, _("Comment"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_EDITABLE | ST_HANDLER_FIELD_START_HIDDEN); st_handler_field_set_description(field, _("The song comment")); st_handler_add_field(local_handler, field); field = st_handler_field_new(FIELD_DURATION, _("Duration"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE); st_handler_field_set_description(field, _("The song duration")); st_handler_add_field(local_handler, field); field = st_handler_field_new(FIELD_AUDIO, _("Audio"), G_TYPE_STRING, ST_HANDLER_FIELD_VISIBLE | ST_HANDLER_FIELD_START_HIDDEN | ST_HANDLER_FIELD_VOLATILE); st_handler_field_set_description(field, _("The song audio properties")); st_handler_add_field(local_handler, field); /* invisible fields */ st_handler_add_field(local_handler, st_handler_field_new(FIELD_BITRATE, _("Bitrate"), G_TYPE_INT, 0)); st_handler_add_field(local_handler, st_handler_field_new(FIELD_SAMPLERATE, _("Sample rate"), G_TYPE_INT, 0)); st_handler_add_field(local_handler, st_handler_field_new(FIELD_CHANNELS, _("Channels"), G_TYPE_INT, 0)); st_handlers_add(local_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; local_plugin = plugin; st_plugin_set_name(plugin, "local"); st_plugin_set_label(plugin, _("Local")); pixbuf = st_pixbuf_new_from_file(UIDIR "/local.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("view-web", _("Open a web page"), "epiphany %q"); return TRUE;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?