DLNA(一)

导读:
本文集主要讲的是,dlna的投屏底层的原理,以及一步步的教你实现,对网络图片/视频或者本地的图片/视频的投屏到电视盒子上面(demo里面用的是电信的悦me盒子

PS由于第一次接触投屏,我只讲我自己的理解,以及自己项目里面的所使用的功能模块,如有理解不到位的,可以一起交流学习下。🐶🐶🐶

主要参考:

说明:
对于投屏功能,本文主要是利用的iOS DLNA投屏功能了解一下,里的框架,感谢作者的源码。

我是根据作者的代码,新增了一些实际需要的方法,以及实现了可讲本地图片、视频投影到盒子上面。

具体的代码见gitHubDemo里面的具体的包括实现都有具体的实现


我们从upnp中文文档,可大致可得出下面的流程
1.寻址
2.发现
3.描述
4.控制、事件、展示

下面我结合悦me盒子来做具体的描述
1.寻址:设备通过寻址来获得一个网络地址 (具体的说明见upnp中文文档)
这是设备和路由完成的
2.发现
当设备已经有自己的ip地址(步骤1),那么怎么样才能获取到设备呢?
我们可以通过udp请求,来喊话

发现设备:搜索请求消息字符串

 NSData * sendData = [[self getSearchString] dataUsingEncoding:NSUTF8StringEncoding]; 
 [_udpSocket sendData:sendData toHost:ssdpAddres port:ssdpPort withTimeout:-1 tag:1];
 
 其中:getSearchString为: 
 [NSString stringWithFormat:
 @"M-SEARCH * HTTP/1.1\r\nHOST: %@:%d\r\nMAN: \"ssdp:discover\"\r\nMX: 3\r\nST: %@\r\nUSER-AGENT: iOS UPnP/1.1 mccree/1.0\r\n\r\n",
ssdpAddres, 
ssdpPort, 
serviceType_AVTransport];
-----
ssdpAddres --> @"239.255.255.250";
ssdpPort --> 1900;
serviceType_AVTransport -->@"urn:schemas-upnp-org:service:AVTransport:1";

通过upd来发送消息,此时在同一个局域网的设备,会收到该消息,然后返回自己的设备信息,下面是悦me盒子返回的示例

HTTP/1.1 200 OK
Location: http://192.168.124.43:1266/
Cache-Control: max-age=1800
Server: UPnP/1.0 DLNADOC/1.50 Platinum/1.0.4.2
EXT: 
USN: uuid:skyworth&208B3756FFED&192.168.124.43::urn:schemas-upnp-org:service:AVTransport:1
ST: urn:schemas-upnp-org:service:AVTransport:1
Date: Thu, 24 Jan 2019 02:38:18 GMT

3.描述 我们发现了设备,看第2步只会返回一些基本的信息,我们还需要去获取设备的详细的信息
我们通过向步骤2拿到的location发送get请求
get:http://192.168.124.43:1266/
返回信息如下:

<html>
<head></head>
<body>
 {type:1 name:root xml:&quot;
  <root xmlns="urn:schemas-upnp-org:device-1-0" xmlns:dlna="urn:schemas-dlna-org:device-1-0">
   <specversion>
    <major>
     1
   </major>
   <minor>
     0
   </minor>
 </specversion>
 <device>
  <devicetype>
   urn:schemas-upnp-org:device:MediaRenderer:1
 </devicetype>
 <friendlyname>
   YuemeTV
 </friendlyname>
 <manufacturer>
   GeniusGitHub
 </manufacturer>
 <manufacturerurl>
   https://github.com/geniusgithub
 </manufacturerurl>
 <modeldescription>
   GeniusGitHub AV Media Renderer Device
 </modeldescription>
 <modelname>
   Genius Software
 </modelname>
 <modelurl>
   https://github.com/geniusgithub
 </modelurl>
 <modelnumber>
   20130520
 </modelnumber>
 <serialnumber />
 <udn>
   uuid:skyworth&amp;208B3756FFED&amp;192.168.124.43
 </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/skyworth&amp;208B3756FFED&amp;192.168.124.43/scpd.xml
 </scpdurl>
 <controlurl>
   /AVTransport/skyworth&amp;208B3756FFED&amp;192.168.124.43/control.xml
 </controlurl>
 <eventsuburl>
   /AVTransport/skyworth&amp;208B3756FFED&amp;192.168.124.43/event.xml
 </eventsuburl>
</service>
<service>
  <servicetype>
   urn:schemas-upnp-org:service:ConnectionManager:1
 </servicetype>
 <serviceid>
   urn:upnp-org:serviceId:ConnectionManager
 </serviceid>
 <scpdurl>
   /ConnectionManager/skyworth&amp;208B3756FFED&amp;192.168.124.43/scpd.xml
 </scpdurl>
 <controlurl>
   /ConnectionManager/skyworth&amp;208B3756FFED&amp;192.168.124.43/control.xml
 </controlurl>
 <eventsuburl>
   /ConnectionManager/skyworth&amp;208B3756FFED&amp;192.168.124.43/event.xml
 </eventsuburl>
</service>
<service>
  <servicetype>
   urn:schemas-upnp-org:service:RenderingControl:1
 </servicetype>
 <serviceid>
   urn:upnp-org:serviceId:RenderingControl
 </serviceid>
 <scpdurl>
   /RenderingControl/skyworth&amp;208B3756FFED&amp;192.168.124.43/scpd.xml
 </scpdurl>
 <controlurl>
   /RenderingControl/skyworth&amp;208B3756FFED&amp;192.168.124.43/control.xml
 </controlurl>
 <eventsuburl>
   /RenderingControl/skyworth&amp;208B3756FFED&amp;192.168.124.43/event.xml
 </eventsuburl>
</service>
</servicelist></device>
</root>&quot;}
</body>
</html>

这个格式很清晰地描述了设备的详细信息,比如设备的名字:YuemeTV,设备类型是媒体渲染播放器、制造商相关信息、UUID、以及它提供的服务列表,每个服务都有serviceType, serviceId, SCPDURL, controlURL和eventSubURL等
比如:serviceType为urn:schemas-upnp-org:service:AVTransport:1,表示这个服务提供的是音视频传输服务,版本号是1

4.接下来:我们怎么使用这些服务呢?
SCPDURL这个字段的内容就是提供的使用路径
将:前面拿到的设备 ip和端口 以及SCPDURL字段的内容,拼接成url即可
以 /AVTransport/skyworth&208B3756FFED&192.168.124.43/scpd.xml为例
发送请求:

<html>
 <head></head>
 <body>
  This XML file does not appear to have any style information associated with it. The document tree is shown below. 
  <scpd xmlns="urn:schemas-upnp-org:service-1-0"> 
   <specversion> 
    <major>
     1
    </major> 
    <minor>
     0
    </minor> 
   </specversion> 
   <actionlist> 
    <action> 
     <name>
      GetCurrentTransportActions
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        Actions
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        CurrentTransportActions
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      GetDeviceCapabilities
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        PlayMedia
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        PossiblePlaybackStorageMedia
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        RecMedia
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        PossibleRecordStorageMedia
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        RecQualityModes
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        PossibleRecordQualityModes
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      GetMediaInfo
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        NrTracks
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        NumberOfTracks
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        MediaDuration
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        CurrentMediaDuration
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        CurrentURI
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        AVTransportURI
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        CurrentURIMetaData
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        AVTransportURIMetaData
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        NextURI
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        NextAVTransportURI
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        NextURIMetaData
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        NextAVTransportURIMetaData
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        PlayMedium
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        PlaybackStorageMedium
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        RecordMedium
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        RecordStorageMedium
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        WriteStatus
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        RecordMediumWriteStatus
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      GetPositionInfo
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        Track
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        CurrentTrack
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        TrackDuration
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        CurrentTrackDuration
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        TrackMetaData
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        CurrentTrackMetaData
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        TrackURI
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        CurrentTrackURI
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        RelTime
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        RelativeTimePosition
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        AbsTime
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        AbsoluteTimePosition
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        RelCount
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        RelativeCounterPosition
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        AbsCount
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        AbsoluteCounterPosition
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      GetTransportInfo
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        CurrentTransportState
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        TransportState
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        CurrentTransportStatus
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        TransportStatus
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        CurrentSpeed
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        TransportPlaySpeed
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      GetTransportSettings
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        PlayMode
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        CurrentPlayMode
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        RecQualityMode
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        CurrentRecordQualityMode
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      Next
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <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>
      Seek
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        Unit
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_SeekMode
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        Target
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_SeekTarget
       </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> 
    <action> 
     <name>
      SetPlayMode
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        NewPlayMode
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        CurrentPlayMode
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      Stop
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
   </actionlist> 
   <servicestatetable> 
    <statevariable sendevents="no"> 
     <name>
      CurrentPlayMode
     </name> 
     <datatype>
      string
     </datatype> 
     <defaultvalue>
      NORMAL
     </defaultvalue> 
     <allowedvaluelist> 
      <allowedvalue>
       NORMAL
      </allowedvalue> 
      <allowedvalue>
       REPEAT_ONE
      </allowedvalue> 
      <allowedvalue>
       REPEAT_ALL
      </allowedvalue> 
      <allowedvalue>
       SHUFFLE
      </allowedvalue> 
      <allowedvalue>
       SHUFFLE_NOREPEAT
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      RecordStorageMedium
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       NOT_IMPLEMENTED
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="yes"> 
     <name>
      LastChange
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      RelativeTimePosition
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      CurrentTrackURI
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      CurrentTrackDuration
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      CurrentRecordQualityMode
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       NOT_IMPLEMENTED
      </allowedvalue> 
     </allowedvaluelist> 
    </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> 
    <statevariable sendevents="no"> 
     <name>
      AVTransportURI
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      TransportState
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       STOPPED
      </allowedvalue> 
      <allowedvalue>
       PAUSED_PLAYBACK
      </allowedvalue> 
      <allowedvalue>
       PLAYING
      </allowedvalue> 
      <allowedvalue>
       TRANSITIONING
      </allowedvalue> 
      <allowedvalue>
       NO_MEDIA_PRESENT
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      CurrentTrackMetaData
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      NextAVTransportURI
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      PossibleRecordQualityModes
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       NOT_IMPLEMENTED
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      CurrentTrack
     </name> 
     <datatype>
      ui4
     </datatype> 
     <allowedvaluerange> 
      <minimum>
       0
      </minimum> 
      <maximum>
       65535
      </maximum> 
      <step>
       1
      </step> 
     </allowedvaluerange> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      AbsoluteTimePosition
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      NextAVTransportURIMetaData
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      PlaybackStorageMedium
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       NONE
      </allowedvalue> 
      <allowedvalue>
       UNKNOWN
      </allowedvalue> 
      <allowedvalue>
       CD-DA
      </allowedvalue> 
      <allowedvalue>
       HDD
      </allowedvalue> 
      <allowedvalue>
       NETWORK
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      CurrentTransportActions
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      RecordMediumWriteStatus
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       NOT_IMPLEMENTED
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      PossiblePlaybackStorageMedia
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       NONE
      </allowedvalue> 
      <allowedvalue>
       UNKNOWN
      </allowedvalue> 
      <allowedvalue>
       CD-DA
      </allowedvalue> 
      <allowedvalue>
       HDD
      </allowedvalue> 
      <allowedvalue>
       NETWORK
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      AVTransportURIMetaData
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      NumberOfTracks
     </name> 
     <datatype>
      ui4
     </datatype> 
     <allowedvaluerange> 
      <minimum>
       0
      </minimum> 
      <maximum>
       65535
      </maximum> 
     </allowedvaluerange> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      A_ARG_TYPE_SeekMode
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       REL_TIME
      </allowedvalue> 
      <allowedvalue>
       TRACK_NR
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      A_ARG_TYPE_SeekTarget
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      PossibleRecordStorageMedia
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       NOT_IMPLEMENTED
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      TransportStatus
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       OK
      </allowedvalue> 
      <allowedvalue>
       ERROR_OCCURRED
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      TransportPlaySpeed
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       1
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
   </servicestatetable> 
  </scpd>
 </body>
</html>

该服务提供了一个actionList即动作列表,一个服务会包含一个或多个功能请求动作,如actionList下这个SetAVTransportURI,顾名思义,这个请求的功能是将一个音视频资源的URI发送给渲染端。一个动作(Action)就好比一个API请求,你还需要传递一些要求的参数,这时就会用到该Action后面argumentList里规定的一些Argument。比如根据第一个参数<name>CurrentURI</name>,表示的就是你想发送的URI;同时<direction>in</direction>表示的是这是一个传入参数,如果为out则表示该Action会返回给你这个参数的值. action如:play播放指令,pause暂停指令,获取播放的媒体的信息GetTransportInfo指令等等

5.控制服务controlurl具体的信息
同理4

<html>
 <head></head>
 <body>
  This XML file does not appear to have any style information associated with it. The document tree is shown below. 
  <scpd xmlns="urn:schemas-upnp-org:service-1-0"> 
   <specversion> 
    <major>
     1
    </major> 
    <minor>
     0
    </minor> 
   </specversion> 
   <actionlist> 
    <action> 
     <name>
      GetMute
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        Channel
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_Channel
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        CurrentMute
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        Mute
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      GetVolume
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        Channel
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_Channel
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        CurrentVolume
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        Volume
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      GetVolumeDB
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        Channel
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_Channel
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        CurrentVolume
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        VolumeDB
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      GetVolumeDBRange
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        Channel
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_Channel
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        MinValue
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        VolumeDB
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        MaxValue
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        VolumeDB
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      ListPresets
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        CurrentPresetNameList
       </name> 
       <direction>
        out
       </direction> 
       <relatedstatevariable>
        PresetNameList
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      SelectPreset
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        PresetName
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_PresetName
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      SetMute
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        Channel
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_Channel
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        DesiredMute
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        Mute
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
    <action> 
     <name>
      SetVolume
     </name> 
     <argumentlist> 
      <argument> 
       <name>
        InstanceID
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_InstanceID
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        Channel
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        A_ARG_TYPE_Channel
       </relatedstatevariable> 
      </argument> 
      <argument> 
       <name>
        DesiredVolume
       </name> 
       <direction>
        in
       </direction> 
       <relatedstatevariable>
        Volume
       </relatedstatevariable> 
      </argument> 
     </argumentlist> 
    </action> 
   </actionlist> 
   <servicestatetable> 
    <statevariable sendevents="yes"> 
     <name>
      LastChange
     </name> 
     <datatype>
      string
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      A_ARG_TYPE_Channel
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       Master
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      A_ARG_TYPE_InstanceID
     </name> 
     <datatype>
      ui4
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      Volume
     </name> 
     <datatype>
      ui2
     </datatype> 
     <allowedvaluerange> 
      <minimum>
       0
      </minimum> 
      <maximum>
       100
      </maximum> 
      <step>
       1
      </step> 
     </allowedvaluerange> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      Mute
     </name> 
     <datatype>
      boolean
     </datatype> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      PresetNameList
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       FactoryDefaults
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      A_ARG_TYPE_PresetName
     </name> 
     <datatype>
      string
     </datatype> 
     <allowedvaluelist> 
      <allowedvalue>
       FactoryDefaults
      </allowedvalue> 
     </allowedvaluelist> 
    </statevariable> 
    <statevariable sendevents="no"> 
     <name>
      VolumeDB
     </name> 
     <datatype>
      i2
     </datatype> 
     <allowedvaluerange> 
      <minimum>
       -32767
      </minimum> 
      <maximum>
       32767
      </maximum> 
     </allowedvaluerange> 
    </statevariable> 
   </servicestatetable> 
  </scpd>
 </body>
</html>

里面包含了:设置音量的动作指令:SetVolume、快退进Seek、获取音量GetVolume等等

下面具体怎么控制的呢?详见 DLNA(二)

友情链接:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容