Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
ISO/IEC 29341-17-10 提供了 ContentDirectory 服务的完整规范,该服务是第17-1部分定义的 UPnP MediaServer 设备的核心服务。第17-1部分从整体上定义了 MediaServer 设备,而第17-10部分则深入探讨 ContentDirectory 服务本身——其数据模型、元数据模式、浏览和搜索语义,以及实现者必须遵循的详细动作规范。任何构建兼容 UPnP 的媒体服务器或需要导航和查询媒体集合的控制点的工程师,都必须研读该标准。
ContentDirectory 服务使用 DIDL-Lite(数字项目声明语言精简版)模式组织媒体内容,这是一种源自 MPEG-21 数字项目规范的基于 XML 的元数据框架。对象模型定义了三个主要的类层次结构:项目(items,单个媒体资源)、容器(containers,项目和子容器的集合)和描述符(descriptors,附加到项目或容器的额外元数据)。层次结构中的每个类从其父类继承属性,创建了丰富且可扩展的元数据结构。
项目进一步特化为音频项目、视频项目、图像项目、播放列表项目、文本项目和其他媒体类型。每种特化类型继承基础项目属性(标题、创作者、日期等)并添加类型特定属性(audioItem 添加比特率、采样频率、声道数;videoItem 添加分辨率位深度、帧率、宽高比)。容器也类似地特化为专辑容器、流派容器、人物容器、播放列表容器和存储系统容器,每种都有其额外的属性。
| 类 | 基类型 | 关键属性 |
|---|---|---|
| audioItem.musicTrack | audioItem | 艺术家、专辑、原始曲目号、时长、比特率、采样频率 |
| videoItem.movie | videoItem | 导演、流派、详细描述、DVD 区域代码、预定开始时间 |
| imageItem.photo | imageItem | 专辑、拍摄日期、曝光时间、光圈值、闪光灯、像素分辨率 |
| container.album.musicAlbum | container.album | 艺术家、流派、制作人、专辑封面 URI、存储封面 URI |
| container.person.musicArtist | container.person | 传记、出生日期、逝世日期、作品集、相似艺术家 |
Browse 动作提供对内容层次结构的树遍历访问。它支持两个互斥的浏览标志:BrowseMetadata(返回指定对象或容器本身的元数据)和 BrowseDirectChildren(返回容器的直接子项)。结果根据 Filter 参数过滤,该参数指定控制点感兴趣的逗号分隔的元数据属性列表。这种过滤机制对性能至关重要——浏览包含数百个项目的相册的控制点可能只需要标题、缩略图和日期,可以省略完整的技术元数据集。
Search 动作使用标准定义的搜索表达式语言提供基于查询的访问。搜索表达式由元数据属性与字面值的比较组成,结合逻辑 AND、OR 和 NOT 运算符。支持搜索的属性通过 GetSearchCapabilities 动作通告。重要的是,标准并不要求所有属性都可搜索——只有 SearchCaps 中列出的属性才保证支持搜索查询,实现者可以根据其存储引擎的能力选择要为哪些属性建立搜索索引。
高效实现 ContentDirectory 服务需要复杂的数据工程。对象层次结构可以使用多种方法存储:小型库(最多数千个项目)使用内存树;中型库使用具有物化路径或嵌套集编码的 SQL 数据库;具有数十万项目的大型库使用专用搜索引擎(Elasticsearch、Apache Solr)。存储后端的选择直接影响浏览响应时间、搜索延迟和可搜索属性的集合。
标准定义了一种资源抽象,将媒体对象与其底层数据资源分离。一个项目可以有多个资源(例如,一部电影的 480p、720p 和 1080p 分辨率版本,或具有不同音轨)。每个资源由 protocolInfo 字符串描述,该字符串编码传输协议、网络格式和编码参数。控制点根据其播放能力和网络条件选择合适的资源。这种抽象支持自适应流式传输场景,无需专用的流式传输协议。
另一个重要的实现考虑是更新机制。ContentDirectory 服务支持两种形式的变更通知:SystemUpdateID 计数器(在内容树的任何变更时递增)和 ContainerUpdateIDs 状态变量(跟踪特定容器的变更)。控制点使用前者作为变更检测触发器,使用后者高效地仅刷新实际发生变更的树的部分。工程师应确保 ContainerUpdateIDs 正确反映每个内容变更的范围,以避免控制点执行不必要的全树刷新。