static void compare_date_time (ExifEntry * entry, ExifTagCheckData * testdata) { gint year = 0, month = 1, day = 1, hour = 0, minute = 0, second = 0; GstDateTime *exif_datetime; GstDateTime *datetime; const gchar *str; if (!gst_tag_list_get_date_time_index (testdata->taglist, GST_TAG_DATE_TIME, 0, &datetime)) { GST_WARNING ("Failed to get datetime from taglist"); return; } str = (gchar *) entry->data; sscanf (str, "%04d:%02d:%02d %02d:%02d:%02d", &year, &month, &day, &hour, &minute, &second); exif_datetime = gst_date_time_new_local_time (year, month, day, hour, minute, second); fail_if (exif_datetime == NULL); fail_unless (gst_date_time_get_year (datetime) == gst_date_time_get_year (exif_datetime) && gst_date_time_get_month (datetime) == gst_date_time_get_month (exif_datetime) && gst_date_time_get_day (datetime) == gst_date_time_get_day (exif_datetime) && gst_date_time_get_hour (datetime) == gst_date_time_get_hour (exif_datetime) && gst_date_time_get_minute (datetime) == gst_date_time_get_minute (exif_datetime) && gst_date_time_get_second (datetime) == gst_date_time_get_second (exif_datetime)); gst_date_time_unref (exif_datetime); gst_date_time_unref (datetime); testdata->result = TRUE; }
static void check_date_1977_06_23 (const GstTagList * tags, const gchar * file) { GstDateTime *date = NULL; gst_tag_list_get_date_time (tags, GST_TAG_DATE_TIME, &date); fail_unless (date != NULL, "Tags from %s should contain a GST_TAG_DATE_TIME tag"); fail_unless_equals_int (gst_date_time_get_year (date), 1977); fail_unless_equals_int (gst_date_time_get_month (date), 6); fail_unless_equals_int (gst_date_time_get_day (date), 23); gst_date_time_unref (date); }
static void gst_date_time_set_local_timezone (GstDateTime * dt) { struct tm tt; time_t t; g_return_if_fail (dt != NULL); memset (&tt, 0, sizeof (tt)); tt.tm_mday = gst_date_time_get_day (dt); tt.tm_mon = gst_date_time_get_month (dt) - 1; tt.tm_year = gst_date_time_get_year (dt) - 1900; tt.tm_hour = gst_date_time_get_hour (dt); tt.tm_min = gst_date_time_get_minute (dt); tt.tm_sec = gst_date_time_get_second (dt); t = mktime (&tt); dt->tzoffset = gmt_offset (&tt, t) / 60; }
static void print_one_tag (const GstTagList * list, const gchar * tag, gpointer user_data) { int i, num; num = gst_tag_list_get_tag_size (list, tag); for (i = 0; i < num; ++i) { const GValue *val; /* Note: when looking for specific tags, use the g_tag_list_get_xyz() API, * we only use the GValue approach here because it is more generic */ val = gst_tag_list_get_value_index (list, tag, i); if (G_VALUE_HOLDS_STRING (val)) { const char* unformatted = g_value_get_string (val); gchar* formatted = strescape(unformatted,"\"","\""); fprintf (tagHack,"(%s . \"%s\")\n", tag, formatted); g_free(formatted); } else if (G_VALUE_HOLDS_UINT (val)) { unsigned int uint = g_value_get_uint (val); fprintf(tagHack,"(%s . #x%x)\n", tag, uint); } else if (G_VALUE_HOLDS_DOUBLE (val)) { fprintf(tagHack, "(%s . %g)\n", tag, g_value_get_double (val)); } else if (G_VALUE_HOLDS_BOOLEAN (val)) { fprintf(tagHack,"(%s . %s)\n", tag, (g_value_get_boolean (val)) ? "#t" : "#f"); } else if (GST_VALUE_HOLDS_BUFFER (val)) { fprintf(tagHack, "(%s . (buffer %u))", tag, gst_buffer_get_size (gst_value_get_buffer (val))); } else if (GST_VALUE_HOLDS_DATE_TIME (val)) { GstDateTime* date = (GstDateTime*)g_value_get_boxed(val); fprintf(tagHack, "(%s . (date 0 0 0 %u %u %u))\n", tag, gst_date_time_has_day(date) ? gst_date_time_get_day(date) : 0, gst_date_time_has_month(date) ? gst_date_time_get_month(date) : 1, gst_date_time_has_year(date) ? gst_date_time_get_year (date) : 0); } else { fprintf(tagHack, "(%20s . (type %s))", tag, G_VALUE_TYPE_NAME (val)); } } }
void sj_extractor_extract_track (SjExtractor *extractor, const TrackDetails *track, GFile *file, GError **error) { GParamSpec *spec; GstStateChangeReturn state_ret; SjExtractorPrivate *priv; GstIterator *iter; GValue item = {0, }; GstTagSetter *tagger; gboolean done; char *uri; g_return_if_fail (SJ_IS_EXTRACTOR (extractor)); g_return_if_fail (file != NULL); g_return_if_fail (track != NULL); priv = extractor->priv; /* See if we need to rebuild the pipeline */ if (priv->rebuild_pipeline != FALSE) { build_pipeline (extractor); if (priv->construct_error != NULL) { g_propagate_error (error, priv->construct_error); priv->construct_error = NULL; return; } } /* Need to do this, as playback will have locked the read speed to 2x previously */ spec = g_object_class_find_property (G_OBJECT_GET_CLASS (priv->cdsrc), "read-speed"); if (spec && spec->value_type == G_TYPE_INT) { g_object_set (G_OBJECT (priv->cdsrc), "read-speed", ((GParamSpecInt*)spec)->maximum, NULL); } /* Set the output filename */ gst_element_set_state (priv->filesink, GST_STATE_NULL); uri = g_file_get_uri (file); g_object_set (G_OBJECT (priv->filesink), "location", uri, NULL); g_free (uri); /* Set the metadata */ iter = gst_bin_iterate_all_by_interface (GST_BIN (priv->pipeline), GST_TYPE_TAG_SETTER); done = FALSE; while (!done) { switch (gst_iterator_next (iter, &item)) { case GST_ITERATOR_OK: /* TODO: generate this as a taglist once, and apply it to all elements */ tagger = g_value_get_object (&item); gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_REPLACE_ALL, GST_TAG_TITLE, track->title, GST_TAG_ARTIST, track->artist, GST_TAG_TRACK_NUMBER, track->number, GST_TAG_TRACK_COUNT, track->album->number, GST_TAG_ALBUM, track->album->title, GST_TAG_DURATION, track->duration * GST_SECOND, NULL); if (track->composer != NULL && strcmp (track->composer, "") != 0) { gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_COMPOSER, track->composer, NULL); } if (track->composer_sortname != NULL && strcmp (track->composer_sortname, "") != 0) { gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_COMPOSER_SORTNAME, track->composer_sortname, NULL); } if (track->album->album_id != NULL && strcmp (track->album->album_id, "") != 0) { gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_MUSICBRAINZ_ALBUMID, track->album->album_id, NULL); } if (track->album->artist_id != NULL && strcmp (track->album->artist_id, "") != 0) { gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_MUSICBRAINZ_ALBUMARTISTID, track->album->artist_id, NULL); } if (track->album->artist != NULL && strcmp (track->album->artist, "") != 0) { gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_ALBUM_ARTIST, track->album->artist, NULL); } if (track->album->artist_sortname != NULL && strcmp (track->album->artist_sortname, "") != 0) { gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_ALBUM_ARTIST_SORTNAME, track->album->artist_sortname, NULL); } if (track->artist_id != NULL && strcmp (track->artist_id, "") != 0) { gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_MUSICBRAINZ_ARTISTID, track->artist_id, NULL); } if (track->track_id != NULL && strcmp (track->track_id, "") != 0) { gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_MUSICBRAINZ_TRACKID, track->track_id, NULL); } if (track->artist_sortname != NULL && strcmp (track->artist_sortname, "") != 0) { gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST_SORTNAME, track->artist_sortname, NULL); } if (track->album->genre != NULL && strcmp (track->album->genre, "") != 0) { char **values, **l; values = g_strsplit (track->album->genre, ",", 0); for (l = values; *l; l++) { g_strstrip (*l); gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_GENRE, *l, NULL); } g_strfreev (values); } if (track->album->release_date) { GDate *date; guint year = 1; guint month = 1; guint day = 1; if (gst_date_time_has_year (track->album->release_date)) { year = gst_date_time_get_year (track->album->release_date); } if (gst_date_time_has_month (track->album->release_date)) { month = gst_date_time_get_month (track->album->release_date); } if (gst_date_time_has_day (track->album->release_date)) { day = gst_date_time_get_day (track->album->release_date); } date = g_date_new_dmy (day, month, year); /* We set both GST_TAG_DATE_TIME and GST_TAG_DATE as most taggers * use GST_TAG__DATE_TIME, but a few (id3v2mux/apemux) are still using * GST_TAG_DATE */ gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_DATE_TIME, track->album->release_date, GST_TAG_DATE, date, NULL); g_date_free (date); } if (track->album->disc_number > 0) { gst_tag_setter_add_tags (tagger, GST_TAG_MERGE_APPEND, GST_TAG_ALBUM_VOLUME_NUMBER, track->album->disc_number, NULL); } g_value_unset (&item); break; case GST_ITERATOR_RESYNC: /* TODO? */ g_warning ("Got GST_ITERATOR_RESYNC, not sure what to do"); gst_iterator_resync (iter); break; case GST_ITERATOR_ERROR: done = TRUE; break; case GST_ITERATOR_DONE: done = TRUE; break; } } g_value_unset (&item); gst_iterator_free (iter); /* Seek to the right track */ g_object_set (G_OBJECT (priv->cdsrc), "track", track->number, NULL); /* Let's get ready to rumble! */ state_ret = gst_element_set_state (priv->pipeline, GST_STATE_PLAYING); if (state_ret == GST_STATE_CHANGE_ASYNC) { /* Wait for state change to either complete or fail, but not for too long, * just to catch immediate errors. The rest we'll handle asynchronously */ state_ret = gst_element_get_state (priv->pipeline, NULL, NULL, GST_SECOND / 2); } if (state_ret == GST_STATE_CHANGE_FAILURE) { GstMessage *msg; msg = gst_bus_poll (GST_ELEMENT_BUS (priv->pipeline), GST_MESSAGE_ERROR, 0); if (msg) { gst_message_parse_error (msg, error, NULL); gst_message_unref (msg); } else if (error) { /* this should never happen, create generic error just in case */ *error = g_error_new (SJ_ERROR, SJ_ERROR_INTERNAL_ERROR, "Error starting ripping pipeline"); } gst_element_set_state (priv->pipeline, GST_STATE_NULL); priv->rebuild_pipeline = TRUE; return; } priv->tick_id = g_timeout_add (250, (GSourceFunc)tick_timeout_cb, extractor); g_source_set_name_by_id (priv->tick_id, "[sound-juicer] tick_timeout_cb"); }
gchar * __gst_date_time_serialize (GstDateTime * datetime, gboolean serialize_usecs) { GString *s; gfloat gmt_offset; guint msecs; /* we always have at least the year */ s = g_string_new (NULL); g_string_append_printf (s, "%04u", gst_date_time_get_year (datetime)); if (datetime->fields == GST_DATE_TIME_FIELDS_Y) goto done; /* add month */ g_string_append_printf (s, "-%02u", gst_date_time_get_month (datetime)); if (datetime->fields == GST_DATE_TIME_FIELDS_YM) goto done; /* add day of month */ g_string_append_printf (s, "-%02u", gst_date_time_get_day (datetime)); if (datetime->fields == GST_DATE_TIME_FIELDS_YMD) goto done; /* add time */ g_string_append_printf (s, "T%02u:%02u", gst_date_time_get_hour (datetime), gst_date_time_get_minute (datetime)); if (datetime->fields == GST_DATE_TIME_FIELDS_YMD_HM) goto add_timezone; /* add seconds */ g_string_append_printf (s, ":%02u", gst_date_time_get_second (datetime)); /* add microseconds */ if (serialize_usecs) { msecs = gst_date_time_get_microsecond (datetime); if (msecs != 0) { g_string_append_printf (s, ".%06u", msecs); /* trim trailing 0s */ while (s->str[s->len - 1] == '0') g_string_truncate (s, s->len - 1); } } /* add timezone */ add_timezone: gmt_offset = gst_date_time_get_time_zone_offset (datetime); if (gmt_offset == 0) { g_string_append_c (s, 'Z'); } else { guint tzhour, tzminute; tzhour = (guint) ABS (gmt_offset); tzminute = (guint) ((ABS (gmt_offset) - tzhour) * 60); g_string_append_c (s, (gmt_offset >= 0) ? '+' : '-'); g_string_append_printf (s, "%02u%02u", tzhour, tzminute); } done: return g_string_free (s, FALSE); }