最近开始着手研究DLNA较底层的实现,目标是实现一个部分实现DLNA协议的类库,开发语言用Java,也许会涉及其它开发语言。
DLNA(Digital Living Network Alliance),数字生活网络联盟,这其实是一个组织,具体信息见其官网:http://www.dlna.org/home。国内很少见,但是在国外已经开始有普及的趋势。现在市面上已经有很多DLNA认证的设备和软件,最长见的有Sony BrandView电视、Windows Media Player 12、PS3、一部分手机软件(三星的All share,索尼爱立信的一些软件)等等。一些个人软件也有实现了DLNA部分协议,但是没有通过DLNA认证(认证程序是CTT,有一系列的case需要测试通过)的,例如Android平台上的2player和ps3mediaserver等。
DLNA是一个应用协议栈,它根据功能的不同把设备分成多个角色,如DMR,DMC,DMS等等。DM就是Digital Media的意思,R、C、S分别代表Renderer、Controller和Server。每个角色都有各自明确的分工,不同设备通过通过DLNA进行通信之后,也扮演着不同的角色。具体内容以官方white paper为准。
其实,跑去DLNA上层应用协议栈,它的核心协议实际上是UPNP(Universal Plug and Play),就是通用即插即用。这也是一个应用级的协议。它也是一系列协议的堆栈。
upnp协议堆栈图
我这里所指的应用级协议是应用层的协议,或者商用协议,开放协议一般都是RFC XX之类的东西,听同事说是由IEEE之类的组织负责发表这些协议。
看过UPNP一些基本文档之后,我发现,对于Java实现者而言,实现难度没有那么复杂。操作系统一般都是已经集成UPNP服务,我们只需要调用这个服务就可以。例如在windows下,有一个upnp.dll专门提供这样的服务,如果你的win os的这个服务出现问题,那么对硬件的发现和使用可能会出现一些问题(这点不是很准确,需要考证)。
下面列出我自己学习过程中自提的几个问题和自答:
1.每个UPNP设备可能都有一个描述文件?
我的Galaxy S(2.2系统)下,有一个系统服务就是DMS。当你用手机连接上局域网之后,这个服务可能就启动了,然后可以按照一下格式访问DMS的描述文件:http://手机ip:33003/description.xml。例如我的手机获取到的ip是192.168.1.188,那么当我访问http://192.168.1.188:33003/description.xml时,会看到一下内容:
<root>
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<device>
<dlna:X_DLNADOC>DMS-1.50</dlna:X_DLNADOC>
<dlna:X_DLNADOC>M-DMS-1.50</dlna:X_DLNADOC>
<dlna:X_DLNACAP>av-upload,image-upload,audio-upload</dlna:X_DLNACAP>
<deviceType>urn:schemas-upnp-org:device:MediaServer:1</deviceType>
<friendlyName>Galaxy S</friendlyName>
<manufacturer>SAMSUNG Electronics</manufacturer>
<manufacturerURL>http://www.sec.co.kr</manufacturerURL>
<modelDescription>
Provides content through UPnP ContentDirectory service
</modelDescription>
<modelName>SAMSUNG Media Server</modelName>
<modelNumber>1.0</modelNumber>
<modelURL>http://www.sec.co.kr</modelURL>
<UDN>uuid:ed86b8f4-4077-31e1-949b-a3214a16e3e1</UDN>
<iconList>
<icon>
<mimetype>image/jpeg</mimetype>
<height>48</height>
<width>48</width>
<depth>24</depth>
<url>/icon/icon.jpeg</url>
</icon>
<icon>
<mimetype>image/jpeg</mimetype>
<height>120</height>
<width>120</width>
<depth>24</depth>
<url>/icon/icon2.jpeg</url>
</icon>
<icon>
<mimetype>image/png</mimetype>
<height>48</height>
<width>48</width>
<depth>24</depth>
<url>/icon/icon.png</url>
</icon>
<icon>
<mimetype>image/png</mimetype>
<height>120</height>
<width>120</width>
<depth>24</depth>
<url>/icon/icon2.png</url>
</icon>
</iconList>
<serviceList>
<service>
<serviceType>urn:schemas-upnp-org:service:ContentDirectory:1</serviceType>
<serviceId>urn:upnp-org:serviceId:ContentDirectory</serviceId>
<SCPDURL>cds.xml</SCPDURL>
<controlURL>ContentDirectory_control</controlURL>
<eventSubURL>ContentDirectory_event</eventSubURL>
</service>
<service>
<serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
<serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
<SCPDURL>cms.xml</SCPDURL>
<controlURL>ConnectionManager_control</controlURL>
<eventSubURL>ConnectionManager_event</eventSubURL>
</service>
</serviceList>
</device>
</root>
这个配置文件基本描述了当前这个DLNA软件支持什么的协议版本(specVersion)和设备信息(device)。device节点描述了更多信息,什么deviceType啊、friendlyName啊等。关键看几个点,dlna:X_DLNACAP,它竟然是av-upload,image-upload,audio-upload,它意思就是说它支持视频、图片、音频上传。serviceList节点的值表明它目前支持2个服务,CMS(Content Manager Service,内容管理服务)和CDS(Content Directory Service,内容目录服务)。
SCPDURL是这两个服务的描述文件。可以分别通过/cms.xml和/cds.xml来访问。
2.什么是cds,如何实现?
CDS就像是一个文件服务器,它把你本地的文件可以通过HTTP的方式发布到网络上去。
我所知道的可用的组件有:在嵌入式设备上,可以用开源的(好像是GPL协议)的NanoHTTPD来做一个HTTP服务器;在桌面应用上,选择就太多了,什么netty、httpd之类应该都可以用。ps3mediaserver用的就是netty实现该功能。
3.什么是cms,如何实现?
//追查ing
4.什么是组播?Java中如何实现?
组播就是Multicast,具体概念见wiki。java就有组播的实现类:java.net.MulticastSocket.
5.UPNP如何实现?
我目前看到的比较明显的方式是组播(upnp只应用与局域网)。upnp协议定义了一些基本组件,例如device、service、av transmission等,基于upnp的其它协议都是扩展这些组件就可以了。DLNA其实就是扩展了upnp device、service等之后的应用协议。upnp有默认的组播地址,我看psm的实现写的是239.255.255.250,不知道是不是这个。另外upnp默认端口好像是1900,如果建立一个组播socket,然后读取这个端口的数据,就会发现有很多数据,什么M-SEARCH、NOTIFY之类的,并会发现一些挺有意思的事情(前提是你所在的局域网够大)。
6.netty和NanoHTTPD实现的区别?
a>对比一下获取还n文件的URL就知道了:
netty:http://192.168.1.100:5001/description/fetch
NanoHTTPD: http://192.168.1.100:5001/description.xml
7.哪里去找upnp和dlna的资料?
不用问,对于这种标准的东西,直接上官方查spec,如果涉及RFC的部分,可以去这个网站:www.faqs.org。
8.描述DLNA的一个场景的工作过程。
场景:用户将手机A中的媒体内容播放到电视B上。(DMC+DMR)
在这个场景中,前提是,A和B必须连接到同一个局域网中。假定电视B先接入局域网,手机A后接入局域网,然后再进行播放操作,那么该场景大概是这样的:
B接入局域网以后,B需要建立多播socket,然后加入DLNA这个多播组(譬如说是239.255.255.250,数据端口是1900),同时不断监听1900端口发送过来的报文数据。
如果报文以M-SEARCH开头,那么就说明,局域网内有设备正在进行查找。B现在扮演DMR的角色,那么它就应该处理所有Renderer的M-SEARCH报文,接收到相应报文之后,需要给查询方发送一个回复报文,回复报文中包含了当前DMR的基本信息。
A现在加入局域网,它也建立多播socket,也加入到多播组中,然后根据A上用户选择进行DMR搜索之后,A发出M-SEARCH报文,局域网多播机制会将该报文发送给DLNA多播组中所有监听者,于是B也收到了该报文。B开始解析报文,它知道对方搜索的正式DMR,于是它立刻给多播组内发一条回复报文,告诉搜索方自己就是DMR。于是A又收到了该回复报文,A解析了该回复,得到了DMR的基本信息,它接着把这些基本信息装载到UI上,于是用户看到了该DMR的信息。
如果用户已经选择了某个媒体资源,那么就可以直接进行具体的流媒体push操作了。
关于push操作,其实是这样的。无论对于DMR+DMC的push场景,或者DMS+DMR的pull场景,媒体提供方其实也要提供一个服务就是流媒体服务器(就是NanoHTTPD或者netty等去实现的)。所以在A和B这个场景中,A是DMC,所以它提供了一个媒体服务器。当报文发出并得到回复之后,事实上这一步只是确定了DMR有谁,接着用户选择了某个DMR,这就确定了要与之通信的DMR是谁,然后,A和B其实就已经建立了一种端对端的关系,A会先发起一个HTTP请求,告诉B,我要播放什么格式的内容,它的URL地址是什么,然后B接收到请求之后,解析到要播放的地址文件格式及其地址等信息之后,先会判断它支持不支持这个媒体内容,如果不知吃,那么就需要返回一个400或者什么错误码给A(错误码,DLNA spec里都有详细介绍),如果它支持,那么就开始建立与该流媒体的连接,通过HTTP去拿数据,然后根据媒体类型再在本地进行解码,然后进行播放。
在刚才的过程中,如果媒体文件是视频或者音频,那就更复杂一些,一是B要进行实时解码播放,二是还需要把播放的进度不断返回给A,因为对于A来讲,它需要把播放进度条展示给用户去看。同时A一般还会提供一些更具体的视频、音频操作,例如暂停、恢复、跳转等。这些都是协议里面规定的,具体如何去通信,还要仔细的阅读spec。
DMR搜索报文 写道
M-SEARCH * HTTP/1.1
USER-AGENT: SEC_HHP_Galaxy S/1.0
ST: urn:schemas-upnp-org:device:MediaRenderer:1
MX: 3
MAN: "ssdp:discover"
HOST: 239.255.255.250:1900
目前还没找到回复报文,因为回复报文都是需要截取DMR的数据包,可是我手头还没有DMR设备,唯一能用的WMP12,只能在win7下用,只好等以后有空把win7的开发环境配置好,才能抓取。
补充:为什么默认组播地址和端口用的是239.255.255.250:1900,是因为这是SSDP协议所用的地址。
引用
SSDP is a text-based protocol based on HTTPU. It uses the User Datagram Protocol (UDP) as underlying transport protocol. Services are announced by the hosting system with multicast addressing to a specifically designated IP multicast address at port number 1900. In IPv4, the multicast address is 239.255.255.250[1] and SSDP over IPv6 uses the address set FF0X::C for all scope ranges indicated by X.[2]
9.基于DLNA的应用有什么特点吗?
除了即插即用之外,我暂时还注意到另外一个特点。
我们知道,对于web应用来说,服务器端大多是被动的,即便某些服务可能会主动推送数据,但是那也要提前注册了才行。
而UPNP应用中,由于基于组播,DLNA media server一旦建立,就需要自己每隔一个时间段往组播组中发送心跳数据报,以保证同组中关注DMS的设备更新它的DMS列表。(这点可能不是很对,不过目前看起来确实很想这样,以后花时间再具体考证)。
//
- 大小: 16.7 KB
分享到:
相关推荐
工业软件系列报告之开篇:软件为体,工业铸魂.pdf
1. 投资评级与分析师信息:报告开篇即提出了投资评级,即“增持”(维持),并提供了分析报告撰写者谢春生的姓名、执业证书编号以及联系方式。同时,提及了研究助理杨亚宇的联系信息。这为读者提供了与报告撰写者...
在《***-德邦证券-A股投资者微观结构系列开篇:投资者主体定价权的迁移与转变.pdf》中,德邦证券详细分析了A股市场的这一变化趋势。 首先,报告指出A股市场定价权的直接参与者主要有四大投资主体:个人投资者、机构...
企业架构_-_开篇:TOGAF介绍
本报告主要探讨的是中国“专精特新”中小企业的投资价值,特别是在制造业中的“单项冠军”企业。"专精特新"是指专业化、精细化、特色化和新颖化的中小企业,这类企业在特定领域有深厚积累,具有创新能力,能填补产业...
A股市场规则研究系列开篇:开弓之箭,IPO制度变迁与展望
A股市场规则研究系列开篇:开弓之箭,IPO制度变迁与展望.pdf
20210310-德邦证券-A股市场规则研究系列开篇:开弓之箭,IPO制度变迁与展望
电气设备行业新能源车2019系列报告开篇:承前启后,孕育新机-20190410-广发证券-35页(1).pdf
20210827-德邦证券-“专精特新”系列研究开篇:“专精特新”中觅“单项冠军”.rar
### 解密搜索引擎技术实战:Lucene&Java精华版 #### 搜索引擎基础知识及工作原理 本书开篇便从搜索引擎的基本概念入手,详细介绍了搜索引擎的工作原理和技术框架。在**第1章**“搜索引擎总体结构”中,作者从搜索...
01响应式入门:02Java9中的响应式编程:03Rxjava开篇:304Rxjava中create方法的设计思想:405Observables和Observable.cache():506无休止数据流与定时控制:607Demo的设计初衷:708Observable.cache()源码解读:809...
标题所涉及的知识点: 1. 性能优化实践:性能优化是前端开发中的一个重要环节,它不仅关系到用户对产品的使用体验,还影响到产品的市场竞争力。 2. 知识体系构建:通过系统性的学习和实践来构建知识体系,能够帮助...
企业架构(Enterprise Architecture,EA)是一种系统化的方法,用于规划、设计、实施和管理组织的业务、信息和技术组件。在企业架构中,TOGAF(The Open Group Architecture Framework)是广泛应用的一个框架,它为...
在电气设备行业新能源车系列报告的开篇中,我们可以解读出以下几个关键知识点: 1. 新能源汽车补贴政策更新 2019年新能源汽车补贴政策正式落地,标志着新版补贴政策实施。政策调整主要表现为对车辆安全性和一致性的...
从零基础开始学习,第一阶段:Java开篇,第二阶段:Java语言语法,第三阶段:集成开发工具的使用,第四阶段:面向对象,第五Javase进阶,第6阶段 :数据库+JDBC,第7阶段 :前端精讲,第8阶段 :算法篇,第9阶段 :...
【宏观经济】报告中提出的"强国牛"概念,指的是在金融供给侧改革背景下,A股市场表现超出预期,核心驱动力在于通过股权融资支持实体经济和科技创新,推动国家经济强盛。2019年A股行情的持续发展并非仅由低估值和流动...
1. **Java基础知识**:教程的开篇通常会涵盖Java语言的基础,包括数据类型、变量、运算符、控制结构(如if语句和循环)、方法以及类的基本概念。 2. **面向对象编程**:Java是一种面向对象的语言,教程将深入讲解类...
java版直播间源码 SIMVISO ...Rxjava开篇: 04 Rxjava中create方法的设计思想: 05 Observables和Observable.cache(): 06 无休止数据流与定时控制: 07 Demo的设计初衷: 08 Observable.cache()源