Kodi Community Forum

Full Version: Playlist.add UPNP file resource, missing metadata
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
first of all I want to congratulate with the XBMC team that is doing an AMAZING work!
I'm planning to develop a new android app that instead of being a remote (since we already have an EXCELLENT one thanks to YATSE developer(s) Nod Nod Nod ) wants to be a smart way to share music with friends.
The app it's in a very early stage and I'm still exploring the JSONRPC api but I think I've encountered a bug.

Let me explain.
Suppose we have 2 upnp resources:
1 - An album, that XMBC treat as a folder (DIR: "upnp://55370cfc-82ed-4290-a37f-3927585a4ada/43868/")
2 - A song, that XBMC treat as a file (FILE: "upnp://55370cfc-82ed-4290-a37f-3927585a4ada/43914")

So I have this little function that allow me to make XBMC calls from chromium with injected jquery (I'll post it here just to help reproducing the problem)

Code:
function xbmc(data) {
$.ajax({
  data: data,
  contentType: "application/json",
  jsonp: 'jsonp_callback',
  url: "http://localhost:8081/jsonrpc",
  type: 'post', //make this a post instead of a get
  success: function (data) {
      window.lastRes = data;
      console.log( data );
  },

  error:function( result ){
     console.log( result );
     console.log('error!!!');
  }
})
};

Now the DIR calls:
Code:
// will correctly return an object with the songs inside DIR
xbmc( '{"jsonrpc":"2.0", "method":"Files.GetDirectory", "params":[DIR], "id":"1"}')

// will correctly add all songs in that album to the playlist (with full metadata!)
xbmc( '{"jsonrpc":"2.0", "method":"Playlist.Add", "params":[0,{"directory":"DIR"}], "id":"1"}');

Things seems instead not to work with songs:
Code:
// will add the song but no metadata will be read from the file
// (the label will be empty "" or the name of the upnp device in source, no cover, no album, no metadata)
xbmc( '{"jsonrpc":"2.0", "method":"Playlist.Add", "params":[0,{"file":FILE}], "id":"1"}');

// will return an error "Invalid params."
xbmc( '{"jsonrpc":"2.0", "method":"Files.GetFileDetails", "params":[FILE], "id":"1"}')

I found that YATSE behave the same way so I think it _may_ be a bug in the current JSONRPC implementation (go to Files/Playlist -> Audio Files -> YOUR UPNP SOURCE and try adding an album and than a single file).
I also found an old pull somehow related to this problem but I'm no C++ expert so before digging more into xbmc code I thought it may be a good idea to ask here.

Can anybody confirm the problem? Is it a bug or am I doing something wrong?

Thanks!

P.S. : I'm using JSON-RPC API v6
Depending on how you look at it, it's either a bug or a missing feature. Currently JSON-RPC only really knows how to handle files that are either in the video or in the music library.
Talking about missing features Smile

Since Frodo is near out, how do you want to organize feature requests and all changes asking for next version ?

It would be cool to have a way to centralize everything to not make multiple time the same request and have a quick view of what have been accepted / rejected and easy way to discuss :p

Making a thread / request don't seems optimum and having just one thread will perhaps gives you too much work to update the first post for easier following.

Perhaps use a temporary Wiki page to follow requests / status and the discussion page to discuss / argue about the features ?
AFAIK an update of our trac is in order. Maybe we'll get the Feature Request functionality back. I really liked keeping trac of all the JSON-RPC API related bugs and feature requests on trac. In the mean time you can also create issues on my xbmc fork on github (there are already a few there) but IMO users shouldn't have to go to a devs personal repo to do feature requests and bug reports for xbmc.
The main problem about trac will be for the start where I'm pretty sure you'll refuse some FR that will then be lost and hard to find so same and same FR will be made Sad

Github is better for searching globally on open / closed issues by default.
(2012-12-11, 23:48)Montellese Wrote: [ -> ]Depending on how you look at it, it's either a bug or a missing feature. Currently JSON-RPC only really knows how to handle files that are either in the video or in the music library.

Thanks for your quick reply.
I see what you mean when you say "Currently JSON-RPC only really knows how to handle files that are either in the video or in the music library. " so upnp is in some sort of gray zone (it can be seen as an external library or as an abstracted file system).
What it's not yet clear to me is if the behaviour of UPNP/dlna device as a directory is something unexpected or it should actually behave like this.
I belive that seeing UPNP/dlna device (or library info like artist/album/etc.) as a directory and a resource (video/song) as a file is not entirely correct but is probably the fastest way to have both things working in a small time (DIR implemtation is ok, can we force xbmc to read FILE metadata as if it were "music" when added to Audio playlist?).
(2012-12-12, 09:51)Tolriq Wrote: [ -> ]The main problem about trac will be for the start where I'm pretty sure you'll refuse some FR that will then be lost and hard to find so same and same FR will be made Sad

Github is better for searching globally on open / closed issues by default.

FR are allowed to create on trac if you got an ok from a dev.
We want to prevent to much FR showing up on trac that will never see the daylight.

Github might be better but it spams everyone like crazy with e-mails and imo you will loose overview on the open PR
Ok what is the proposed plan for the first big wave of FR and cleanup that will come with it ?
Just a quick follow up to go back IT.
I was able to write an ugly hack that should provide a workaround (probably leaking memory, creating black holes and destroying humanity).
It seems that CDirectory::GetDirectory(dirPath, CFileItemList, "") behave correctly and populate the list with CFileItem(s) that have all needed metadata.
So:
1 - I have modified CFileItemHandler::FillFileItemList so that it now checks if the member "file" exits and it's a UPNP file.
2 - In that case it looks for a parent folder (are UPNP "folders" separated by "%"? It seems so!)
3 - It than calls CDirectory::GetDirectory(parentDir, tempList, "") and extract from tempList only the file matching the path specified in member "file".

I know it's very dirty and probably buggy but it works for me and I thought you may be interested in seeing it.

Code:
diff --git a/xbmc/interfaces/json-rpc/FileItemHandler.cpp b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
index 3cd9294..df2a586 100644
--- a/xbmc/interfaces/json-rpc/FileItemHandler.cpp
+++ b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
@@ -40,6 +40,7 @@
#include "music/MusicThumbLoader.h"
#include "Util.h"
#include "pvr/channels/PVRChannel.h"
+#include "utils/StringUtils.h"

using namespace MUSIC_INFO;
using namespace JSONRPC;
@@ -374,6 +375,24 @@ bool CFileItemHandler::FillFileItemList(const CVariant &parameterObject, CFileIt
     if (!added)
     {
       CFileItemPtr item = CFileItemPtr(new CFileItem(file, false));
+      if(URIUtils::IsUPnP(file)) {
+        size_t found;
+        found = file.find_last_of("%");
+        const char* parent = StringUtils::Left(file,found).c_str();
+        CFileItemList tempList;
+        CDirectory directory;
+        if (directory.GetDirectory(parent, tempList, ""))
+        {
+          for (int index = 0; index < tempList.Size(); index++)
+          {
+            if (tempList[index]->GetPath() == file)
+            {
+              item = tempList[index];
+              break;
+            }
+          }
+        }
+      }
       if (item->IsPicture())
       {
         CPictureInfoTag picture;
Okay, this one won't leak memory. I'll try to fix it the clean way (without calling GetDirectory) but since I'm kinda in a dead end I'll post this version for now. If I ever succeed I'll try posting the correct version on github

Code:
diff --git a/xbmc/interfaces/json-rpc/FileItemHandler.cpp b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
index 3cd9294..9f91013 100644
--- a/xbmc/interfaces/json-rpc/FileItemHandler.cpp
+++ b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
@@ -40,6 +40,7 @@
#include "music/MusicThumbLoader.h"
#include "Util.h"
#include "pvr/channels/PVRChannel.h"
+#include "utils/StringUtils.h"

using namespace MUSIC_INFO;
using namespace JSONRPC;
@@ -374,6 +375,27 @@ bool CFileItemHandler::FillFileItemList(const CVariant &parameterObject, CFileIt
     if (!added)
     {
       CFileItemPtr item = CFileItemPtr(new CFileItem(file, false));
+      if(URIUtils::IsUPnP(file)) {
+        size_t found;
+        found = file.find_last_of("%");
+        const char* parent = StringUtils::Left(file,found).c_str();
+        CFileItemList tempList;
+        CDirectory directory;
+        if (directory.GetDirectory(parent, tempList, ""))
+        {
+          for (int index = 0; index < tempList.Size(); index++)
+          {
+            if (tempList[index]->GetPath() == file)
+            {
+              CFileItemPtr tempItem(new CFileItem(*tempList[index]));
+              item.~CFileItemPtr();
+              item = tempItem;
+              break;
+            }
+          }
+          tempList.Clear();
+        }
+      }
       if (item->IsPicture())
       {
         CPictureInfoTag picture;