Fetch all DLNA root storage directories in Cling?

4.3k views Asked by At

I'm using the awesome Cling library to scan my network for UPnP devices. My goal is to throw together a little DLNA library browser so I can learn the technology. I have so far been able to 1. scan the network and get connected UPnP devices, 2. scan each remote device and determine if it has a DLNA service running, and 3. browse immediate children of known nodes. In short, this is my method that is able to run all of this:

    public void remoteDeviceAdded(Registry registry, RemoteDevice device) {
        logger.debug("remote device added: {}[{}]", device.getDetails().getFriendlyName(),
            device.getType().getType());

        if (device.getType().getType().equals("MediaServer")) {         
            for (RemoteService service : device.getServices()) {
                if (service.getServiceType().getType().equals("ContentDirectory")) {
//              '1' is Music, '2' is Video, '3' is Pictures
                    this.service.getControlPoint().execute(new Browse(service, "3", BrowseFlag.DIRECT_CHILDREN) {
                        @Override public void received(ActionInvocation arg0,
                                DIDLContent didl) {
                            logger.debug("found {} items.", didl.getItems().size());
                        }

                        @Override public void updateStatus(Status arg0) { };

                        @Override public void failure(ActionInvocation arg0, UpnpResponse arg1, String arg2) { };
                    });
                }
            }
        }
    }

I know, it probably looks like a horrible mess and it is, but it works :) When I drop into a debugger, I can see what I've got. However, unlike the instructions from the guide here, I don't get back any actual media items, just storage directories in the browse result. This kind of makes sense as DLNA organizes things into a hierarchy like so:

Music
    All Music
    Artists
        Fleetwood Mac
        ...
    Albums
    ...
Video
    All Video
    Folders
...

My question is this, what's the easiest way to browse these folders and climb through the hierarchy? I'm already at a point where I'm connected to the UPnP DLNA server that I was looking for, now how do I get these root storage directories? In the browse command given above, I have to actually pass a string representation of some index to get "Music" or "Video" or the like. How do I get the top level of storage directories, then how can I browse each one of those directories? My goal is to at least build a simple browser.

1

There are 1 answers

2
Naftuli Kay On BEST ANSWER

Ok, turns out that I get to answer my own question as a result of some help on the Cling mailing list.

Apparently, all elements in DLNA have a unique id number by which you can reference them in Cling. In order to fetch /, one must request node "0". In order to access /../ (one step higher than the top!?), you can request node "-1". Since the DLNA spec is nonexistent is worthless on this matter, this is by convention only. So, requesting for node "0" really should get you the top-most node, but who knows? It might get you a red herring or a rabid moose or the end of the world. Risks are what we live for, right?

In any case, the DLNA "filesystem" kind of works like this:

/[0]
    Browse Folders/[1]
    Music/[2]
        All Music/[5]
            Heart Is Hard To Find[6]
            ...
        ...
    Pictures/[3]
    Video/[4]

Thus, if I wanted to sequentially browse my way into "All Music" which is node '5', I'd first request '0', display the children containers, then browse into node '2' on user interaction, then browse into node '5' on user interaction, then select node '6' which is the actual file I'm looking for, and perform some action on it.

Understanding the way DLNA works is key in facilitating all of this. All important stuff is served out over HTTP, detection of peers is facilitated over UPnP. So first, find all UPnP clients on your network, then sort through all clients and determine which ones are running DLNA, then get to browsing. Find what you're looking for, then stream it over HTTP to play it. Theory for the win.