raster pushed a commit to branch master.

http://git.enlightenment.org/apps/rage.git/commit/?id=8d0775986922ec256b304dc937fc74434e22d27b

commit 8d0775986922ec256b304dc937fc74434e22d27b
Author: Carsten Haitzler (Rasterman) <[email protected]>
Date:   Tue Nov 28 14:32:59 2017 +0900

    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.
---
 src/bin/mpris.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 src/bin/mpris.h |   1 +
 src/bin/thumb.c |   8 ++++
 src/bin/video.c | 132 ++++++++++++++++++++++++++++++++++++++++++---------
 src/bin/video.h |   5 +-
 5 files changed, 261 insertions(+), 29 deletions(-)

diff --git a/src/bin/mpris.c b/src/bin/mpris.c
index 2820c12..ab9c0ec 100644
--- a/src/bin/mpris.c
+++ b/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),
@@ -950,6 +1075,13 @@ mpris_position_change(double pos)
 }
 
 void
+mpris_metadata_change(void)
+{
+   if (!iface_player) return;
+   eldbus_service_property_changed(iface_player, "Metadata");
+}
+
+void
 mpris_init(Evas_Object *win)
 {
    elm_need_eldbus();
diff --git a/src/bin/mpris.h b/src/bin/mpris.h
index 481e521..045800c 100644
--- a/src/bin/mpris.h
+++ b/src/bin/mpris.h
@@ -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);
diff --git a/src/bin/thumb.c b/src/bin/thumb.c
index 12b5c83..288051b 100644
--- a/src/bin/thumb.c
+++ b/src/bin/thumb.c
@@ -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];
diff --git a/src/bin/video.c b/src/bin/video.c
index 1b31a76..3efc0ae 100644
--- a/src/bin/video.c
+++ b/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
diff --git a/src/bin/video.h b/src/bin/video.h
index 5562882..7c635c4 100644
--- a/src/bin/video.h
+++ b/src/bin/video.h
@@ -26,7 +26,7 @@ void video_eject(Evas_Object *obj);
 int video_chapter_count(Evas_Object *obj);
 void video_chapter_set(Evas_Object *obj, int chapter);
 int video_chapter_get(Evas_Object *obj);
-const char * video_chapter_name_get(Evas_Object *obj, int chapter);
+const char *video_chapter_name_get(Evas_Object *obj, int chapter);
 void video_volume_set(Evas_Object *obj, double vol);
 double video_volume_get(Evas_Object *obj);
 Eina_Bool video_has_video_get(Evas_Object *obj);
@@ -56,5 +56,6 @@ const char *video_meta_year_get(Evas_Object *obj);
 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);
+Evas_Object *video_meta_artwork_get(Evas_Object *obj, const char *path, int 
type);
+const char *video_artfile_get(Evas_Object *obj);
 #endif

-- 


Reply via email to