19 #ifndef GSTREAMER_META_DATA_EXTRACTOR_H_ 20 #define GSTREAMER_META_DATA_EXTRACTOR_H_ 22 #include "../engine.h" 39 static const std::map<std::string, std::string> lut
41 {GST_TAG_ALBUM, std::string{xesam::Album::name}},
42 {GST_TAG_ALBUM_ARTIST, std::string{xesam::AlbumArtist::name}},
43 {GST_TAG_ARTIST, std::string{xesam::Artist::name}},
44 {GST_TAG_LYRICS, std::string{xesam::AsText::name}},
45 {GST_TAG_COMMENT, std::string{xesam::Comment::name}},
46 {GST_TAG_COMPOSER, std::string{xesam::Composer::name}},
47 {GST_TAG_DATE, std::string{xesam::ContentCreated::name}},
48 {GST_TAG_ALBUM_VOLUME_NUMBER, std::string{xesam::DiscNumber::name}},
49 {GST_TAG_GENRE, std::string{xesam::Genre::name}},
50 {GST_TAG_TITLE, std::string{xesam::Title::name}},
51 {GST_TAG_TRACK_NUMBER, std::string{xesam::TrackNumber::name}},
52 {GST_TAG_USER_RATING, std::string{xesam::UserRating::name}}
66 [](
const GstTagList *list,
72 auto md = static_cast<media::Track::MetaData*>(user_data);
75 switch(gst_tag_get_type(tag))
80 if (gst_tag_list_get_boolean(list, tag, &value))
87 if (gst_tag_list_get_int(list, tag, &value))
94 if (gst_tag_list_get_uint(list, tag, &value))
101 if (gst_tag_list_get_int64(list, tag, &value))
108 if (gst_tag_list_get_uint64(list, tag, &value))
115 if (gst_tag_list_get_float(list, tag, &value))
122 if (gst_tag_list_get_double(list, tag, &value))
129 if (gst_tag_list_get_string(list, tag, &value))
148 : pipe(gst_pipeline_new(
"meta_data_extractor_pipeline")),
149 decoder(gst_element_factory_make (
"uridecodebin", NULL)),
150 bus(gst_element_get_bus(pipe))
152 gst_bin_add(GST_BIN(pipe), decoder);
154 auto sink = gst_element_factory_make (
"fakesink", NULL);
155 gst_bin_add (GST_BIN (pipe), sink);
157 g_signal_connect (decoder,
"pad-added", G_CALLBACK (on_new_pad), sink);
163 gst_object_unref(pipe);
168 static const std::chrono::nanoseconds state_change_timeout
173 std::chrono::milliseconds{5000}
176 auto ret = gst_element_set_state(pipe, new_state);
178 bool result =
false; GstState current, pending;
181 case GST_STATE_CHANGE_FAILURE:
182 result =
false;
break;
183 case GST_STATE_CHANGE_NO_PREROLL:
184 case GST_STATE_CHANGE_SUCCESS:
185 result =
true;
break;
186 case GST_STATE_CHANGE_ASYNC:
187 result = GST_STATE_CHANGE_SUCCESS == gst_element_get_state(
191 state_change_timeout.count());
200 if (!gst_uri_is_valid(uri.c_str()))
201 throw std::runtime_error(
"Invalid uri");
204 std::promise<core::ubuntu::media::Track::MetaData> promise;
205 std::future<core::ubuntu::media::Track::MetaData> future{promise.get_future()};
207 core::ScopedConnection on_new_message_connection
213 if (msg.
type == GST_MESSAGE_TAG)
215 MetaDataExtractor::on_tag_available(msg.detail.tag, meta_data);
216 }
else if (msg.
type == GST_MESSAGE_ASYNC_DONE)
218 promise.set_value(meta_data);
223 g_object_set(decoder,
"uri", uri.c_str(), NULL);
224 gst_element_set_state(pipe, GST_STATE_PAUSED);
226 if (std::future_status::ready != future.wait_for(std::chrono::seconds(4)))
229 throw std::runtime_error(
"Problem extracting meta data for track");
239 static void on_new_pad(GstElement*, GstPad* pad, GstElement* fakesink)
243 sinkpad = gst_element_get_static_pad (fakesink,
"sink");
245 if (!gst_pad_is_linked (sinkpad)) {
246 if (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)
247 g_error (
"Failed to link pads!");
250 gst_object_unref (sinkpad);
259 #endif // GSTREAMER_META_DATA_EXTRACTOR_H_
core::Signal< Message > on_new_message