导读:
本文集主要讲的是,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:"
<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&208B3756FFED&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&208B3756FFED&192.168.124.43/scpd.xml
</scpdurl>
<controlurl>
/AVTransport/skyworth&208B3756FFED&192.168.124.43/control.xml
</controlurl>
<eventsuburl>
/AVTransport/skyworth&208B3756FFED&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&208B3756FFED&192.168.124.43/scpd.xml
</scpdurl>
<controlurl>
/ConnectionManager/skyworth&208B3756FFED&192.168.124.43/control.xml
</controlurl>
<eventsuburl>
/ConnectionManager/skyworth&208B3756FFED&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&208B3756FFED&192.168.124.43/scpd.xml
</scpdurl>
<controlurl>
/RenderingControl/skyworth&208B3756FFED&192.168.124.43/control.xml
</controlurl>
<eventsuburl>
/RenderingControl/skyworth&208B3756FFED&192.168.124.43/event.xml
</eventsuburl>
</service>
</servicelist></device>
</root>"}
</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(二)
友情链接: