获取 Cling 中所有 DLNA 根存储目录?
我正在使用很棒的 Cling
库来扫描网络中的 UPnP 设备。我的目标是组装一个小型 DLNA 库浏览器,以便我可以学习该技术。到目前为止,我已经能够 1. 扫描网络并连接 UPnP 设备,2. 扫描每个远程设备并确定它是否正在运行 DLNA 服务,以及 3. 浏览已知节点的直接子节点。简而言之,这是我能够运行所有这些的方法:
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) { };
});
}
}
}
}
我知道,它可能看起来像一团糟,确实如此,但它有效:)当我进入调试器时,我可以看到我得到了什么。但是,与指南中的说明不同 在这里,我没有取回任何实际的媒体项目,只是浏览结果中的存储目录。这是有道理的,因为 DLNA 将事物组织成层次结构,如下所示:
Music
All Music
Artists
Fleetwood Mac
...
Albums
...
Video
All Video
Folders
...
我的问题是,浏览这些文件夹并浏览层次结构的最简单方法是什么?我已经连接到我正在寻找的 UPnP DLNA 服务器,现在如何获取这些根存储目录?在上面给出的浏览命令中,我实际上必须传递某个索引的字符串表示形式才能获取“音乐”或“视频”等。如何获取最顶层的存储目录,那么如何浏览这些目录中的每一个呢?我的目标是至少构建一个简单的浏览器。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,事实证明,由于 Cling 邮件列表上的一些帮助,我可以回答自己的问题。
显然,DLNA 中的所有元素都有一个唯一的 ID 号,您可以通过它在 Cling 中引用它们。为了获取
/
,必须请求节点“0”。为了访问/../
(比顶部高一级!?),您可以请求节点“-1”。由于 DLNA 规范不存在在这个问题上毫无价值,这只是按照惯例。因此,请求节点“0”确实应该为您提供最顶层的节点,但谁知道呢?它可能会给你带来一条红鲱鱼、一头狂暴的驼鹿或世界末日。风险就是我们生存的意义,对吗?无论如何,DLNA“文件系统”的工作方式如下:
因此,如果我想按顺序浏览到节点“5”的“所有音乐”,我首先请求“0”,显示子容器,然后浏览到用户交互上的节点“2”,然后浏览到用户交互上的节点“5”,然后选择节点“6”(我正在查找的实际文件),并对其执行一些操作。
了解 DLNA 的工作方式是促进这一切的关键。所有重要的内容都通过 HTTP 提供,对等点的检测通过 UPnP 进行。因此,首先,找到网络上的所有 UPnP 客户端,然后对所有客户端进行排序并确定哪些客户端正在运行 DLNA,然后开始浏览。找到您要查找的内容,然后通过 HTTP 进行流式传输以进行播放。胜利的理论。
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 specis nonexistentis 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:
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.