2 * Dictix / DixTagWriter - dix-tag-writer.c
4 * Copyright (C) Martin Blanchard 2011 <tinram@gmx.fr>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
29 #include <glib/gi18n.h>
32 #include <gst/pbutils/pbutils.h>
34 #include "dix-tag-writer.h"
41 struct _DixTagWriterPrivate
50 #define DIX_TAG_WRITER_GET_PRIVATE(obj) \
51 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), DIX_TYPE_TAG_WRITER, DixTagWriterPrivate))
53 G_DEFINE_TYPE (DixTagWriter
, dix_tag_writer
, GST_TYPE_PIPELINE
)
56 dix_tag_writer_set_property (GObject
*object
, guint prop_id
, const GValue
*value
, GParamSpec
*pspec
)
58 DixTagWriter
*writer
= (DixTagWriter
*) object
;
59 DixTagWriterPrivate
*priv
= writer
->priv
;
63 priv
->uri
= g_strdup (g_value_get_string (value
));
67 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
72 dix_tag_writer_get_property (GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
74 DixTagWriter
*writer
= (DixTagWriter
*) object
;
75 DixTagWriterPrivate
*priv
= writer
->priv
;
79 g_value_set_string (value
, priv
->uri
);
83 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
88 dix_tag_writer_finalize (GObject
*object
)
90 DixTagWriter
*writer
= (DixTagWriter
*) object
;
91 DixTagWriterPrivate
*priv
= writer
->priv
;
96 if (priv
->tags
!= NULL
) {
97 gst_tag_list_free (priv
->tags
);
101 G_OBJECT_CLASS (dix_tag_writer_parent_class
)->finalize (object
);
105 dix_tag_writer_class_init (DixTagWriterClass
* klass
)
107 GObjectClass
*gobject_class
= (GObjectClass
*) klass
;
109 gobject_class
->set_property
= dix_tag_writer_set_property
;
110 gobject_class
->get_property
= dix_tag_writer_get_property
;
111 gobject_class
->finalize
= dix_tag_writer_finalize
;
113 g_object_class_install_property (gobject_class
,
115 g_param_spec_string ("file-uri",
116 "FLAC audio file uri",
117 "Uri of the flac audio file we're about to write to",
119 G_PARAM_CONSTRUCT_ONLY
| G_PARAM_READWRITE
));
121 g_type_class_add_private (gobject_class
, sizeof (DixTagWriterPrivate
));
125 dix_tag_writer_init (DixTagWriter
* writer
)
127 DixTagWriterPrivate
*priv
= DIX_TAG_WRITER_GET_PRIVATE (writer
);
130 gst_object_set_name (GST_OBJECT(writer
), "DictixTagWriter");
134 priv
->tags
= gst_tag_list_new ();
138 dix_tag_writer_new (const gchar
* uri
)
140 g_return_val_if_fail ((uri
!= NULL
), NULL
);
141 if (g_str_has_suffix (uri
, ".flac") == FALSE
) {
142 g_warning ("TagWriter only support FLAC audio file.\n");
147 return g_object_new (DIX_TYPE_TAG_WRITER
, "file-uri", uri
, NULL
);
151 dix_tag_writer_save (DixTagWriter
*writer
)
153 g_return_if_fail (DIX_IS_TAG_WRITER (writer
));
154 DixTagWriterPrivate
*priv
= writer
->priv
;
155 GError
*error
= NULL
;
156 gchar
*filename
= NULL
;
158 gchar
*basename
= NULL
;
159 gchar
*hidden
= NULL
;
160 GstElement
*source
= NULL
;
161 GstElement
*decoder
= NULL
;
162 GstElement
*setter
= NULL
;
163 GstElement
*sink
= NULL
;
165 GOutputStream
*stream
= NULL
;
166 gboolean done
= FALSE
;
171 if (G_UNLIKELY (priv
->uri
== NULL
)) {
172 g_warning ("No file specified...\n");
177 if (priv
->tags
== NULL
) {
181 filename
= g_filename_from_uri (priv
->uri
, NULL
, NULL
);
182 path
= g_path_get_dirname (filename
);
183 basename
= g_path_get_basename (filename
);
184 hidden
= g_build_filename (path
,
185 g_strconcat (".", basename
, NULL
),
188 file
= g_file_new_for_path (hidden
);
189 stream
= G_OUTPUT_STREAM (g_file_create (file
,
190 G_FILE_CREATE_PRIVATE
,
194 g_warning ("%s\n", error
->message
);
199 if (G_LIKELY (priv
->bus
== NULL
)) {
200 source
= gst_element_factory_make ("giosrc", "DictixTagWriterSource");
201 if (source
== NULL
) {
204 g_object_set (G_OBJECT (source
), "location", priv
->uri
, NULL
);
205 gst_bin_add (GST_BIN (writer
), source
);
207 decoder
= gst_element_factory_make ("flacdec", "DictixTagWriterDecoder");
208 if (decoder
== NULL
) {
209 gst_object_unref (source
);
213 gst_bin_add (GST_BIN (writer
), decoder
);
214 gst_element_link (source
, decoder
);
216 setter
= gst_element_factory_make ("flactag", "DictixTagWriterSetter");
217 if (setter
== NULL
) {
218 gst_object_unref (source
);
219 gst_object_unref (decoder
);
223 gst_bin_add (GST_BIN (writer
), setter
);
224 gst_element_link (decoder
, setter
);
226 sink
= gst_element_factory_make ("giostreamsink", "DictixTagWriterSink");
228 gst_object_unref (source
);
229 gst_object_unref (decoder
);
230 gst_object_unref (setter
);
234 gst_bin_add (GST_BIN (writer
), sink
);
235 gst_element_link (setter
, sink
);
237 priv
->bus
= gst_element_get_bus (GST_ELEMENT (writer
));
240 g_object_set (sink
, "stream", G_OUTPUT_STREAM (stream
), NULL
);
242 gst_tag_setter_merge_tags (GST_TAG_SETTER (setter
),
244 GST_TAG_MERGE_REPLACE
);
246 gst_element_set_state (GST_ELEMENT (writer
), GST_STATE_PLAYING
);
249 message
= gst_bus_timed_pop (priv
->bus
, GST_CLOCK_TIME_NONE
);
251 switch (GST_MESSAGE_TYPE (message
)) {
252 case GST_MESSAGE_ERROR
: {
253 /* TODO: Handle that... */
256 } case GST_MESSAGE_EOS
: {
265 gst_message_unref (message
);
268 gst_element_set_state (GST_ELEMENT (writer
), GST_STATE_NULL
);
270 g_output_stream_close (stream
, NULL
, NULL
);
271 g_object_unref (stream
);
273 old
= g_file_new_for_uri (priv
->uri
);
274 new = g_file_new_for_path (hidden
);
276 g_file_copy_attributes (old
,
278 G_FILE_COPY_ALL_METADATA
,
283 G_FILE_COPY_OVERWRITE
,
296 dix_tag_writer_set_title (DixTagWriter
*writer
, const gchar
*title
)
298 g_return_if_fail (DIX_IS_TAG_WRITER (writer
));
299 g_return_if_fail (title
!= NULL
);
300 DixTagWriterPrivate
*priv
= writer
->priv
;
302 if (G_UNLIKELY (priv
->bus
!= NULL
)) {
306 if (! g_utf8_validate (title
, -1, NULL
)) {
307 g_warning ("Title should be an valid utf8 string");
312 gst_tag_list_add (priv
->tags
,
313 GST_TAG_MERGE_REPLACE_ALL
,