dlan协议 ios_dlan协议 - CSDN
精华内容
参与话题
  • 由于我司需求,需要在iOS和安卓客户端实现DLNA投屏和控制。经过一番折腾,决定由我来研究DLNA。说起来又兴奋又紧张,兴奋希望自己能够弄出来然后跟安卓组讲解原理,紧张是因为怕自己能力不足做不出来。DLNA网上的...

    由于我司需求,需要在iOS和安卓客户端实现DLNA投屏和控制。经过一番折腾,决定由我来研究DLNA。说起来又兴奋又紧张,兴奋希望自己能够弄出来然后跟安卓组讲解原理,紧张是因为怕自己能力不足做不出来。

    DLNA网上的资料比较笼统不好入门,官方资料直接是每个1000多页的10几个PDF文档,根本无从下手。相关开源项目有名的有Platinum UPnP,但是由于它是基于C++实现的,相关文档并不全面。iOS相关开源项目都三四年没更新的,找来找去只好自己去啃自己去实现了。还好买到一本不错的书《智能家庭网络:技术、标准与应用实现》。通过近俩星期的研究,搞懂了DLNA核心协议UPnP基本逻辑,实现了投屏和控制功能的Demo。

    下面就整理一下实现基本概念,实现过程和一些坑。

    如果要直接看实现过程,请看以下三篇文章:

    基础概念

    DLNA

    DLNA的全称是DIGITAL LIVING NETWORK ALLIANCE(数字生活网络联盟), 其宗旨是Enjoy your music, photos and videos, anywhere anytime, DLNA(Digital Living Network Alliance) 由索尼、英特尔、微软等发起成立、旨在解决个人PC,消费电器,移动设备在内的无线网络和有线网络的互联互通,使得数字媒体和内容服务的无限制的共享和增长成为可能,目前成员公司已达280多家。

    DLNA标准包括多项协议及标准,其中最重要的部分是UPnP。对于我们目前的需求UPnP就能满足全部要求。

    UPnP

    通用即插即用(英语:Universal Plug and Play,简称UPnP)是由“通用即插即用论坛”(UPnP™ Forum)推广的一套网络协议。该协议的目标是使家庭网络(数据共享、通信和娱乐)和公司网络中的各种设备能够相互无缝连接,并简化相关网络的实现。UPnP通过定义和发布基于开放、因特网通讯网协议标准的UPnP设备控制协议来实现这一目标。

    UPnP这个概念是从即插即用(Plug-and-play)派生而来的,即插即用是一种热拔插技术。

    协议栈

    UPnP设备体系结构包含了设备之间、控制点之间、设备和控制点之间的通信。完整的UPnP由设备寻址、设备发现、设备描述、设备控制、事件通知和基于Html的描述界面几部分构成。

    UPnP协议栈

    1. UPnP是一个多层协议构成的框架体系,每一层都以相邻的下层为基础,同时又是相邻上层的基础。直至达到应用层为止。该图中的最下面是就是IP和TCP,共两层,负责设备的IP地址。
    2. 三层是HTTP、HTTPU、HTTPMU,这一层,属于传送协议层。传送的是内容都经过“封装”后,存放在特定的XML文件中的。对应的SSDP、GENA、SOAP指的是保存在XML文件中的数据格式。到这一层,已经解决了UPnP设备的IP地址和传送信息问题。
    3. 第四层是UPnP设备体系定义,仅仅是一个抽象的、公用的设备模型。任何UPnP设备都必须使用这一层。
    4. 第五层是UPnP论坛的各个专业委员会的设备定义层,在这个论坛中,不同电器设备由不同的专业委员会定义,例如:电视委员会只负责定义网络电视设备部分,空调器委员会只负责定义网络空调设备部分,依此类推。所有的不同类型的设备都被定义成一个专门的架构或者模板,供建立设备的时候使用。可以推知,进入这一层,设备已经被指定了明确用途。当然,这些都必须遵守标准化的规范。从目前看,UPnP已经可以支持大部分的设备:从电脑、电脑外设,移动设备和家用消费类电子设备等等,无所不包,随着这个体系的普及,将可能有更多的厂家承认这一标准,最终,可能演化为公认的行业标准。
    5. 最上层,也就是应用层,由UPnP设备制造厂商定义的部分。这一层的信息是由设备制造厂商来“填充” 的,这部分一般有设备厂商提供的、对设备控制和操作的底层代码,然后,就是名称序列号呀,厂商信息之类的东西。

    设备

    设备是提供服务的网路实体,是一个逻辑概念,一个屋里设备可以包含一个或者多个逻辑设备。例如一台PC可以有两个逻辑设备———视频播放器和图片浏览器。

    服务

    服务是UPnP中最小的可控单元,它包括一系列可控制而动作和一组记录该服务目前情况的状态。服务是依赖于设备存在的。

    控制点

    控制UPnP设备工作的网络终端,主要功能包括获取设备描述和相关服务列表;获取感兴趣的服务描述;发出控制消息控制设备动作;向感兴趣的服务发出订阅消息,以便当服务状态改变时,自动获得时间通知。

    UPnP组件

    一些术语

    • UUID

    UUID含义是通用唯一识别码(Universally Unique Identifier),其目的是让分布式系统中的所有元素,都有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。其格式为xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),分别为当前日期和时间,时钟序列,全局唯一的IEEE机器识别号,如果有网卡,从网卡mac地址获得,没有网卡以其他方式获得。

    • UDN

    单一设备名(Unique Device Name),基于UUID,表示一个设备。在不同的时间,对于同一个设备此值应该是唯一的。

    • URI

    Web上可用的每种资源 - HTML文档、图像、视频片段、程序等 - 由一个通用资源标志符(Universal Resource Identifier,简称”URI”)进行定位。 URI一般由三部分组成:访问资源的命名机制;存放资源的主机名;资源自身的名称,由路径表示。考虑下面的URI,它表示了当前的HTML 4.0规范:http://www.webmonkey.com.cn/html/html40/它表示一个可通过HTTP协议访问的资源,位于主机www.webmonkey.com.cn上,通过路径/html/html40访问。

    • URL

    URL是URI命名机制的一个子集,URL是Uniform Resource Location的缩写,译为“统一资源定位符”。通俗地说,URL是Internet上用来描述信息资源的字符串,主要用在各种www客户程序和服务器程序上。采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。

    • URN

    URN:URL的一种更新形式,统一资源名称(URN,Uniform Resource Name)。唯一标识一个实体的标识符,但是不能给出实体的位置。标识持久性Internet资源。URN可以提供一种机制,用于查找和检索定义特定命名空间的架构文件。尽管普通的URL可以提供类似的功能,但是在这方面,URN 更加强大并且更容易管理,因为 URN 可以引用多个 URL。

    实现

    工作机制

    UPnP设备的发现和控制分为6个步骤:寻址、发现、描述、控制、事件及展现。

    UPnP工作机制

    这三点分别在后面的三篇文章中进行介绍。

    整体流程

    整体工作流程如下:

    UPnP整体工作流程

    参考

    本文来自:Eliyar’s Blog,作者:@艾力亚尔

    第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。

    mobilehub

    展开全文
  • DLNA投屏 iOS

    2020-07-30 23:31:48
    DLNA最新投屏自研代码. 兼容Sony, 华为, 乐视,小米等各种电视
  • 乐播投屏之手机投屏集成包、SDK含三大投屏协议 提示:仅提供研究分享,如需商用请自行联系官方。 简介:乐播投屏发送端SDK,已全面支持iOS和Android系统;接入后,能让您的App轻松拥有投屏与镜像能力,云投屏、扫描...
  • 使用Platium库开发dlna投屏功能

    千次阅读 2017-09-19 20:44:21
    这几天公司的应用(iOS端)上要加一个dlna的功能,就是局域网内设备投屏控制的一个功能,并提供移动端控制。因为三方库Platinum是使用C++写的,所以我被分配去做库的Objective-C封装的工作。第一次接手这种事,对一个...
    

    这几天公司的应用(iOS端)上要加一个dlna的功能,就是局域网内设备投屏控制的一个功能,并提供移动端控制。因为三方库Platinum是使用C++写的,所以我被分配去做库的Objective-C封装的工作。第一次接手这种事,对一个非计算机专业的学生来说还是蛮有挑战性的。组长说要先写一个接口设计文档来描述将要封装的接口和调用方式。只能网上查看各种资料喽!

    这里是我一顿狂搜、看各种博客后搜集到的有用资料,列表如下:

    链接 描述
    Open Connectivity Foundation (OCF)官网 这里有UPnP相关的文档和各家公司开发的SDK,例如:Plutinosoft开发的Platinum库也可以从这里了顺藤摸瓜找到
    dlna官网 这里有对dlna协议描述的文档下载,可以说要全面的学习dlna,这里的文档是不可或缺的,当然,实际中我们也没有必要学太深,不过知道这个资源,学习时就有底了;-)
    一个关于dlan介绍的博客 上面两个网站就是通过阅读这个博客《DLNA&UPnP开发笔记》系列共四篇文章后找到的,值的阅读



    好了,有了以上的几个资源,我们就可以开动了。我工作中使用了Platinum库进行dlna的媒体控制器(DMC)开发,所以也没有对dlna有太全面的了解,一切是从对Platinum库所提供的示例程序和项目README文件进行编译库和相关开发学习的。

    那么,第一步就是,拉下项目进行编译和运行示例了。

    编译Platinum库

    首先,使用git拉下项目最近一次的提交

    git clone --depth=1 https://github.com/plutinosoft/Platinum.git

    因为Platinum的编译需要依赖一个名为Neptune的C++跨平台运行环境,当然这个项目里已经有解决方法,不需要我们另外下载或编译Neptune库,我们只需要通过Carthage工具,将Neptune的framework下载到Platinum的项目目录下。具体过程如下:

    你要先进行Platinum项目目录下,发现其中有着名为CartfileCartfile.resolved这样的文件,文件中指明了Carthage这个工具软件所要下载的framework名称和版本,其实carthage这个工具类似于CocoaPods这个工具。不过你的Mac上很可能并没有安装carthage,所以你其实可以通过先在Mac上安装homebrew这个工具,然后使用homebrew来安装carghage。如下:

    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"  # 安装homebrew
    
    brew install carthage  # homebrew 安装成功后,安装carthage
    
    cd Platinum/  # 进入Platinum项目目录下
    
    carthage update  # 运行carthage 让其下载 Carthfile文件中指定的framework

    当以上过程完成后,你会发现在Platinum/Carthage这个目录下面,已经存在Neptune这个C++跨平台运行环境的分别针对Mac和iOS的framework了,你只要确保以上的命令运行成功,并最终得到Neptune的FrameWork就可以编译Platinum的针对iOS的项目和示例程序了。

    使用XCode打开/Platinum/Build/Targets/universal-apple-macosx/Platinum.xcodeproj项目文件,然后分别运行各Target,就可以生成相关的framework和示例运行程序了。

    生成同时支持真机和模拟机的framework动态链接库

    选择Platinum-iOS编译方案(Scheme),在编辑方案(Edit Scheme…)对话框,运行(Run)分类中的信息(Info)选项卡下,选择编译配置(Build Configuration)为Release。设置好编译方案后,选择任一模拟器(e.g: iphone SE)编译一次,再选择通用iOS设备(Generic iOS Device)编译一次,这两次编译,分别得到对应于i386 x86_64架构的模拟器framework和对应于真机armv7 arm64架构的framework,我们把这两个对应于不同架构的framework合并成一个framework就完成了同时满足真机调试和模拟器调试的framework了。

    生成的两个针对不同架构的framework所在的目录如下,你也可以通过右键Show in Finder的方式找到它们的位置, 这两个目录路径动态变化,不完全与我的一致。

    #这个目录对应于真机的 armv7 arm64 架构
    /Users/JokerAtBaoFeng/Library/Developer/Xcode/DerivedData/Platinum-bawuiqxkhqixgybjjufqgvmduavh/Build/Products/Release-iphoneos 
    
    #这个目录对应于模拟器的 i386 x86_64 架构
    /Users/JokerAtBaoFeng/Library/Developer/Xcode/DerivedData/Platinum-bawuiqxkhqixgybjjufqgvmduavh/Build/Products/Release-iphonesimulator

    你可以分别使用下面的命令来查看framework中的文件支持的架构,如下:

    lipo -info Release-iphoneos/Platinum.framework/Platinum

    输出:

    Architectures in the fat file: Release-iphoneos/Platinum.framework/Platinum are: armv7 arm64

    lipo -info Release-iphonesimulator/Platinum.framework/Platinum

    输出:

    Architectures in the fat file: Release-iphonesimulator/Platinum.framework/Platinum are: i386 x86_64

    利用下面的命令将两个framework合并, 并替换Release-iphoneos/Platinum.framework/Platinum文件,这个文件就是合并之后的文件:

    lipo -create Release-iphoneos/Platinum.framework/Platinum Release-iphonesimulator/Platinum.framework/Platinum -output Release-iphoneos/Platinum.framework/Platinum

    这时你就可以使用Release-iphoneos/Platinum.framework导入你要用到的项目中去了。哦,对了,由于Platinum.framework运行需要依赖Neptune.framework,所以导入自己的项目时,记得把carthage下载的Neptune.framework一并导入。

    再次查看合并后的framework所支持的架构:

    lipo -info Release-iphoneos/Platinum.framework/Platinum

    输出:
    Architectures in the fat file: Release-iphoneos/Platinum.framework/Platinum are: i386 x86_64 armv7 arm64

    可以看到,它已经同时支持i386 x86_64 armv7 arm64了。

    Platinum.framework和Neptune.framework的使用

    你可以直接把这两个framework文件直接拖入项目中,并在提示时选择Copy Items if needed,然后点击finished完成导入。

    然后到项目对应Target下的Build Phases|Link Binary With Libraries下确保PlatinumNeptune两个framework都在列表中。

    由于iOS新版本支持了动态链接库,而我们上述过程默认生成的也是动态的framework, 所以还需要在Target的General | Embedded Binaries 中同样的添加上述的两个framework,以使我们在安装应用的同时,也将对应的动态库拷贝到机器中去,否则会由于机器上缺少对应framework而报错。

    在项目中使用framework的头文件,需要使用尖括号<header.h>而非双引号"header.h"

    这样,你就可以使用自己编译好的framework了。

    对库的熟悉过程

    首先是对三方库的使用,来理解接口调用方式。还好库里提供了几个例子程序,先慢慢看了三天。移植了其中一个关于媒体控制器的示例到项目中,仅仅实现了查找附近设备的功能。但这是个好的开头,对我来说有相当的鼓励作用。开发过程中主要是参照MicroMediaController的代码进行的。

    我发现对于优质C++库的学习,真是一种赏心悦目的体验,当然看懂C++的细节还是相当痛苦的。

    这个Platinum库应该是遵循dlna协议编写的,相关的文档很少,项目属于自注释型的,也就是说,代码中的注释就是文档的大部分,不过要学习这个库,dlan协议还是有必要详细看看的,否则即使通过修改程序,达到了最初设定的功能目标,想要扩展一些功能,却是会边参数都不会传递的,因为这些参数是在协议是规定的。

    在接口封闭的过程中,发现参考别人的封闭方法实在能够学习很多,比例我在用Objective-C封C++接口的过程中,就参考了Platinum项目目录下Platinum/Source/Extras/ObjectiveC/MediaServer的封装方法。

    未完,待续…

    #issue1

    在识别小米盒子的时候,总是识别不到,修改了Platinum中的部分代码,并重新编译后导入项目,得以正常识别:

    修改前

    PltCtrlPoint.cpp

    class PLT_DeviceReadyIterator { public: PLT_DeviceReadyIterator() {} NPT_Result operator()(PLT_DeviceDataReference& device) const { NPT_Result res = device->m_Services.ApplyUntil( PLT_ServiceReadyIterator(), NPT_UntilResultNotEquals(NPT_SUCCESS)); if (NPT_FAILED(res)) return res; res = device->m_EmbeddedDevices.ApplyUntil( PLT_DeviceReadyIterator(), NPT_UntilResultNotEquals(NPT_SUCCESS)); if (NPT_FAILED(res)) return res; // a device must have at least one service or embedded device // otherwise it's not ready if (device->m_Services.GetItemCount() == 0 && device->m_EmbeddedDevices.GetItemCount() == 0) { return NPT_FAILURE; } return NPT_SUCCESS; } };

    修改后

    PltCtrlPoint.cpp

    class PLT_DeviceReadyIterator { public: PLT_DeviceReadyIterator() {} NPT_Result operator()(PLT_DeviceDataReference& device) const { NPT_Result res = device->m_Services.ApplyUntil( PLT_ServiceReadyIterator(), NPT_UntilResultNotEquals(NPT_SUCCESS)); // if (NPT_FAILED(res)) return res; res = device->m_EmbeddedDevices.ApplyUntil( PLT_DeviceReadyIterator(), NPT_UntilResultNotEquals(NPT_SUCCESS)); // if (NPT_FAILED(res)) return res; if(NPT_FAILED(res) && NPT_FAILED(res)) return res; // a device must have at least one service or embedded device // otherwise it's not ready if (device->m_Services.GetItemCount() == 0 && device->m_EmbeddedDevices.GetItemCount() == 0) { return NPT_FAILURE; } return NPT_SUCCESS; } };

    修改原因

    我发现对于搜索到的小米盒子,代码过不了下面这个函数的第55行:

    PltCtrlPoint.cpp

    /*---------------------------------------------------------------------- | PLT_CtrlPoint::ProcessGetSCPDResponse +---------------------------------------------------------------------*/
    NPT_Result
    PLT_CtrlPoint::ProcessGetSCPDResponse(NPT_Result                    res, 
                                          const NPT_HttpRequest&        request,
                                          const NPT_HttpRequestContext& context,
                                          NPT_HttpResponse*             response,
                                          PLT_DeviceDataReference&      device)
    {
        NPT_COMPILER_UNUSED(context);
    
        NPT_AutoLock lock(m_Lock);
    
        PLT_DeviceReadyIterator device_tester;
        NPT_String              scpd;
        PLT_DeviceDataReference root_device;
        PLT_Service*            service;
    
        NPT_String prefix = NPT_String::Format("PLT_CtrlPoint::ProcessGetSCPDResponse for a service of device \"%s\" @ %s (result = %d, status = %d)", 
            (const char*)device->GetFriendlyName(), 
            (const char*)request.GetUrl().ToString(),
            res,
            response?response->GetStatusCode():0);
    
        // verify response was ok
        NPT_CHECK_LABEL_FATAL(res, bad_response);
        NPT_CHECK_POINTER_LABEL_FATAL(response, bad_response);
    
        PLT_LOG_HTTP_RESPONSE(NPT_LOG_LEVEL_FINER, prefix, response);
    
        // make sure root device hasn't disappeared
        NPT_CHECK_LABEL_WARNING(FindDevice(device->GetUUID(), root_device, true),
                                bad_response);
    
        res = device->FindServiceBySCPDURL(request.GetUrl().ToRequestString(), service);
        NPT_CHECK_LABEL_SEVERE(res, bad_response);
    
        // get response body
        res = PLT_HttpHelper::GetBody(*response, scpd);
        NPT_CHECK_LABEL_FATAL(res, bad_response);
    
        // DIAL support
        if (root_device->GetType().Compare("urn:dial-multiscreen-org:device:dial:1") == 0) {
            AddDevice(root_device);
            return NPT_SUCCESS;
        }
    
        // set the service scpd
        res = service->SetSCPDXML(scpd);
        NPT_CHECK_LABEL_SEVERE(res, bad_response);
    
        // if root device is ready, notify listeners about it and embedded devices
        if (NPT_SUCCEEDED(device_tester(root_device))) {
            AddDevice(root_device);
        }
    
        return NPT_SUCCESS;
    
    bad_response:
        NPT_LOG_SEVERE_2("Bad SCPD response for device \"%s\":%s", 
            (const char*)device->GetFriendlyName(),
            (const char*)scpd);
    
        if (!root_device.IsNull()) RemoveDevice(root_device);
        return res;
    }

    #issue2

    个人发现小米盒子对于dlan协议实现部分的静音控制命令似乎有些出入,我使用示例程序发送静音命令到小米盒子,发现只能使设备静音,却不能使设备恢复声音,这个问题有待进一步确认。

    展开全文
  • DLNA技术浅析

    千次阅读 2012-04-12 08:46:28
    首先推荐给大家DLNA的官网,可以了解更新更全的资料。... DLNA(Digital Living Network Alliance) 由索尼、英特尔、微软等发起成立、该组织机构成立的目的解决个人PC,消费电器,移动设备在内的无线网络和有线网络的...

    首先推荐给大家DLNA的官网,可以了解更新更全的资料。http://www.dlna.org/

    DLNA(Digital Living Network Alliance) 由索尼、英特尔、微软等发起成立、该组织机构成立的目的解决个人PC,消费电器,移动设备在内的无线网络和有线网络的互联互通,使得数字媒体和内容服务的无限制的共享。DLNA是一种在家庭网络中实现数据共享的一种工业标准。

      DLNA(数字生活网络联盟)是一种解决的方案,一种大家可以遵守的规范,是一种标准化的尝试。其选择的各种技术和协议都是目前所应用很广泛的技术和协议。

                                                                                    

    DLNA标准定义了以下几种主要的产品类型:

      Digital Media Server(DMS)-提供了媒体档案的获取、录制、储存以及作为源头的能力。当然,有需要的话,多媒体档案的版权保护机制也可以被包含在内。DMS将会提供多媒体档案伺服的能力,提供诸如多种数字媒体播放装置的直接获取内容以及播放能力。这类型的装置包含了机上盒、录放影机、具有多媒体服务器功能的个人电脑、内含硬盘的家庭剧院、广播接收器、影像撷取装置等。

      Digital Media Player(DMP)-这种装置泛指可线上寻找并播放或输出任何由DMS所提供的媒体档案的能力。某些DMP装置包含了电视、家庭剧院、打印机、PDA、多媒体手机、无线萤幕以及某些游乐器终端等。

      Digital Media Render (DMR)- 这种装置属于消费类电子设备,通过有线或无线家庭网络从计算机接收数字媒体流。有些 DMR 集成了显示屏和扬声器。有些 DMR 必须连接到外部输出设备,例如电视、有源音箱或立体声系统。

      媒体中继装置:传送或接收从服务器来的媒体档案到另一设备上,做为多媒体格式的通用化。以备之后储存或上传下载之用。

      Digital Media Controller(DMC)-作为遥控装置使用,可寻找DMS上可播放的媒体档案,并指定到可播放该内容的终端播放装置进行播放的动作。此类装置不仅只限定于遥控功能,具备基本操作介面的智慧型终端装置也可以当作DMC使用。

      Digital Media Printer(DMPr)-可以在DLNA网络架构下提供打印功能的打印机,可提供打印图片或图文穿插文件的功能,DMPr也提供了图形范本的功能,可以让打印图形输出为标准的格式。基本上,DMPr功能就与传统USB打印机类似。

    DLNA的传输层定义

      DLNA标准是基于远有网络架构上的中界层,主要是能让支持此层定义的设备可以相互沟通,而不需另外做其他的设定动作,以1.0版的DLNA标准来说,就支持了Ethernet(IEEE803.3u)与Wi-Fi(802.11 a/b/g),作为DLNA标准设备,网络的支持算是必备的。  至于在各设备之间的相互侦测,则是采用UPnP标准。DMP设备通过UpnP机制来搜寻网络上可相互匹配的DMS装置,成功连接之后便可以进行后续的播放或传输动作。这个动作是全自动的,因此使用者无须进行任何干涉。而在媒体内容的发现方面,也同样是采用UPnP机制。而在传输上,目前仍仅止于支持HTTP标准协议,随后的版本才会将RTP(Real-time Transport Protocol)传输协议加入。

      而在可传输的多媒体格式上,则分为必备支持以及可自选支持两方面,在必备支持方面,图形档案格式为JPG、音效格式为LPCM,影片格式为MPEG-2。而在可选择格式方面,图形档案为PNG、GIF与TIFF,音效压缩格式则是AAC、AC-3、ATRAC3Plus、MP3、WMA9等等,至于在影片压缩格式上,则是包含了MPEG-1、MPEG-4、AVC以及WMV9等等,由于目前网络传输速度还有待突破,因此厂商大多也偏向于支持高压缩比的压缩格式。

      DLNA将其整个应用规定成5个功能组件。从下到上依次为:网络互连,网络协议,媒体传输,设备的发现控制和管理,媒体格式。见图1和表1。以下将针对每个功能组件作进一步的阐述。
      1.网络互连。其规定了所接入网络的类型和协议。目前,主要包括:
      有线网络:802.3.i/u
      无线网络:802.11/a/b/g

      2.网络协议。其规定了所使用的网络协议。目前,其规定必须支持IPv4。但是,考虑到地址空间等IPv4的缺点,将在不久的将来支持IPv6。当然,考虑已经存在的IPv4的诸多应用和设备。在未来的很长一段时间内同时支持IPv4和IPv6并保证IPv4和IPv6的互连的双重协议栈将会受到亲赖。

      3.媒体传输。其规定了所有DLNA设备都必须支持使用HTTP协议进行媒体的传输。这将使得未来很长一段时间如何提高HTTP协议上高速安全的进行大数据量的传输成为一个课题。单纯就安全而然,TLS也许是个不错的选择。另外,在IPv6的协议中IPSEC已经成为了一个必选项。这也在一定程度上解决了安全问题。不过好像使用软件做加解密的工作始终都不是个正确的选择。因为,在真正的应用中,很少有客户不对你的速度指手画脚。当然,同时你也可以使用 RTP的其他专用的媒体流传输协议。但是,前提是你已经支持了HTTP协议下的传输。

      4.设备的发现,控制和媒体的管理。这个功能组件是最重要的一个层次。也许是由于英特尔是UPnP的发起者吧,所以,在其再次发起DLNA的时候,UPnP所有的东西当然其不会浪费了呀。是不是因为 UPnP很长时间停留在协议阶段,很少有应用,IDG是个例外,英特尔才又来发起DLNA的呢,我是不得而知了:)目前,其采用了UPnP Device Architecture 1.0和UPnP AV 1.0 and UPnP Printer:1。这只是UPnP论坛上一堆标准中的冰山一角了。将其UPnP的东西,好像还是蛮多的,这里就不详细讲了。总之,其通过一系列的步骤和协议来达到设备的发现和管理,同时也通过厂商定义的AV和Printer标准达到对媒体的管理。一大堆的概念和名词,下次再介绍了:)

      5.媒体格式。这是最后的一个组件了。其规定了进行数字媒体和内容的共享和使用的时候的媒体格式。其必须支持的是:JPEG, LPCM, MPEG2。其他可选的媒体格式见表2。

                                                


    仅就技术而言,DLNA离我们应该说很近了。但是,这里面还有很多商业上的因素。所以,DLNA离我们还有一段距离。

    DLNA的远景相当被看好,目前用于解决设备沟通的方式也相当合宜,只是目前DLNA在标准规范方面还有些许不足,比如说在多媒体档案的数字版权保护机制上仍相当缺乏,而DLNA网络也缺乏安全防护能力,也容易让骇客或病毒、木马等入侵,造成整个DLNA环境的隐忧。加上网络架构对于即时影音播放方面的能力还有待加强,即使加入了QoS机制,但是在总体频宽未有突破之前(比如说新的802.11n标准通过),同时进行多方的高画质影音播放,仍是相当难以达成的。

    展开全文
  • SSDP能够在局域网能简单地发现设备提供的服务。SSDP有两种发现方式:主动通知和搜索响应方式。 寻址 UPnP 技术是架构在 IP 网络之上。因此拥有一个网络中唯一的 IP 地址是 UPnP 设备正常工作的基础。...

    SSDP能够在局域网能简单地发现设备提供的服务。SSDP有两种发现方式:主动通知和搜索响应方式。

    寻址

    UPnP 技术是架构在 IP 网络之上。因此拥有一个网络中唯一的 IP 地址是 UPnP 设备正常工作的基础。UPnP 设备首先查看网络中是否有 DHCP 服务器,如果有,那么使用 DHCP 分配的 IP 即可;如果没有,则需要使用LLA技术来为自己找适合的IP地址。


    另外,在 UPnP 运行过程中,UPnP 设备都需要周期性检测网络中是否有 DHCP 服务器存在,一旦发现有 DHCP 服务器,就必须终止使用 LLA 技术获取的 IP 地址,改用 DHCP 分配的 IP 地址。


    发现


    SSDP

    SSDP:Simple Sever Discovery Protocol,简单服务发现协议,此协议为网络客户提供一种无需任何配置、管理和维护网络设备服务的机制。此协议采用基于通知和发现路由的多播发现方式实现。协议客户端在保留的多播地址:239.255.255.250:1900(IPV4)发现服务,(IPv6 是:FF0x::C)同时每个设备服务也在此地址上上监听服务发现请求。如果服务监听到的发现请求与此服务相匹配,此服务会使用单播方式响应。

    常见的协议请求消息有两种类型,第一种是服务通知,设备和服务使用此类通知消息声明自己存在;第二种是查询请求,协议客户端用此请求查询某种类型的设备和服务。

    iOS中使用GCDAsyncUdpSocket发送和接受SSDP请求、响应及通知,安卓也需要用类此框架来完成

    所以我们发现设备也有两种方法

    1. 主动通知方式:当设备加入到网络中,向网络上所有控制点通知它所提供的服务,通知消息采用多播方式。
    2. 搜索——响应方式:当一个控制点加入到网络中,在网络搜索它感兴趣的所有设备和服务,搜索消息采用多播方式发送,而设备针对搜索的响应则是使用单播方式发送。

    SSDP 设备类型及服务类型


       
       
       
       
       
       
       
       
       
    设备类型 表示文字
    UPnP_RootDevice upnp:rootdevice
    UPnP_InternetGatewayDevice1 urn:schemas-upnp-org:device:InternetGatewayDevice:1
    UPnP_WANConnectionDevice1 urn:schemas-upnp-org:device:WANConnectionDevice:1
    UPnP_WANDevice1 urn:schemas-upnp-org:device:WANConnectionDevice:1
    UPnP_WANCommonInterfaceConfig1 urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1
    UPnP_WANIPConnection1 urn:schemas-upnp-org:device:WANConnectionDevice:1
    UPnP_Layer3Forwarding1 urn:schemas-upnp-org:service:WANIPConnection:1
    UPnP_WANConnectionDevice1 urn:schemas-upnp-org:service:Layer3Forwarding:1
    服务类型 表示文字
    UPnP_MediaServer1 urn:schemas-upnp-org:device:MediaServer:1
    UPnP_MediaRenderer1 urn:schemas-upnp-org:device:MediaRenderer:1
    UPnP_ContentDirectory1 urn:schemas-upnp-org:service:ContentDirectory:1
    UPnP_RenderingControl1 urn:schemas-upnp-org:service:RenderingControl:1
    UPnP_ConnectionManager1 urn:schemas-upnp-org:service:ConnectionManager:1
    UPnP_AVTransport1 urn:schemas-upnp-org:service:AVTransport:1

    主动通知方式

    当设备添加到网络后,定期向(239.255.255.250:1900)发送SSDP通知消息宣告自己的设备和服务。

    宣告消息分为 ssdp:alive(设备可用)ssdp:byebye(设备不可用)

    ssdp:alive 消息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    NOTIFY * HTTP/1.1           // 消息头
    NT:                         // 在此消息中,NT头必须为服务的服务类型。(如:upnp:rootdevice)
    HOST:                       // 设置为协议保留多播地址和端口,必须是:239.255.255.250:1900(IPv4)或FF0x::C(IPv6
    NTS:                        // 表示通知消息的子类型,必须为ssdp:alive
    LOCATION:                   // 包含根设备描述得URL地址  device 的webservice路径(如:http://127.0.0.1:2351/1.xml) 
    CACHE-CONTROL:              // max-age指定通知消息存活时间,如果超过此时间间隔,控制点可以认为设备不存在 (如:max-age=1800)
    SERVER:                     // 包含操作系统名,版本,产品名和产品版本信息( 如:Windows NT/5.0, UPnP/1.0)
    USN:                        // 表示不同服务的统一服务名,它提供了一种标识出相同类型服务的能力。如:
                                // 根/启动设备 uuid:f7001351-cf4f-4edd-b3df-4b04792d0e8a::upnp:rootdevice
                                // 连接管理器  uuid:f7001351-cf4f-4edd-b3df-4b04792d0e8a::urn:schemas-upnp-org:service:ConnectionManager:1
                                // 内容管理器 uuid:f7001351-cf4f-4edd-b3df-4b04792d0e8a::urn:schemas-upnp-org:service:ContentDirectory:1
    

    ssdp:byebye 消息

    当设备即将从网络中退出时,设备需要对每一个未超期的 ssdp:alive 消息多播形式发送ssdp:byebye 消息,其格式如下:

    1
    2
    3
    4
    
    NOTIFY * HTTP/1.1       // 消息头
    HOST:                   // 设置为协议保留多播地址和端口,必须是:239.255.255.250:1900(IPv4)或FF0x::C(IPv6
    NTS:                    // 表示通知消息的子类型,必须为ssdp:byebye
    USN:                    // 同上
    

    搜索——响应方式

    当控制点,如手机客户端,加入到网络中,可以通过多播搜索消息来寻找网络上感兴趣的设备。我写DLNA模块时候也用主动搜索方式来发现设备。主动搜索可以使用多播方式在整个网络上搜索设备和服务,也可以使用单播方式搜索特定主机上的设备和服务。

    多播搜索消息

    一般情况我们使用多播搜索消息来搜索所有设备即可。多播搜索消息如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    M-SEARCH * HTTP/1.1             // 请求头 不可改变
    MAN: "ssdp:discover"            // 设置协议查询的类型,必须是:ssdp:discover
    MX: 5                           // 设置设备响应最长等待时间,设备响应在0和这个值之间随机选择响应延迟的值。这样可以为控制点响应平衡网络负载。
    HOST: 239.255.255.250:1900      // 设置为协议保留多播地址和端口,必须是:239.255.255.250:1900(IPv4)或FF0x::C(IPv6
    ST: upnp:rootdevice             // 设置服务查询的目标,它必须是下面的类型:
                                    // ssdp:all  搜索所有设备和服务 
                                    // upnp:rootdevice  仅搜索网络中的根设备 
                                    // uuid:device-UUID  查询UUID标识的设备 
                                    // urn:schemas-upnp-org:device:device-Type:version  查询device-Type字段指定的设备类型,设备类型和版本由UPNP组织定义。 
                                    // urn:schemas-upnp-org:service:service-Type:version  查询service-Type字段指定的服务类型,服务类型和版本由UPNP组织定义。
    

    如果需要实现投屏,则设备类型 STurn:schemas-upnp-org:service:AVTransport:1

    多播搜索响应

    多播搜索 M-SEARCH 响应与通知消息很类此,只是将NT字段作为ST字段。响应必须以一下格式发送:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    HTTP/1.1 200 OK             // * 消息头
    LOCATION:                   // * 包含根设备描述得URL地址  device 的webservice路径(如:http://127.0.0.1:2351/1.xml) 
    CACHE-CONTROL:              // * max-age指定通知消息存活时间,如果超过此时间间隔,控制点可以认为设备不存在 (如:max-age=1800)
    SERVER:                     // 包含操作系统名,版本,产品名和产品版本信息( 如:Windows NT/5.0, UPnP/1.0)
    EXT:                        // 为了符合HTTP协议要求,并未使用。
    BOOTID.UPNP.ORG:            // 可以不存在,初始值为时间戳,每当设备重启并加入到网络时+1,用于判断设备是否重启。也可以用于区分多宿主设备。
    CONFIGID.UPNP.ORG:          // 可以不存在,由两部分组成的非负十六进制整数,由两部分组成,第一部分代表跟设备和其上的嵌入式设备,第二部分代表这些设备上的服务。
    USN:                        // * 表示不同服务的统一服务名
    ST:                         // * 服务的服务类型
    DATE:                       // 响应生成时间
    

    其中主要关注带有 * 的部分即可。这里还有一个大坑,有些设备返回来的字段名称可能包含有小写,如LOCATION和Location,需要做处理。
    此外还需根据LOCATION保存设备的IP和端口地址。
    响应例子如下:

    1
    2
    3
    4
    5
    6
    7
    8
    
    HTTP/1.1 200 OK
    Cache-control: max-age=1800
    Usn: uuid:88024158-a0e8-2dd5-ffff-ffffc7831a22::urn:schemas-upnp-org:service:AVTransport:1
    Location: http://192.168.1.243:46201/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/desc.xml
    Server: Linux/3.10.33 UPnP/1.0 Teleal-Cling/1.0
    Date: Tue, 01 Mar 2016 08:47:42 GMT+00:00
    Ext: 
    St: urn:schemas-upnp-org:service:AVTransport:1
    

    描述

    控制点发现设备之后仍然对设备知之甚少,仅能知道UPnP类型,UUID和设备描述URL。为了进一步了解设备和服务,需要获取并解析XML描述文件。
    描述文件有两种类型:
    设备描述文档(DDD)服务描述文档(SDD)

    设备描述文档

    设备描述文档是对设备的基本信息描述,包括厂商制造商信息、设备信息、设备所包含服务基本信息等。

    设备描述采用XML格式,可以通过HTTP GET请求获取。其链接为设备发现消息中的Location。如上述设备的描述文件获取请求为

    1
    2
    
    GET http://192.168.1.243:46201/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/desc.xml HTTP/1.1
    HOST: 192.168.1.243:46201
    

    设备响应如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    
    HTTP/1.1 200 OK
    Content-Length    : 3612
    Content-type      : text/xml
    Date              : Tue, 01 Mar 2016 10:00:36 GMT+00:00
    
    <?xml version="1.0" encoding="UTF-8"?>
    <root xmlns="urn:schemas-upnp-org:device-1-0" xmlns:qq="http://www.tencent.com">
        <specVersion>
            <major>1</major>
            <minor>0</minor>
        </specVersion>
        <device>
            <deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
            <UDN>uuid:88024158-a0e8-2dd5-ffff-ffffc7831a22</UDN>
            <friendlyName>客厅的小米盒子</friendlyName>
            <qq:X_QPlay_SoftwareCapability>QPlay:1</qq:X_QPlay_SoftwareCapability>
            <manufacturer>Xiaomi</manufacturer>
            <manufacturerURL>http://www.xiaomi.com/</manufacturerURL>
            <modelDescription>Xiaomi MediaRenderer</modelDescription>
            <modelName>Xiaomi MediaRenderer</modelName>
            <modelNumber>1</modelNumber>
            <modelURL>http://www.xiaomi.com/hezi</modelURL>
            <serialNumber>11262/180303452</serialNumber>
            <presentationURL>device_presentation_page.html</presentationURL>
            <UPC>123456789012</UPC>
            <dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMR-1.50</dlna:X_DLNADOC>
            <dlna:X_DLNACAP xmlns:dlna="urn:schemas-dlna-org:device-1-0">,</dlna:X_DLNACAP>
            <iconList>
                <icon>
                    <mimetype>image/png</mimetype>
                    <width>128</width>
                    <height>128</height>
                    <depth>8</depth>
                    <url>icon/icon128x128.png</url>
                </icon>
            </iconList>
            <serviceList>
                <service>
                    <serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
                    <serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
                    <controlURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/AVTransport/action</controlURL>
                    <eventSubURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/AVTransport/event</eventSubURL>
                    <SCPDURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/AVTransport/desc.xml</SCPDURL>
                </service>
                <service>
                    <serviceType>urn:schemas-upnp-org:service:RenderingControl:1</serviceType>
                    <serviceId>urn:upnp-org:serviceId:RenderingControl</serviceId>
                    <controlURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/RenderingControl/action</controlURL>
                    <eventSubURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/RenderingControl/event</eventSubURL>
                    <SCPDURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/RenderingControl/desc.xml</SCPDURL>
                </service>
                <service>
                    <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
                    <serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
                    <controlURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/ConnectionManager/action</controlURL>
                    <eventSubURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/ConnectionManager/event</eventSubURL>
                    <SCPDURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/ConnectionManager/desc.xml</SCPDURL>
                </service>
                <service>
                    <serviceType>urn:mi-com:service:RController:1</serviceType>
                    <serviceId>urn:upnp-org:serviceId:RController</serviceId>
                    <controlURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/RController/action</controlURL>
                    <eventSubURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/RController/event</eventSubURL>
                    <SCPDURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/RController/desc.xml</SCPDURL>
                </service>
            </serviceList>
            <av:X_RController_DeviceInfo xmlns:av="urn:mi-com:av">
                <av:X_RController_Version>1.0</av:X_RController_Version>
                <av:X_RController_ServiceList>
                    <av:X_RController_Service>
                        <av:X_RController_ServiceType>controller</av:X_RController_ServiceType>
                        <av:X_RController_ActionList_URL>http://192.168.1.243:6095/</av:X_RController_ActionList_URL>
                    </av:X_RController_Service>
                    <av:X_RController_Service>
                        <av:X_RController_ServiceType>data</av:X_RController_ServiceType>
                        <av:X_RController_ActionList_URL>http://api.tv.duokanbox.com/bolt/3party/</av:X_RController_ActionList_URL>
                    </av:X_RController_Service>
                </av:X_RController_ServiceList>
            </av:X_RController_DeviceInfo>
        </device>
    </root>
    

    其中响应消息体为XML格式的设备描述内容。信息结构比较明确,就不一一介绍了。解析该XML,保存设备的一些基本信息如deviceTypefriendlyNameiconList 等。之后我们关注该设备提供的服务列表,投屏最关注的服务为urn:schemas-upnp-org:service:AVTransport:1:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    <?xml version="1.0" encoding="UTF-8"?>
    <root xmlns="urn:schemas-upnp-org:device-1-0" xmlns:qq="http://www.tencent.com">
        <device>
            <serviceList>
                <service>
                    <serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
                    <serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
                    <controlURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/AVTransport/action</controlURL>
                    <eventSubURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/AVTransport/event</eventSubURL>
                    <SCPDURL>/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/AVTransport/desc.xml</SCPDURL>
                </service>
            </serviceList>
        </device>
    </root>
    

    如只需要实现简单的投屏,则保存urn:schemas-upnp-org:service:AVTransport:1服务的上述信息即可。如需要进一步了解该服务,则需要获取并解析服务描述文档。

    坑点1:有些设备 SCPDURLcontrolURLeventSubURL 开头包含/ ,有些设备不包含,拼接URL时需要注意。

    服务描述文档

    为了实现简单的投屏和控制(播放、暂停、停止、快进)操作并不需要解析服务描述文件。所有动作均为UPnP规范动作,具体动作请求参见基于DLNA实现iOS,Android投屏:SOAP控制设备

    服务描述文档是对服务功能的基本说明,包括服务上的动作及参数,还有状态变量和其数据类型、取值范围等。

    和设备描述文档一致,服务描述文档也是采用XML语法,并遵守标准UPnP服务schema文件格式要求。获取上述服务SDD语法如下:

    1
    2
    
    GET http://192.168.1.243:46201/dev/88024158-a0e8-2dd5-ffff-ffffc7831a22/svc/upnp-org/AVTransport/desc.xml
    HOST: 192.168.1.243:46201
    

    设备响应如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    
    HTTP/1.1 200 OK
    Content-Length    : 3612
    Content-type      : text/xml
    Date              : Tue, 01 Mar 2016 10:00:36 GMT+00:00
    <!-- 省略了部分动作和状态变量 -->
    <?xml version="1.0" encoding="UTF-8"?>
    <scpd xmlns="urn:schemas-upnp-org:service-1-0">
        <specVersion>
            <major>1</major>
            <minor>0</minor>
        </specVersion>
        <actionList>
            <action>
                <name>Pause</name>
                <argumentList>
                    <argument>
                        <name>InstanceID</name>
                        <direction>in</direction>
                        <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                    </argument>
                </argumentList>
            </action>
            <action>
                <name>Play</name>
                <argumentList>
                    <argument>
                        <name>InstanceID</name>
                        <direction>in</direction>
                        <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                    </argument>
                    <argument>
                        <name>Speed</name>
                        <direction>in</direction>
                        <relatedStateVariable>TransportPlaySpeed</relatedStateVariable>
                    </argument>
                </argumentList>
            </action>
            <action>
                <name>Previous</name>
                <argumentList>
                    <argument>
                        <name>InstanceID</name>
                        <direction>in</direction>
                        <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                    </argument>
                </argumentList>
            </action>
            <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>
            ...
        </actionList>
        <serviceStateTable>
            <stateVariable sendEvents="no">
                <name>CurrentTrackURI</name>
                <dataType>string</dataType>
            </stateVariable>
            <stateVariable sendEvents="no">
                <name>CurrentMediaDuration</name>
                <dataType>string</dataType>
            </stateVariable>
            <stateVariable sendEvents="no">
                <name>AbsoluteCounterPosition</name>
                <dataType>i4</dataType>
            </stateVariable>
            <stateVariable sendEvents="no">
                <name>RelativeCounterPosition</name>
                <dataType>i4</dataType>
            </stateVariable>
            <stateVariable sendEvents="no">
                <name>A_ARG_TYPE_InstanceID</name>
                <dataType>ui4</dataType>
            </stateVariable>
            ...
        </serviceStateTable>
    </scpd>
    

    • actionList 目前服务上所包含的动作列表。
    • actionList 目前服务上所包含的状态变量。

    以Pause动作为例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    <?xml version="1.0" encoding="UTF-8"?>
    <scpd xmlns="urn:schemas-upnp-org:service-1-0">
        <actionList>
            <action>
                <!-- 动作名称 -->
                <name>Pause</name>
                <!-- 参数列表 -->
                <argumentList>
                    <argument>
                        <!-- 参数名称 -->
                        <name>InstanceID</name>
                        <!-- 输出或输出-->
                        <direction>in</direction>
                        <!-- 声明参数有关的状态变量 -->
                        <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>
                    </argument>
                </argumentList>
            </action>
            ...
        </actionList>
        <serviceStateTable>
        <!-- 状态变量 -->
            <stateVariable>
                <!-- 是否发送事件消息,如果为yes则该状态变量发生变化时生成事件消息。 -->
                <stateVariable sendEvents="no">
                <!-- 状态变量名称 -->
                <name>A_ARG_TYPE_InstanceID</name>
                <!-- 状态数据类型 -->
                <dataType>ui4</dataType>
            </stateVariable>
            ...
        </serviceStateTable>
    </scpd>
    

    为了实现简单的投屏和控制(播放、暂停、停止、快进)操作并不需要解析服务描述文件。所有动作均为UPnP规范动作,具体动作请求参见基于DLNA实现iOS,Android投屏:SOAP控制设备


    展开全文
  • DLNA DMR实现

    千次阅读 2015-09-28 12:07:23
    由于机顶盒行业的管制日趋严厉,从手机上推送视频到电视上观看成为一个需求,所以需要开发一...DLNA协议是建立在UPnP协议的基础上的,它依靠UPnP协议来完成设备的搜索、发现和控制,DLNA协议在此基础上对多媒体设备进行
  • 版权声明:本文为博主原创文章,未经博主允许不得转载 *作者:MingChaoSun *博客地址:http://blog.csdn.net/sunmc1204953974 https://blog.csdn.net/sunmc1204953974/article/details/39611357 ...
  • 在android系统中开发DLNA

    千次阅读 2017-09-19 21:12:31
     内容目录 Part 1.... Part 2.... Part 2....Part 1.... DLNA,Digital Living Network Alliance的简称,意在解决pc,家电,移动设备在局域网内的多媒体共享(音频,视频,图片)。说DLNA是多屏互动,太牵强了,专业点来...
  • Airplay、DLNA和Miracast三种技术的介绍

    万次阅读 2018-03-13 15:50:48
    Airplay、DLNA和Miracast三种技术的介绍AirPlayAirPlay 是苹果开发的一种无线技术,可以通过WiFi将iPhone 、iPad、iPod touch 等iOS 设备上的包括图片、音频、视频通过无线的方式传输到支持AirPlay 设备。...
  • Airplay vs DLNA vs Miracast

    千次阅读 2015-08-04 15:04:00
    之前在关注电视机和手机的时候,看到过一些地方提到: DLNA 以及多屏幕共享。 最典型的的莫过于: 手机上显示任何内容,都可以投放到电视的大屏幕上,比如手上上的图片放到电视上看,手机上的游戏,放到电视上显示,...
  • Android DLNA投屏-基本原理

    千次阅读 2019-07-24 10:28:38
    1. DLNA简介 DLNA(Digital Living Network Alliance),即数字家庭网络联盟。 DLNA不是技术,而是一种解决方案,它...DLNA包含多种网络协议,如http、https、upnp等,其中upnp是其重要组成部分。 DLNA主要包含以...
  • Cling 源码解析

    2017-04-12 15:21:03
    DLAN学习
  • AirPlay、DLNA、Miracast三大无线技术介绍 收藏人:礁石浪花 2014-03-11 | 阅:188 转:1   | 来源  | 分享  ... 
1 2 3
收藏数 47
精华内容 18
关键字:

dlan协议 ios