/* * metadata_write_probe: * @pad: sink pad of metadata muxer * @buffer: received buffer * @u_data: image bin object * * Buffer probe that sets Xmp.dc.type and Xmp.dc.format tags * to metadata muxer based on preceding element src pad caps. * * Returns: TRUE always */ static gboolean metadata_write_probe (GstPad * pad, GstBuffer * buffer, gpointer u_data) { /* Add XMP tags */ GstCameraBinImage *img = NULL; GstTagSetter *setter = NULL; GstPad *srcpad = NULL; GstCaps *caps = NULL; GstStructure *st = NULL; img = GST_CAMERABIN_IMAGE (u_data); g_return_val_if_fail (img != NULL, TRUE); if (GST_IS_TAG_SETTER (img->formatter)) { setter = GST_TAG_SETTER (img->formatter); } if (!setter) { GST_WARNING_OBJECT (img, "setting tags failed"); goto done; } /* Xmp.dc.type tag */ gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE, GST_TAG_CODEC, "Image", NULL); /* Xmp.dc.format tag */ if (img->enc) { srcpad = gst_element_get_static_pad (img->enc, "src"); } GST_LOG_OBJECT (img, "srcpad:%" GST_PTR_FORMAT, srcpad); if (srcpad) { caps = gst_pad_get_negotiated_caps (srcpad); GST_LOG_OBJECT (img, "caps:%" GST_PTR_FORMAT, caps); if (caps) { /* If there are many structures, we can't know which one to use */ if (gst_caps_get_size (caps) != 1) { GST_WARNING_OBJECT (img, "can't decide structure for format tag"); goto done; } st = gst_caps_get_structure (caps, 0); if (st) { GST_DEBUG_OBJECT (img, "Xmp.dc.format:%s", gst_structure_get_name (st)); gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE, GST_TAG_VIDEO_CODEC, gst_structure_get_name (st), NULL); } } } done: if (caps) gst_caps_unref (caps); if (srcpad) gst_object_unref (srcpad); return TRUE; }
static gpointer test_threads_thread_func2 (gpointer data) { GstTagSetter *setter = GST_TAG_SETTER (data); GTimer *timer; timer = g_timer_new (); g_atomic_int_inc (&threads_running); while (g_atomic_int_get (&spin_and_wait)) g_usleep (0); GST_INFO ("Go!"); g_timer_start (timer); while (g_timer_elapsed (timer, NULL) < THREADS_TEST_SECONDS) { gst_tag_setter_add_tags (setter, GST_TAG_MERGE_PREPEND, GST_TAG_CODEC, "MP42", GST_TAG_COMMENT, "deep insights go here", GST_TAG_TRACK_COUNT, 10, NULL); } g_timer_destroy (timer); GST_INFO ("Done"); return NULL; }
static void set_metadata (GstElement * camera) { GstTagSetter *setter = GST_TAG_SETTER (camera); GTimeVal time = { 0, 0 }; gchar *desc_str; GDate *date = g_date_new (); g_get_current_time (&time); g_date_set_time_val (date, &time); desc_str = g_strdup_printf ("captured by %s", g_get_real_name ()); gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE, GST_TAG_DATE, date, GST_TAG_DESCRIPTION, desc_str, GST_TAG_TITLE, "gst-camerabin-test capture", GST_TAG_GEO_LOCATION_LONGITUDE, 1.0, GST_TAG_GEO_LOCATION_LATITUDE, 2.0, GST_TAG_GEO_LOCATION_ELEVATION, 3.0, GST_TAG_DEVICE_MANUFACTURER, "gst-camerabin-test manufacturer", GST_TAG_DEVICE_MODEL, "gst-camerabin-test model", NULL); g_free (desc_str); g_date_free (date); }
static gpointer test_threads_thread_func1 (gpointer data) { GstTagSetter *setter = GST_TAG_SETTER (data); GTimer *timer; timer = g_timer_new (); g_atomic_int_inc (&threads_running); while (g_atomic_int_get (&spin_and_wait)) g_usleep (0); GST_INFO ("Go!"); g_timer_start (timer); while (g_timer_elapsed (timer, NULL) < THREADS_TEST_SECONDS) { gst_tag_setter_add_tags (setter, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, "some artist", GST_TAG_TITLE, "some title", GST_TAG_TRACK_NUMBER, 6, NULL); } g_timer_destroy (timer); GST_INFO ("Done"); return NULL; }
static void setup (void) { GstTagSetter *setter; gchar *desc_str; GstCaps *filter_caps; GstBus *bus; gint i; GST_INFO ("init"); main_loop = g_main_loop_new (NULL, TRUE); camera = gst_check_setup_element ("camerabin"); setup_camerabin_elements (camera); g_signal_connect (camera, "image-done", G_CALLBACK (capture_done), main_loop); bus = gst_pipeline_get_bus (GST_PIPELINE (camera)); gst_bus_add_watch (bus, (GstBusFunc) capture_bus_cb, main_loop); gst_bus_set_sync_handler (bus, bus_sync_callback, main_loop); gst_object_unref (bus); filter_caps = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420"); g_object_set (G_OBJECT (camera), "filter-caps", filter_caps, NULL); gst_caps_unref (filter_caps); /* force a low framerate here to not timeout the tests because of the * encoders */ g_signal_emit_by_name (camera, "set-video-resolution-fps", 320, 240, 5, 1, NULL); /* Set some default tags */ setter = GST_TAG_SETTER (camera); desc_str = g_strdup_printf ("Created by %s", g_get_real_name ()); gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE, GST_TAG_DESCRIPTION, desc_str, NULL); g_free (desc_str); if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { GST_WARNING ("setting camerabin to PLAYING failed"); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_object_unref (camera); camera = NULL; } /* create the taglists */ for (i = 0; i < TAGLISTS_COUNT; i++) { taglists[i] = gst_tag_list_new_full (GST_TAG_ARTIST, "test-artist", GST_TAG_GEO_LOCATION_LONGITUDE, g_random_double_range (-180, 180), GST_TAG_GEO_LOCATION_LATITUDE, g_random_double_range (-90, 90), GST_TAG_GEO_LOCATION_ELEVATION, g_random_double_range (0, 3000), NULL); } GST_INFO ("init finished"); }
void Pipeline::writeMetadata() { // To make the video appear in gallery, we need to set the // manufacturer and model tags gst_tag_setter_add_tags(GST_TAG_SETTER(camerabin), GST_TAG_MERGE_REPLACE, GST_TAG_DEVICE_MANUFACTURER, systemInfo.manufacturer().toUtf8().constData(), NULL); gst_tag_setter_add_tags(GST_TAG_SETTER(camerabin), GST_TAG_MERGE_REPLACE, GST_TAG_DEVICE_MODEL, systemInfo.model().toUtf8().constData(), NULL); }
void addTag(const char *tag, GstDateTime *value) { GstTagSetter *s = setter(); if (!s) { return; } gst_tag_setter_add_tags(s, GST_TAG_MERGE_REPLACE, tag, value, NULL); gst_object_unref(s); }
void addTag(const char *tag, const QString& value) { GstTagSetter *s = setter(); if (!s) { return; } gst_tag_setter_add_tags(s, GST_TAG_MERGE_REPLACE, tag, value.toUtf8().data(), NULL); gst_object_unref(s); }
static void setup (void) { GstTagSetter *setter; gchar *desc_str; GstCaps *filter_caps; GstBus *bus; GST_INFO ("init"); main_loop = g_main_loop_new (NULL, TRUE); camera = gst_check_setup_element ("camerabin"); setup_camerabin_elements (camera); g_signal_connect (camera, "img-done", G_CALLBACK (capture_done), main_loop); bus = gst_pipeline_get_bus (GST_PIPELINE (camera)); gst_bus_add_watch (bus, (GstBusFunc) capture_bus_cb, main_loop); gst_object_unref (bus); filter_caps = gst_caps_from_string ("video/x-raw-yuv,format=(fourcc)I420"); g_object_set (G_OBJECT (camera), "filter-caps", filter_caps, NULL); gst_caps_unref (filter_caps); /* force a low framerate here to not timeout the tests because of the * encoders */ g_signal_emit_by_name (camera, "user-res-fps", 320, 240, 5, 1, NULL); /* Set some default tags */ setter = GST_TAG_SETTER (camera); desc_str = g_strdup_printf ("Created by %s", g_get_real_name ()); gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE, GST_TAG_DESCRIPTION, desc_str, NULL); g_free (desc_str); if (gst_element_set_state (GST_ELEMENT (camera), GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { GST_WARNING ("setting camerabin to PLAYING failed"); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); gst_object_unref (camera); camera = NULL; } GST_INFO ("init finished"); }
void TransCoder::pipeRun(int ind) { GstElement *source, *dec, *conv, *encoder, *muxer, *fileout, *tagger, *volume; GstBus *bus; GstState state; GstPad *audiopad;//, *encoderpad; numTrack = ind; bool preenc; int vbr = 0; loop = g_main_loop_new (NULL, FALSE); pipeline = gst_pipeline_new ("audio-transcoder"); // Входной файл source = gst_element_factory_make ("filesrc", "file-source"); g_object_set (source, "location", localFileNamesEncoder->fromUnicode(refparser->getSoundFile()).data(), NULL); dec = gst_element_factory_make ("decodebin", "decoder"); g_signal_connect (dec, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL); gst_bin_add_many (GST_BIN (pipeline), source, dec, NULL); gst_element_link (source, dec); audio = gst_bin_new ("audiobin"); conv = gst_element_factory_make ("audioconvert", "aconv"); volume = gst_element_factory_make ("volume", "vol"); audiopad = gst_element_get_static_pad (conv, "sink"); fileout = gst_element_factory_make ("filesink", "file-out"); // Выходной файл QRegExp rxFileSlash("/"); QRegExp rxTilda("^~(.*)"); QString filename; QTextStream out(stdout); QString comment = trUtf8("CuePlayer ") + qApp->applicationVersion(); QString trackName = refparser->getTrackTitle(ind); QString title = refparser->getTitle(); trackName.replace(rxFileSlash, trUtf8("⁄")); title.replace(rxFileSlash, trUtf8("⁄")); if (rxTilda.indexIn(lineEdit->text()) != -1) lineEdit->setText(QDir::homePath() + rxTilda.cap(1)); QDir updir(lineEdit->text()); if (!updir.exists()) updir.mkdir(lineEdit->text()); QString dirname = lineEdit->text() + "/" + title; QDir dir(dirname); if (!dir.exists()) dir.mkdir(dirname); if (ind < 10) filename = dirname + "/" + "0" + QString::number(ind,10) + " - " + trackName + "." + containerBox->currentText(); else filename = dirname + "/" + QString::number(ind,10) + " - " + trackName + "." + containerBox->currentText(); g_object_set (fileout, "location", localFileNamesEncoder->fromUnicode(filename).data(), NULL); tmpfile.setFileName(dirname + "/" + QString::number(ind,10) + " - " + trackName + ".tmp"); switch (codecBox->currentIndex()) { case CODEC_VORBIS: if (tmpfile.exists()) { g_object_set (source, "location", localFileNamesEncoder->fromUnicode(tmpfile.fileName()).data(), NULL); encoder = gst_element_factory_make ("vorbisenc", "audio-encoder"); tagger = gst_element_factory_make ("vorbistag", "tagger"); muxer = gst_element_factory_make ("oggmux", "audio-muxer"); gst_bin_add_many (GST_BIN (audio), conv, encoder, tagger, muxer, fileout, NULL); gst_element_link_many (conv, encoder, tagger, muxer, fileout, NULL); if (!settings.value("preferences/vorbisquality").isNull()) { g_object_set (encoder, "max-bitrate", settings.value("preferences/vorbismaxbitrate").toInt(), "bitrate", settings.value("preferences/vorbisbitrate").toInt(), "min-bitrate", settings.value("preferences/vorbisminbitrate").toInt(), "quality", settings.value("preferences/vorbisquality").toDouble()/10, "managed", settings.value("preferences/vorbismanaged").toBool(), NULL); } gst_tag_setter_add_tags (GST_TAG_SETTER (tagger), GST_TAG_MERGE_REPLACE_ALL, GST_TAG_TITLE, refparser->getTrackTitle(ind).toUtf8().data(), GST_TAG_ARTIST, refparser->getPerformer().toUtf8().data(), GST_TAG_TRACK_NUMBER, ind, GST_TAG_TRACK_COUNT, refparser->getTrackNumber(), GST_TAG_ALBUM, refparser->getAlbum().toUtf8().data(), GST_TAG_ENCODER, APPNAME, GST_TAG_ENCODER_VERSION, qApp->applicationVersion().toUtf8().data(), GST_TAG_COMMENT, comment.toUtf8().data(), GST_TAG_CODEC, "vorbis", NULL); containerBox->setCurrentIndex(CODEC_VORBIS); } else { preenc = true; encoder = gst_element_factory_make ("flacenc", "audio-encoder"); g_object_set(encoder, "quality", 0, NULL); gst_bin_add_many (GST_BIN (audio), conv, volume, encoder, fileout, NULL); gst_element_link_many (conv, volume, encoder, fileout, NULL); g_object_set (volume, "mute", true, NULL); g_object_set (fileout, "location", localFileNamesEncoder->fromUnicode(tmpfile.fileName()).data(), NULL); } break; case CODEC_LAME: encoder = gst_element_factory_make ("lame", "audio-encoder"); muxer = gst_element_factory_make ("id3v2mux", "audio-muxer"); gst_bin_add_many (GST_BIN (audio), conv, encoder, muxer, fileout, NULL); gst_element_link_many (conv, encoder, muxer, fileout, NULL); if (settings.value("preferences/lamevbr").toInt()) vbr = settings.value("preferences/lamevbr").toInt() + 1; if (!settings.value("preferences/lamequality").isNull()) { g_object_set (encoder, "bitrate", bitrateList.at(settings.value("preferences/lamebitrate").toInt()), //"compression-ratio", settings.value("preferences/lamecompressionratio").toInt(), // Баг. Перекрывает VBR "quality", settings.value("preferences/lamequality").toInt(), "mode", settings.value("preferences/lamemode").toInt(), "force-ms", settings.value("preferences/lameforcems").toBool(), "free-format", settings.value("preferences/lamefreeformat").toBool(), "copyright", settings.value("preferences/lamecopyright").toBool(), "original", settings.value("preferences/lameoriginal").toBool(), "error-protection", settings.value("preferences/lameerrprot").toBool(), "padding-type", settings.value("preferences/lamepaddingtype").toInt(), "extension", settings.value("preferences/lameextension").toBool(), "strict-iso", settings.value("preferences/lamestrictiso").toBool(), "vbr", vbr, "disable-reservoir", settings.value("preferences/lamedisrese").toBool(), NULL); } gst_tag_setter_add_tags (GST_TAG_SETTER (muxer), GST_TAG_MERGE_REPLACE_ALL, GST_TAG_TITLE, refparser->getTrackTitle(ind).toUtf8().data(), GST_TAG_ARTIST, refparser->getPerformer().toUtf8().data(), GST_TAG_TRACK_NUMBER, ind, GST_TAG_TRACK_COUNT, refparser->getTrackNumber(), GST_TAG_ALBUM, refparser->getAlbum().toUtf8().data(), GST_TAG_ENCODER, APPNAME, GST_TAG_ENCODER_VERSION, qApp->applicationVersion().toUtf8().data(), GST_TAG_COMMENT, comment.toUtf8().data(), GST_TAG_CODEC, "lame", NULL); containerBox->setCurrentIndex(CODEC_LAME); break; case CODEC_FLAC: encoder = gst_element_factory_make ("flacenc", "audio-encoder"); tagger = gst_element_factory_make ("flactag", "tagger"); if (!settings.value("preferences/flacquality").isNull()) { g_object_set (encoder, "quality", settings.value("preferences/flacquality").toInt(), "streamable-subset", settings.value("preferences/flacstreamablesubset").toBool(), "mid-side-stereo", settings.value("preferences/flacmidsidestereo").toBool(), "loose-mid-side-stereo", settings.value("preferences/flacloosemidsidestereo").toBool(), "blocksize", settings.value("preferences/flacblocksize").toInt(), "max-lpc-order", settings.value("preferences/flacmaxlpcorder").toInt(), "qlp-coeff-precision", settings.value("preferences/flacqlpcoeffprecision").toInt(), "qlp-coeff-prec-search", settings.value("preferences/flacqlpcoeffprecsearch").toBool(), "escape-coding", settings.value("preferences/flacescapecoding").toBool(), "exhaustive-model-search", settings.value("preferences/flacexhaustivemodelsearch").toBool(), "min-residual-partition-order", settings.value("preferences/flacminresidualpartitionorder").toInt(), "max-residual-partition-order", settings.value("preferences/flacmaxresidualpartitionorder").toInt(), "rice-parameter-search-dist", settings.value("preferences/flacriceparametersearchdist").toInt(), NULL); } gst_bin_add_many (GST_BIN (audio), conv, encoder, tagger, fileout, NULL); gst_element_link_many (conv, encoder, tagger, fileout, NULL); gst_tag_setter_add_tags (GST_TAG_SETTER (tagger), GST_TAG_MERGE_REPLACE_ALL, GST_TAG_TITLE, refparser->getTrackTitle(ind).toUtf8().data(), GST_TAG_ARTIST, refparser->getPerformer().toUtf8().data(), GST_TAG_TRACK_NUMBER, ind, GST_TAG_TRACK_COUNT, refparser->getTrackNumber(), GST_TAG_ALBUM, refparser->getAlbum().toUtf8().data(), GST_TAG_ENCODER, APPNAME, GST_TAG_ENCODER_VERSION, qApp->applicationVersion().toUtf8().data(), GST_TAG_COMMENT, comment.toUtf8().data(), GST_TAG_CODEC, "flac", NULL); containerBox->setCurrentIndex(CODEC_FLAC); break; case CODEC_FAAC: encoder = gst_element_factory_make ("faac", "audio-encoder"); gst_bin_add_many (GST_BIN (audio), conv, encoder, fileout, NULL); gst_element_link_many (conv, encoder, fileout, NULL); if (!settings.value("preferences/faacprofile").isNull()) { g_object_set(encoder, "outputformat", settings.value("preferences/faacoutputformat").toInt(), "bitrate", settings.value("preferences/faacbitrate").toInt(), "profile", settings.value("preferences/faacprofile").toInt()+1, "tns", settings.value("preferences/faactns").toBool(), "midside", settings.value("preferences/faacmidside").toBool(), "shortctl", settings.value("preferences/faacshortctl").toInt(), NULL); } containerBox->setCurrentIndex(CODEC_FAAC); break; case CODEC_NO: default: break; } gst_element_add_pad (audio, gst_ghost_pad_new ("sink", audiopad)); gst_object_unref (audiopad); gst_bin_add (GST_BIN (pipeline), audio); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); gst_bus_add_watch (bus, bus_call, loop); gst_object_unref (bus); //g_signal_connect (pipeline, "deep-notify", G_CALLBACK (gst_object_default_deep_notify), NULL); // Дебаг! out << trUtf8("Кодируется: ") << refparser->getSoundFile() << endl; gst_element_set_state (pipeline, GST_STATE_PLAYING); gst_element_get_state( GST_ELEMENT(pipeline), &state, NULL, GST_MSECOND * 300); if (state == GST_STATE_PLAYING) { timer->start(TIME); if (ind == refparser->getTrackNumber()) setTrackTime(refparser->getTrackIndex(ind),saveTotalTime); else setTrackTime(refparser->getTrackIndex(ind),refparser->getTrackIndex(ind+1)); if (preenc) g_object_set (volume, "mute", false, NULL); g_print ("Запущено...\n"); g_main_loop_run (loop); } else { out << trUtf8("Ошибка перехода в PLAYING\n"); transcode = false; stopAll(); } }
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"); }
static void set_tags (GstElement *pipeline, track_info_t *track) { GstIterator *iter; GstTagSetter *tagger; gboolean done = FALSE; iter = gst_bin_iterate_all_by_interface( GST_BIN(pipeline), GST_TYPE_TAG_SETTER ); while (!done) { switch (gst_iterator_next(iter, (gpointer)&tagger)) { case GST_ITERATOR_OK: gst_tag_setter_add_tags( tagger, GST_TAG_MERGE_REPLACE, GST_TAG_TITLE, track->title, GST_TAG_ARTIST, track->artist, GST_TAG_TRACK_NUMBER, track->track_num, GST_TAG_ALBUM, track->album->title, GST_TAG_DURATION, track->duration *GST_SECOND, GST_TAG_MUSICBRAINZ_ALBUMID, track->album->album_id, GST_TAG_MUSICBRAINZ_ALBUMARTISTID, track->album->artist_id, GST_TAG_MUSICBRAINZ_ARTISTID, track->artist_id, GST_TAG_MUSICBRAINZ_TRACKID, track->track_id, GST_TAG_MUSICBRAINZ_SORTNAME, track->artist_sortname, NULL ); 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 ); } if (track->album->release_date) { gst_tag_setter_add_tags( tagger, GST_TAG_MERGE_APPEND, GST_TAG_DATE, track->album->release_date, NULL ); } break; case GST_ITERATOR_RESYNC: fprintf(stderr, "got iterator resync. wtf\n"); gst_iterator_resync(iter); break; case GST_ITERATOR_ERROR: fprintf(stderr, "iterator error. wtf\n"); /* falling */ case GST_ITERATOR_DONE: done = TRUE; break; } } gst_iterator_free(iter); }
CAMLprim value ocaml_gstreamer_tag_setter_add_tag(value _t, value _mode, value _name, value _v) { gst_tag_setter_add_tags(TagSetter_val(_t), merge_mode_of_int(_mode), String_val(_name), String_val(_v), NULL); return Val_unit; }
gboolean ly_mdh_push(LyMdhMetadata *md) { if(!md||!g_str_has_prefix(md->uri, "file://")) return FALSE; if(!g_mutex_trylock(ly_mdh_put_mutex)) { ly_log_put_with_flag(G_LOG_LEVEL_WARNING, _("An old task is running, Tag Failed!")); return FALSE; } /* * BUILD */ GstElement *filesrc=NULL; GstElement *demux=NULL; GstElement *mux=NULL; GstElement *parse=NULL; GstElement *filesink=NULL; GstElement *tagger=NULL; GstBus *bus=NULL; const gchar *codec=NULL; ly_mdh_put_pipeline=gst_pipeline_new("pipeline"); filesrc=gst_element_factory_make("filesrc","filesrc"); filesink=gst_element_factory_make("filesink","filesink"); if(!ly_mdh_put_pipeline||!filesrc||!filesink) { if(ly_mdh_put_pipeline); gst_object_unref(ly_mdh_put_pipeline); g_mutex_unlock(ly_mdh_put_mutex); return FALSE; } //MP3 if(strstr(md->codec,"MP3")!=NULL) { demux=gst_element_factory_make("id3demux","demux"); tagger=gst_element_factory_make("id3v2mux","tagger"); codec = "LAME"; if(!demux||!tagger) { gst_object_unref(ly_mdh_put_pipeline); g_mutex_unlock(ly_mdh_put_mutex); return FALSE; } } //OGG else if(strstr(md->codec,"Vorbis")!=NULL) { tagger = gst_element_factory_make("vorbistag", "tagger"); demux=gst_element_factory_make("oggdemux","demux"); mux=gst_element_factory_make("oggmux","mux"); parse = gst_element_factory_make("vorbisparse", "parse"); codec = "Vorbis"; if(!demux||!mux||!tagger||!parse) { gst_object_unref(ly_mdh_put_pipeline); g_mutex_unlock(ly_mdh_put_mutex); return FALSE; } } //FLAC else if(strstr(md->codec,"FLAC")!=NULL) { tagger = gst_element_factory_make("flactag", "tagger"); codec="FLAC"; if(!tagger) { gst_object_unref(ly_mdh_put_pipeline); g_mutex_unlock(ly_mdh_put_mutex); return FALSE; } } //APE else if(strstr(md->codec,"Monkey's Audio")!=NULL) { demux=gst_element_factory_make("apedemux","demux"); tagger=gst_element_factory_make("apev2mux","tagger"); codec="LAME"; if(!demux||!tagger) { gst_object_unref(ly_mdh_put_pipeline); g_mutex_unlock(ly_mdh_put_mutex); return FALSE; } } else { gst_object_unref(ly_mdh_put_pipeline); g_mutex_unlock(ly_mdh_put_mutex); return FALSE; } /* * SET */ gchar location_i[1024]=""; gchar location_o[1024]=""; g_snprintf(location_i, sizeof(location_i), "%s", md->uri+7); g_snprintf(location_o, sizeof(location_o), "%s%s-%s.audio", LY_GLA_TEMPDIR, md->artist, md->title); g_object_set(G_OBJECT(filesrc), "location", location_i, NULL); g_object_set(G_OBJECT(filesink), "location", location_o, NULL); gst_tag_setter_add_tags(GST_TAG_SETTER(tagger), GST_TAG_MERGE_REPLACE_ALL, GST_TAG_TITLE, md->title, GST_TAG_ARTIST, md->artist, GST_TAG_ALBUM, md->album, GST_TAG_GENRE, md->genre, GST_TAG_TRACK_NUMBER, md->track, GST_TAG_ENCODER, "Linnya", GST_TAG_ENCODER_VERSION, 1, GST_TAG_CODEC,codec, NULL); /* *LINK */ //MP3 if(strstr(md->codec,"MP3")!=NULL) { gst_bin_add_many(GST_BIN(ly_mdh_put_pipeline), filesrc, demux,tagger,filesink, NULL); g_signal_connect(demux, "pad-added",G_CALLBACK(ly_mdh_push_add_id3_pad_cb), tagger); gst_element_link(filesrc, demux); gst_element_link(tagger, filesink); } //OGG else if(strstr(md->codec,"Vorbis")!=NULL) { gst_bin_add_many(GST_BIN(ly_mdh_put_pipeline), filesrc, demux, tagger, parse, mux, filesink, NULL); g_signal_connect(demux, "pad-added",G_CALLBACK(ly_mdh_push_add_ogg_pad_cb), tagger); gst_element_link(filesrc, demux); gst_element_link_many(tagger, parse, mux, filesink,NULL); } //FLAC else if(strstr(md->codec,"FLAC")!=NULL) { gst_bin_add_many(GST_BIN(ly_mdh_put_pipeline), filesrc, tagger, filesink, NULL); gst_element_link_many(filesrc, tagger, filesink, NULL); } //APE else if(strstr(md->codec,"Monkey's Audio")!=NULL) { gst_bin_add_many(GST_BIN(ly_mdh_put_pipeline), filesrc, demux,tagger,filesink, NULL); g_signal_connect(demux, "pad-added",G_CALLBACK(ly_mdh_push_add_id3_pad_cb), tagger); gst_element_link(filesrc, demux); gst_element_link(tagger, filesink); } else { gst_object_unref(ly_mdh_put_pipeline); g_mutex_unlock(ly_mdh_put_mutex); return FALSE; } bus = gst_pipeline_get_bus(GST_PIPELINE(ly_mdh_put_pipeline)); gst_bus_add_watch(bus, (GstBusFunc)ly_mdh_push_handler_cb, g_memdup(md,sizeof(LyMdhMetadata))); gst_object_unref(bus); gst_element_set_state(ly_mdh_put_pipeline, GST_STATE_NULL); gst_element_set_state(ly_mdh_put_pipeline, GST_STATE_READY); if(gst_element_set_state(ly_mdh_put_pipeline, GST_STATE_PLAYING)==GST_STATE_CHANGE_FAILURE) { gst_element_set_state(ly_mdh_put_pipeline, GST_STATE_NULL); gst_object_unref(ly_mdh_put_pipeline); g_mutex_unlock(ly_mdh_put_mutex); return FALSE; } return TRUE; }