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:
#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,
guint remaining,
gpointer user_data G_GNUC_UNUSED,
{
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[]) {
g_setenv (GRL_PLUGIN_PATH_VAR, EXAMPLE_GRILO_PLUGIN_DIR, TRUE);
grl_init (&argc, &argv);
GrlRegistry *registry = grl_registry_get_default();
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);
GrlSource *source =
grl_registry_lookup_source(registry, EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID);
g_assert (source);
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);
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
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:
#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,
guint remaining,
gpointer user_data G_GNUC_UNUSED,
{
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[]) {
g_setenv (GRL_PLUGIN_PATH_VAR, EXAMPLE_GRILO_PLUGIN_DIR, TRUE);
grl_init (&argc, &argv);
GrlRegistry *registry = grl_registry_get_default();
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);
GrlSource *source =
grl_registry_lookup_source(registry, EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID);
g_assert (source);
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);
grl_source_query (source,
"title:Soul*",
keys,
options,
browse_cb,
NULL);
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
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:
#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,
guint remaining,
gpointer user_data G_GNUC_UNUSED,
{
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[]) {
g_setenv (GRL_PLUGIN_PATH_VAR, EXAMPLE_GRILO_PLUGIN_DIR, TRUE);
grl_init (&argc, &argv);
GrlRegistry *registry = grl_registry_get_default();
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);
GrlSource *source =
grl_registry_lookup_source(registry, EXAMPLE_GRL_MEDIA_SCANNER_PLUGIN_ID);
g_assert (source);
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);
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);
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);
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
g_list_free (keys);
g_object_unref (caps);
g_object_unref (options);
return 0;
}