1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3 * Copyright (C) 2006 Jonathan Matthew <jonathan@kaolin.wh9.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <libsoup/soup.h>
31 #define RB_TYPE_LASTFM_SRC (rb_lastfm_src_get_type())
32 #define RB_LASTFM_SRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),RB_TYPE_LASTFM_SRC,RBLastFMSrc))
33 #define RB_LASTFM_SRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),RB_TYPE_LASTFM_SRC,RBLastFMSrcClass))
34 #define RB_IS_LASTFM_SRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),RB_TYPE_LASTFM_SRC))
35 #define RB_IS_LASTFM_SRC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),RB_TYPE_LASTFM_SRC))
37 typedef struct _RBLastFMSrc RBLastFMSrc
;
38 typedef struct _RBLastFMSrcClass RBLastFMSrcClass
;
49 struct _RBLastFMSrcClass
51 GstBinClass parent_class
;
60 static GstStaticPadTemplate srctemplate
= GST_STATIC_PAD_TEMPLATE ("src",
65 static GstElementDetails rb_lastfm_src_details
=
66 GST_ELEMENT_DETAILS ("RB Last.FM Source",
68 "Reads a last.fm radio stream",
69 "Jonathan Matthew <jonathan@kaolin.wh9.net>");
71 static void rb_lastfm_src_uri_handler_init (gpointer g_iface
, gpointer iface_data
);
74 _do_init (GType lastfm_src_type
)
76 static const GInterfaceInfo urihandler_info
= {
77 rb_lastfm_src_uri_handler_init
,
82 g_type_add_interface_static (lastfm_src_type
, GST_TYPE_URI_HANDLER
,
86 GST_BOILERPLATE_FULL (RBLastFMSrc
, rb_lastfm_src
, GstBin
, GST_TYPE_BIN
, _do_init
);
89 rb_lastfm_src_base_init (gpointer g_class
)
91 GstElementClass
*element_class
= GST_ELEMENT_CLASS (g_class
);
92 gst_element_class_add_pad_template (element_class
,
93 gst_static_pad_template_get (&srctemplate
));
94 gst_element_class_set_details (element_class
, &rb_lastfm_src_details
);
98 rb_lastfm_src_init (RBLastFMSrc
*src
, RBLastFMSrcClass
*klass
)
100 rb_debug ("creating rb last.fm src element");
104 rb_lastfm_src_pad_probe_cb (GstPad
*pad
, GstBuffer
*buffer
, RBLastFMSrc
*src
)
106 guint8
*data
= GST_BUFFER_DATA (buffer
);
108 static char sync
[5] = "SYNC";
110 s
= memmem (data
, GST_BUFFER_SIZE (buffer
), sync
, 4);
115 rb_debug ("got song change tag");
116 s
= gst_structure_new ("rb-lastfm-new-song", NULL
);
117 msg
= gst_message_new_application (GST_OBJECT (src
), s
);
118 gst_element_post_message (GST_ELEMENT (src
), msg
);
125 rb_lastfm_src_set_uri (RBLastFMSrc
*src
, const char *uri
)
129 rb_debug ("stream uri: %s", uri
);
130 g_free (src
->lastfm_uri
);
131 src
->lastfm_uri
= g_strdup (uri
);
134 gst_element_remove_pad (GST_ELEMENT (src
), src
->ghostpad
);
135 gst_object_unref (src
->ghostpad
);
136 src
->ghostpad
= NULL
;
138 gst_bin_remove (GST_BIN (src
), src
->http_src
);
139 gst_object_unref (src
->http_src
);
140 src
->http_src
= NULL
;
143 /* create actual HTTP source */
144 src
->http_src
= gst_element_make_from_uri (GST_URI_SRC
, src
->lastfm_uri
, NULL
);
145 gst_bin_add (GST_BIN (src
), src
->http_src
);
146 gst_object_ref (src
->http_src
);
148 /* create ghost pad */
149 pad
= gst_element_get_pad (src
->http_src
, "src");
150 src
->ghostpad
= gst_ghost_pad_new ("src", pad
);
151 gst_element_add_pad (GST_ELEMENT (src
), src
->ghostpad
);
152 gst_object_ref (src
->ghostpad
);
153 gst_object_unref (pad
);
156 gst_pad_add_buffer_probe (pad
, G_CALLBACK (rb_lastfm_src_pad_probe_cb
), src
);
160 rb_lastfm_src_set_property (GObject
*object
,
165 RBLastFMSrc
*src
= RB_LASTFM_SRC (object
);
169 rb_lastfm_src_set_uri (src
, g_value_get_string (value
));
172 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
178 rb_lastfm_src_get_property (GObject
*object
,
183 RBLastFMSrc
*src
= RB_LASTFM_SRC (object
);
187 g_value_set_string (value
, src
->lastfm_uri
);
190 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
196 rb_lastfm_src_finalize (GObject
*object
)
199 src
= RB_LASTFM_SRC (object
);
201 g_free (src
->lastfm_uri
);
204 gst_object_unref (src
->ghostpad
);
207 gst_object_unref (src
->http_src
);
209 G_OBJECT_CLASS (parent_class
)->finalize (object
);
213 rb_lastfm_src_class_init (RBLastFMSrcClass
*klass
)
215 GObjectClass
*gobject_class
;
216 GstElementClass
*element_class
;
218 gobject_class
= G_OBJECT_CLASS (klass
);
219 gobject_class
->finalize
= rb_lastfm_src_finalize
;
220 gobject_class
->set_property
= rb_lastfm_src_set_property
;
221 gobject_class
->get_property
= rb_lastfm_src_get_property
;
223 element_class
= GST_ELEMENT_CLASS (klass
);
225 g_object_class_install_property (gobject_class
,
227 g_param_spec_string ("uri",
229 "last.fm stream uri",
235 /* URI handler interface */
238 rb_lastfm_src_uri_get_type (void)
244 rb_lastfm_src_uri_get_protocols (void)
246 static gchar
*protocols
[] = {"xrblastfm", NULL
};
251 rb_lastfm_src_uri_get_uri (GstURIHandler
*handler
)
253 RBLastFMSrc
*src
= RB_LASTFM_SRC (handler
);
255 return src
->lastfm_uri
;
259 rb_lastfm_src_uri_set_uri (GstURIHandler
*handler
,
262 RBLastFMSrc
*src
= RB_LASTFM_SRC (handler
);
265 if (GST_STATE (src
) == GST_STATE_PLAYING
|| GST_STATE (src
) == GST_STATE_PAUSED
) {
269 if (g_str_has_prefix (uri
, "xrblastfm://") == FALSE
) {
273 http_uri
= g_strdup_printf ("http://%s", uri
+ strlen ("xrblastfm://"));
274 g_object_set (src
, "uri", http_uri
, NULL
);
281 rb_lastfm_src_uri_handler_init (gpointer g_iface
,
284 GstURIHandlerInterface
*iface
= (GstURIHandlerInterface
*) g_iface
;
286 iface
->get_type
= rb_lastfm_src_uri_get_type
;
287 iface
->get_protocols
= rb_lastfm_src_uri_get_protocols
;
288 iface
->get_uri
= rb_lastfm_src_uri_get_uri
;
289 iface
->set_uri
= rb_lastfm_src_uri_set_uri
;
293 plugin_init (GstPlugin
*plugin
)
295 gboolean ret
= gst_element_register (plugin
, "rblastfmsrc", GST_RANK_PRIMARY
, RB_TYPE_LASTFM_SRC
);
299 GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR
,
302 "element to access last.fm streams",