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 + -
显示快捷键?