implement metadata for mpris so evene thumbs work for non-thumbed files
this allows us to port to artfiles always too... this way music-control displays the albumart. music-control is a bit broken in that it doesnt keep aspect ratio etc. of these. need to fix that over there.... but... it's coming together.
This commit is contained in:
parent
34ab03ac29
commit
8d07759869
144
src/bin/mpris.c
144
src/bin/mpris.c
|
@ -45,7 +45,6 @@ https://specifications.freedesktop.org/mpris-spec/latest/Player_Interface.html
|
|||
*
|
||||
* Not implemented:
|
||||
* Tracklist objects
|
||||
* Metadata
|
||||
* SetPosition (requires Tracklist objects)
|
||||
*
|
||||
* In rage generally and here:
|
||||
|
@ -677,14 +676,140 @@ SETTER(shuffle)
|
|||
return eldbus_message_method_return_new(msg);
|
||||
}
|
||||
|
||||
/*
|
||||
GETTER(metadata)
|
||||
{
|
||||
// XXX: return metadata
|
||||
eldbus_message_iter_arguments_append(iter, "a{sv}", NULL);
|
||||
Inf *inf = evas_object_data_get(mainwin, "inf");
|
||||
Eldbus_Message_Iter *array = NULL, *entry = NULL, *var, *var2;
|
||||
uint64_t len = 0;
|
||||
char *buf = NULL;
|
||||
const char *s;
|
||||
|
||||
// XXX: TODO:
|
||||
// mpris:trackid
|
||||
|
||||
eldbus_message_iter_arguments_append(iter, "a{sv}", &array);
|
||||
|
||||
s = video_file_get(inf->vid);
|
||||
if (s)
|
||||
{
|
||||
if (s[0] == '/')
|
||||
{
|
||||
buf = alloca(strlen(s) + sizeof("file://") + 1);
|
||||
sprintf(buf, "file://%s", s);
|
||||
}
|
||||
else if (strstr(s, "://"))
|
||||
{
|
||||
buf = alloca(strlen(s) + 1);
|
||||
strcpy(buf, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
char cwd[PATH_MAX];
|
||||
|
||||
if (getcwd(cwd, sizeof(cwd) - 1))
|
||||
{
|
||||
cwd[sizeof(cwd) - 1] = 0;
|
||||
buf = alloca(strlen(cwd) + 1 + strlen(s) + sizeof("file://") + 1);
|
||||
sprintf(buf, "file://%s/%s", cwd, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buf)
|
||||
{
|
||||
eldbus_message_iter_arguments_append(array, "{sv}", &entry);
|
||||
eldbus_message_iter_basic_append(entry, 's', "xesam:url");
|
||||
var = eldbus_message_iter_container_new(entry, 'v', "s");
|
||||
eldbus_message_iter_basic_append(var, 's', buf);
|
||||
eldbus_message_iter_container_close(entry, var);
|
||||
eldbus_message_iter_container_close(array, entry);
|
||||
}
|
||||
|
||||
s = video_artfile_get(inf->vid);
|
||||
if (s)
|
||||
{
|
||||
buf = alloca(strlen(s) + sizeof("file://") + 1);
|
||||
sprintf(buf, "file://%s", s);
|
||||
eldbus_message_iter_arguments_append(array, "{sv}", &entry);
|
||||
eldbus_message_iter_basic_append(entry, 's', "mpris:artUrl");
|
||||
var = eldbus_message_iter_container_new(entry, 'v', "s");
|
||||
eldbus_message_iter_basic_append(var, 's', buf);
|
||||
eldbus_message_iter_container_close(entry, var);
|
||||
eldbus_message_iter_container_close(array, entry);
|
||||
}
|
||||
|
||||
s = video_title_get(inf->vid);
|
||||
if (!s) s = video_meta_title_get(inf->vid);
|
||||
if (s)
|
||||
{
|
||||
eldbus_message_iter_arguments_append(array, "{sv}", &entry);
|
||||
eldbus_message_iter_basic_append(entry, 's', "xesam:title");
|
||||
var = eldbus_message_iter_container_new(entry, 'v', "s");
|
||||
eldbus_message_iter_basic_append(var, 's', buf);
|
||||
eldbus_message_iter_container_close(entry, var);
|
||||
eldbus_message_iter_container_close(array, entry);
|
||||
}
|
||||
|
||||
s = video_meta_album_get(inf->vid);
|
||||
if (s)
|
||||
{
|
||||
eldbus_message_iter_arguments_append(array, "{sv}", &entry);
|
||||
eldbus_message_iter_basic_append(entry, 's', "xesam:album");
|
||||
var = eldbus_message_iter_container_new(entry, 'v', "s");
|
||||
eldbus_message_iter_basic_append(var, 's', buf);
|
||||
eldbus_message_iter_container_close(entry, var);
|
||||
eldbus_message_iter_container_close(array, entry);
|
||||
}
|
||||
|
||||
s = video_meta_artist_get(inf->vid);
|
||||
if (s)
|
||||
{
|
||||
eldbus_message_iter_arguments_append(array, "{sv}", &entry);
|
||||
eldbus_message_iter_basic_append(entry, 's', "xesam:artist");
|
||||
var = eldbus_message_iter_container_new(entry, 'v', "as");
|
||||
eldbus_message_iter_arguments_append(var, "as", &var2);
|
||||
eldbus_message_iter_basic_append(var2, 's', s);
|
||||
eldbus_message_iter_container_close(var, var2);
|
||||
eldbus_message_iter_container_close(entry, var);
|
||||
eldbus_message_iter_container_close(array, entry);
|
||||
}
|
||||
|
||||
s = video_meta_comment_get(inf->vid);
|
||||
if (s)
|
||||
{
|
||||
eldbus_message_iter_arguments_append(array, "{sv}", &entry);
|
||||
eldbus_message_iter_basic_append(entry, 's', "xesam:comment");
|
||||
var = eldbus_message_iter_container_new(entry, 'v', "as");
|
||||
eldbus_message_iter_arguments_append(var, "as", &var2);
|
||||
eldbus_message_iter_basic_append(var2, 's', s);
|
||||
eldbus_message_iter_container_close(var, var2);
|
||||
eldbus_message_iter_container_close(entry, var);
|
||||
eldbus_message_iter_container_close(array, entry);
|
||||
}
|
||||
|
||||
s = video_meta_genre_get(inf->vid);
|
||||
if (s)
|
||||
{
|
||||
eldbus_message_iter_arguments_append(array, "{sv}", &entry);
|
||||
eldbus_message_iter_basic_append(entry, 's', "xesam:genre");
|
||||
var = eldbus_message_iter_container_new(entry, 'v', "as");
|
||||
eldbus_message_iter_arguments_append(var, "as", &var2);
|
||||
eldbus_message_iter_basic_append(var2, 's', s);
|
||||
eldbus_message_iter_container_close(var, var2);
|
||||
eldbus_message_iter_container_close(entry, var);
|
||||
eldbus_message_iter_container_close(array, entry);
|
||||
}
|
||||
|
||||
len = video_length_get(inf->vid) * 1000000.0;
|
||||
eldbus_message_iter_arguments_append(array, "{sv}", &entry);
|
||||
eldbus_message_iter_basic_append(entry, 's', "mpris:length");
|
||||
var = eldbus_message_iter_container_new(entry, 'v', "x");
|
||||
eldbus_message_iter_basic_append(var, 'x', len);
|
||||
eldbus_message_iter_container_close(entry, var);
|
||||
eldbus_message_iter_container_close(array, entry);
|
||||
|
||||
eldbus_message_iter_container_close(iter, array);
|
||||
return EINA_TRUE;
|
||||
}
|
||||
*/
|
||||
|
||||
GETTER(volume)
|
||||
{
|
||||
|
@ -782,7 +907,7 @@ static const Eldbus_Property properties_player[] =
|
|||
PROP_RW("LoopStatus", "s", loop_status),
|
||||
PROP_RW("Rate", "d", rate),
|
||||
PROP_RW("Shuffle", "b", shuffle),
|
||||
// PROP_RO("Metadata", "a{sv}", metadata),
|
||||
PROP_RO("Metadata", "a{sv}", metadata),
|
||||
PROP_RW("Volume", "d", volume),
|
||||
PROP_RO("Position", "x", position),
|
||||
PROP_RO("MinimumRate", "d", minimum_rate),
|
||||
|
@ -949,6 +1074,13 @@ mpris_position_change(double pos)
|
|||
eldbus_service_property_changed(iface_player, "Position");
|
||||
}
|
||||
|
||||
void
|
||||
mpris_metadata_change(void)
|
||||
{
|
||||
if (!iface_player) return;
|
||||
eldbus_service_property_changed(iface_player, "Metadata");
|
||||
}
|
||||
|
||||
void
|
||||
mpris_init(Evas_Object *win)
|
||||
{
|
||||
|
|
|
@ -3,5 +3,6 @@ void mpris_volume_change(void);
|
|||
void mpris_loop_status_change(void);
|
||||
void mpris_playback_status_change(void);
|
||||
void mpris_position_change(double pos);
|
||||
void mpris_metadata_change(void);
|
||||
void mpris_init(Evas_Object *win);
|
||||
void mpris_shutdown(void);
|
||||
|
|
|
@ -9,6 +9,7 @@ static Evas_Object *vidimage = NULL;
|
|||
static Eet_File *ef = NULL;
|
||||
static Ecore_Timer *vid_timeout = NULL;
|
||||
static Eina_Bool is_audio = EINA_FALSE;
|
||||
static Eina_Bool is_video = EINA_FALSE;
|
||||
static Eina_Bool is_movie = EINA_FALSE;
|
||||
static int iw, ih, incr = 0;
|
||||
static Eina_Bool poster = 0;
|
||||
|
@ -78,6 +79,7 @@ _cb_loaded(void *data, Evas_Object *obj, void *info EINA_UNUSED)
|
|||
(len >= (60.0 * 60.0)) &&
|
||||
(len <= (5.0 * 60.0 * 60.0)))
|
||||
is_movie = EINA_TRUE;
|
||||
if (poster == 2) is_video = EINA_TRUE;
|
||||
}
|
||||
|
||||
if (is_movie)
|
||||
|
@ -86,6 +88,12 @@ _cb_loaded(void *data, Evas_Object *obj, void *info EINA_UNUSED)
|
|||
_cb_fetched, (void *)file);
|
||||
return;
|
||||
}
|
||||
else if (is_video)
|
||||
{
|
||||
albumart_find(file, NULL, NULL, title, NULL,
|
||||
_cb_fetched, (void *)file);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf_base[PATH_MAX];
|
||||
|
|
132
src/bin/video.c
132
src/bin/video.c
|
@ -3,6 +3,7 @@
|
|||
#include "rage_config.h"
|
||||
#include "config.h"
|
||||
#include "albumart.h"
|
||||
#include "mpris.h"
|
||||
|
||||
typedef struct _Video Video;
|
||||
|
||||
|
@ -13,6 +14,10 @@ struct _Video
|
|||
Ecore_Timer *smooth_timer;
|
||||
Ecore_Job *restart_job;
|
||||
const char *file;
|
||||
const char *realfile;
|
||||
const char *artfile;
|
||||
Ecore_Exe *exe;
|
||||
Ecore_Event_Handler *exe_handler;
|
||||
int w, h;
|
||||
int iw, ih, piw, pih, tw, th;
|
||||
int resizes;
|
||||
|
@ -33,6 +38,27 @@ static Evas_Smart_Class _parent_sc = EVAS_SMART_CLASS_INIT_NULL;
|
|||
|
||||
static void _ob_resize(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h);
|
||||
|
||||
static Eina_Bool
|
||||
_cb_thumb_exe(void *data, int type EINA_UNUSED, void *event)
|
||||
{
|
||||
Ecore_Exe_Event_Del *ev = event;
|
||||
Video *sd = evas_object_smart_data_get(data);
|
||||
char *path;
|
||||
|
||||
if (!sd) return EINA_TRUE;
|
||||
if (ev->exe == sd->exe)
|
||||
{
|
||||
sd->exe = NULL;
|
||||
if (ev->exit_code == 0)
|
||||
{
|
||||
path = albumart_file_get(sd->realfile);
|
||||
eina_stringshare_replace(&(sd->artfile), path);
|
||||
mpris_metadata_change();
|
||||
}
|
||||
}
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_art_check(Evas_Object *obj)
|
||||
{
|
||||
|
@ -50,28 +76,9 @@ _art_check(Evas_Object *obj)
|
|||
}
|
||||
if (sd->doart)
|
||||
{
|
||||
char *thumb = NULL, *realfile = NULL;
|
||||
char *thumb = NULL;
|
||||
|
||||
evas_object_show(sd->o_img);
|
||||
if (!strncasecmp(sd->file, "file:/", 6))
|
||||
{
|
||||
Efreet_Uri *uri = efreet_uri_decode(sd->file);
|
||||
if (uri)
|
||||
{
|
||||
realfile = ecore_file_realpath(uri->path);
|
||||
efreet_uri_free(uri);
|
||||
}
|
||||
}
|
||||
else if ((!strncasecmp(sd->file, "http:/", 6)) ||
|
||||
(!strncasecmp(sd->file, "https:/", 7)))
|
||||
realfile = strdup(sd->file);
|
||||
else
|
||||
realfile = ecore_file_realpath(sd->file);
|
||||
if (realfile)
|
||||
{
|
||||
thumb = albumart_file_get(realfile);
|
||||
free(realfile);
|
||||
}
|
||||
thumb = albumart_file_get(sd->realfile);
|
||||
if (thumb)
|
||||
{
|
||||
Evas_Coord ox, oy, ow, oh;
|
||||
|
@ -83,6 +90,8 @@ _art_check(Evas_Object *obj)
|
|||
evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
|
||||
_ob_resize(obj, ox, oy, ow, oh);
|
||||
}
|
||||
eina_stringshare_replace(&(sd->artfile), thumb);
|
||||
mpris_metadata_change();
|
||||
free(thumb);
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +99,39 @@ _art_check(Evas_Object *obj)
|
|||
{
|
||||
evas_object_hide(sd->o_img);
|
||||
}
|
||||
if (!sd->artfile)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
const char *libdir;
|
||||
char *s;
|
||||
|
||||
ecore_exe_run_priority_set(10);
|
||||
s = ecore_file_escape_name(sd->realfile);
|
||||
if (s)
|
||||
{
|
||||
libdir = elm_app_lib_dir_get();
|
||||
if (libdir)
|
||||
{
|
||||
if (!sd->exe_handler)
|
||||
sd->exe_handler = ecore_event_handler_add
|
||||
(ECORE_EXE_EVENT_DEL, _cb_thumb_exe, obj);
|
||||
snprintf(buf, sizeof(buf),
|
||||
"%s/rage/utils/rage_thumb %s 10000 %i",
|
||||
libdir, s, 2);
|
||||
if (sd->exe)
|
||||
{
|
||||
ecore_exe_kill(sd->exe);
|
||||
ecore_exe_free(sd->exe);
|
||||
sd->exe = NULL;
|
||||
}
|
||||
sd->exe = ecore_exe_pipe_run(buf,
|
||||
ECORE_EXE_TERM_WITH_PARENT |
|
||||
ECORE_EXE_NOT_LEADER,
|
||||
obj);
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -153,11 +195,13 @@ _cb_vid_stop(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|||
{
|
||||
sd->restart_job = ecore_job_add(_cb_restart, data);
|
||||
evas_object_smart_callback_call(data, "loop", NULL);
|
||||
mpris_metadata_change();
|
||||
}
|
||||
else
|
||||
{
|
||||
sd->restart_job = NULL;
|
||||
evas_object_smart_callback_call(data, "stop", NULL);
|
||||
mpris_metadata_change();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,6 +228,7 @@ _cb_open_done(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|||
if (!sd) return;
|
||||
evas_object_smart_callback_call(data, "opened", NULL);
|
||||
_art_check(data);
|
||||
mpris_metadata_change();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -200,6 +245,7 @@ _cb_length_change(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNU
|
|||
Video *sd = evas_object_smart_data_get(data);
|
||||
if (!sd) return;
|
||||
evas_object_smart_callback_call(data, "length", NULL);
|
||||
mpris_metadata_change();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -208,6 +254,7 @@ _cb_title_change(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUS
|
|||
Video *sd = evas_object_smart_data_get(data);
|
||||
if (!sd) return;
|
||||
evas_object_smart_callback_call(data, "title", NULL);
|
||||
mpris_metadata_change();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -216,6 +263,7 @@ _cb_audio_change(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUS
|
|||
Video *sd = evas_object_smart_data_get(data);
|
||||
if (!sd) return;
|
||||
evas_object_smart_callback_call(data, "audio", NULL);
|
||||
mpris_metadata_change();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -224,6 +272,7 @@ _cb_channels_change(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_U
|
|||
Video *sd = evas_object_smart_data_get(data);
|
||||
if (!sd) return;
|
||||
evas_object_smart_callback_call(data, "channels", NULL);
|
||||
mpris_metadata_change();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -232,6 +281,7 @@ _cb_play_start(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED
|
|||
Video *sd = evas_object_smart_data_get(data);
|
||||
if (!sd) return;
|
||||
evas_object_smart_callback_call(data, "play_start", NULL);
|
||||
mpris_metadata_change();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -240,6 +290,7 @@ _cb_play_finish(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSE
|
|||
Video *sd = evas_object_smart_data_get(data);
|
||||
if (!sd) return;
|
||||
evas_object_smart_callback_call(data, "play_finish", NULL);
|
||||
mpris_metadata_change();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -355,6 +406,8 @@ _smart_del(Evas_Object *obj)
|
|||
Video *sd = evas_object_smart_data_get(obj);
|
||||
if (!sd) return;
|
||||
if (sd->file) eina_stringshare_del(sd->file);
|
||||
if (sd->realfile) eina_stringshare_del(sd->realfile);
|
||||
if (sd->artfile) eina_stringshare_del(sd->artfile);
|
||||
if (sd->clip) evas_object_del(sd->clip);
|
||||
if (sd->o_vid) evas_object_del(sd->o_vid);
|
||||
if (sd->o_img) evas_object_del(sd->o_img);
|
||||
|
@ -362,6 +415,17 @@ _smart_del(Evas_Object *obj)
|
|||
if (sd->smooth_timer) sd->smooth_timer = ecore_timer_del(sd->smooth_timer);
|
||||
if (sd->restart_job) ecore_job_del(sd->restart_job);
|
||||
|
||||
if (sd->exe)
|
||||
{
|
||||
ecore_exe_kill(sd->exe);
|
||||
ecore_exe_free(sd->exe);
|
||||
sd->exe = NULL;
|
||||
}
|
||||
if (sd->exe_handler)
|
||||
{
|
||||
ecore_event_handler_del(sd->exe_handler);
|
||||
sd->exe_handler = NULL;
|
||||
}
|
||||
_parent_sc.del(obj);
|
||||
|
||||
emotion_shutdown();
|
||||
|
@ -563,12 +627,30 @@ video_add(Evas_Object *parent)
|
|||
void
|
||||
video_file_set(Evas_Object *obj, const char *file)
|
||||
{
|
||||
char *realfile = NULL;
|
||||
Video *sd = evas_object_smart_data_get(obj);
|
||||
if (!sd) return;
|
||||
evas_object_hide(sd->o_img);
|
||||
evas_object_hide(sd->o_vid);
|
||||
evas_object_hide(sd->clip);
|
||||
eina_stringshare_replace(&(sd->file), file);
|
||||
if (!strncasecmp(sd->file, "file:/", 6))
|
||||
{
|
||||
Efreet_Uri *uri = efreet_uri_decode(sd->file);
|
||||
if (uri)
|
||||
{
|
||||
realfile = ecore_file_realpath(uri->path);
|
||||
efreet_uri_free(uri);
|
||||
}
|
||||
}
|
||||
else if ((!strncasecmp(sd->file, "http:/", 6)) ||
|
||||
(!strncasecmp(sd->file, "https:/", 7)))
|
||||
realfile = strdup(sd->file);
|
||||
else
|
||||
realfile = ecore_file_realpath(sd->file);
|
||||
eina_stringshare_replace(&(sd->realfile), realfile);
|
||||
free(realfile);
|
||||
eina_stringshare_replace(&(sd->artfile), NULL);
|
||||
emotion_object_file_set(sd->o_vid, sd->file);
|
||||
video_position_set(obj, 0.0);
|
||||
if ((sd->file) && (sd->doart))
|
||||
|
@ -1082,6 +1164,14 @@ video_file_autosub_set(Evas_Object *obj, const char *file, const char *sub)
|
|||
video_file_set(obj, file);
|
||||
}
|
||||
|
||||
const char *
|
||||
video_artfile_get(Evas_Object *obj)
|
||||
{
|
||||
Video *sd = evas_object_smart_data_get(obj);
|
||||
if (!sd) return NULL;
|
||||
return sd->artfile;
|
||||
}
|
||||
|
||||
// emotion_object_seekable_get
|
||||
// emotion_object_play_speed_set
|
||||
// emotion_object_play_speed_get
|
||||
|
|
|
@ -57,4 +57,5 @@ const char *video_meta_genre_get(Evas_Object *obj);
|
|||
const char *video_meta_comment_get(Evas_Object *obj);
|
||||
void video_file_autosub_set(Evas_Object *obj, const char *file, const char *sub);
|
||||
Evas_Object *video_meta_artwork_get(Evas_Object *obj, const char *path, int type);
|
||||
const char *video_artfile_get(Evas_Object *obj);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue