Android DLNA投屏-基本原理
转 https://www.jianshu.com/p/19934892a235
1. DLNA简介
DLNA(Digital Living Network Alliance),即数字家庭网络联盟。
DLNA不是技术,而是一种解决方案,它是多种技术的整合,并致力于构建家庭媒体共享。
DLNA包含多种网络协议,如http、https、upnp等,其中upnp是其重要组成部分。
DLNA主要包含以下四种产品:
DMS,即Digital Media Server(数字媒体服务器)的缩写,其主要作用是作为媒体内容的提供者,为DMP/DMR提供内容播放,DMS可控制提供哪些媒体内容。
DMP,即Digital Media Player(数字媒体播放器)的缩写,可搜索并播放DMS的内容,其作用相当于DMR+DMC。
DMC,即Digital Media Controller(数字媒体控制器)的缩写,可搜索并控制DMR播放DMS提供的内容,即控制DMR与DMS的交互。
DMR,即Digital Media Renderer(数字媒体渲染器)的缩写,可播放DMS提供的内容。
2.Upnp设备架构(Upnp Device Architecture)
Upnp DA将家庭网络中的角色分为三种:控制点、设备和服务。它们之间主要通过HTTP技术实现通信。设备和相关服务的规格信息使用XML方式向其他节点公布。
Upnp DA中各角色的关系如下图:
Upnp组件架构.png
各个角色的基本概念如下:
- 根设备/设备,即硬件设备,如电脑、电视盒子等。一个设备可提供多个服务。但是家用电器内部一般都包含了多个功能不同的设备,这样由多个设备集合而成的设备集合体,被称为根设备。
- 设备所能提供的功能服务。分为控制服务、事件服务、展示服务。服务是Upnp系统中最小的可控制单元(动作与状态)。
- 控制点。即控制设备,可发现并控制其他设备。如控制其他设备的视频播放、暂停等。
在DLNA投屏的过程中,Android设备充当的角色是控制点
,它初始化并配置好DMS和DMR设备之间的连接,并不直接参与真正的内容传输,内容传输由DMS和DMR完成。
3.DLNA网络传输流程
DLNA的网络传输由设备发现开始。首先,一个新的控制点(Control Point)加入局域网,那么这个Control Point就会开始搜索局域网内可用的设备了。当控制点开始搜索时,它会从UDP端口发送如下格式的搜索请求消息:
M-SEARCH * HTTP/1.1MX: 1 //最大时间间隔数ST: upnp:rootdevice //搜索的设备类型MAN: "ssdp:discover" User-Agent: iOS 10.2.1 product/versionConnection: closeHost: 239.255.255.250 //多播地址
如果发现可用设备,则会从UDP端口收到如下响应消息:
HTTP/1.1 200 OKCache-control: max-age=1800Date: Thu, 16 Feb 2017 09:09:45 GMTEXT:LOCATION: http://10.2.9.152:49152/TxMediaRenderer_desc.xml //URL for UPnP description for deviceServer: search targetUSN: uuid:3c970e3c0c0d0000_MR::upnp:rootdevice //composite identifier for the advertismentBOOTID.UPNP.ORG: 1487062102 //number increased each time device sends an initial announce or an update messageCONFIGID.UPNP.ORG: 499354 //number used for caching description informationSEARCHPORT.UPNP.ORG: number identifies port on which device responds to unicast M-SEARCHST: upnp:rootdevice //device type
可以看到,在响应消息中,LOCATION
这个字段是一个url:
LOCATION: http://10.2.9.152:49152/TxMediaRenderer_desc.xml //URL for UPnP description for device
这个url指向的是设备服务和信息描述文档
,一般为xml格式。我们可以直接通过浏览器访问该链接查看该设备的相关信息:
<root xmlns="urn:schemas-upnp-org:device-1-0" xmlns:dlna="urn:schemas-dlna-org:device-1-0" configId="499354"><specVersion><major>1</major><minor>1</minor></specVersion><device><deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType><friendlyName>卧室的创维盒子Q+</friendlyName><manufacturer>Plutinosoft LLC</manufacturer><manufacturerURL>http://www.plutinosoft.com</manufacturerURL><modelDescription>Plutinosoft AV Media Renderer Device</modelDescription><modelName>AV Renderer Device</modelName><modelURL>http://www.plutinosoft.com/platinum</modelURL><UDN>uuid:9c443d47158b-dmr</UDN><dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMR-1.50</dlna:X_DLNADOC><serviceList><service><serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType><serviceId>urn:upnp-org:serviceId:AVTransport</serviceId><SCPDURL>/AVTransport/9c443d47158b-dmr/scpd.xml</SCPDURL><controlURL>/AVTransport/9c443d47158b-dmr/control.xml</controlURL><eventSubURL>/AVTransport/9c443d47158b-dmr/event.xml</eventSubURL></service>...</serviceList></device>
</root>
在设备信息描述文档中,有一个名为<serviceList>
的节点,该节点是设备可提供服务的描述。有多个<service>
节点,
在<serviceList>
节点中,包含了多个在<service>
节点,每一个<service>
节点代表着一个服务
。
<service>
节点中主要包含着以下节点:
<serviceType>
service的类型<serviceId>
service的ID值<SCPDURL>
该节点的url指向服务的动作描述文档(SDD)
,可以直接通过浏览器访问<controlURL>
该节点为服务请求url,在发送动作请求消息时,需要将动作参数以规定格式发送给该url以获取响应消息
可以看出,<SCPDURL>
节点的url并没有标出域名和端口号,因为其域名和端口号与响应消息中LOCATION
字段的域名和端口号一致。如上述代码中的<SCPDURL>
的完整url应为:
http://10.2.9.152:49152/AVTransport/9c443d47158b-dmr/scpd.xml
通过浏览器访问url,可获取如下格式的内容:
<scpd xmlns="urn:schemas-upnp-org:service-1-0"><specVersion><major>1</major><minor>0</minor></specVersion><actionList><action><name>SetAVTransportURI</name><argumentList><argument><name>InstanceID</name><direction>in</direction><relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable></argument><argument><name>CurrentURI</name><direction>in</direction><relatedStateVariable>AVTransportURI</relatedStateVariable></argument><argument><name>CurrentURIMetaData</name><direction>in</direction><relatedStateVariable>AVTransportURIMetaData</relatedStateVariable></argument></argumentList></action>...<serviceStateTable><stateVariable sendEvents="no"><name>AVTransportURI</name><dataType>string</dataType></stateVariable>...</serviceStateTable>
</scpd>
可以看到,文档中包含一个名为<actionList>
的节点,该节点为服务的动作描述。
<actionList>
中包含了多个<action>
节点,每个节点对应着一个动作
。
每个<action>
节点中都包含着如下节点:
<name>
动作名<argumentList>
参数列表。每个<argumentList>
节点中包含了多个<argument>
节点,每个<argument>
节点代表着一个动作参数。一个<argument>
节点包含着如下节点:<name>
参数名<direction>
该节点参数取值为in/out
, 当<direction>
的值为in
时,表明这个参数的值是传入值,当为out
时,表明这个参数的值是返回值,则该值会随着订阅事件一起返回给订阅者。<relatedStateVariable>
该节点的值是一个<stateVariable>
节点的映射,映射的内容可在下方<serviceStateTable>
节点中找到,<stateVariable>
节点包含值的类型及取值范围等信息。
简单的来说,可以把一个action
当成一个API接口,而action
中的argument
则可表示为API接口的参数,而service
即是多个相关接口的集合。
通过上面的信息,就可以请求服务动作,实现设备控制了。开发者可根据文档中规定的请求参数,发送如下格式的请求消息:
POST /AVTransport/9c443d47158b-dmr/control.xml HTTP/1.1
HOST: 10.2.9.152
Content-Type: text/xml; charset="utf-8"
SOAPAction: "urn:schemas-upnp-org:service:AVTransport:1#SetAVTransportURI"
<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><CurrentURI>yourAVURI</CurrentURI></u:SetAVTransportURI></s:Body>
</s:Envelope>
POST
字段后面跟的是<controlURL>
节点的url,HOST
对应的LOCATION
字段的IP。
SOAPAction
的格式:"<serviceType>节点的值#请求的action的名称"
<s:Body>
节点的内容是请求体,请求体的格式为:
<u:请求的action的名称 xmlns:u="<serviceType>节点的值"><参数1>参数值</参数1><参数2>参数值</参数2>...</u:请求的action的名称>
如果请求成功,会获取如下格式的响应消息:
HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Date: Thu, 16 Feb 2017 09:09:45 GMT
Server: OS/version UPnP/1.1 product/version
<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetAVTransportURI xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><u:SetAVTransportURIResponse><_xmlns:u>"urn:schemas-upnp-org:service:AVTransport:1"</_xmlns:u></u:SetAVTransportURIResponse></u:SetAVTransportURI></s:Body></s:Envelope>
这样,整个传输流程就完成了。同一种类型的设备提供的服务大部分相同,但也可能有所差异,因此,在请求设备服务之前,最好先浏览其设备描述文档
,查看设备支持哪些服务。
Android DLNA投屏-基本原理相关推荐
- android 投屏开发框架,Android DLNA投屏-基于CyberGarage开发投屏功能
在上一篇博客<Android DLNA投屏-基本原理>中,讲到了DLNA的一些基本原理.了解这些基本原理,对开发是很有帮助的.但仅仅依据原理去进行Android DLNA开发,是比较困难的 ...
- Android dlna 投屏
android dlna 投屏demo github地址 https://github.com/liulei9385/CyberLink4Android
- 原 android dlna投屏,README.md · Royal520/VideoDlnaScreen - Gitee.com
# **视频投屏,支持网络投屏和本地投屏** ## **android Dlna开发** [GitHub主页](https://github.com/yanbo469/VideoDlnaScreen) ...
- Android PC投屏简单尝试—最终章2
源码地址:https://github.com/deepsadness/AppRemote 上一章中,我们简单实现了PC的投屏功能. 但是还是存在这一些缺陷. 屏幕的尺寸数据是写死的 不能通过PC来对 ...
- Android PC投屏简单尝试—最终章1
回顾之前的几遍文章,我们分别通过RMTP协议和简单的Socket 发送Bitmap图片的Base64编码来完成投屏. 回想这系列文章的想法来源-Vysor,它通过 USB来进行连接的.又看到了 scr ...
- Android PC投屏简单尝试(录屏直播)2—硬解章(MediaCodec+RMTP)
代码地址 :https://github.com/deepsadness/MediaProjectionDemo 想法来源 上一边文章的最后说使用录制的Api进行录屏直播.本来这边文章是预计在5月份完 ...
- Android PC投屏简单尝试- 自定义协议章(Socket+Bitmap)
代码地址 :https://github.com/deepsadness/MediaProjectionDemo 效果预览 投屏效果预览 简单说明: 使用Android MediaProjection ...
- 纯OC实现iOS DLNA投屏功能了解一下
iOS上实现DLNA功能Github上搜一下大多是基于C++的Platinum,于是就想能不能靠OC实现一套方便iOS开发者.于是就有了MRDLNA这个库. DLNA投屏的相关的介绍,协议,具体XML ...
- Android手机投屏win10
Android手机投屏win10 win10-操作系统 win10-投影到此电脑 win10-选择所有位置都可用 win10-记住你的win10名称 Android-更多连接方式 Android-无线 ...
最新文章
- 2021年浅谈多任务学习
- 目标检测 - 如何在图片中标记Annotations中的坐标信息?
- 【aspnetcore】添加自定义json配置文件
- jsf 单元测试_构建和测试JSF.next
- VGAE(Variational graph auto-encoders)论文及代码解读
- python数据录入和分析_hive+python数据分析入门
- 10 文件无效_新手必看!10个CAD常见问题解决技巧
- 下一个十年,什么样的测试会被大厂争抢?
- 结构体02:结构体数组
- python3 zip函数
- automake连载--Linux下使用autoconfig automake进阶
- 访问iis元数据库失败怎么解决?
- paip.c#使用匿名函数建立委托提高可读性
- 上海交通大学计算机专业考研多少分进复试,2019考研:初试分数370+,有希望进上海交通大学么?...
- java label 位置_java 怎样设置label的位置
- 【渝粤题库】陕西师范大学209008 教师伦理学 作业
- cups ipp oracle,基于IPP的逐步打印服务器使用CUPS
- GPS北斗校时服务器(时间服务器)在港口自动化系统应用
- java自定义日历控件_【无私分享】修订版干货!!!一个炫酷的自定义日历控件,摆脱日历时间选择烦恼,纯福利~...
- Nginx的 allow / deny 理解