summaryrefslogtreecommitdiffstats
path: root/extensions/audio-video-properties
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:39:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:39:48 +0000
commit3ade071f273aaa973e44bf95d6b1d4913a18f03b (patch)
treee2f99d267ae18427645404f215b984afbe73098d /extensions/audio-video-properties
parentInitial commit. (diff)
downloadnautilus-3ade071f273aaa973e44bf95d6b1d4913a18f03b.tar.xz
nautilus-3ade071f273aaa973e44bf95d6b1d4913a18f03b.zip
Adding upstream version 43.2.upstream/43.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'extensions/audio-video-properties')
-rw-r--r--extensions/audio-video-properties/meson.build26
-rw-r--r--extensions/audio-video-properties/totem-gst-helpers.c58
-rw-r--r--extensions/audio-video-properties/totem-gst-helpers.h25
-rw-r--r--extensions/audio-video-properties/totem-mime-types.h282
-rw-r--r--extensions/audio-video-properties/totem-properties-main.c148
-rw-r--r--extensions/audio-video-properties/totem-properties-view.c416
-rw-r--r--extensions/audio-video-properties/totem-properties-view.h48
7 files changed, 1003 insertions, 0 deletions
diff --git a/extensions/audio-video-properties/meson.build b/extensions/audio-video-properties/meson.build
new file mode 100644
index 0000000..e78e7f6
--- /dev/null
+++ b/extensions/audio-video-properties/meson.build
@@ -0,0 +1,26 @@
+libm = cc.find_library('m')
+
+libtotem_properties_page_sources = files(
+ 'totem-properties-main.c',
+ 'totem-properties-view.c',
+ 'totem-gst-helpers.c',
+)
+
+libtotem_properties_page_deps = [
+ libm,
+ gst_tag_dep,
+ gst_pbutils_dep,
+]
+
+libtotem_properties_page = shared_module(
+ 'totem-properties-page',
+ sources: libtotem_properties_page_sources,
+ dependencies: libtotem_properties_page_deps + [
+ nautilus_extension
+ ],
+ c_args: [
+ '-DG_LOG_DOMAIN="TotemPropertiesPage"'
+ ],
+ install: true,
+ install_dir: extensiondir
+)
diff --git a/extensions/audio-video-properties/totem-gst-helpers.c b/extensions/audio-video-properties/totem-gst-helpers.c
new file mode 100644
index 0000000..e01996d
--- /dev/null
+++ b/extensions/audio-video-properties/totem-gst-helpers.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2003-2007 the GStreamer project
+ * Julien Moutte <julien@moutte.net>
+ * Ronald Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2005-2008 Tim-Philipp Müller <tim centricular net>
+ * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ * Copyright © 2009 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include "totem-gst-helpers.h"
+#include <gst/gstprotection.h>
+
+/* Disable decoders that require a display environment to work,
+ * and that might cause crashes */
+void
+totem_gst_disable_display_decoders (void)
+{
+ GstRegistry *registry;
+ const char *blacklisted_plugins[] = {
+ "bmcdec",
+ "vaapi",
+ "video4linux2"
+ };
+ guint i;
+
+ /* Disable the vaapi plugin as it will not work with the
+ * fakesink we use:
+ * See: https://bugzilla.gnome.org/show_bug.cgi?id=700186 and
+ * https://bugzilla.gnome.org/show_bug.cgi?id=749605 */
+ registry = gst_registry_get ();
+
+ for (i = 0; i < G_N_ELEMENTS (blacklisted_plugins); i++) {
+ GstPlugin *plugin =
+ gst_registry_find_plugin (registry,
+ blacklisted_plugins[i]);
+ if (plugin)
+ gst_registry_remove_plugin (registry, plugin);
+ }
+}
+
+/*
+ * vim: sw=2 ts=8 cindent noai bs=2
+ */
diff --git a/extensions/audio-video-properties/totem-gst-helpers.h b/extensions/audio-video-properties/totem-gst-helpers.h
new file mode 100644
index 0000000..9ec559c
--- /dev/null
+++ b/extensions/audio-video-properties/totem-gst-helpers.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2001,2002,2003,2004,2005 Bastien Nocera <hadess@hadess.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef HAVE_TOTEM_GST_HELPERS_H
+#define HAVE_TOTEM_GST_HELPERS_H
+
+void totem_gst_disable_display_decoders (void);
+
+#endif /* HAVE_TOTEM_GST_HELPERS_H */
diff --git a/extensions/audio-video-properties/totem-mime-types.h b/extensions/audio-video-properties/totem-mime-types.h
new file mode 100644
index 0000000..6551f31
--- /dev/null
+++ b/extensions/audio-video-properties/totem-mime-types.h
@@ -0,0 +1,282 @@
+/* generated with mime-types-include.sh, don't edit */
+G_GNUC_UNUSED static const gchar *mime_types[] = {
+"application/mxf",
+"application/ogg",
+"application/ram",
+"application/sdp",
+"application/smil",
+"application/smil+xml",
+"application/vnd.apple.mpegurl",
+"application/vnd.ms-asf",
+"application/vnd.ms-wpl",
+"application/vnd.rn-realmedia",
+"application/vnd.rn-realmedia-vbr",
+"application/x-extension-m4a",
+"application/x-extension-mp4",
+"application/x-flac",
+"application/x-flash-video",
+"application/x-matroska",
+"application/x-netshow-channel",
+"application/x-ogg",
+"application/x-quicktime-media-link",
+"application/x-quicktimeplayer",
+"application/x-shorten",
+"application/x-smil",
+"application/xspf+xml",
+"audio/3gpp",
+"audio/3gpp2",
+"audio/aac",
+"audio/ac3",
+"audio/AMR",
+"audio/AMR-WB",
+"audio/basic",
+"audio/dv",
+"audio/eac3",
+"audio/flac",
+"audio/m4a",
+"audio/midi",
+"audio/mp1",
+"audio/mp2",
+"audio/mp3",
+"audio/mp4",
+"audio/mpeg",
+"audio/mpegurl",
+"audio/mpg",
+"audio/ogg",
+"audio/opus",
+"audio/prs.sid",
+"audio/scpls",
+"audio/vnd.rn-realaudio",
+"audio/wav",
+"audio/webm",
+"audio/x-aac",
+"audio/x-aiff",
+"audio/x-ape",
+"audio/x-flac",
+"audio/x-gsm",
+"audio/x-it",
+"audio/x-m4a",
+"audio/x-m4b",
+"audio/x-matroska",
+"audio/x-mod",
+"audio/x-mp1",
+"audio/x-mp2",
+"audio/x-mp3",
+"audio/x-mpg",
+"audio/x-mpeg",
+"audio/x-mpegurl",
+"audio/x-ms-asf",
+"audio/x-ms-asx",
+"audio/x-ms-wax",
+"audio/x-ms-wma",
+"audio/x-musepack",
+"audio/x-opus+ogg",
+"audio/x-pn-aiff",
+"audio/x-pn-au",
+"audio/x-pn-realaudio",
+"audio/x-pn-realaudio-plugin",
+"audio/x-pn-wav",
+"audio/x-pn-windows-acm",
+"audio/x-realaudio",
+"audio/x-real-audio",
+"audio/x-s3m",
+"audio/x-sbc",
+"audio/x-scpls",
+"audio/x-shorten",
+"audio/x-speex",
+"audio/x-stm",
+"audio/x-tta",
+"audio/x-wav",
+"audio/x-wavpack",
+"audio/x-vorbis",
+"audio/x-vorbis+ogg",
+"audio/x-xm",
+"image/vnd.rn-realpix",
+"image/x-pict",
+"misc/ultravox",
+"text/google-video-pointer",
+"text/x-google-video-pointer",
+"video/3gp",
+"video/3gpp",
+"video/3gpp2",
+"video/dv",
+"video/divx",
+"video/fli",
+"video/flv",
+"video/mp2t",
+"video/mp4",
+"video/mp4v-es",
+"video/mpeg",
+"video/mpeg-system",
+"video/msvideo",
+"video/ogg",
+"video/quicktime",
+"video/vivo",
+"video/vnd.divx",
+"video/vnd.mpegurl",
+"video/vnd.rn-realvideo",
+"video/vnd.vivo",
+"video/webm",
+"video/x-anim",
+"video/x-avi",
+"video/x-flc",
+"video/x-fli",
+"video/x-flic",
+"video/x-flv",
+"video/x-m4v",
+"video/x-matroska",
+"video/x-mjpeg",
+"video/x-mpeg",
+"video/x-mpeg2",
+"video/x-ms-asf",
+"video/x-ms-asf-plugin",
+"video/x-ms-asx",
+"video/x-msvideo",
+"video/x-ms-wm",
+"video/x-ms-wmv",
+"video/x-ms-wmx",
+"video/x-ms-wvx",
+"video/x-nsv",
+"video/x-ogm+ogg",
+"video/x-theora",
+"video/x-theora+ogg",
+"video/x-totem-stream",
+NULL
+};
+G_GNUC_UNUSED static const gchar *audio_mime_types[] = {
+"audio/3gpp",
+"audio/3gpp2",
+"audio/aac",
+"audio/ac3",
+"audio/AMR",
+"audio/AMR-WB",
+"audio/basic",
+"audio/dv",
+"audio/eac3",
+"audio/flac",
+"audio/m4a",
+"audio/midi",
+"audio/mp1",
+"audio/mp2",
+"audio/mp3",
+"audio/mp4",
+"audio/mpeg",
+"audio/mpg",
+"audio/ogg",
+"audio/opus",
+"audio/prs.sid",
+"audio/scpls",
+"audio/vnd.rn-realaudio",
+"audio/wav",
+"audio/webm",
+"audio/x-aac",
+"audio/x-aiff",
+"audio/x-ape",
+"audio/x-flac",
+"audio/x-gsm",
+"audio/x-it",
+"audio/x-m4a",
+"audio/x-m4b",
+"audio/x-matroska",
+"audio/x-mod",
+"audio/x-mp1",
+"audio/x-mp2",
+"audio/x-mp3",
+"audio/x-mpg",
+"audio/x-mpeg",
+"audio/x-ms-asf",
+"audio/x-ms-asx",
+"audio/x-ms-wax",
+"audio/x-ms-wma",
+"audio/x-musepack",
+"audio/x-opus+ogg",
+"audio/x-pn-aiff",
+"audio/x-pn-au",
+"audio/x-pn-wav",
+"audio/x-pn-windows-acm",
+"audio/x-realaudio",
+"audio/x-real-audio",
+"audio/x-s3m",
+"audio/x-sbc",
+"audio/x-shorten",
+"audio/x-speex",
+"audio/x-stm",
+"audio/x-tta",
+"audio/x-wav",
+"audio/x-wavpack",
+"audio/x-vorbis",
+"audio/x-vorbis+ogg",
+"audio/x-xm",
+"application/x-flac",
+NULL
+};
+G_GNUC_UNUSED static const gchar *video_mime_types[] = {
+"application/mxf",
+"application/ogg",
+"application/ram",
+"application/sdp",
+"application/vnd.apple.mpegurl",
+"application/vnd.ms-asf",
+"application/vnd.ms-wpl",
+"application/vnd.rn-realmedia",
+"application/vnd.rn-realmedia-vbr",
+"application/x-extension-m4a",
+"application/x-extension-mp4",
+"application/x-flash-video",
+"application/x-matroska",
+"application/x-netshow-channel",
+"application/x-ogg",
+"application/x-quicktimeplayer",
+"application/x-shorten",
+"image/vnd.rn-realpix",
+"image/x-pict",
+"misc/ultravox",
+"text/x-google-video-pointer",
+"video/3gp",
+"video/3gpp",
+"video/3gpp2",
+"video/dv",
+"video/divx",
+"video/fli",
+"video/flv",
+"video/mp2t",
+"video/mp4",
+"video/mp4v-es",
+"video/mpeg",
+"video/mpeg-system",
+"video/msvideo",
+"video/ogg",
+"video/quicktime",
+"video/vivo",
+"video/vnd.divx",
+"video/vnd.mpegurl",
+"video/vnd.rn-realvideo",
+"video/vnd.vivo",
+"video/webm",
+"video/x-anim",
+"video/x-avi",
+"video/x-flc",
+"video/x-fli",
+"video/x-flic",
+"video/x-flv",
+"video/x-m4v",
+"video/x-matroska",
+"video/x-mjpeg",
+"video/x-mpeg",
+"video/x-mpeg2",
+"video/x-ms-asf",
+"video/x-ms-asf-plugin",
+"video/x-ms-asx",
+"video/x-msvideo",
+"video/x-ms-wm",
+"video/x-ms-wmv",
+"video/x-ms-wmx",
+"video/x-ms-wvx",
+"video/x-nsv",
+"video/x-ogm+ogg",
+"video/x-theora",
+"video/x-theora+ogg",
+"video/x-totem-stream",
+"audio/x-pn-realaudio",
+NULL
+};
diff --git a/extensions/audio-video-properties/totem-properties-main.c b/extensions/audio-video-properties/totem-properties-main.c
new file mode 100644
index 0000000..d592ccd
--- /dev/null
+++ b/extensions/audio-video-properties/totem-properties-main.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2000, 2001 Eazel Inc.
+ * Copyright (C) 2003 Andrew Sobala <aes@gnome.org>
+ * Copyright (C) 2005 Bastien Nocera <hadess@hadess.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#define GST_USE_UNSTABLE_API 1
+#include <gst/gst.h>
+
+#include "totem-properties-view.h"
+#include "totem-gst-helpers.h"
+#include <nautilus-extension.h>
+
+#define WANT_MIME_TYPES 1
+#include "totem-mime-types.h"
+
+static GType tpp_type = 0;
+static void properties_model_provider_iface_init
+ (NautilusPropertiesModelProviderInterface *iface);
+static GList *totem_properties_get_models
+ (NautilusPropertiesModelProvider *provider, GList *files);
+
+static void
+totem_properties_plugin_register_type (GTypeModule *module)
+{
+ const GTypeInfo info = {
+ sizeof (GObjectClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) NULL,
+ NULL,
+ NULL,
+ sizeof (GObject),
+ 0,
+ (GInstanceInitFunc) NULL
+ };
+ const GInterfaceInfo properties_model_provider_iface_info = {
+ (GInterfaceInitFunc)properties_model_provider_iface_init,
+ NULL,
+ NULL
+ };
+
+ tpp_type = g_type_module_register_type (module, G_TYPE_OBJECT,
+ "TotemPropertiesPlugin",
+ &info, 0);
+ g_type_module_add_interface (module,
+ tpp_type,
+ NAUTILUS_TYPE_PROPERTIES_MODEL_PROVIDER,
+ &properties_model_provider_iface_info);
+}
+
+static void
+properties_model_provider_iface_init (NautilusPropertiesModelProviderInterface *iface)
+{
+ iface->get_models = totem_properties_get_models;
+}
+
+static gpointer
+init_backend (gpointer data)
+{
+ gst_init (NULL, NULL);
+ totem_gst_disable_display_decoders ();
+ return NULL;
+}
+
+static GList *
+totem_properties_get_models (NautilusPropertiesModelProvider *provider,
+ GList *files)
+{
+ static GOnce backend_inited = G_ONCE_INIT;
+ NautilusFileInfo *file;
+ char *uri;
+ NautilusPropertiesModel *model;
+ guint i;
+ gboolean found;
+
+ /* only add properties model if a single file is selected */
+ if (files == NULL || files->next != NULL)
+ return NULL;
+ file = files->data;
+
+ /* only add the properties model to these mime types */
+ found = FALSE;
+ for (i = 0; mime_types[i] != NULL; i++) {
+ if (nautilus_file_info_is_mime_type (file, mime_types[i])) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (found == FALSE)
+ return NULL;
+
+ /* okay, make the model, init'ing the backend first if necessary */
+ g_once (&backend_inited, init_backend, NULL);
+
+ uri = nautilus_file_info_get_uri (file);
+ model = totem_properties_view_new (uri);
+ g_free (uri);
+
+ return g_list_prepend (NULL, model);
+}
+
+/* --- extension interface --- */
+void
+nautilus_module_initialize (GTypeModule *module)
+{
+ /* set up translation catalog */
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+
+ totem_properties_plugin_register_type (module);
+ totem_properties_view_register_type (module);
+}
+
+void
+nautilus_module_shutdown (void)
+{
+}
+
+void
+nautilus_module_list_types (const GType **types,
+ int *num_types)
+{
+ static GType type_list[1];
+
+ type_list[0] = tpp_type;
+ *types = type_list;
+ *num_types = G_N_ELEMENTS (type_list);
+}
+
diff --git a/extensions/audio-video-properties/totem-properties-view.c b/extensions/audio-video-properties/totem-properties-view.c
new file mode 100644
index 0000000..5957d05
--- /dev/null
+++ b/extensions/audio-video-properties/totem-properties-view.c
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2003 Andrew Sobala <aes@gnome.org>
+ * Copyright (C) 2004 Bastien Nocera <hadess@hadess.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <config.h>
+
+#include <glib/gi18n-lib.h>
+
+#define GST_USE_UNSTABLE_API 1
+#include <gst/tag/tag.h>
+#include <gst/pbutils/pbutils.h>
+
+#include "totem-properties-view.h"
+#include <math.h>
+
+struct TotemPropertiesViewPriv {
+ NautilusPropertiesModel *model;
+ GListStore *store;
+ GstDiscoverer *disco;
+};
+
+static GObjectClass *parent_class = NULL;
+static void totem_properties_view_finalize (GObject *object);
+
+G_DEFINE_TYPE (TotemPropertiesView, totem_properties_view, G_TYPE_OBJECT)
+
+void
+totem_properties_view_register_type (GTypeModule *module)
+{
+ totem_properties_view_get_type ();
+}
+
+static void
+totem_properties_view_class_init (TotemPropertiesViewClass *class)
+{
+ parent_class = g_type_class_peek_parent (class);
+ G_OBJECT_CLASS (class)->finalize = totem_properties_view_finalize;
+}
+
+static void
+append_item (TotemPropertiesView *props,
+ const char *name,
+ const char *value)
+{
+ g_autoptr (NautilusPropertiesItem) item = NULL;
+
+ item = nautilus_properties_item_new (name, value);
+
+ g_list_store_append (props->priv->store, item);
+}
+
+/* Copied from bacon-video-widget-properties.c
+ * Copyright (C) 2002 Bastien Nocera
+ */
+static char *
+time_to_string_text (gint64 msecs)
+{
+ char *secs, *mins, *hours, *string;
+ int sec, min, hour, _time;
+
+ _time = (int) (msecs / 1000);
+ sec = _time % 60;
+ _time = _time - sec;
+ min = (_time % (60*60)) / 60;
+ _time = _time - (min * 60);
+ hour = _time / (60*60);
+
+ hours = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d hour", "%d hours", hour), hour);
+
+ mins = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d minute",
+ "%d minutes", min), min);
+
+ secs = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d second",
+ "%d seconds", sec), sec);
+
+ if (hour > 0)
+ {
+ /* 5 hours 2 minutes 12 seconds */
+ string = g_strdup_printf (C_("time", "%s %s %s"), hours, mins, secs);
+ } else if (min > 0) {
+ /* 2 minutes 12 seconds */
+ string = g_strdup_printf (C_("time", "%s %s"), mins, secs);
+ } else if (sec > 0) {
+ /* 10 seconds */
+ string = g_strdup (secs);
+ } else {
+ /* 0 seconds */
+ string = g_strdup (_("0 seconds"));
+ }
+
+ g_free (hours);
+ g_free (mins);
+ g_free (secs);
+
+ return string;
+}
+
+static void
+update_general (TotemPropertiesView *props,
+ const GstTagList *list)
+{
+ struct {
+ const char *tag_name;
+ const char *title;
+ } items[] = {
+ { GST_TAG_TITLE, N_("Title") },
+ { GST_TAG_ARTIST, N_("Artist") },
+ { GST_TAG_ALBUM, N_("Album") },
+ };
+ guint i;
+ GDate *date;
+ GstDateTime *datetime;
+ gchar *comment;
+
+ for (i = 0; i < G_N_ELEMENTS(items); i++) {
+ char *string;
+
+ if (gst_tag_list_get_string_index (list, items[i].tag_name, 0, &string) != FALSE) {
+ append_item (props, gettext (items[i].title), string);
+ g_free (string);
+ }
+ }
+
+ /* Comment else use Description defined by:
+ * http://xiph.org/vorbis/doc/v-comment.html */
+ if (gst_tag_list_get_string (list, GST_TAG_COMMENT, &comment) ||
+ gst_tag_list_get_string (list, GST_TAG_DESCRIPTION, &comment)) {
+
+ append_item (props, _("Comment"), comment);
+ g_free (comment);
+ }
+
+ /* Date */
+ if (gst_tag_list_get_date (list, GST_TAG_DATE, &date)) {
+ char *string;
+
+ string = g_strdup_printf ("%d", g_date_get_year (date));
+ g_date_free (date);
+ append_item (props, _("Year"), string);
+ g_free (string);
+ } else if (gst_tag_list_get_date_time (list, GST_TAG_DATE_TIME, &datetime)) {
+ char *string;
+
+ string = g_strdup_printf ("%d", gst_date_time_get_year (datetime));
+ gst_date_time_unref (datetime);
+ append_item (props, _("Year"), string);
+ g_free (string);
+ }
+}
+
+static void
+set_codec (TotemPropertiesView *props,
+ GstDiscovererStreamInfo *info,
+ const char *title)
+{
+ GstCaps *caps;
+ const char *nick;
+
+ nick = gst_discoverer_stream_info_get_stream_type_nick (info);
+ if (g_str_equal (nick, "audio") == FALSE &&
+ g_str_equal (nick, "video") == FALSE &&
+ g_str_equal (nick, "container") == FALSE)
+ return;
+
+ caps = gst_discoverer_stream_info_get_caps (info);
+ if (caps) {
+ if (gst_caps_is_fixed (caps)) {
+ char *string;
+
+ string = gst_pb_utils_get_codec_description (caps);
+ append_item (props, title, string);
+ g_free (string);
+ }
+ gst_caps_unref (caps);
+ }
+}
+
+static void
+set_bitrate (TotemPropertiesView *props,
+ guint bitrate,
+ const char *title)
+{
+ char *string;
+
+ if (!bitrate) {
+ return;
+ }
+ string = g_strdup_printf (_("%d kbps"), bitrate / 1000);
+ append_item (props, title, string);
+ g_free (string);
+}
+
+static void
+update_video (TotemPropertiesView *props,
+ GstDiscovererVideoInfo *info)
+{
+ guint width, height;
+ guint fps_n, fps_d;
+ float framerate = 0.0;
+ char *string;
+
+ width = gst_discoverer_video_info_get_width (info);
+ height = gst_discoverer_video_info_get_height (info);
+ string = g_strdup_printf (N_("%d × %d"), width, height);
+ append_item (props, _("Dimensions"), string);
+ g_free (string);
+
+ set_codec (props, (GstDiscovererStreamInfo *) info, _("Video Codec"));
+ set_bitrate (props, gst_discoverer_video_info_get_bitrate (info), _("Video Bit Rate"));
+
+ /* Round up/down to the nearest integer framerate */
+ fps_n = gst_discoverer_video_info_get_framerate_num (info);
+ fps_d = gst_discoverer_video_info_get_framerate_denom (info);
+ if (fps_d > 0.0) {
+ framerate = (float) fps_n / (float) fps_d;
+ }
+
+ if (framerate > 1.0) {
+ string = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE,
+ "%0.2f frame per second",
+ "%0.2f frames per second",
+ (int) (ceilf (framerate))),
+ framerate);
+ append_item (props, _("Frame Rate"), string);
+ g_free (string);
+ }
+}
+
+static void
+update_audio (TotemPropertiesView *props,
+ GstDiscovererAudioInfo *info)
+{
+ guint samplerate, channels;
+
+ set_codec (props, (GstDiscovererStreamInfo *) info, _("Audio Codec"));
+
+ set_bitrate (props, gst_discoverer_audio_info_get_bitrate (info), _("Audio Bit Rate"));
+
+ samplerate = gst_discoverer_audio_info_get_sample_rate (info);
+ if (samplerate) {
+ char *string;
+ string = g_strdup_printf (_("%d Hz"), samplerate);
+ append_item (props, _("Sample Rate"), string);
+ g_free (string);
+ }
+
+ channels = gst_discoverer_audio_info_get_channels (info);
+ if (channels) {
+ char *string;
+
+ if (channels > 2) {
+ string = g_strdup_printf ("%s %d.1", _("Surround"), channels - 1);
+ } else if (channels == 1) {
+ string = g_strdup (_("Mono"));
+ } else if (channels == 2) {
+ string = g_strdup (_("Stereo"));
+ } else {
+ string = g_strdup (""); //Should not happen
+ }
+ append_item (props, _("Channels"), string);
+ g_free (string);
+ }
+}
+
+static void
+discovered_cb (GstDiscoverer *discoverer,
+ GstDiscovererInfo *info,
+ GError *error,
+ TotemPropertiesView *props)
+{
+ GList *video_streams, *audio_streams;
+ const GstTagList *taglist;
+ gboolean has_audio, has_video;
+ const char *label;
+ GstClockTime duration;
+ g_autofree char *duration_string = NULL;
+ GstDiscovererStreamInfo *sinfo;
+
+ if (error) {
+ g_warning ("Couldn't get information about '%s': %s",
+ gst_discoverer_info_get_uri (info),
+ error->message);
+ append_item (props, _("Oops! Something went wrong."), error->message);
+ return;
+ }
+
+ video_streams = gst_discoverer_info_get_video_streams (info);
+ has_video = (video_streams != NULL);
+ audio_streams = gst_discoverer_info_get_audio_streams (info);
+ has_audio = (audio_streams != NULL);
+
+ if (has_audio == has_video)
+ label = _("Audio and Video Properties");
+ else if (has_audio)
+ label = _("Audio Properties");
+ else
+ label = _("Video Properties");
+
+ nautilus_properties_model_set_title (props->priv->model, label);
+
+ /* General */
+ duration = gst_discoverer_info_get_duration (info);
+ duration_string = time_to_string_text (duration / GST_SECOND * 1000);
+ append_item (props, _("Duration"), duration_string);
+
+ sinfo = gst_discoverer_info_get_stream_info (info);
+ if (sinfo) {
+ set_codec (props, sinfo, _("Container"));
+ gst_discoverer_stream_info_unref (sinfo);
+ }
+
+ taglist = gst_discoverer_info_get_tags (info);
+ update_general (props, taglist);
+
+ /* Video and Audio */
+ if (video_streams)
+ update_video (props, video_streams->data);
+ if (audio_streams)
+ update_audio (props, audio_streams->data);
+
+ gst_discoverer_stream_info_list_free (video_streams);
+ gst_discoverer_stream_info_list_free (audio_streams);
+}
+
+static void
+totem_properties_view_init (TotemPropertiesView *props)
+{
+ GError *err = NULL;
+
+ props->priv = g_new0 (TotemPropertiesViewPriv, 1);
+
+ props->priv->store = g_list_store_new (NAUTILUS_TYPE_PROPERTIES_ITEM);
+
+ props->priv->model = nautilus_properties_model_new (_("Audio/Video Properties"),
+ G_LIST_MODEL (props->priv->store));
+
+ props->priv->disco = gst_discoverer_new (GST_SECOND * 60, &err);
+ if (props->priv->disco == NULL) {
+ g_warning ("Could not create discoverer object: %s", err->message);
+ g_error_free (err);
+ return;
+ }
+ g_signal_connect (props->priv->disco, "discovered",
+ G_CALLBACK (discovered_cb), props);
+}
+
+static void
+totem_properties_view_finalize (GObject *object)
+{
+ TotemPropertiesView *props;
+
+ props = TOTEM_PROPERTIES_VIEW (object);
+
+ if (props->priv != NULL) {
+ if (props->priv->disco) {
+ g_signal_handlers_disconnect_by_func (props->priv->disco,
+ discovered_cb,
+ props);
+ gst_discoverer_stop (props->priv->disco);
+ g_clear_object (&props->priv->disco);
+ }
+ g_free (props->priv);
+ }
+ props->priv = NULL;
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+totem_properties_view_set_location (TotemPropertiesView *props,
+ const char *location)
+{
+ g_assert (TOTEM_IS_PROPERTIES_VIEW (props));
+
+ if (props->priv->disco)
+ gst_discoverer_stop (props->priv->disco);
+
+ if (location != NULL && props->priv->disco != NULL) {
+ gst_discoverer_start (props->priv->disco);
+
+ if (gst_discoverer_discover_uri_async (props->priv->disco, location) == FALSE) {
+ g_warning ("Couldn't add %s to list", location);
+ return;
+ }
+ }
+}
+
+NautilusPropertiesModel *
+totem_properties_view_new (const char *location)
+{
+ TotemPropertiesView *props;
+
+ props = g_object_new (TOTEM_TYPE_PROPERTIES_VIEW, NULL);
+
+ totem_properties_view_set_location (props, location);
+
+ g_object_weak_ref (G_OBJECT (props->priv->model), (GWeakNotify) g_object_unref, props);
+
+ return props->priv->model;
+}
diff --git a/extensions/audio-video-properties/totem-properties-view.h b/extensions/audio-video-properties/totem-properties-view.h
new file mode 100644
index 0000000..5990859
--- /dev/null
+++ b/extensions/audio-video-properties/totem-properties-view.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2003 Andrew Sobala <aes@gnome.org>
+ * Copyright (C) 2005 Bastien Nocera <hadess@hadess.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef TOTEM_PROPERTIES_VIEW_H
+#define TOTEM_PROPERTIES_VIEW_H
+
+#include <nautilus-extension.h>
+
+#define TOTEM_TYPE_PROPERTIES_VIEW (totem_properties_view_get_type ())
+#define TOTEM_PROPERTIES_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TOTEM_TYPE_PROPERTIES_VIEW, TotemPropertiesView))
+#define TOTEM_PROPERTIES_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TOTEM_TYPE_PROPERTIES_VIEW, TotemPropertiesViewClass))
+#define TOTEM_IS_PROPERTIES_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TOTEM_TYPE_PROPERTIES_VIEW))
+#define TOTEM_IS_PROPERTIES_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TOTEM_TYPE_PROPERTIES_VIEW))
+
+typedef struct TotemPropertiesViewPriv TotemPropertiesViewPriv;
+
+typedef struct {
+ GObject parent;
+ TotemPropertiesViewPriv *priv;
+} TotemPropertiesView;
+
+typedef struct {
+ GObjectClass parent;
+} TotemPropertiesViewClass;
+
+GType totem_properties_view_get_type (void);
+void totem_properties_view_register_type (GTypeModule *module);
+
+NautilusPropertiesModel *totem_properties_view_new (const char *location);
+
+#endif /* TOTEM_PROPERTIES_VIEW_H */