Ubuntu TV Media Scanner
A centralized index for removable media content.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Grilo MediaScanner plugin

Table of Contents

The grl-mediascanner Grilo plugin provides access to the mediascanner index via the Grilo API.

Application developers should generally use the Grilo API instead of using the mediascanner API directly.

Full Text Search

This Grilo plugin supports grl_source_search(), performing a case-insensitive search for substrings in all text fields that have enabled full text search (see the Properties Schema).

It also searches for substrings of similar meaning using Lucene's stemming alogrithms.

This example-grilo-search.c example shows how to do perform a full text search with Grilo:

/*
* This file is part of the Ubuntu TV Media Scanner
* Copyright (C) 2012-2013 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as
* published by the Free Software Foundation.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact: Jim Hodapp <jim.hodapp@canonical.com>
* Authored by: Murray Cumming <murrayc@openismus.com>
*/
#include <grilo.h>
#include <stdio.h>
#define EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID "grl-mediascanner"
GMainLoop* loop = NULL;
static void
browse_cb (GrlSource *source G_GNUC_UNUSED,
guint browse_id G_GNUC_UNUSED,
GrlMedia *media,
guint remaining,
gpointer user_data G_GNUC_UNUSED,
const GError *error)
{
/* First we check if the operation failed for some reason */
g_assert_no_error (error);
if (media) {
const gchar *title = grl_media_get_title (media);
if (GRL_IS_MEDIA_BOX (media)) {
guint childcount = grl_media_box_get_childcount (GRL_MEDIA_BOX (media));
printf ("Container: title='%s', child count=%d\n", title, childcount);
} else {
guint seconds = grl_media_get_duration (media);
const gchar *url = grl_media_get_url (media);
printf ("Media: title='%s', length(seconds)=%d\n", title, seconds);
printf (" URL=%s\n", url);
}
g_object_unref (media);
}
if (remaining <= 0) {
g_main_loop_quit (loop);
}
}
int main(int argc, char *argv[]) {
/*
* These defines are set by the build system.
* Uncomment this to use the installed grilo plugins,
* instead of the locally-built grilo plugins.
*/
g_setenv (GRL_PLUGIN_PATH_VAR, EXAMPLE_GRILO_PLUGIN_DIR, TRUE);
grl_init (&argc, &argv);
/*
* Load the Grilo plugin:
*/
GrlRegistry *registry = grl_registry_get_default();
GError *error = NULL;
gboolean plugin_loaded = grl_registry_load_plugin_by_id (
registry, EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID, &error);
g_assert (plugin_loaded);
g_assert_no_error (error);
/*
* Get the plugin:
*
GrlPlugin *plugin =
grl_registry_lookup_plugin (registry,
EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID);
g_assert (plugin);
*/
GrlSource *source =
grl_registry_lookup_source(registry, EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID);
g_assert (source);
/*
* List the content:
*/
g_assert (grl_source_supported_operations (source) & GRL_OP_SEARCH);
GrlCaps *caps = grl_source_get_caps (source, GRL_OP_SEARCH);
g_assert (caps);
GrlOperationOptions *options = grl_operation_options_new (caps);
grl_operation_options_set_count (options, 5);
grl_operation_options_set_flags (options, GRL_RESOLVE_IDLE_RELAY);
GList * keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
GRL_METADATA_KEY_DURATION,
GRL_METADATA_KEY_URL,
GRL_METADATA_KEY_CHILDCOUNT,
NULL);
grl_source_search (source,
"springsteen",
keys,
options,
browse_cb,
NULL);
/*
* Start the main loop so our callback can be called:
*/
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
/*
* Release objects:
*/
g_list_free (keys);
g_object_unref (caps);
g_object_unref (options);
return 0;
}

Query Syntax

When using this plugin with grl_source_query(), you may use the lucene query syntax, using the mediascanner Properties Schema.

This example-grilo-query.c example shows how to perform a query with Grilo:

/*
* This file is part of the Ubuntu TV Media Scanner
* Copyright (C) 2012-2013 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as
* published by the Free Software Foundation.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact: Jim Hodapp <jim.hodapp@canonical.com>
* Authored by: Murray Cumming <murrayc@openismus.com>
*/
#include <grilo.h>
#include <stdio.h>
#define EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID "grl-mediascanner"
GMainLoop* loop = NULL;
static void
browse_cb (GrlSource *source G_GNUC_UNUSED,
guint browse_id G_GNUC_UNUSED,
GrlMedia *media,
guint remaining,
gpointer user_data G_GNUC_UNUSED,
const GError *error)
{
/* First we check if the operation failed for some reason */
g_assert_no_error (error);
if (media) {
const gchar *title = grl_media_get_title (media);
if (GRL_IS_MEDIA_BOX (media)) {
guint childcount = grl_media_box_get_childcount (GRL_MEDIA_BOX (media));
printf ("Container: title='%s', child count=%d\n", title, childcount);
} else {
guint seconds = grl_media_get_duration (media);
const gchar *url = grl_media_get_url (media);
printf ("Media: title='%s', length(seconds)=%d\n", title, seconds);
printf (" URL=%s\n", url);
}
g_object_unref (media);
}
if (remaining <= 0) {
g_main_loop_quit (loop);
}
}
int main(int argc, char *argv[]) {
/*
* These defines are set by the build system.
* Uncomment this to use the installed grilo plugins,
* instead of the locally-built grilo plugins.
*/
g_setenv (GRL_PLUGIN_PATH_VAR, EXAMPLE_GRILO_PLUGIN_DIR, TRUE);
grl_init (&argc, &argv);
/*
* Load the Grilo plugin:
*/
GrlRegistry *registry = grl_registry_get_default();
GError *error = NULL;
gboolean plugin_loaded = grl_registry_load_plugin_by_id (
registry, EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID, &error);
g_assert (plugin_loaded);
g_assert_no_error (error);
/*
* Get the plugin:
*
GrlPlugin *plugin =
grl_registry_lookup_plugin (registry,
EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID);
g_assert (plugin);
*/
GrlSource *source =
grl_registry_lookup_source(registry, EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID);
g_assert (source);
/*
* List the content:
*/
g_assert (grl_source_supported_operations (source) & GRL_OP_QUERY);
GrlCaps *caps = grl_source_get_caps (source, GRL_OP_QUERY);
g_assert (caps);
GrlOperationOptions *options = grl_operation_options_new (caps);
grl_operation_options_set_count (options, 5);
grl_operation_options_set_flags (options, GRL_RESOLVE_IDLE_RELAY);
GList * keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
GRL_METADATA_KEY_DURATION,
GRL_METADATA_KEY_URL,
GRL_METADATA_KEY_CHILDCOUNT,
NULL);
/*
* The query string syntax is plugin-specific.
* TODO(M4): This uses the lucene query syntax: https://lucene.apache.org/core/3_6_0/queryparsersyntax.html
* TODO(M4): Link to our gtk-doc docs for our grilo plugin.
*/
grl_source_query (source,
"title:Soul*",
keys,
options,
browse_cb,
NULL);
/*
* Start the main loop so our callback can be called:
*/
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
/*
* Release objects:
*/
g_list_free (keys);
g_object_unref (caps);
g_object_unref (options);
return 0;
}

Range Filters

This Grilo plugin supports range filters with grl_operation_options_set_key_range_filter_value() on fields that have enabled range filters (see the Properties Schema).

This example-grilo-search-range-filter.c example shows how to use a range filter with Grilo:

/*
* This file is part of the Ubuntu TV Media Scanner
* Copyright (C) 2012-2013 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as
* published by the Free Software Foundation.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contact: Jim Hodapp <jim.hodapp@canonical.com>
* Authored by: Murray Cumming <murrayc@openismus.com>
*/
#include <grilo.h>
#include <stdio.h>
#define EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID "grl-mediascanner"
GMainLoop* loop = NULL;
static void
browse_cb (GrlSource *source G_GNUC_UNUSED,
guint browse_id G_GNUC_UNUSED,
GrlMedia *media,
guint remaining,
gpointer user_data G_GNUC_UNUSED,
const GError *error)
{
/* First we check if the operation failed for some reason */
g_assert_no_error (error);
if (media) {
const gchar *title = grl_media_get_title (media);
if (GRL_IS_MEDIA_BOX (media)) {
guint childcount = grl_media_box_get_childcount (GRL_MEDIA_BOX (media));
printf ("Container: title='%s', child count=%d\n", title, childcount);
} else {
guint seconds = grl_media_get_duration (media);
const gchar *url = grl_media_get_url (media);
printf ("Media: title='%s', length(seconds)=%d\n", title, seconds);
printf (" URL=%s\n", url);
}
g_object_unref (media);
}
if (remaining <= 0) {
g_main_loop_quit (loop);
}
}
int main(int argc, char *argv[]) {
/*
* These defines are set by the build system.
* Uncomment this to use the installed grilo plugins,
* instead of the locally-built grilo plugins.
*/
g_setenv (GRL_PLUGIN_PATH_VAR, EXAMPLE_GRILO_PLUGIN_DIR, TRUE);
grl_init (&argc, &argv);
/*
* Load the Grilo plugin:
*/
GrlRegistry *registry = grl_registry_get_default();
GError *error = NULL;
gboolean plugin_loaded = grl_registry_load_plugin_by_id (
registry, EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID, &error);
g_assert (plugin_loaded);
g_assert_no_error (error);
/*
* Get the plugin:
*
GrlPlugin *plugin =
grl_registry_lookup_plugin (registry,
EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID);
g_assert (plugin);
*/
GrlSource *source =
grl_registry_lookup_source(registry, EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID);
g_assert (source);
/*
* List the content:
*/
g_assert (grl_source_supported_operations (source) & GRL_OP_SEARCH);
GrlCaps *caps = grl_source_get_caps (source, GRL_OP_SEARCH);
g_assert (caps);
GrlOperationOptions *options = grl_operation_options_new (caps);
grl_operation_options_set_count (options, 5);
grl_operation_options_set_flags (options, GRL_RESOLVE_IDLE_RELAY);
/*
* Return only the items that are within this range:
*/
GValue min_duration = G_VALUE_INIT;
g_value_init(&min_duration, G_TYPE_DOUBLE);
g_value_set_double(&min_duration, 0);
GValue max_duration = G_VALUE_INIT;
g_value_init(&max_duration, G_TYPE_DOUBLE);
g_value_set_double(&max_duration, 400); /* (seconds) */
grl_operation_options_set_key_range_filter_value (options,
grl_registry_lookup_metadata_key(registry, "duration"),
&min_duration,
&max_duration);
GList * keys = grl_metadata_key_list_new (GRL_METADATA_KEY_TITLE,
GRL_METADATA_KEY_DURATION,
GRL_METADATA_KEY_URL,
GRL_METADATA_KEY_CHILDCOUNT,
NULL);
grl_source_search (source,
"legend",
keys,
options,
browse_cb,
NULL);
/*
* Start the main loop so our callback can be called:
*/
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
/*
* Release objects:
*/
g_list_free (keys);
g_object_unref (caps);
g_object_unref (options);
return 0;
}